隐式和显式等待不起作用。
如何解决?
如何在PageFactory中使用FluentWait,因此在测试中无需使用定位器。
旨在完全不使用Thread.sleep。
使用的工具:Selenium,TestNG,WebDriverManager
网站是在AngularJS上构建的。
public class LoginPage {
private WebDriver driver;
public StudioMenuPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy(xpath = "//div[@class='login']")
private WebElement loginButton;
public WebElement getLoginButton() {
return loginButton;
}
}
public class TestBase {
public static WebDriver driver = null;
@BeforeTest()
public void initialize() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--no-sandbox");
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
}
public class LoginTest extends TestBase {
LoginPage loginPage;
@Test
private void makeLogin() {
loginPage = new LoginPage(driver);
// Does not work with Implicit Wait:
/*
loginPage.getLoginButton().click;
*/
// Works with Thread.sleep:
/*
Thread.sleep(4000);
loginPage.getLoginButton().click;
*/
// Does not work with Explicit Wait:
/*
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(loginPage.getLoginButton()));
loginPage.getLoginButton().click;
*/
// Works with FluentWait:
/*
new FluentWait<>(driver).withTimeout(Duration.ofSeconds(5)).pollingEvery(Duration.ofMillis(500))
.ignoring(WebDriverException.class)
.until(d -> {
WebElement el = d.findElement(By.xpath("//div[@class='login']"));
el.click();
return el;
});
*/
}
如果使用隐式和显式服务员,则会发生以下错误:
org.openqa.selenium.WebDriverException: unknown error: Element <div class="login">...</div> is not clickable at point (225, 334). Other element would receive the click: <div id="cdk-overlay-0" class="cdk-overlay-pane" dir="ltr" style="pointer-events: auto; top: 316px; left: 201.5px;">...</div>
(Session info: headless chrome=73.0.3683.86)
(Driver info: chromedriver=2.46.628411 (3324f4c8be9ff2f70a05a30ebc72ffb013e1a71e),platform=Mac OS X 10.14.4 x86_64) (WARNING: The server did not provide any stacktrace information)
答案 0 :(得分:2)
第一:我们不会混合使用隐式和显式等待!这样做可能导致无法预测的等待时间。
建议您将 PageFactory 与 AjaxElementLocatorFactory 结合使用,这将为每个被访问的元素随时等待长达指定的秒数,并且会忽略< strong> CacheLookup 标签。
PageFactory.initElements(new AjaxElementLocatorFactory(driver,15),this);
如果在给定的时间间隔内未找到该元素,它将抛出 NoSuchElementException 异常。
以下示例显示了如何在Page Factory中实现FluentWait-
protected synchronized void waitForElementVisibilityAndClick(WebElement element, int timeOut, String elementName) {
protected static Wait<WebDriver> wait = null;
try {
wait = new FluentWait<WebDriver>((WebDriver) driver).withTimeout(timeOut, TimeUnit.SECONDS).pollingEvery(1,
TimeUnit.SECONDS);
wait.until(ExpectedConditions.visibilityOf(element));
element.click();
}catch(Exception e) {
}
}