Stop loading page watir-webdriver - ruby

Is there a way to stop loading a page with watir-webdriver on firefox? Or is there a way to force something in my script even if the page is still loading? At a point in my script, the website will hang and the script eventually timeouts.

You can use the Timeout class to force it to give up after waiting a reasonable amount of time (and this is internally how Watir performs it's waits as well)
begin
Timeout::timeout(10) do
# perform actions that may hang here
end
rescue Timeout::Error => msg
put "Recovered from Timeout"
end

If the website hangs, you should be able to use a wait method to timeout the script if an element does not appear. These are mainly used as an answer to AJAX, but they should work for this condition as well. For example, if the script hangs after you click a link, and you expect the next page to have a specific title or text:
#browser.link(:name => "Let's Hang!").click
Watir::Wait.until(30) { #browser.title == "new page" }
or
Watir::Wait.until(30) { #browser.text.include? ("confirmation text") }
or
#browser.image(:src => "awesome.jpg").wait_until_present(30)
Each of these will wait 30 seconds for the condition to be met before exiting with an error. You can change the time (30) to exit within your app's hang window.

please have a look at the Selenium issue http://code.google.com/p/selenium/issues/detail?id=687 it's not fixed yet, watir-webdriver is also based on Selenium, hope it answers your question.

Related

Last index can't be located

I have a very different problem here.
I have this code
xpath = "//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table"
array = #browser.table(xpath: xpath, visible: true).rows.map { |row| [row.cells[0], row.cells[0].text] }
col = array.filter_map { |x| x if x[1].eql?(result) }
When I am executing the aforementioned code, it throws the following error
timed out after 10 seconds, waiting for #<Watir::Row: located: false; {:xpath=>\"//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table\", :visible=>true, :tag_name=>\"table\"} --> {:index=>10}> to be located\""
10 is actually the last index of the table.
But it works fine if I put sleep 5 before my code segment. However, I was expecting WATIR to be automatically waited, but this is not the case, May I know why?
Here is more clear explanation
I am printing this line
p #browser.table(xpath: xpath, visible: true).rows.count
With sleep this is printing 10
without sleep, this is throwing the following error ends with {:index=>11}> to be located\, you could see the full error below
"timed out after 10 seconds, waiting for #<Watir::Row: located: false; {:xpath=>\"//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table\", :visible=>true, :tag_name=>\"table\"} --> {:index=>11}> to be located\""
Per the Documentation on waiting there are a few key points that should be noted:
The idea behind implicit waits is good, but there are two main issues with this form of implementation, so Watir does not recommend and does not provide direct access for setting them.
The wait happens during the locate instead of when trying to act on the element. This makes it impossible to immediately query the state of an element before it is there.
Implicit waits by themselves will not be sufficient to handle all of the synchronization issues in your code. The combination of delegating waiting responsibilities to the driver and leveraging polling in the code (explicit waits) can cause weirdness that is difficult to debug...
...The second and recommended approach to waiting in Selenium is to use explicit waits...
...Note that Watir does its automatic waiting when taking actions, not when attempting to locate...
In your case the wait is needed for location and thus the "automatic" wait you were expecting is not actually how watir works.
The Watir library does however provide mechanisms for explicit waits:
wait_until which waits until a specific condition is true
wait Waits until readyState of document is complete.
It appears that based on your posted issue that a waiting timeout has expired for your location before the element could be found.
It is possible that wait_until would resolve this e.g.
table = #browser.table(xpath: xpath).wait_until(&:visible?)
puts table.rows.count

watir/ruby waiting for iframe to exist

I have a problem waiting for an iframe to exist on page after entering a date range and I would rather not use sleep. I am using ruby/watir
I have tried solutions like this -
wait_until(10, "iFrame has not loaded") do
#browser.iframe(id: "dtl00_DP1_content").exists?
end
but this simply returns this error - Selenium::WebDriver::Error::NoSuchWindowError: no such window
So how do I wait for an iframe that does not yet exist please?
I am not sure whether you only want to wait for an Iframe, If you want to perform any operation on an element which is present in the iframe, then you could do as I mentioned in my comment.
#browser.iframe(name: "something").text_field(name: "username").set 'raja'
Or If you still wait for an iframe to appear, then write the following code
#browser.wait_until { #browser.iframe(id: "dtl00_DP1_content").exists? }
The above code waits for 30 seconds, but If you want to increase the time to wait, then write the following code, the following code would wait fo 50 seconds.
#browser.wait_until(timeout: 50) { #browser.iframe(id: "dtl00_DP1_content").exists? }

How can I interrupt a Watir script while keeping connectivity to the browser?

I have a script that uses Watir webdriver. However, it takes a long time and I need to stop it occasionally. I'd like to be able to interrupt it and handle the interrupt by performing a few tasks, such as logging out of the website I am on. Then, it would need a way to resume the process. I am using ruby, and, so far, I have tried rescue Interrupt => e as well as Signal.trap("TSTP") do |signo| {...}. In both of these, I cannot perform any closing operations on the browser because it seems that I have lost connection to it. Is there any way I can pause the script by keyboard and perform some exit operations on the Watir browser?
Signal.trap("TSTP") do |signo|
browser.link(:text=> "Logout").click
ap "Paused. Press <enter> to continue."
$stdin.gets
Process.kill("STOP", Process.pid)
end
After stopping gives me ^Z/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout).

Watir webdriver - click an element and not wait for load

I have 2 sides in my page, clicking one of the buttons on the left side, refreshes the right side.
Now I want to see whether the site gets stuck if i click the buttons too fast while not letting the right side to fully load.
Right now watir waits for the click command to return, so the test doesnt do what it should:
arr = ["div1", "div2", "div3"]
for i in 1..20
print "#{i}\r"
choise = arr.sample
b.div(:id=>choise).click
end
Any way to make it send the command and return without any delays?
Are you getting the same result in multiple browsers?
The spec (which may or may not be implemented or implemented the same way by the different browsers), says that webdriver prevents other commands from being executed while there are outstanding network requests. Though, it also says it should wait for document.readyState to be present for the frame currently handling the commands, so it is unclear if the outstanding network request is supposed to apply to only the current frame or to all frames.
But since Webdriver is designed for commands to be handled in a synchronous manner, it is likely just not designed to do what you are trying to do.
Not sure but you can try with javascripts:
#browser.execute_script("document.getElementById('choise').click")
b.div(:id => 'choise').exist? - to check exist it or aren't
b.div(:id => 'choise').click
I think titusfortner is right. But look this answer.
begin
Timeout::timeout(10) do
# perform actions that may hang here
end
rescue Timeout::Error => msg
put "Recovered from Timeout"
end

How can I implement wait_for_page_to_load in Selenium 2?

I am new to automated web testing and I am currently migrating from an old Selenium RC implementation to Selenium 2 in Ruby. Is there a way to halt the execution of commands until the page gets loaded, similar to "wait_for_page_to_load" in Selenium RC?
I fixed a lot of issues I was having in that department adding this line after starting my driver
driver.manage.timeouts.implicit_wait = 20
This basically makes every failed driver call you make retry for maximum 20 seconds before throwing an exception, which is usually enough time for your AJAX to finish.
Try using Javascript to inform you!
I created a couple methods that checks via our javascript libraries and waits to see if the page has finished loading the DOM and that all ajax requests are complete. Here's a sample snippet. The javascript you will need to use is just going to depend on your library.
Selenium::WebDriver::Wait.new(:timeout => 30).until { #driver.execute_script("[use javascript to return true once loaded, false if not]"}
I then wrapped these methods in a clickAndWait method that clicks the element and calls the waitForDomLoad and waitForAjaxComplete. Just for good measure, the very next command after a clickAndWait is usually a waitForVisble element command to ensure that we are on the right page.
# Click element and wait for page elements, ajax to complete, and then run whatever else
def clickElementAndWait(type, selector)
#url = #driver.current_url
clickElement(type, selector)
# If the page changed to a different URL, wait for DOM to complete loading
if #driver.current_url != #url
waitForDomLoad
end
waitForAjaxComplete
if block_given?
yield
end
end
If you are using capybara, whenever you are testing for page.should have_content("foo"), capybara will not fail instantly if the page doesn't have the content (yet) but will wait for a while to see if an ajax call will change that.
So basically: after you click, you want to check right away for have_content("some content that is a consequence of that click").

Resources