显式等待Selenium Webdriver

尝试理解显式等待的方法。

require 'rubygems' require 'selenium-webdriver' require 'cucumber' $driver = Selenium::WebDriver.for :firefox $driver.manage.timeouts.implicit_wait = 3 Then /^do search$/ do driver = $driver one_way = driver.find_element(:id, "search.ar.type.code.oneWay").click sleep 5 from = driver.find_element :xpath => "//div[@class = 'origin column1']//input[@type = 'text']" from.click 

因此,在单击one_way单选按钮并且输入表单发生更改后,我将sleep 5设置为显示时间元素,否则将出现错误“元素不可见…”。 所以我认为这是理解显式等待的好时机,因为我需要等到元素出现。

  wait = Selenium::WebDriver::Wait.new(:timeout => 40) wait.until {from = driver.find_element(:xpath, "//div[@class = 'origin column1']//input[@type = 'text']") from.click } 

但是得到错误“Selenium :: WebDriver :: Error :: ElementNotVisibleError:Element当前不可见,因此可能无法与之交互”。 为什么此代码不会等到元素出现并单击它?

问题是元素还没有在DOM中,因此你需要在那里加时间延迟。

也就是说, ruby的API doco说你应该这样做

 require 'rubygems' # not required for ruby 1.9 or if you installed without gem require 'selenium-webdriver' driver = Selenium::WebDriver.for :firefox driver.get "http://somedomain/url_that_delays_loading" wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds begin element = wait.until { driver.find_element(:id => "some-dynamic-element") } ensure driver.quit end 

请注意,然后可以从wait.until方法中分配.click()元素, .click()不是代码中的find_element()方法。

然而,任意延迟并不总是有效,如果站点繁忙,则延迟可能不够长。 更好的选择是等待元素变为可点击或可见。

Java API具有ExpectedConditions方便的方法 ,可以像这样使用…

 WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid"))); element.click(); 

不幸的是,我不认为Ruby有这个。 您可能需要编写自己的ExpectedCondition类或包。

我不是Ruby开发人员,但这里是Java中的一个函数的概念,可用于实现您的ExpectedCondition

 public WebElement findElementInTime(WebDriver driver, By by, int timeoutInSeconds) { log.debug("==================+>>>>>> looking for element for "+ timeoutInSeconds + " seconds"); WebElement ret = null; for (int second = 0; second < timeoutInSeconds; second++) { try { if (isElementPresent(driver,by)) { log.debug("found element :-)"); ret = driver.findElement(by); break; }} catch (Exception e) { log.debug("oops... sleeping 1 sec wait for button"); } log.debug("sleeping 1 sec wait for button"); } return ret; }