博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个有意思的Ruby Webdriver超时问题的解决过程
阅读量:6377 次
发布时间:2019-06-23

本文共 3190 字,大约阅读时间需要 10 分钟。

rescue in receive

由于写ruby的时候感觉混身上下都拽起来了,所以比較喜欢用ruby写代码。

今天遇到了一个webdriver timeout的问题,问题本身还是由于我对webdriver不了解以及破文档导致的。首先我们把问题简化一下:

driver = Selenium::WebDriver.for :safari

driver.navigate.to "http://www.faraway.com"

wait = Selenium::WebDriver::Wait.new(:timeout => 1000) # seconds
wait.until { driver.find_element(:css, 'input[name="username"]') }

由于考虑到站点太远了,速度比較慢,于是timeout设的值比較大:timeout => 1000

这里我们訪问:faraway这个站点,然后等待出现输入框输入username。

得到了例如以下错误信息:

/Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/safari/server.rb:41:in`rescue in receive': timed out waiting for Safari to respond (Selenium::WebDriver::Error::TimeOutError)
from /Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/safari/server.rb:36:in `receive'
from /Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/safari/bridge.rb:68:in `raw_execute'
from /Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/remote/bridge.rb:612:in `execute'
from /Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/remote/bridge.rb:110:in `get'
from /Users/twer/.rvm/gems/ruby-2.1.1@global/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/common/navigation.rb:14:in `to'
fromfaraway.rb:26:in `<main>'

看了出错的地方就是我wait的地方调用的。我心想我这不是设了:timeout => 1000。wait的等待时间为1000秒吗,怎么还搞不定啊?

Monkey Patch来解救我了

搞不定啊,上面有人在吹啊,咋办嘛。暴力解决。

我找到了上面红色部分标明的文件/selenium/webdriver/safari/server.rb。()

找到了出错的地方41行,是在receive函数里:

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
能够看出,是now >= end_time用来计算是否超时。在看前面end_time是由Time.now + @command_timeout得到的,然后进入begin/rescue/retry的。奇怪,我的:timeout => 1000不应该是work的吗?

第一个monkey patch

我把上面那部分代码直接拷到了我的源文件faraway.rb中,做了例如以下改动:

if now >= end_time

   puts @command_timeout
   raise Error::TimeOutError, "timed out waiting for Safari to respond"
end

发现@command_timeout不是1000。而是60,也就是一分钟

第二个monkey patch

until msg = @frame.next

   end_time = Time.now + 1000
这样强制让@command_timeout设为1000

这样执行,没有问题了

探个到底

尽管monkey patch能够解决我连接faraway的问题。可是,作为高速试验得到反馈还行。真这样用还是不太愉快。

于是我就開始读源码,webdriver本身的代码还是挺简单的。非常easy看懂。详细怎么看我就不讲了。分分钟发现了问题事实上是在这里:

driver = Selenium::WebDriver.for :safari, timeout: 1000
driver.navigate.to "http://www.faraway.com"

红色的部分在文档上是没有交代的,那这里的timeout是什么意思呢?我的wait不是已经有timeout了吗。怎么在Driver的创建时还须要呢?

原因是这是两种不同的timeout。wait的timeout表示的是。我们的driver会等待多久知道这个元素出现。而我们出错的地方是driver接收server返回信息的timeout。

还不清楚?

这样说,在wait的时候,driver会周期轮询的去运行until中的代码。看看until中的情况是否得到了满足。

每次运行的时候Driver对会发一个请求。这个请求事实上也是有timeout时间的。所以我们最開始遇到的问题并非wait本身timeout了。

而是driver发送命令后接收的时候timeout了。

明了了吧,都是faraway.com搞得怪,想重现这个问题。把command timeout改为1试试

假设我再次不幸。。

我一仅仅搅得自己是运气比較背的那种人。

只是解决这个问题的过程还是非常开心。ruby这样的动态语言,能够打monkey patch,对于高速定位问题,解决这个问题还是非常有帮助的。开心。

转载地址:http://imtqa.baihongyu.com/

你可能感兴趣的文章
洛谷 题解 P3627 【[APIO2009]抢掠计划】
查看>>
springboot传入json和文件_SpringBoot系列教程22-整合SpringMVC之HttpMessageConverters
查看>>
不礼让行人怎么抓拍的_张家川公安交警持续曝光机动车不礼让行人【第24期】...
查看>>
用pythonturtle写名字_去年爆款新生儿名字,家长自以为起的不错,却有“棺材”的意思...
查看>>
句子分类_语法微课句子的分类+文本讲解
查看>>
显示提示_体检报告显示:“转氨酶”升高!提示身体可能出现了这些健康问题...
查看>>
图形化分析工具_推荐一款基于小米 soar 的开源 sql 分析与优化的 web 图形化工具...
查看>>
485 工控机 接线方式_RS485温湿度传感器的接线方式及注意事项
查看>>
12306排队是什么意思_12306订单请求排队中是什么意思 要等多久
查看>>
u3d游戏开发视频潭州_unity3d教程视频-unity3d教程中文零基础入门/u3d游戏开发/特效案例/项目实战V2.0 最新版 - 极光站...
查看>>
c++区块链实例_cpp 区块链模拟示例(二)工程代码解析
查看>>
hourglass论文_论文笔记 Stacked Hourglass Networks for Human Pose Estimation
查看>>
java 接口的本质_Java基本概念:接口
查看>>
java死锁的解决_java中常见的死锁以及解决方法代码
查看>>
java菜单栏不下拉_我java代码中的下拉列表设好后为什么无法下拉?
查看>>
java传递引用类型的实质_java的引用类型以及值传递
查看>>
java策略模式使用场景,Java设计模式—策略模式
查看>>
RHEL6.3实现基于加密的用户认证验证访问
查看>>
SCCM2012 R2实战系列之十一:解决OSD分发Windows7 系统盘盘符为’D’问题
查看>>
经验分享:我是如何在网店无货源情况下快速出单?
查看>>