2012-04-25 12 views
9

selenium webdriverのページオブジェクトに関する簡単な質問。私たちのサイトは非常にダイナミックで、多くのAjaxとさまざまな認証状態を持っています。それぞれのページオブジェクトをどのように定義するかを理解するのは難しいですが、わたしはそれを理解して、私たちのサイトを表すいくつかのページオブジェクトを定義しました。Selenium WebDriverページオブジェクト

どのようにページ間で交差を処理しますか。だから私は自分のホームページと私のアカウントページと私の結果ページのための1つのページオブジェクトを取得します。次に、複数のアクションを実行するユーザーをシミュレートするために、すべてのページを横断するテストを作成する必要があります。

How do you say私は新しい使用を作成するためのホームページオブジェクトを与える - いくつかのユーザーアクションを実行するアカウントページオブジェクトを取得する - その後、結果ページオブジェクトを取得して、これらのアクションをすべて単一のスクリプトから確認します。

どのように人々がこれをやっていますか?

言って、以下のホームページを表現するためのコードです:

おかげ

+0

"ページオブジェクト"とはどういう意味ですか? – Alp

答えて

10

ユーザーがに新しいURLを入力したシミュレートしていますブラウザのURLバー、それは必要なページオブジェクトを作成するのはテストクラスの責任です。

一方、ブラウザが別のページを指し示すような操作をページ上で行っている場合(たとえば、リンクをクリックしたりフォームを送信した場合など)、そのページの責任があります次のページオブジェクトを返すオブジェクト。

私はそれはあなたのサイトに出てプレーしたい正確にどのようにあなたを伝えるためにあなたのホームページ、アカウントページ、および結果ページ間の関係について十分に知らないので、私は、一例として、オンラインストアのアプリを使用します代わりに。

検索ページがあるとします。 SearchPageでフォームを送信すると、ResultsPageが返されます。結果をクリックすると、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

+0

このコードの問題は、各ページがPageFactory.initObjects()とドライバインスタンスは、2つの異なるページ上のすべてのオブジェクトを初期化することはできません(2つの異なるウィンドウまたは埋め込みフレームと言います)。ですから、これは多くのものにとって素晴らしいデザインパターンであると私は同意しますが、このパターンは特定のアプリケーションでのみ機能するようにすばやく分類されます。 WebDriver PageFactoryが設計されている方法、ページオブジェクトを開く方がはるかに優れている、ガベージコレクションのマークを付けて、次のページをインスタンス化する、それを使うなど。PageFactoryを回避策として拡張する可能性があります。 – djangofan

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); 
    } 


} 

そして、お客様のページは次のように表示されます。ここで私は実証しています、取得する方法、たとえば、ログインしているユーザー:

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はそこの中で最高の1つです。以下はマニュアルの例です

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") } 
    } 
} 
0

Page Objectパターンを使用してSelenium Webdriverテストを書くのが楽しいです。しかし、次のページまたはページコンポーネントを常に明示的にインスタンス化して戻さなければならないという冗長さと繰り返しで、個人的に悩まされました。だから、Pythonのメタクラスの恩恵を受けて、私はlibrary, called Keteparaha, that automatically figures out what should be returned from a selenium page object's method callsと書いた。

2

一般的に、サイトを使用しているユーザーが実際に行っていることをモデル化したいと考えています。これは、ページオブジェクトを使用するときに、ドメイン固有言語(DSL)の形式をとることになります。しかし、再利用可能なページコンポーネントと混乱してしまいます。

Java 8にはデフォルトメソッドが用意されているため、再利用可能なページコンポーネントはデフォルトメソッドを使用してmixinとして扱うことができます。私はここにいくつかのコードサンプルを掲載したブログ記事を掲載しています。http://blog.jsdevel.me/2015/04/pageobjects-done-right-in-java-8.html