Modèle d'objet de page (POM) et usine de pages dans Selenium

Qu'est-ce que le modèle d'objet de page ?

Modèle d'objet de page (POM) est un modèle de conception, couramment utilisé dans l'automatisation des tests, qui crée un référentiel d'objets pour les éléments de l'interface utilisateur Web. L'avantage du modèle est qu'il réduit la duplication de code et améliore la maintenance des tests.

Selon ce modèle, pour chaque page Web de l’application, il devrait y avoir une classe de page correspondante. Cette classe Page identifiera les WebElements de cette page Web et contient également des méthodes Page qui effectuent des opérations sur ces WebElements. Le nom de ces méthodes doit être donné en fonction de la tâche qu'elles effectuent, c'est-à-dire que si un chargeur attend que la passerelle de paiement apparaisse, le nom de la méthode POM peut être waitForPaymentScreenDisplay().

Modèle d'objet de page

Pourquoi un modèle objet de page ?

Démarrer une UI Automation dans Selenium WebDriver n’est PAS une tâche difficile. Il vous suffit de trouver des éléments, d'effectuer des opérations dessus.

Considérez ce script simple pour vous connecter à un site Web

Modèle d'objet de page

Comme vous pouvez le constater, tout ce que nous faisons est de trouver des éléments et de remplir des valeurs pour ces éléments.

Ceci est un petit script. La maintenance des scripts semble facile. Mais avec le temps, la suite de tests va se développer. À mesure que vous ajoutez de plus en plus de lignes à votre code, les choses deviennent difficiles.

Le principal problème avec la maintenance des scripts est que si 10 scripts différents utilisent le même élément de page, avec toute modification de cet élément, vous devez modifier les 10 scripts. Cela prend du temps et est sujet aux erreurs.

Une meilleure approche de la maintenance des scripts consiste à créer un fichier de classe distinct qui trouverait les éléments Web, les remplirait ou les vérifierait. Cette classe peut être réutilisée dans tous les scripts utilisant cet élément. À l’avenir, s’il y a une modification dans l’élément Web, nous devrons effectuer la modification dans un seul fichier de classe et non dans 1 scripts différents.

Cette approche est appelée Page Object Model dans Selenium. Cela contribue à rendre le code plus lisible, maintenable et réutilisable.

Modèle d'objet de page

Avantages du POM

  1. Le modèle de conception d'objet de page indique que les opérations et les flux dans l'interface utilisateur doivent être séparés de la vérification. Ce concept rend notre code plus propre et facile à comprendre.
  2. Le deuxième avantage est que le référentiel d'objets est indépendant des cas de test, nous pouvons donc utiliser le même référentiel d'objets dans un but différent avec différents outils. Par exemple, nous pouvons intégrer Page Object Model dans Selenium avec TestNG/JUnit pour des raisons fonctionnelles. Essais et en même temps avec JBehave/Cucumber pour les tests d'acceptation.
  3. Le code devient réduit et optimisé grâce aux méthodes de page réutilisables dans les classes POM.
  4. Les méthodes obtiennent des noms plus réalistes qui peuvent être facilement mappés avec l'opération se déroulant dans l'interface utilisateur. c'est-à-dire que si après avoir cliqué sur le bouton nous atterrissons sur la page d'accueil, le nom de la méthode ressemblera à 'gotoHomePage()'.

Comment implémenter POM ?

POM simple :

Il s'agit de la structure de base du modèle d'objet Page dans lequel tous les éléments Web du AUT et les méthodes qui fonctionnent sur ces éléments Web sont conservées dans un fichier de classe. Une tâche telle que la vérification doit être distincte dans le cadre des méthodes de test.

Implémenter POM

Exemple complet

Cas de test: Accédez au site de démonstration Guru99.

Étape 1) Accédez au site de démonstration Guru99

Implémenter POM

Étape 2) Sur la page d'accueil, vérifiez que le texte « Guru99 Bank » est présent

Implémenter POM

Étape 3) Connectez-vous à l'application

Implémenter POM

Étape 4) Vérifiez que la page d'accueil contient le texte « Manger Id : démo »

Implémenter POM

Voilà, nous avons affaire à 2 pages

  1. Page de connexion
  2. Page d'accueil (affichée une fois connecté)

En conséquence, nous créons 2 POM dans les classes Selenium

Page de connexion Guru99 POM

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99Login {

    WebDriver driver;

    By user99GuruName = By.name("uid");

    By password99Guru = By.name("password");

    By titleText =By.className("barone");

    By login = By.name("btnLogin");

    public Guru99Login(WebDriver driver){

        this.driver = driver;

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        driver.findElement(user99GuruName).sendKeys(strUserName);

    }

    //Set password in password textbox

    public void setPassword(String strPassword){

         driver.findElement(password99Guru).sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            driver.findElement(login).click();

    }

    //Get the title of Login Page

    public String getLoginTitle(){

     return    driver.findElement(titleText).getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();        
    }

}

Page d'accueil de Guru99 POM en sélénium

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99HomePage {

    WebDriver driver;

    By homePageUserName = By.xpath("//table//tr[@class='heading3']");

    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

    }

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    driver.findElement(homePageUserName).getText();

        }

}

Guru99 POM simple dans le cas de test Selenium

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import pages.Guru99HomePage;

import pages.Guru99Login;

public class Test99GuruLogin {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage;

    @BeforeTest

    public void setup(){

	System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("http://demo.guru99.com/V4/");

    }

    /**

     * This test case will login in http://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

Qu’est-ce que Page Factory dans Selenium ?

Usine de pages en sélénium est un concept de framework de modèle d'objet de page intégré pour Selenium WebDriver, mais il est très optimisé. Il est utilisé pour l'initialisation des objets Page ou pour instancier l'objet Page lui-même. Il est également utilisé pour initialiser les éléments de la classe Page sans utiliser « FindElement/s ».

Ici également, nous suivons le concept de séparation du référentiel d'objets de page et des méthodes de test. De plus, avec l'aide de la classe PageFactory dans Selenium, nous utilisons des annotations @FindBy pour trouver WebElement. Nous utilisons la méthode initElements pour initialiser les éléments Web

Usine de pages en sélénium

@FindBy Peut accepter tagName, partialLinkText, nom, linkText, identifiant, css, className, xpath comme attributs.

Regardons le même exemple que ci-dessus en utilisant Page Factory

Page de connexion Guru99 avec Page Factory

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99Login {

    /**

     * All WebElements are identified by @FindBy annotation

     */

    WebDriver driver;

    @FindBy(name="uid")

    WebElement user99GuruName;

    @FindBy(name="password")

    WebElement password99Guru;    

    @FindBy(className="barone")

    WebElement titleText;

    @FindBy(name="btnLogin")

    WebElement login;

    public Guru99Login(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        user99GuruName.sendKeys(strUserName);     
    }

    //Set password in password textbox

    public void setPassword(String strPassword){

    password99Guru.sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            login.click();

    }  

    //Get the title of Login Page

    public String getLoginTitle(){

     return    titleText.getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();           

    }

}

Page d'accueil de Guru99 avec Page Factory

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99HomePage {

    WebDriver driver;

    @FindBy(xpath="//table//tr[@class='heading3']")

    WebElement homePageUserName;    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }   

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    homePageUserName.getText();

        }

}

Guru99 TestCase avec le concept Page Factory

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import PageFactory.Guru99HomePage;

import PageFactory.Guru99Login;

public class Test99GuruLoginWithPageFactory {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage; 

    @BeforeTest

    public void setup(){

        System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("http://demo.guru99.com/V4/");

    }

    /**

     * This test go to http://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

}

La structure complète du projet ressemblera au diagramme :

Usine de pages en sélénium

AjaxElementLocatorFactory

AjaxElementLocatorFactory est un concept de chargement paresseux de PageFactory dans Selenium. Il est utilisé pour rechercher les éléments Web uniquement lorsque les éléments sont utilisés dans une opération. Il attribue un délai d'attente pour les WebElements à la classe de page d'objet. L'un des principaux avantages de l'utilisation du modèle PageFactory dans Selenium est la classe AjaxElementLocatorFactory.

Ici, lorsqu'une opération est effectuée sur un élément, l'attente de sa visibilité ne commence qu'à partir de ce moment. Si l'élément n'est pas trouvé dans l'intervalle de temps donné, Cas de test l'exécution lèvera l'exception 'NoSuchElementException'.

Usine de localisation AjaxElement

Résumé

  1. Le modèle d'objet de page dans Selenium WebDriver est un modèle de conception de référentiel d'objets.
  2. Le modèle objet de page Selenium crée notre code de test maintenable et réutilisable.
  3. Page Factory est un moyen optimisé de créer un référentiel d'objets dans le concept de framework Page Object Model.
  4. AjaxElementLocatorFactory est un concept de chargement paresseux dans Page Factory – modèle de conception d'objet de page pour identifier les WebElements uniquement lorsqu'ils sont utilisés dans une opération.

Téléchargez les fichiers du projet Selenium pour la démo dans ce didacticiel