Selenium:我怎么能告诉 Selenium 等待按钮元素?

Selenium: How can i say to Selenium to wait for a button element?

我有一个验证按钮,在我点击它后会有一些延迟(在我点击它后它会显示一个包含元素的网格)然后出现一个 NEXT 按钮,该按钮重定向到下一页。我有这个代码:

((JavascriptExecutor)driver).executeScript("arguments[0].click()",driver.findElement(By.cssSelector("div#button-verify-wrapper > a")));
Thread.sleep(18000);
driver.findElement(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a")).click();
Thread.sleep(5000);

但是我想点击NEXT按钮,在所有格子充电之后(这需要一段时间取决于当时的服务器),因为下一个按钮是在格子出现后才出现的.

有selenium语句可以做到吗?

Selenium 提供了两种类型的 waits 如下:-

  • Explicit wait :-

    显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。最坏的情况是 Thread.sleep(),它将条件设置为要等待的确切时间段。提供了一些方便的方法,可帮助您编写仅在需要时等待的代码。 WebDriverWait in combination with ExpectedCondition 是实现这一目标的一种方式。所以你应该尝试 :-

    WebDriverWait wait = WebDriverWait(drive, 10);
    wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("div#button-verify-wrapper > a"))).click();
    
    wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a"))).click();
    //Now find further element with WebDriverWait for the process
    
  • Implicit wait :-

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

    driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
    
    driver.findElement(By.cssSelector("div#button-verify-wrapper > a"))).click();
    driver.findElement(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a")).click();
    //Now find further element for the process 
    

我会提倡显式等待,您甚至可以将其作为一种带有显式等待的通用方法以供重用。许多与点击的交互可以明确等待元素变为可点击。虽然不推荐,但我确实理解有时 Thread.sleep 可能是唯一可行的选择,直到可以实施更好的方法。

一个是 Saurabh Gaur 提到的 WebDriverWait。另一个类似的选项提供了更精细的控制和自定义轮询。

另一个是 FluentWait:https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html

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

   WebElement foo = wait.until(new Function() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.id("foo"));
     }
   });

但请注意,使用 FluentWait,您可能会误以为您可以忽略其他 class 异常,例如 StaleElementReference,而编译器不会抱怨。 StaleElementReference 仍然会发生,与 TimeoutException class.

相同