class HomePage {
loginBox = {
usernameTextBox = findElement(By.cssSelector("input.login"));
passwordTextBox = findElement(By.cssSelector("input.password"));
};
headerTitle = findElement(By.cssSelector("h1.title"));
}
,然后在测试中,您可以按
function loginTest() {
homePage = new HomePage();
homePage.loginBox.usernameTextBox.sendKeys(username);
homePage.loginBox.passwordTextBox.sendKeys(password);
homePage.loginBox.loginButton.click();
assert homePage.headerTitle.contains("Logged In")
}
然而,在Java中,当您尝试使用PageFactory构建内部类时,它似乎并没有陷入内部类中。如果将内部类设置为静态,则可以直接实例化内部类页面对象,但是必须将它们分配给新的对象字段(例如
homePageLoginBox = PageFactory.initElements(HomePage.loginBox.class);
),这意味着必须显式实例化每个内部类。Page Factory是否有办法一次创建一个分层的页面结构,并实例化和访问这样一个有组织的Page Object(包括所有细分)?
#1 楼
继承很快就会变得混乱,您可以尝试使用合成来代替使用继承来做一件事。将嵌套的页面对象创建为完整的顶级类,然后将它们作为要访问的实例字段放入代码中。// It's own file
public class MyPage {
private final WebDriver driver;
// Nest your "inner" class through composition instead of inheritance
public final LoginBoxPage loginBox;
public MyPage(WebDriver driver) {
this.driver = driver;
loginBox = new LoginBoxPage(driver);
}
// It's own file
public class LoginBoxPage {
private final WebDriver driver;
private final By username = By.css(...);
private final By password = By.css(...);
private final By submitButton = By.css(...);
public LoginBoxPage(WebDriver driver) {
this.driver = driver;
}
public LoginBoxPage username(String user) {
driver.findElement(this.username).sendKeys(user);
return this;
}
public LoginBoxPage password(String pw) {
driver.findElement(this.password).sendKeys(pw);
return this;
}
public void submit() {
driver.findElement(submitButton).click();
}
}
此特定示例可以像下面这样使用:
public void test() {
WebDriver driver = new ChromeDriver();
MyPage myPage = new MyPage(driver);
// utilizing fluent returns
myPage.loginBox.username("herp").password("derp").submit();
// or not
myPage.loginBox.username("herp");
myPage.loginBox.password("derp");
myPage.loginBox.submit();
}
评论
我认为,使页面对象不可变,可以减少副作用,从而极大地提高了长期可维护性。如果您有公共实例字段,请将其保留为最终值可确保您的分配不会被浪费。我将它们公开,以使其更接近您对javascript的熟悉,但是通常我会将带有吸气剂的组合式内部页面对象设为私有,以进一步推动家庭不变性。
–朱利安
17年8月25日在18:22
在您的示例中,您没有像homePageLoginBox = PageFactory.initElements(HomePage.loginBox.class); ...那样使用pageFactory。
– 1234
18年7月25日在22:48
@Studeera不,您什么都没有丢失。当我写这篇文章时,我不知道PageObject是一个特定的实现,因为我从未使用过它。因此,我认为该主题更广泛地讨论了页面对象模型。后见之明。我不知道如何使用PageFactory实现将它们放在一起。
–朱利安
18年8月15日在20:04
评论
您是否尝试过重载类实例化方法,并在父实例上包含子类实例?@mutt我最终明确地初始化了内部类。我不认为pageFactory.initElements()执行构造函数,对吗?无论如何,您都必须以某种方式将驱动程序对象传递给它们...
是的,这就是为什么我提到超载。您基本上可以重新编写initElements()并允许它传递到驱动程序中,以便您可以针对现有实例实例化它们,而不是新实例化。
PageFactory并不是页面对象的实现。在我当前的项目中,我们只是使用充满定位器的嵌套静态类,以及将它们作为参数的辅助方法。不仅省去了无需实例化的麻烦,而且还大大减少了StaleElementExceptions。