2

我目前有以下设置,但我不确定我的等待(隐式和 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);


    }

为什么要给后面的wait分配一个WebElement,WebElement元素接收到什么?这是正确的实施吗?-

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

3 回答 3

6

隐式等待()

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

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

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

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


页面加载超时()

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

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

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

在这里,您可以在 Selenium 中的 pageLoadTimeout 中找到详细讨论不工作

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


为什么选择 WebDriverWait?

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

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

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

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

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


您的具体问题

  • 为什么有必要将 WebElement 分配给以下 waitWebDriverWaitExpectedConditions结合不仅返回WebElement,而且根据ExpectedConditions还可以返回voidBooleanList

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

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

于 2018-05-25T07:56:20.013 回答
2

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

隐式等待是告诉 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 秒。轮询时间取决于您使用的 webdriver。你必须知道的是它会在 10 秒内尝试查找元素。当然,如果元素位于这个时间结束之前,代码会继续。否则,抛出异常。

显式等待是您定义的代码,用于在继续执行代码之前等待某个条件发生。最坏的情况是 Thread.sleep(),它将条件设置为要等待的确切时间段。提供了一些方便的方法来帮助您编写只等待所需时间的代码。WebDriverWait 与 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 或非空对象。

而且,最后,写着:这个例子在功能上也等同于第一个隐式等待例子。

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

所以,回到你的问题:

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

你说要等待,每当你尝试定位一个元素时,存在(记住,它就像 presentOfElementLocated)直到 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 元素的visibilityOfElementLocated,直到 30 秒。

最后:

为什么要给后面的wait分配一个WebElement,WebElement元素接收到什么?这是正确的实施吗?

WebElement 元素接收什么?如果不是 id:"id" 的 webelement,还有什么?当然,如果它是可见的。否则会抛出异常。

于 2018-05-25T08:25:26.260 回答
0

在您的情况下,您只需要等待页面加载,您的实施就可以了。@ Before 是 Cucumber Hooks 之一,这意味着您的方法将在每个场景之前运行。我建议使用 fluent wait 而不是 webdriverwait ,原因如下:

使用 FluentWait 实例时:

  1. 您可以检查定义的条件(可见性,不可见性......)
  2. 在页面上搜索元素时忽略特定类型的异常等待,例如 NoSuchElementExceptions 或 StaleElementException。
  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);

希望我有所帮助。

于 2018-05-24T23:52:22.740 回答