Ruby Watir reference Chrome Print Preview - ruby

I'm writing a script to cycle through some links and print to PDF.
When you click on one of the links a new window pops up of the document to be printed and on top of that new window Chrome's print preview box pops up.
I'm trying to change the printer and then click the print button.
What's happening with my code however is that watir is only looking at the window html and not the print preview html so the elements are unable to be located.
My code looks like this:
begin
browser.window(title: 'Window Title Name').use do
browser.div(:id => "navbar-scroll-container").button(:class => "destination-settings-change-button").click
sleep(1)
browser.element(:title => "CutePDF Writer").click
browser.button(:visible_text => 'Print').click
end
rescue Watir::Exception::NoMatchingWindowFoundException
retry
end
I have tried using just "browser.windows.last.use do" instead of the title name but that also doesn't work.
I know it can only see the underlying window's html because when I puts browser.html the output is that underlying windows html.
If you want to look at the html situation just Ctrl+P this page (in chrome) to see what I mean.

Of course, after posting a question I soon found a sort of answer; basically chrome opens 2 browser windows and the print preview one couldn't be accessed by title (because it had the same title as the underlying one) but could be accessed by browser.window(:index => 1).use do. not sure why browser.windows.last.use do didn't work. Also following that I would have thought browser.window(:index => 2).use do would have been the correct one as index 0 would be the originally opened one, index 1 the popup and index 2 the print preview.

Related

Ruby: File dialog wont close

I am using the ruby gem gtk2 to display a simple file dialog, where the user can select a file from his computer. It works just fine, however there is one little problem.
The file dialog doesnt close after selecting the file, but it stays open until the whole script finished.
My file dialog looks like this:
def ask_for_file(question)
dialog = Gtk::FileChooserDialog.new(question, nil,
Gtk::FileChooser::ACTION_OPEN,
"gnome-vfs",
[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT],
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
)
if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
file_name = dialog.filename.to_s
return file_name
else
return nil
end
end
When I call it in my script like this:
path = ask_for_file("Test?")
sleep(5)
puts "continue with #{path}"
The file dialog stays open for 5 seconds and is unresponsive in that time. How could I get it to close after a file has been selected, but before the 5 second sleep?
I tried to use dialog.destroy in ask_for_file just before returning the file_name but that didnt seem to help.
I solved it by creating a new window with a button to open the file dialog. Upon clicking the open button, I also send a signal to destroy the main window. This way everything closes immediatly after I selected a file.
For reference see this example
You need to manually call gtk_widget_destroy() on GTK+-provided dialog boxes like GtkFileChooserDialog; clicking on one of the buttons won't be enough. Note that this destroys the file chooser part of the dialog as well, so be sure to get your filename and anything else of value out before you do.

verify scroller button works with preloaded data with watir-webdriver

I am trying to verify that a scroller button is working correctly. The button is an arrow image that slides a row of images/links, showing 5 out of the 10 images that are all loaded at page load. Whats making it difficult is that images are populated from a 3rd party provided so the urls change all the time. The only other identifier is by its class and text, the class is the same for all of them.
Since they are all loaded at the same time its hard to determine if the images are changing.
If you go to http://www.hayneedle.com/product/curiousgeorgepeelstickgiantmural.cfm and scroll to "Suggestions For You" you can see the on the right to scroll to a new set of suggestions. This button has broke before so need a simple way to regression it.
Any suggestions?
You can check if an image is actually visible to the user by using the present? method. You could also use the visible? method, but it throws an exception if the element does not exist. You can see a comparison of these and the .exists? method in the blog post, "Checking for an element – exists?, visible?, present?".
Knowing this, you could click the scrolling arrow and then check if last image is present (ie actually visible).
# Go to the page
browser = Watir::Browser.new :firefox
browser.goto 'http://www.hayneedle.com/product/curiousgeorgepeelstickgiantmural.cfm'
# This is the scroller control
scroller = browser.div(:id => 'HN_PP_RelatedCats')
# (optional) Check that the last image is *not* displayed
puts browser.div(:class => 'HN_Scroller_Cont').link(:index => 9).present?
#=> false
# Click the right scroller
scroller.div(:class => 'HN_Scroller_R').click
# Check that the last image is displayed
puts browser.div(:class => 'HN_Scroller_Cont').link(:index => 9).when_present.present?
#=> true
Note that the check for the last link/image is using when_present.present?. The when_present allows the scrolling to finish. Without it, you might end up checking the element before the scrolling is done (ie you false negative). The present? is there to return a true/false result.

How to set WATIR focus on new window

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

How can I automate a slider using watir-webdriver and ruby?

I am trying to automate a Jquery UI slider using watir-webdriver and ruby but am having no luck. I want to be able to manipulate the slider to either increase or decrease the value. I have searched everywhere and asked a few of my colleagues but no one has an answer. I am attaching a piece of HTML code for the slider. Any help would be much appreciated.
URL link: http://www.whatcar.com/new-car-deals/ (price range slider)
I haven't done any coding for the slider as I have no idea how to go about it. If I could be set on the right path that would be fantastic. Also it seems the HTML code doesn't seem to be showing on the question I am asking.
it's a Jquery widget that appears (looking at the scripts) to respond to key presses once one of the handles has been clicked on. the handles are link objects, inside a pair of divs, the outer one has the ID value 'slider-range'
You should be able to address them via browser.div(:id => 'slider-range').link(:index => n) where n = 0 for the lefthand one and n=1 for the right hand one.
Try this manually first
Click on the left handle for the slider
Then press arrow keys on the keyboard.. it will move 1K(pounds) up or down with each right or left arrow keypress.
Once you have moved it right, click the Home key and it should reset to its min value
repeat above for the right handle but reset it to far right using the End key.
In theory you could fire a click event at the right slider to get focus, then fire off some keypress events to first set it far right (end) followed by enough left arrows to move it down to the top value you want.
Repeat for the left handle, setting it to the left end with the home key, and moving it with right arrow keypresses
I don't have the time right now to experiment further and develop an exact script, but I think you could probably create two little functions even that took an upper and lower range value and did the required number of keypresses to move the lower up from 5K to the right amount, and the upper down from 100k
Note that this thing is very very event driven, it responds (at least when watching the dev tools while playing with it) to being moused over, mousedown, mouseup, etc.. if using click does not work to 'get the attention' of the control so it will respond to keypresses, try using the onmousedown event instead.
Using the code from your answer, to move the left slider to 12K I'd try
browser.div(:id => 'slider-range').link(:index => 0).click #make sure it has focus
browser.div(:id => 'slider-range').link(:index => 0).send_keys :home #set to 5K
7.times do
browser.div(:id => 'slider-range').link(:index => 0).send_keys :arrow_right
end
Thank you very much Chuck. I got it working. Here is the script I used:
#browser.link(:xpath, "/html/body/div/div[3]/div[4]/div/div/div/a").send_keys :arrow_right
Still needs a bit of tweaking, but I should be ok now.
This worked great. We just added these sliders to our website and my first thought was "how are we going to automate that!?"
I wanted to add an example will full code that is available publicly for people to experiment with. The following interacts with an example on jqueryui.com.
require "watir-webdriver"
#browser = Watir::Browser.new :chrome
#browser.goto "http://jqueryui.com/slider/#default"
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").click
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").send_keys :home
puts "clicked home"
7.times do
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").send_keys :arrow_right
end
To achieve this using Rspec and Watir-Webdriver with Page-Object gem I used:
div(:slider, id: "slider-range") #in page file
#then in spec file
browser.slider_element.input.send_keys :home
This answer comes from http://watir.com/guides/special-keys/

Testing if a new window opens with Watir-Webdriver

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

Resources