【问题标题】:Explicit wait for Selenium Webdriver显式等待 Selenium Webdriver
【发布时间】:2016-01-20 09:03:30
【问题描述】:

处理试图理解显式等待的方法。

    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 is not current visible and so may not be interact with”。为什么此代码不等到元素出现并单击它?

【问题讨论】:

  • 见下面answer第一个代码sn-p
  • @har07,谢谢。我看到在哪里做了一些研究,但我试图了解如何使用点击命令与元素交互

标签: ruby xpath selenium-webdriver


【解决方案1】:

问题是该元素尚未在 DOM 中,因此您需要在其中放置时间延迟。

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

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

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

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

Java API 有 ExpectedConditions convenience methods 可以这样使用...

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;
    }

【讨论】:

  • 感谢您的评论,它给了我一些想法,所以我会继续寻找!
猜你喜欢
  • 2013-12-03
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 2017-04-19
  • 1970-01-01
  • 2012-05-11
相关资源
最近更新 更多