I've been doing some dabbling with test automation using Ruby and Watir webdriver...I am running into an oddity where I open a new window, but when I act upon it, it performs all my actions behind the parent windowHere's how I set it up (using Firefox if that makes a difference):
# opens new window
b.button(:text => 'Upload').click
b.window(:url => 'urlname'). use do
# action performed on the new window
b.select_list(:id => 'selector').select 'Foo'
end
Note: it correctly performs actions on the select list present, but it does this behind the main browser.Is there something specific I need to write in order for it to remain in front of the main window?
This should work:
b.window(:url => 'urlname').focus
Put that line just after your .use line, and you should see the new window called to the foreground. You may actually find that you don't end up needing the .use line (or the do/end) at all.
Related
I want to make my own window, using Glade (3.14.2).
At a certain point in my program, I want to
1) Put up the window and let the user do stuff
2) Wait for it to close
3) Get values from the window object
4) Continue on in my code
So basically, I want to treat the window like a modal dialog - but one that I write and control.
I've tried for a few hours. The window appears just fine, as designed in Glade. The user can interact with it.
When the window closes, code that's been connected with signal_connect('destroy') executes.
But the code that invoked the window's show() method... does not continue executing after the window closes.
class GrammarNodeEditor
#this makes the class visual:
include GladeGUI
def initialize(raw_node = nil, &close_block)
#raw_node = raw_node || {type: :Sequence, data: []}
#original_data = #raw_node[:data]
#close_block = close_block
end
def show
puts "GNE Window Opening"
load_glade(__FILE__)
#builder["window1"].title = "Edit/Create Grammar Node"
#builder["window1"].signal_connect('destroy') {|*args|
#close_block.call(self)
puts "GNE WINDOW DESTROY"
}
show_window()
puts "Done showing window"
end
Here is how I invoke it:
rhs_editor = GrammarNodeEditor.new {|obj|
puts "In closeblck, obj is #{obj.inspect}"
#rhs = obj.raw_node
}
puts "About to call show in GR:Init"
rhs_editor.show
puts "Back from calling show in GR:Init"
Here is the output:
About to call show in GR:Init
GNE Window Opening
In closeblck, obj is #<GrammarNodeEditor:0x7b82a88 #raw_node={:type=>:Sequence, :data=>[]}, [more junk here]>
GNE WINDOW DESTROY
The first two lines of output appear after I open the window. The 3rd and 4th appear when I close the window.
Note that "Done showing window" and "Back from calling show in GR:Init" are not printed at all.
Just to make this a little more interesting, I want to be able to do this from within code that puts up another window. My top-level window has a button to create a new Rule. The Rule must be initialized with a Node, and then the Rule must be edited. So first I need to put up a Node-definition window (as shown above) and then, when I have a Node defined, I want to put up a Rule window that uses that Node.
So I think I need to call this code within either the initialize() or the show() method of the GrammarRuleWindow class (another Glade-defined window).
Can someone explain why my puts's aren't being printed, and how to make the control flow go on through them?
Thanks!
...So it turned out the problem was that I had created the window's .glade file directly in Glade, rather than using the VisualRuby IDE.
Creating the .glade in VR adds some stuff to the file that VR needs. Specifically, the file needs to contain the line
<signal name="destroy" handler="destroy_window" swapped="no"/>
before the first <child...> tag.
I'm writing tests using Selenium WebDriver and rautomation to handle system popup. I tried it on irb like following:
require 'selenium-webdriver'
require 'rautomation'
driver = Selenium::WebDriver.for :firefox
driver.get "http://rubygems.org/gems/rautomation-0.9.2.gem"
window = RAutomation::Window.new :title => "Opening rautomation-0.9.2.gem"
ok_button = window.button(:text => "&OK")
ok_button.exists?
cancel_button = window.button(:text => "&Cancel")
cancel_button.exists?
ok_button.exists? and cancel_button.exists? are returning false. Hence I can't click on the buttons.
I also tried:
window.buttons.length
to find number of buttons, but it's returning 0.
Could someone please help me why the buttons aren't detected using rautomation? Please correct me if I'm doing something wrong.
Here is a popup:
For my condition, I have to send two :tab key and then send :enter to save the file. like:
driver.get "http://rubygems.org/gems/rautomation-0.9.2.gem"
window = RAutomation::Window.new :title => /Opening/i
if window.exist?
window.activate
window.send_keys :tab;
sleep 2;
window.send_keys :tab;
sleep 2;
window.send_keys :enter
end
I don't know why I can't just save the file with:
window.activate; sleep 1; window.send_keys :enter
The problem with this dialog is that it does not use native Windows controls. When you use Spy++ or AutoIt Window Info Tool then they do not show you any controls in that window either.
When using RAutomation you can check if it has native controls on it or not like this:
win = RAutomation::Window.new :title => /Opening rautomation/
p win.present?
p win.controls.length
p win.text
win.close
The output of this script will be:
true
0
""
In other words - window was present, it had zero controls of any kind and text was an empty string. Also, closing the window really closed it which you can verify visually - this means that we were interacting with the correct window and not accidentally with some other empty window (beware: this might sometimes happen too).
This all means that you cannot interact with the controls directly with AutoIt, RAutomation or many other automation tools. There might be some specific automation tools available for handling these kind of dialogs - i'm not sure.
There is however a workaround how to work with these kind of windows - send needed keystrokes to the window. In this case, sending a return/enter key would do the trick since that is the same as clicking on the "OK" button - you can try that manually.
Here is example code, which works the same as clicking on the "OK" button:
win = RAutomation::Window.new :title => /Opening rautomation/
win.activate
sleep 1
win.send_keys :enter
I'm not sure why, but for some reason you have to activate the window manually by calling Window#activate and wait a second before sending that enter key.
After doing that a new dialog will pop up, which uses native Windows controls - you can handle that as you would have expected RAutomation to work in the first place.
However, if you would use a :ms_uia adapter instead of the default :win32 then you don't need to activate and sleep.
Here is a fully working example with :ms_uia adapter:
win = RAutomation::Window.new :title => /Opening rautomation/, :adapter => :ms_uia
win.send_keys :enter
file_dialog = RAutomation::Window.new :title => /Enter name of file/
file_dialog.button(:value => "&Save").click
To click "Cancel" on the first dialog instead of "OK" you can just use Window#close as i was using to test the window above.
I would recommend you to use :ms_uia adapter instead of :win_32 since it is getting more stable every day and will be a new default one in the far future.
To set :ms_uia adapter for default one you can use environment variable RAUTOMATION_ADAPTER before loading RAutomation itself like this:
ENV["RAUTOMATION_ADAPTER"] ||= :ms_uia
require "rautomation"
I do not see any popup when I click that link. Chrome just downloads a file. :) This could help: http://watirwebdriver.com/browser-downloads/
This code worked for me:
window = RAutomation::Window.new(:title => /Opening rautomation-0.9.2.gem/i)
window.activate
p window.exists? # => true
sleep 2
window.send_keys(:down)
window.send_keys(:enter)
I'm new to WATIR testing (and do I love it!) and have run into a wall on how to refocus my WATIR script to a newly opened window.. Here's my (simplified) script....
#!/usr/bin/ruby
require 'rubygems'
require 'watir-webdriver'
browser=Watir::Browser.new
browser.goto("http://0:3050")
browser.text_field(:name,"userkey300203830").set("OKJHNB")
browser.button(:id, "interview48").click
puts "Expected Result:"
puts "A successful display of cars"
if browser.window(:title=>"300203830").exists?
puts " Test passed. New window opened!"
else
puts " Test Failed! No window found"
end
It all works right up to the end. After the key "interview48" is clicked, a new window is opened with the title "300203830". Looks like I find it but I just don't know how to now focus on that window.
browser.window(:title => "300203830").use do
# do something
end
More information: http://watir.github.io/docs/browser-popups/
Additionally for more than 2 windows you can use the following:
browser.windows[n].use
#n is variable for which window. n will access them in order of opened or tabs from left to right
browser.windows.last.use
browser.windows.first.use
You can use the above commands if you open a new window from first browser instance and would like to toggle between the two.
There are 3 primary selectors for windows:
:title - typically the easiest
:url - often used with a Regexp value
:element - a unique element might be the least brittle (new as of Watir 6.18!)
browser.window(title: 'new window')
browser.window(url: /my_page.html/)
browser.window(element: browser.div(id: 'my-element'))
Locating by index is no longer supported
More information: Watir Browser Windows
If there is only one other window you want to use, so as of Watir 6.18, the easiest way to work with that window is with Browser#switch_window. It can only be used if there are only 2 windows, and all it does is switch to the other one, no additional locating required.
browser.switch_window
I'm using Watir-webdriver and I was wondering if there was a good way to check if a new window opens. I've googled around a bit and couldn't find anything though it feels like there should be an easy answer.
I have a printer friendly link and I want to test that the link opens in a new window or tab and I would like to test this with ie, firefox, chrome and safari if possible.
Thanks!
You can check the number of windows:
browser.windows.size
or check if a specific window exists:
browser.window(:title => "foo").exists?
More examples in the specs.
You can also use index based browser window checking where you need to worry about index only and it follows zero based index ordering. So, the default window is of index: 0 and if a new window opens it will be of index: 1, the next will be of index: 2 and so on.
To check first child window if you want to test that the link opens in a new window ,
browser.window(index: 1).exists?
Or to work inside this window,
browser.window(index: 1).use do
# do scripting here
end
I have a main menu window. On clicking any menu item it opens a child window using window.open? I am writing automated test script for this using Watin. How do i write Test script for the child windows.
The Watin.Core.IE class has a static AttatchToIE method you can use. It takes a Watin.Core.Constraint object as an argument (i.e. you have to use Find.ById, Find.ByName, etc.) to help Watin find the window you are looking for, and it returns a reference to an IE object.
Example:
IE myIE = IE.AttatchToIE(Find.ByTitle("Child Window Title"));
From there you can use the myIE object to run your tests, make sure it loads, make sure it has the expected text, etc.