2012-04-25 9 views
9

Domanda rapida relativa agli oggetti della pagina nel web driver del selenio. il nostro sito è molto dinamico con molti ajax e vari stati di autenticazione. È difficile capire come definire ciascun oggetto di pagina, ma diciamo che ho capito e definito diversi oggetti di pagina che rappresentano il nostro sito.Oggetto pagina Selenium WebDriver

Come gestite il passaggio da una pagina all'altra. Quindi ottengo un oggetto di pagina per la mia home page e uno per la pagina del mio account e uno per la mia pagina dei risultati. Quindi ho bisogno di scrivere un test che attraversi tutte le mie pagine per simulare un utente che esegue più azioni.

Come si dice dammi un oggetto HomePage per creare un nuovo utilizzo -> quindi ottenere un oggetto pagina account per eseguire alcune azioni dell'utente - quindi ottenere un oggetto pagina risultato per verificare tutte quelle azioni da un singolo script.

Come stanno facendo le persone?

grazie

+0

Cosa intendete esattamente per "oggetto pagina"? – Alp

risposta

10

Quando stai simulando avendo all'utente di inserire un nuovo URL nella la barra dell'URL del browser, quindi è responsabilità della classe di test creare l'oggetto della pagina di cui ha bisogno.

D'altra parte, quando si sta facendo qualche operazione sulla pagina che indurrebbe il browser a puntare a un'altra pagina - ad esempio, facendo clic su un collegamento o inviando un modulo - allora è responsabilità di quella pagina oggetto per restituire l'oggetto della pagina successiva.

Poiché non conosco abbastanza le relazioni tra la tua pagina iniziale, la pagina dell'account e la pagina dei risultati per dirti esattamente come si svolgerà nel tuo sito, userò un'app store online come esempio anziché.

Diciamo che hai una pagina di ricerca. Quando si invia il modulo in SearchPage, viene restituita una ResultsPage. E quando fai clic su un risultato, ottieni una pagina prodotto. Così le classi sarebbero simile a questa (abbreviato in appena i relativi metodi):

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

} 

Il metodo di prova per eseguire questa storia sarebbe simile a questa:

@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 

} 

Quindi, come si può vedere, c'è questo "concatenamento" di oggetti Page dove ognuno restituisce il successivo.

Il risultato è che si finisce con un sacco di oggetti di pagina diversi che istanziano altri oggetti di pagina. Quindi, se hai un sito di dimensioni considerevoli, potresti prendere in considerazione l'utilizzo di un framework di iniezione delle dipendenze per la creazione di tali oggetti di pagina.

+0

Questo è quello che pensavo di dover fare. sembra appena un po 'goffo come il nostro sito è molto ajaxy e le azioni sul sito tornare in luoghi diversi a seconda di quale stato l'utente è attualmente. – ducati1212

+0

Il problema con questo codice è che ogni pagina deve chiamare PageFactory.initObjects() e l'istanza del driver non può inizializzare tutti gli oggetti su 2 pagine diverse (diciamo che sono 2 finestre differenti o una cornice incorporata). Quindi, mentre sono d'accordo che questo è un ottimo modello di progettazione per molte cose, questo schema si riduce rapidamente a funzionare solo per alcune applicazioni. Il modo in cui WebDriver PageFactory è progettato, è molto meglio aprire un oggetto di pagina, usarlo, contrassegnarlo per la garbage collection, quindi istanziare la pagina successiva, usarlo, ecc. Forse potresti estendere PageFactory, come soluzione, forse. – djangofan

4

Beh, ho creato le mie classi Java che rappresentano le pagine:

dire, il sotto è il codice per rappresentare home page. Qui l'utente può accedere:

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


} 

E la pagina per Cliente può assomigliare a questa. Qui sto dimostrando, come ottenere, per esempio, utente connesso:

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

} 

e il test può andare in questo modo:

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

Suggerisco di utilizzare un framework che fornisce supporto per questi modelli. Geb è uno dei migliori in circolazione.Di seguito è riportato un esempio tratto dal loro manuale

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

Generalmente si desidera modellare cosa effettivamente fa un utente quando si utilizza il sito. Questo finisce per assumere la forma di un Domain Specific Language (DSL) quando si usano oggetti di pagina. Si confonde però con i componenti della pagina riutilizzabili.

Ora che Java 8 è fuori con metodi predefiniti, i componenti di pagina riutilizzabili possono essere trattati come mixin utilizzando metodi predefiniti. Ho un post sul blog con alcuni esempi di codice trovati che spiegano questo in modo più dettagliato: http://blog.jsdevel.me/2015/04/pageobjects-done-right-in-java-8.html