我有,例如, “SignUp Page”作为要实现的页面对象之一:
public class SignUpPage {
WebDriver driver;
public SignUpPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
}
我想在此页面中添加(查找)元素(使用@FindBy),这将在其他方法中使用:
public class SignUpPage {
WebDriver driver;
public SignUpPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy (id = "register-email")
private WebElement emailField;
@FindBy (id = "register-confirm-email")
private WebElement confirmEmailField;
@FindBy (id = "register-password")
private WebElement passwordField;
public SignUpPage typeEmail(String email) {
emailField.sendKeys(email);
return this;
}
public SignUpPage typeConfirmEmail(String email) {
confirmEmailField.sendKeys(email);
return this;
}
}
有没有更好的组织@FindBy注释的方法?例如不要重复这么多次,因为我们有很多元素。
您可以尝试将页面拆分为不同的对象,以便可以重复使用其他页面上的某些元素。
如果您查看您的SignUpPage,它可能包含以下元素: - Navbar - 注册表单 - 页脚
如果您查看着陆页,它可能还有一个导航栏和页脚
如果为这些元素中的每一个创建单独的类,则可以将这些元素作为“has-a”关系船的每个页面的一部分添加
public class SignUpPage {
public SignUpForm signUpForm;
public NavBar navBar;
public Footer footer;
private WebDriver driver;
public SignUpPage(WebDriver driver) {
this.driver = driver;
signUpForm = new SignUpForm(driver);
navbar = new NavBar(driver);
footer = new Footer(driver)
}
}
public class SignUpForm {
WebDriver driver;
public SignUpForm(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy (id = "register-email")
private WebElement emailField;
@FindBy (id = "register-confirm-email")
private WebElement confirmEmailField;
@FindBy (id = "register-password")
private WebElement passwordField;
public SignUpPage typeEmail(String email) {
emailField.sendKeys(email);
return this;
}
public SignUpPage typeConfirmEmail(String email) {
confirmEmailField.sendKeys(email);
return this;
}
}
public class NavBar {
WebDriver driver;
public NavBar(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy (id = "menu")
private WebElement menu;
}
public class Footer {
WebDriver driver;
public Footer(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy (id = "contactList")
private WebElement contactList;
}
如果你将Login(String mail, String password)
这样的方法添加到NavBar
类,你可以从每个有NavBar
的页面调用它来使用像
LandingPage.NavBar.Login("[email protected]", "s3cr3t");
// Or
LandingPage.NavBar.GoToSignUpPage().SignUp("[email protected]", "s3cr3t");
在最后一个例子中,SignUpPage
有一个SignUpForm
,在调用SignUp
时使用
当我们有多个标准来标识一个或多个WebElement对象时,您可以使用以下之一
@FindBys
@FindBys({
@FindBy(id = "register-email")
@FindBy(id = "register-confirm-email")
@FindBy(id = "register-password")
})
private List<WebElement> elementsWithBoth_EmailANDPassword;
@找到所有 :
@FindAll({
@FindBy(id = "register-email")
@FindBy(id = "register-confirm-email")
@FindBy(id = "register-password")
})
private List<WebElement> elementsWithBoth_EmailANDPassword
检查这个link。希望这可以帮助。
当您通过PageFactory
实施POM
时,所以在每个Page Object
中你需要定义每个WebElement
,你想在Page Object
中与之交互,就像我们在正常情况下反复做driver.findElement()
和driver.findElements()
一样。
所以你正在谈论上述观点。
已经说过你的代码块中仍然存在一些缺陷,如下所示:
SignUpPage
:页面对象类的constructor
,即public class SignUpPage {}
不应该用于初始化Page Object
。从逻辑上讲,当调用constructor
时,会自动调用Page Object Class的PageFactory.initElements()
。理想情况下,构造函数看起来像:
WebDriver driver;
//constructor
public SignUpPage(WebDriver driver)
{
this.driver=driver;
}
PageFactory.initElements(driver, this)
:Page Object
的初始化必须从你的Test Class
(可能在@Test
Annotation下)控制,你可以在运行时根据你的Page Object
要求加载任何Test Case
,如下所示:
@Test (priority=0)
public void checkSignUp()
{
//Initialize the Page Object - SignUpPage.class
SignUpPage sign_up_page = PageFactory.initElements(driver, SignUpPage.class);
//Call the method - typeEmail(String email) within SignUpPage.class
sign_up_page.typeEmail("Dmitry");
}