使用@FindBy注释和PageFactory映射动态元素

时间:2017-03-27 03:10:16

标签: java selenium automated-tests

对于下面的Page Object示例类,我有一个accountsLink私有成员,它在加载时映射到Login页面上的非动态元素。当从构造函数调用initElements方法时,使用FindBy批注初始化它。

public class Login {
    private WebDriver driver;

    @FindBy(id = "account")
    private WebElement accountsLink;

    //constructor, elements are initialized by the PageFactory
    public MainPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    //clicking accounts opens a dynamic ajax menu which has a Sign In Button
    public SignInPage clickAccountsLink() {
        accountsLink.click();   
        WebElement signInButton = driver.findElement(By.id("signin"));
        signInButton.click();
        return new SignInPage(driver);
    }
}

现在出现问题。我有另一个元素(signInButton),它只在你点击accountsLink元素时动态加载。此操作不会将您带到另一个页面,但只会显示一个ajax菜单,其中会出现登录按钮。

我的问题是,由于signInButton元素仅在单击accountsLink元素时出现,它是否可以使用FindBy注释声明为Login类的成员,或者我是否必须坚持使用当前使用驱动程序的解决方案。 clickAccountsLink方法中的findElement(By.id(" signin"))?

我希望我的问题有道理。

2 个答案:

答案 0 :(得分:1)

当调用PageFactory.initElements时,它会解析当前的DOM。如果WebElement在那段时间内不存在,则无法将其作为变量的值给出,就像您使用{找不到现有WebElement一样{1}}。

您的解决方案是可行的方法,但在加载driver.findElement时我会使用explicit waitExpected Conditions

答案 1 :(得分:0)

你可以声明,我不认为它会给你任何错误。 Page Factory初始化类时会创建一个虚拟元素。它仅在您第一次与元素相交时才创建实际元素。

例如,在下面的类 NoExistingElement 元素不存在且它不会给我任何错误,如果我将调用 enterText 方法类。测试用例将通过而没有任何错误。

但是,如果我将尝试调用 NoExistingElement 元素上的任何函数,那么只有它会因Webdriver异常而失败,ElementNotFoundException

   public class GoogleSearch {

    @FindBy(name="q")
    static WebElement searchBox;

    @FindBy(name = "qqqqq")
    WebElement NoExistingElement;

    public GoogleSearch(WebDriver driver){
        PageFactory.initElements(driver, this);
        driver.get("https://www.google.com");

    }

    public void searchOnGoogle(String text){
        searchBox.sendKeys(text);

    }
}