如何通过Selenium正确配置隐式/显式等待和pageLoadTimeout



我目前有以下设置,但我不确定我的等待(隐式和pageLoadTimeout)是否有效。这是正确的实现吗?通过将其放在 @Before("@setup") 中,它是否适用于每个场景或步骤定义运行?司机会相应地等待吗,每次我打电话给@Given,@When..等?

@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();

隐式等待()

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

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

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

在这里,您将在硒中使用隐式等待中找到详细的讨论


pageLoadTimeout()

pageLoadTimeout()设置在引发错误之前等待页面加载完成的时间跨度。

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

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

在这里,您可以在页面中找到详细的讨论加载超时在硒不起作用

注意:尽量避免配置pageLoadTimeout(),除非测试规范明确提到相同。


为什么选择WebDriverWait?

现代浏览器使用JavaScript,AJAX和React Native,其中网页中的元素是动态加载的。因此,在继续下一行代码之前等待特定条件,显式等待,即WebDriverWait是继续前进的方法。

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

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

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

在这里你可以找到详细的讨论 用显式等待替换隐式等待 (selenium webdriver & java)


您的具体问题

  • 为什么有必要将WebElement分配给以下等待WebDriverWait与ExpectConditions结合使用不仅返回WebElement,而且根据ExpectConditions也可以返回void,Boolean,List。

  • WebElement 元素接收什么?:根据您使用ExpectConditions作为visibilityOfElementLocated()的代码块,一旦元素存在于网页的 DOM 树上并且可见,WebElement就会返回。可见性意味着元素不仅显示,而且具有大于0的高度和宽度。

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

如果你刚开始使用硒,这是一个合法的问题。我总是建议看看官方文档。

隐式等待是告诉 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为 myDynamicElement的 Web 元素时 DOM 中不存在它,那么您说要重试直到 10 秒。轮询时间取决于您使用的 Web 驱动程序。您必须知道的是,它将尝试在 10 秒内找到该元素。当然,如果元素在此时间结束之前找到,则代码将继续。否则,将引发异常。

显式等待是您定义的代码,用于等待特定条件 在继续执行代码之前发生。最糟糕的情况是 Thread.sleep(),它将条件设置为确切的时间段 等。提供了一些方便的方法可以帮助您编写 仅根据需要等待的代码。WebDriverWait in 与预期条件相结合是一种方式 完成。

例:

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

这将在引发超时异常之前等待最多 10 秒,或者如果 它发现元素将在 0 - 10 秒内返回它。WebDriverWait 默认情况下,每 500 毫秒调用一次预期条件,直到它 返回成功。成功的返回值 预期条件函数类型是 true 的布尔值,或 非空对象。

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

因此,如果您使用presenceOfElementLocation作为预期条件(对于您尝试定位的每个元素),则与使用隐式等待完全相同。但条件不只有这个。正如您从预期条件中看到的那样,您可以指定其他条件(例如:elementToBeClickable,stalenessOf 等)。

所以,回到你的问题:

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

你说要等待,当你尝试找到一个元素时,存在(记住,它就像存在元素定位)直到 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:"id" 的 Web 元素的可见性 OfElementLocate到 30 秒。

最后:

为什么需要将WebElement分配给以下等待, WebElement 元素接收什么?这是对的吗 实现?

WebElement 元素接收什么?如果不是带有 id:"id" 的 WebElement 怎么办?当然,如果它是可见的。否则,将引发异常。

你只需要等待页面加载,你的实现就可以了。@ Before 是黄瓜钩子之一,这意味着您的方法将在每个场景之前运行。 我建议使用流畅的等待而不是webdriverwait,原因如下:

使用 FluentWait 实例时:

  1. 您可以检查定义的条件(可见性,不可见性...
  2. 忽略特定类型的异常等待,例如 NoSuchElementExceptions 或在页面上搜索元素时出现过时元素异常。
  3. 您可以为每个条件指定轮询和超时。

例如:

// 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);

希望我有帮助。

最新更新