对于下面的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"))?
我希望我的问题有道理。
答案 0 :(得分:1)
当调用PageFactory.initElements
时,它会解析当前的DOM。如果WebElement
在那段时间内不存在,则无法将其作为变量的值给出,就像您使用{找不到现有WebElement
一样{1}}。
您的解决方案是可行的方法,但在加载driver.findElement
时我会使用explicit wait和Expected 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);
}
}