如何通过Selenium正确配置Implicit / Explicit Waits和pageLoadTimeout?

时间:2018-05-24 21:33:00

标签: java selenium page-load-time webdriverwait implicitwait

我目前有以下设置,但我不确定我的等待(Implicit和pageLoadTimeout)是否正常工作。 这是正确的实现吗?通过将其放在@Before(" @ setup")中,它是否适用于每个场景或步骤定义运行?每当我打电话给@Given,@ When..etc?

时,司机会不会相应地等待
@Before("@setup")
    public void setUp() {

        driver.manage().deleteAllCookies();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);


    }

为什么有必要将WebElement分配给以下等待, WebElement元素收到什么?这是正确的实施吗? -

 WebDriverWait wait = new WebDriverWait(driver, 30);
 WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
boolean status = element.isDisplayed();

3 个答案:

答案 0 :(得分:2)

implicitlyWait()

implicitlyWait()是告诉 WebDriver 实例,即驱动程序在尝试查找元素时轮询HTML DOM一段时间或元素,如果它们不是立即可用的。默认等待配置设置为 0 。设置后,隐式等待将在 WebDriver 对象实例的生命周期内设置。

您的代码试用版非常完美,如:

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

您可以在Using implicit wait in selenium

中找到详细讨论

pageLoadTimeout()

pageLoadTimeout()设置等待页面加载完成的时间跨度,然后再抛出错误。

您的代码试用版非常完美,如:

driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);

您可以在pageLoadTimeout in Selenium not working

中找到详细的讨论
  

注意:除非测试规范明确提及相同内容,否则请尽量避免配置pageLoadTimeout()

为什么选择WebDriverWait?

现代浏览器使用JavaScriptAJAXReact Native,其中网页中的元素已加载动态。因此,在继续下一行代码Explicit Waits之前等待满足特定条件,即WebDriverWait是继续前进的方法。

  

注意:根据Explicit and Implicit Waits的官方文档,不要混合隐式和显式等待。这样做会导致不可预测的等待时间。

您的代码试用版非常适合等待元素的可见性,如下所示:

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

您可以在此处找到Replace implicit wait with explicit wait (selenium webdriver & java)

的详细讨论

您的具体问题

  • 为什么有必要将WebElement分配给以下等待 WebDriverWait ExpectedConditions一起不仅返回WebElement但是,取决于 ExpectedConditions ,也可以返回 void Boolean List

  • WebElement元素接收什么?:根据您使用 ExpectedConditions 作为visibilityOfElementLocated()的代码块, WebElement < / em>将在网页DOM Tree上的在线元素后返回,并且可见可见性表示元素不仅显示,而且高度和宽度也大于 0

  • 这是正确的实现吗?:您的实现接近完美但最后一行代码boolean status = element.isDisplayed();是多余的,因为visibilityOfElementLocated()返回元素一旦完成元素可见(即元素不仅显示,而且高度和宽度也大于 0 )。

答案 1 :(得分:2)

如果你刚刚开始使用硒,那是一个合法的问题。我总是建议您查看official doc

  

隐式等待是告诉WebDriver对DOM进行轮询   尝试查找一个或多个元素的时间量   没有立即可用。默认设置为0.一旦设置,   隐式等待是为WebDriver对象实例的生命周期设置的。

示例:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

在这种情况下,如果尝试找到ID时,如果DOM中没有id myDynamicElement 的网络元素,则表示要重新尝试直到10秒。轮询时间取决于您使用的webdriver 。你必须要知道的是它将尝试找到10秒的元素。当然,如果元素位于此时间结束之前,则代码将继续。否则,抛出异常。

  

显式等待是您定义的等待某个条件的代码   在进一步进入代码之前发生。最糟糕的情况是   Thread.sleep(),它将条件设置为精确的时间段   等待。提供了一些便于您编写的便捷方法   只需要等待的代码。 WebDriver等待   与ExpectedCondition的结合是一种可行的方式   来完成的。

示例:

WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
  

在抛出TimeoutException之前等待最多10秒或者等待   它发现元素将在0-10秒内返回。 WebDriverWait   默认情况下,每500毫秒调用一次ExpectedCondition直到它   成功返回。成功的返回值   ExpectedCondition函数类型是布尔值true或a   非空对象。

最后,写着:此示例在功能上也与第一个隐式等待示例等效。

因此,如果您使用 presenceOfElementLocated 作为预期条件(对于您尝试定位的每个元素),则使用隐式等待完全相同。但这并不是唯一的条件。从ExpectedConditions可以看出,您可以指定其他条件(例如:elementToBeClickable,stalenessOf等)。

所以,回到你的问题:

使用

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

你要等待,每当你尝试找到元素存在(记住,它就像presenceOfElementLocated )直到30秒。

使用

driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);

您需要将网页设置为30秒。

使用:

 WebDriverWait wait = new WebDriverWait(driver, 30);
 WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
boolean status = element.isDisplayed();

您说要等待ID为&#34; id&#34;的网络元素的 visibilityOfElementLocated ,直到30秒。

最后:

  

为什么有必要将WebElement分配给以下等待,   WebElement元素收到什么?这是对的   执行?

WebElement元素接收什么?如果不是带有id的webelement还有什么:&#34; id&#34;?当然,如果它可见。否则,将抛出异常。

答案 2 :(得分:0)

您只需等待案例中的页面加载,您的实施就可以了。 @ Before是Cucumber Hooks之一,它意味着你的方法将在每个场景之前运行。 我建议使用流利的等待而不是webdriverwait,这就是原因:

使用FluentWait实例时:

  1. 您可以检查已定义的条件(可见性,......的隐身性)
  2. 忽略特定类型的异常等待,例如NoSuchElementExceptions 搜索页面上的元素时出现StaleElementException。
  3. 您可以为每种情况指定轮询和超时。
  4. 例如:

     // Waiting 30 seconds for an element to be present on the page, checking for its presence once every 5 seconds. 
    
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS).ignoring(NoSuchElementException.class);
    

    希望我帮助过。