Selenium:定义元素的优化(Page Object)

时间:2017-12-21 09:41:05

标签: java selenium selenium-webdriver

我有,例如“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注释?例如不要重复这么多次,因为我们有很多元素。

3 个答案:

答案 0 :(得分:1)

您可以尝试将页面拆分为不同的对象,以便可以重复使用其他页面上的某些元素。

如果您查看您的SignUpPage,它可能包含以下元素: - 导航栏 - 注册表格 - 页脚

如果您查看着陆页,它可能还有一个导航栏和页脚

如果您为每个元素创建一个单独的类,您可以将这些元素作为“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("me@xyz.com", "s3cr3t");
// Or
LandingPage.NavBar.GoToSignUpPage().SignUp("me@xyz.com", "s3cr3t");

在上一个示例中,SignUpPage 有一个 SignUpForm,在调用SignUp

时使用

答案 1 :(得分:0)

当我们有多个标准来识别一个或多个WebElement对象时,您可以使用以下其中一个

@FindBys

@FindBys({
  @FindBy(id = "register-email")
  @FindBy(id = "register-confirm-email")
  @FindBy(id = "register-password")
})

private List<WebElement> elementsWithBoth_EmailANDPassword;

@FindAll:

@FindAll({
   @FindBy(id = "register-email")
   @FindBy(id = "register-confirm-email")
   @FindBy(id = "register-password")
})

private List<WebElement> elementsWithBoth_EmailANDPassword 

检查此link。希望这可以帮助。

答案 2 :(得分:0)

当您通过 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 <下/ strong> 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");
    }