如何在PageFactory中使用FluentWait

时间:2019-05-01 14:36:56

标签: selenium selenium-webdriver

隐式和显式等待不起作用。
如何解决?
如何在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)

1 个答案:

答案 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) {
    }
}