Modelo de objetos de página (POM) y fábrica de páginas en Selenium

¿Qué es el modelo de objetos de página?

Modelo de objetos de página (POM) es un patrón de diseño, utilizado popularmente en la automatización de pruebas, que crea un repositorio de objetos para elementos de la interfaz de usuario web. La ventaja del modelo es que reduce la duplicación de código y mejora el mantenimiento de las pruebas.

Según este modelo, para cada página web de la aplicación, debe haber una clase de página correspondiente. Esta clase de página identificará los elementos web de esa página web y también contiene métodos de página que realizan operaciones en esos WebElements. El nombre de estos métodos se debe proporcionar según la tarea que están realizando, es decir, si un cargador está esperando que aparezca la pasarela de pago, el nombre del método POM puede ser waitForPaymentScreenDisplay().

Modelo de objeto de página

¿Por qué el modelo de objetos de página?

Iniciar una automatización de la interfaz de usuario en Selenium WebDriver NO es una tarea difícil. Solo necesitas encontrar elementos, realizar. operaciones sobre él.

Considere este sencillo script para iniciar sesión en un sitio web

Modelo de objeto de página

Como puede observar, todo lo que estamos haciendo es encontrar elementos y completar valores para esos elementos.

Este es un pequeño guión. El mantenimiento del script parece fácil. Pero con el tiempo el conjunto de pruebas crecerá. A medida que agrega más y más líneas a su código, las cosas se vuelven difíciles.

El principal problema con el mantenimiento de scripts es que si 10 scripts diferentes utilizan el mismo elemento de página, con cualquier cambio en ese elemento, deberá cambiar los 10 scripts. Esto requiere mucho tiempo y es propenso a errores.

Un mejor enfoque para el mantenimiento de scripts es crear un archivo de clase separado que encuentre elementos web, los complete o los verifique. Esta clase se puede reutilizar en todos los scripts que utilicen ese elemento. En el futuro, si hay un cambio en el elemento web, necesitaremos realizar el cambio en solo 1 archivo de clase y no en 10 scripts diferentes.

Este enfoque se llama modelo de objetos de página en Selenium. Ayuda a hacer el código más readable, mantenible y reutilizable.

Modelo de objeto de página

Ventajas del POM

  1. Patrón de diseño de objetos de página dice operaLas operaciones y flujos en la interfaz de usuario deben separarse de la verificación. Este concepto hace que nuestro código sea más limpio y fácil de entender.
  2. El segundo beneficio es que el repositorio de objetos es independiente de los casos de prueba, por lo que podemos usar el mismo repositorio de objetos para un propósito diferente con diferentes herramientas. Por ejemplo, podemos integrar el modelo de objetos de página en Selenium with TestNG/JUnit para funcional Pruebas y al mismo tiempo con JBehave/Cucumber para pruebas de aceptación.
  3. El código se vuelve menos y más optimizado debido a los métodos de página reutilizables en las clases POM.
  4. Los métodos obtienen nombres más realistas que se pueden asignar fácilmente con el operación que sucede en la interfaz de usuario. es decir, si después de hacer clic en el botón llegamos a la página de inicio, el nombre del método será como 'gotoHomePage()'.

¿Cómo implementar POM?

POM sencillo:

Es la estructura básica del marco del modelo de objetos de página donde todos los elementos web del AUT y el método que operaLos datos de estos elementos web se mantienen dentro de un archivo de clase. Una tarea como la verificación debe estar separada como parte de los métodos de prueba.

Implementar POM

Ejemplo completo

Caso de prueba: Vaya al sitio de demostración de Guru99.

Paso 1) Vaya al sitio de demostración de Guru99

Implementar POM

Paso 2) En la página de inicio, verifique que el texto "Guru99 Bank" esté presente

Implementar POM

Paso 3) Inicie sesión en la aplicación

Implementar POM

Paso 4) Verifique que la página de inicio contenga texto como "Id. del administrador: demostración"

Implementar POM

Aquí estamos tratando con 2 páginas.

  1. Página de inicio
  2. Página de inicio (se muestra una vez que inicia sesión)

En consecuencia, creamos 2 POM en Selenium privadas

Página de inicio de sesión de 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();        
    }

}

Página de inicio de Guru99 POM en 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 en Selenium Caso de prueba

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é es Page Factory en Selenium?

Fábrica de páginas en Selenium es un concepto de marco de modelo de objetos de página incorporado para Selenium WebDriver pero está muy optimizado. Se utiliza para la inicialización de objetos de página o para crear una instancia del propio objeto de página. También se utiliza para inicializar elementos de clase de página sin utilizar "FindElement/s".

Aquí también seguimos el concepto de separación entre el repositorio de objetos de página y los métodos de prueba. Además, con la ayuda de la clase PageFactory en Selenium, usamos anotaciones @BuscarPor para encontrar WebElement. Usamos el método initElements para inicializar elementos web.

Página de fábrica en Selenium

@BuscarPor poder aceptar nombre de etiqueta, texto de enlace parcial, nombre, texto de enlace, id, css, nombre de clase, xpath como atributos.

Veamos el mismo ejemplo anterior usando Page Factory

Página de inicio de sesión de Guru99 con 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();           

    }

}

Página de inicio de Guru99 con 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 con el concepto 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 estructura completa del proyecto se verá como el diagrama:

Fábrica de páginas en Selenium

AjaxElementLocatorFábrica

AjaxElementLocatorFábrica es un concepto de carga diferida de PageFactory en Selenium. Se utiliza para encontrar los elementos web solo cuando los elementos se utilizan en cualquier operación. Asigna un tiempo de espera para WebElements a la clase de página de objeto. Una de las ventajas clave de utilizar el patrón PageFactory en Selenium es la clase AjaxElementLocatorFactory.

Aquí, cuando un operaCuando se realiza una operación sobre un elemento, la espera para su visibilidad comienza sólo a partir de ese momento. Si el elemento no se encuentra en el intervalo de tiempo dado, Caso de prueba la ejecución arrojará la excepción 'NoSuchElementException'.

Fábrica de localizadores de elementos Ajax

Resumen

  1. Modelo de objetos de página en Selenium WebDriver es un patrón de diseño de repositorio de objetos.
  2. Selenium El modelo de objetos de página crea nuestro código de prueba mantenible y reutilizable.
  3. Page Factory es una forma optimizada de crear un repositorio de objetos en el concepto del marco del modelo de objetos de página.
  4. AjaxElementLocatorFactory es un concepto de carga diferida en Page Factory: patrón de diseño de objetos de página para identificar WebElements solo cuando se utilizan en cualquier operación.

Descargue nuestra Selenium Archivos de proyecto para la demostración en este tutorial