【问题标题】:Selenium-Webdriver Ruby --> How to wait for images to be fully loaded after clickSelenium-Webdriver Ruby --> 点击后如何等待图片完全加载
【发布时间】:2015-04-28 03:04:11
【问题描述】:

我对 Ruby 和 Selenium-Webdriver 很陌生,所以请帮忙 :)

我正在尝试打开电子邮件活动,发送到我的收件箱,其中包含图像并在 Firefox 中截屏。但我不能让它等到图像完全加载。一旦我点击“显示图像”,屏幕截图已经被拍摄,但当时没有加载图像。在显示所有图像后,如何暂停脚本并稍后截屏?

请帮忙:(

下面是我的脚本:

enter code here

require 'selenium-webdriver'

browser = Selenium::WebDriver.for :firefox

#==========================================================================================

wait = browser.manage.timeouts.implicit_wait = 15
#==========================================================================================
url = 'https://login.yahoo.com/config/login_verify2?.intl=us&.src=ym'
# Open browser (firefox)
browser.navigate.to url
browser.find_element(:id, 'username').send_keys "some yahoo id"
browser.find_element(:id, 'passwd').send_key "some password"
browser.find_element(:id, ".save").click
browser.find_element(:id, "inbox-label").click
browser.find_element(:xpath, "//div[@class='subj']").click
browser.find_element(:xpath, "//a[@title='Display blocked images']").click

result_page_title = browser.find_element(:tag_name, 'title')
    puts "Title of the page: \t\t: #{result_page_title.text}"
    browser.save_screenshot "1.jpg"

【问题讨论】:

  • 代码是否完整?看起来底部至少缺少一个end 语句。

标签: ruby selenium-webdriver


【解决方案1】:

您可以使用Implicit Wait and Explicit Wait 等待特定的Web 元素,直到它出现在页面中。您可以定义的等待时间取决于应用程序。

显式等待:

显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。如果条件达到,它将终止等待并继续执行进一步的步骤。

代码:

 WebDriverWait wait = new WebDriverWait(driver,30);
 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(strEdit)));

或者

 WebElement myDynamicElement = (new WebDriverWait(driver, 30))
 .until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
    return d.findElement(By.id("myDynamicElement"));
}});

这会在抛出 TimeoutException 之前等待最多 30 秒,或者如果它发现元素将在 0 - 30 秒内返回它。默认情况下,WebDriverWait 每 500 毫秒调用一次 ExpectedCondition,直到它成功返回。对于 ExpectedCondition 类型的成功返回是 Boolean 对所有其他 ExpectedCondition 类型返回 true 或非 null 返回值。

您可以根据应用程序的需要使用 ExpectedConditions 类。

隐式等待:

隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用)时轮询 DOM 一段时间

代码:

 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

要记住的一件事是,一旦设置了隐式等待 - 它会在 WebDriver 对象实例的生命周期内一直存在

欲了解更多信息,请使用此链接http://seleniumhq.org/docs/04_webdriver_advanced.jsp

以上代码在Java。根据您的语言需要进行更改。

【讨论】:

  • 此答案可能对 Java 有效,但仅添加“根据您的语言需要更改”并不能回答特定于 Ruby 的问题
  • visibilityOfElementLocated 检查元素的高度和宽度是否大于 0。它不会等到元素加载完毕。
【解决方案2】:

来自the docs 的 Ruby 代码(点击“ruby”按钮):

wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
begin
  element = wait.until { driver.find_element(:id => "some-dynamic-element") }
ensure
  driver.quit
end

这对我有用

【讨论】:

    【解决方案3】:

    为了补充上述答案,以下是我在 Ruby 中使用隐式和显式等待的方式。

    隐式等待

    在使用如下几行初始化后,我将此选项传递给 Selenium::WebDriver:

    browser = Selenium::WebDriver.for :firefox
    browser.manage.timeouts.implicit_wait = 10
    

    只需将“10”替换为您希望浏览器等待页面刷新和其他此类事件的秒数。

    显式等待

    在 Selenium 中声明显式等待有两个步骤。首先通过声明一个等待对象来设置超时时间,然后使用 Selenium::Webdriver 的 .until 方法调用等待。在您的示例中,它看起来像这样:

    wait = Selenium::WebDriver::Wait.new(:timeout => 10)
    wait.until { browser.find_element(:xpath, "//path/to/picture").displayed? }
    

    这将告诉 Webdriver 最多等待 10 秒以显示图片元素。你也可以使用 .enabled?如果您等待的元素是交互式元素 - 这在您使用基于 Ajax 的输入表单时特别有用。

    您还可以在脚本开始时声明一个明确的等待期,然后在需要时再次引用该对象。除非您想设置新的超时,否则无需重新声明它。就个人而言,我喜欢将 wait.until 包裹在一个方法中,因为我知道我会反复引用它。比如:

    def wait_for_element_present( how_long=5, how, what )
      wait_for_it = Selenium::WebDriver::Wait.new(:timeout => how_long )
      wait_for_it.until { @browser.find_element(how, what) }
    end
    

    (我发现将浏览器声明为实例变量更容易,这样您就不必每次都将它传递给方法,但这部分取决于您,我猜?)

    【讨论】:

      【解决方案4】:

      Ruby Selenium bindings 尚不支持预期条件。下面这个 sn-p 与 ExpectedConditions.elementToBeClickable 做同样的事情——可点击只是意味着“可见”和“启用”。

      element = wait_for_clickable_element(:xpath => xpath)
      
      def wait_for_clickable_element(locator)
        wait = Selenium::WebDriver::Wait.new(:timeout => 10)
      
        element = wait.until { @driver.find_element(locator) }
        wait.until { element.displayed? }
        wait.until { element.enabled? }
      
        return element
      end
      

      【讨论】:

      • 就我而言,这无济于事,因为它上面有一层,所以我必须等到该层消失。
      • 如果您对预期图层消失的时间边界有信心,则硬编码睡眠是一个有效的选项。 Selenium 社区普遍认为应该避免睡眠,但我相信硬编码的睡眠通常只占测试执行中可避免的延迟时间的一小部分,所以如果避免它们所需的工程努力变得笨拙,他们没事。另外,如果您能够找到正在消失的图层,那么您应该能够等待它消失时的属性更改
      猜你喜欢
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 2012-03-26
      • 2016-11-09
      相关资源
      最近更新 更多