1

为了抽象和可重用性,将网页上的元素建模为类的理想方法是什么?
目前,我创建的是一个包含以下成员变量的 BaseElement.java 类:

WebDriver webdriver;

构造函数:

protected BaseElement(WebDriver driver)
 {
  //Initialization.
 }

然后我将这个类扩展到代表网页上某个元素的其他类中。
例如,我有一个扩展 BaseElement.java 的 Button.java 类。

  public class ButtonElement extends BaseElement {


        String locator;
        By by;
        WebElement button;

        protected ButtonElement(WebDriver driver, String locator, By by) {
            super(driver);
            this.by = by;
            this.locator = locator;

           //code to find the element using driver.findElement()
           // I am not sure how to use By in here depending upon what I pass in the constructor when I create an object of this class. Any suggestions?
        }

        public void click() {

          button.click();
        }

        //Other methods which will interact with the element in other ways.
  }

因此,在我的 PageObject 类中,我将使用上述内容:

Button loginButton = new Button(driver,"btn-Login",By.id);
loginButton.click();

这是正确的方法吗?有没有更好的方法来抽象,在单个类中隐藏复杂的逻辑,并从 webdriver 的角度重用按钮、文本框、选择列表等元素?提前致谢!

4

3 回答 3

2

Well, in this case, there is more than one correct way to do it.

1st do not reinvent the wheel - there exists PageObject which does probably the same as you want: Read about it here

2nd my personal approach is to have Class for every page I visit and model methods to describe what they are doing. Something like this:

 class InitPage {
   private Webdriver driver;

   public InitPage(){
     driver = new FirefoxDriver();
     driver.get("http://my-test-page.com");
   }

    public WebDriver getDriver(){
     return driver;
    }

    public AdminPage loginToSite(String username, String Password){#
     WebElement login = driver.FindElement(By.id("adm-login");
     login.sendKeys(username);
     WebElement pwd = driver.FindElement(By.id("adm-pwd");
     pwd.sendKeys(password);
     WebElement confirmButton = driver.FindElement(By.id("login-submit");\
     confirmButton.click();
     return new AdminPage(this);

   }

 }


class AdminPage{
  private InitPage initPage

  public AdminPage(InitPage init){
     this.initPage = init;
  }

  public String getLoggedInUser();
  WebElement user = initPage.getDriver().findElement(By.id("usr-credential-name")); //just show off how you approach the webDriver
  return user.getText();   

}

And later on in the tests:

@Test
public void TestLoging(){
  InitPage firstPage = new InitPage();
  AdminPage administration = firstPage.login("Pavel", "omgTooSecretToTellYou!");
  Assert.assertEquals(administration.getLoggedInUser(), "Pavel"); //example how you can do the tests
}
于 2013-03-18T10:57:01.840 回答
2

我不相信每次定位元素时都传递驱动程序是要走的路,但我知道您的目标是避免重复代码。相反,您可以拥有一个访问驱动程序类的类,该类在您的代码开始时被实例化。通过这种方式,您可以传入一个“类型”和“属性”,它将定位任何已实现的元素。例如。类型:Id、Class、XPath;和属性:“文本”、“//div[@class="class"]/div[2]”。

因此,
DriverClass:有一个 WebDriver 实现 FindElement 并为每种类型提供一个开关。
WrapperClass:它具有诸如“Click”或“DoesElementExist”之类的类,它们使用DriverClass 来实现功能。
TestClass:使用对 WrapperClass 的调用来实现您的代码逻辑。

您可以更进一步,在另一个使用 WrapperClass 的类中实现常见的动作分组,这样 TestClass 就变得更干净了。

于 2013-03-21T21:36:27.720 回答
1

我部分同意 Abhijeet 和 Pavel 的观点,当抽象一个 Web 元素时,扩展一个已经实现了 Webelements 接口的所有方法的类对你有好处,否则正如 Pavel 所说,这就像重新发明轮子一样,我个人的看法是是抽象更大的WebElements,例如Forms,它又具有多个Webelements,例如。表格就像较小的页面......但这也是我的个人意见。

于 2015-04-08T14:07:03.830 回答