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().
Pourquoi un modèle objet de page ?
Démarrage d’une UI Automation dans Selenium WebDriver n'est PAS une tâche difficile. Il vous suffit de trouver des éléments et d'effectuer des opérations dessus.
Considérez ce script simple pour vous connecter à un site Web
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 modèle d'objet de page dans SeleniumCela permet de rendre le code plus lisible, maintenable et réutilisable.
Avantages du POM
- 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.
- 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 le modèle d'objet de page dans Selenium au TestNG/JUnit pour fonctionnel Contrôle de qualité et en même temps avec JBehave/Cucumber pour les tests d'acceptation.
- Le code devient réduit et optimisé grâce aux méthodes de page réutilisables dans les classes POM.
- 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.
Exemple complet
Cas de test: Accédez au site de démonstration Guru99.
Étape 1) Accédez au site de démonstration Guru99
Étape 2) Sur la page d'accueil, vérifiez que le texte « Guru99 Bank » est présent
Étape 3) Connectez-vous à l'application
Étape 4) Vérifiez que la page d'accueil contient le texte « Manger Id : démo »
Voilà, nous avons affaire à 2 pages
- Page de connexion
- Page d'accueil (affichée une fois connecté)
En conséquence, nous créons 2 POM dans Selenium les classes
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 dans Selenium
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 Selenium Cas de test
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 Selenium?
Usine de pages dans Selenium est un concept de cadre 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
@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 :
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'expiration 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'.
Résumé
- Modèle d'objet de page dans Selenium WebDriver est un modèle de conception de référentiel d'objets.
- Selenium Le modèle objet de page crée notre code de test maintenable et réutilisable.
- Page Factory est un moyen optimisé de créer un référentiel d'objets dans le concept de framework Page Object Model.
- 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écharger Selenium Fichiers de projet pour la démo de ce didacticiel