An interesting solution to the Ruby Webdriver timeout problem

Source: Internet
Author: User

Rescue in receive

Because when I write Ruby, I feel like I'm dragging my body down, so I prefer to write code in Ruby.

Today I encountered a problem with Webdriver timeout, and the problem itself was due to my lack of understanding of webdriver and the broken documents. First, let's simplify the question:


Driver = Selenium::webdriver.for:safari
Driver.navigate.to "Http://www.faraway.com"

wait = selenium::webdriver::wait.new (: timeout = +) # seconds
Wait.until {driver.find_element (: CSS, ' input[name= ' username "])}

Given that the site is too far away, the speed is slower, so timeout set the value is larger: timeout = 1000

Here we interview: Faraway this site, and then wait for input box input username.

For example, the following error message is obtained:

/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/ selenium/webdriver/safari/server.rb:41:in' rescue in receive ': Timed off waiting for Safari to respond ( Selenium::webdriver::error::timeouterror)
From/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/safari/ Server.rb:36:in ' Receive '
From/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/safari/ Bridge.rb:68:in ' Raw_execute '
From/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/remote/ Bridge.rb:612:in ' Execute '
From/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/remote/ Bridge.rb:110:in ' Get '
From/users/twer/.rvm/gems/[email protected]/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/common/ Navigation.rb:14:in ' to '
from faraway.rb:26: In ' <main> '


The place where I saw the error was called by the place where I wait. I thought I didn't set it up: timeout = 1000. Wait waiting time is 1000 seconds, why still do not make AH?


Monkey patch to save me.

I don't know, there are people blowing on it. Violent settlement.

I found the file/selenium/webdriver/safari/server.rb marked in the red section above. (HTTPS://CODE.GOOGLE.COM/P/SELENIUM/SOURCE/BROWSE/RB/LIB/SELENIUM/WEBDRIVER/SAFARI/SERVER.RB)

Found the place where the error occurred 41 lines, is in the receive function:

def receive
@frame | | = Websocket::frame::incoming::server.new (: Version = @version)
Until Msg = @frame. Next

End_time = Time.now + @command_timeout

Begin
data = @ws. Read_nonblock (1)
Rescue Errno::ewouldblock, Errno::eagain
now = Time.now
If now >= end_time
raise Error::timeouterror, "timed out waiting for Safari to respond" #第41行
End

Io.select ([@ws], nil, nil, end_time-now)
Retry
End

@frame << Data
End

Puts "<<< #{msg}" if $DEBUG

Webdriver.json_load msg.to_s
End


It can be seen that now >= End_time is used to calculate whether to timeout. Before looking at the front end_time is obtained by the Time.now + @command_timeout, then enters the begin/rescue/retry. Strange, my: timeout = 1000 Shouldn't it be work?


First Monkey Patch

I copied the above part of the code directly into my source file faraway.rb, for example, the following changes:

If now >= end_time
Puts @command_timeout
Raise Error::timeouterror, "timed out waiting for Safari to respond"
End

Found that @command_timeout is not 1000. But 60, that's a minute.


A second monkey patch

Until Msg = @frame. Next
End_time = time.now + 1000
This forces @command_timeout to be set to 1000.


There's no problem with doing this.


To explore the end of

Although monkey patch solves my problem of connecting to faraway. However, it is OK to get feedback as a high-speed test. It's still not very pleasant to use.

So I started to read the source code, Webdriver itself is quite simple. Very easy to read. I won't tell you the details. In minutes, the problem was found here:


Driver = Selenium::webdriver.for:safari,timeout:1000
Driver.navigate.to "Http://www.faraway.com"


The red part is not accounted for in the document, what does the timeout here mean? My wait is not already a timeout. How do you still need it when you create a driver?

The reason is that there are two different timeout types. The timeout for wait indicates that. How long our driver will wait to know this element appears. And the place where we went wrong is the timeout that driver receives the server return information.

Not sure yet?

In this case, at wait time, driver will periodically poll the code in the run until. See if the situation in until has been met.

Each time you run the driver will send a request. This request actually has a timeout time. So the problem we started with was not the timeout of the wait itself.

Instead, driver sends a command and receives it when it is timeout.

Clearly, it was faraway.com, who wanted to reproduce the problem. Change command timeout to 1 try


Suppose I am again unfortunate.

I have only stirred myself to be the kind of man of luck.

Just the process of solving this problem is still very happy. Such dynamic language, such as Ruby, can play Monkey patch, for the high-speed positioning problem, solve this problem is very helpful. Happy.


An interesting solution to the Ruby Webdriver timeout problem

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.