2012-04-25 58 views
9

关于selenium webdriver中页面对象的快速问题。我们的网站是非常动态的,有很多ajax和各种身份验证状态。很难弄清楚如何定义每个页面对象,但可以说我已经弄明白了,并定义了代表我们网站的几个页面对象。Selenium WebDriver页面对象

如何处理页面间的交叉。因此,我为我的主页获取页面对象,为我的帐户页面获取页面对象,为我的结果页获取一个页面对象。然后,我需要编写一个测试遍历我的所有页面,以模拟用户执行多个操作。

How do you say给我一个HomePage对象来创建一个新的使用 - >然后获取一个帐户页面对象去执行一些用户操作 - 然后得到一个结果页面对象来验证所有这些操作从一个脚本。

这是怎么回事?

感谢

+0

“页面对象”究竟是什么意思? – Alp 2012-04-25 12:45:25

回答

10

当你模拟让用户输入一个新的URL到浏览器的URL栏,那么测试类负责创建它所需的页面对象。

另一方面,当您在页面上执行一些操作会导致浏览器指向另一个页面 - 例如,单击链接或提交表单 - 那么这是该页面的责任对象返回下一个页面对象。

由于我对主页,帐户页面和结果页面之间的关系知之甚少,无法确切地告诉您网站会如何在您的网站上播放,我将以在线商店应用为例代替。

假设你有一个SearchPage。当您在SearchPage上提交表单时,它将返回一个结果页面。当你点击一个结果时,你会得到一个ProductPage。因此,班会是这个样子(简称只是相关的方法):

public class SearchPage { 

    public void open() { 
     return driver.get(url); 
    } 

    public ResultsPage search(String term) { 
     // Code to enter the term into the search box goes here 
     // Code to click the submit button goes here 
     return new ResultsPage(); 
    } 

} 

public class ResultsPage { 

    public ProductPage openResult(int resultNumber) { 
     // Code to locate the relevant result link and click on it 
     return new ProductPage(); 
    } 

} 

的测试方法来执行这个故事会是这个样子:

@Test 
public void testSearch() { 

    // Here we want to simulate the user going to the search page 
    // as if opening a browser and entering the URL in the address bar. 
    // So we instantiate it here in the test code. 

    SearchPage searchPage = new SearchPage(); 
    searchPage.open(); // calls driver.get() on the correct URL 

    // Now search for "video games" 

    ResultsPage videoGameResultsPage = searchPage.search("video games"); 

    // Now open the first result 

    ProductPage firstProductPage = videoGameResultsPage.openResult(0); 

    // Some assertion would probably go here 

} 

因此,大家可以看到,有这个页面对象的“链接”,每个页面都会返回下一个。

其结果是,你最终会得到很多不同的页面对象实例化其他页面对象。所以如果你有一个相当规模的网站,你可以考虑使用依赖注入框架来创建这些页面对象。

+0

这是我认为我需要做的。它似乎有点笨重,因为我们的网站非常麻烦,并且网站上的操作根据用户当前处于什么状态而返回到不同的地方。 – ducati1212 2012-04-30 12:23:29

+0

10此代码的问题是每个页面都需要调用PageFactory.initObjects()和驱动程序实例无法初始化2个不同页面上的所有对象(可以说它们是2个不同的窗口或嵌入式框架)。所以,虽然我同意这是一个很好的设计模式,但这种模式很快就会崩溃,只能用于某些应用程序。 WebDriver PageFactory的设计方式是,打开一个页面对象,使用它,标记为垃圾收集,然后实例化下一个页面,使用它,等等。或许你可以扩展PageFactory,或许可以解决这个问题。 – djangofan 2013-03-22 16:36:02

4

好吧,我创建了代表的网页自己的Java类:

说,下面的是代码来表示主页。这里用户可以登录:

public class HomePage{ 
    private WebDriver driver; 
    private WebElement loginInput; 
    private WebElement passwordInput; 
    private WebElement loginSubmit; 

    public WebDriver getDriver(){ 
    return driver; 
    } 

    public HomePage(){ 
    driver = new FirefoxDriver(); 
    } 

    public CustomerPage login(String username, String password){ 
    driver.get("http://the-test-page.com"); 
    loginInput = driver.findElement(By.id("username")); 
    loginInput.sendKeys(username); 
    passwordInput = driver.findElement(By.id("password")); 
    passwordInput.sendKeys(password); 
    loginSubmit = driver.findElement(By.id("login")); 
    loginSubmit.click(); 
    return new CustomerPage(this); 
    } 


} 

而Customer的页面可以是这样的。我在这里展示,如何得到的,比如说,登录用户:

public class CustomerPage{ 
    private HomePage homePage; 
    private WebElement loggedInUserSpan; 

public CustomerPage(HomePage hp){ 
    this.homePage = hp; 
    } 

public String getLoggedInUser(){ 
     loggedInUserSpan = homePage.getDriver().findElement(By.id("usrLongName")); 
     return loggedInUserSpan.getText(); 
} 

} 

而且测试可以是这样的:

@Test 
public void testLogin(){ 
    HomePage home = new HomePage(); 
    CustomerPage customer = home.login("janipav", "extrasecretpassword"); 
    Assert.assertEquals(customer.getLoggedInUser(), "Pavel Janicek"); 
} 
1

我建议你使用一个为这些模式提供支持的框架。 Geb是那里最好的之一。下面是他们的手工

Browser.drive { 
    to LoginPage 
    assert at(LoginPage) 
    loginForm.with { 
     username = "admin" 
     password = "password" 
    } 
    loginButton.click() 
    assert at(AdminPage) 
} 

class LoginPage extends Page { 
    static url = "http://myapp.com/login" 
    static at = { heading.text() == "Please Login" } 
    static content = { 
     heading { $("h1") } 
     loginForm { $("form.login") } 
     loginButton(to: AdminPage) { loginForm.login() } 
    } 
} 

class AdminPage extends Page { 
    static at = { heading.text() == "Admin Section" } 
    static content = { 
     heading { $("h1") } 
    } 
} 
2

您通常想要模拟用户在使用您的网站时实际执行的操作。当使用页面对象时,这最终将采用域特定语言(DSL)的形式。尽管可重用页面组件令人困惑。

既然Java 8已经使用默认方法,那么可重用的页面组件可以被视为使用默认方法的mixin。我有一个博客文章,其中发现了一些代码示例,这些代码示例更详细地解释了这些内容:http://blog.jsdevel.me/2015/04/pageobjects-done-right-in-java-8.html

相关问题