2012-04-25 57 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

相關問題