Page Object Model (POM) & Page Factory in Selenium: Ultimate Guide

 

Before we learn about Page Object Model, lets understand -

Why POM ?

Starting a UI Automation in Selenium WebDriver is NOT a tough task. You just need to find elements, perform operations on it .

Consider this simple script to login into a website

As you can observe, all we are doing is finding elements and filling values for those elements.

This is a small script. Script maintenance looks easy. But with time test suite will grow. As you add more and more lines to your code, things become tough.

The chief problem with script maintenance is that if 10 different scripts are using the same page element, with any change in that element, you need to change all 10 scripts. This is time consuming and error prone.

A better approach to script maintenance is to create a separate class file which would find web elements , fill them or verify them. This class can be reused in all the scripts using that element. In future if there is change in the web element , we need to make change in just 1 class file and not 10 different scripts.

This approach is called Page Object Model(POM). It helps make code more readable, maintainable, and reusable.

What is POM?

  • Page Object Model is a design pattern to create Object Repository for web UI elements.
  • Under this model, for each web page in the application there should be corresponding page class.
  • This Page class will find the WebElements of that web page and also contains Page methods which perform operations on those WebElements.
  • Name of these methods should be given as per the task they are performing i.e., if a loader is waiting for payment gateway to be appear, POM method name can be waitForPaymentScreenDisplay().

Advantages of POM

  1. Page Object Patten says operations and flows in the UI should be separated from verification. This concept makes our code cleaner and easy to understand.
  2. Second benefit is the object repository is independent of testcases, so we can use the same object repository for a different purpose with different tools. For example, we can integrate POM with TestNG/JUnit for functional testing and at the same time with JBehave/Cucumber for acceptance testing.
  3. Code becomes less and optimized because of the reusable page methods in the POM classes.
  4. Methods get more realistic names which can be easily mapped with the operation happening in UI. i.e. if after clicking on the button we land on the home page, the method name will be like 'gotoHomePage()'.

How to implement POM ?

Simple POM:

It's the basic structure of Page object model (POM) where all Web Elements of the AUT and the method that operate on these Web Elements are maintained inside a class file. Task like verification should be separate as part of Test methods.

Complete Example

TestCase: Go to Guru99 Demo Site .

Step 1) Go to Guru99 Demo Site
Step 2) In home page check text "Guru99 Bank" is present
Step 3) Login into application
Step 4) Verify that the Home page contains text as "Manger Id : demo"

Here are we are dealing with 2 pages

  1. Login Page
  2. Home Page (shown once you login)

Accordingly we create 2 POM classes

Guru99 Login page 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();        

    }

}

Guru99 Home Page POM

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 Simple POM Test case

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 {

    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage;

    @BeforeTest

    public void setup(){

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

    }

What is Page Factory?

Page Factory is an inbuilt page object model concept for Selenium WebDriver but it is very optimized.

Here as well we follow the concept of separation of Page Object repository and Test methods. Additionally with the help of PageFactory class we use annotations @FindBy to find WebElement. We use initElements method to initialize web elements

@FindBy can accept tagName, partialLinkText, name, linkText, id, css, className, xpath as attributes.

Let's look at the same example as above using Page Factory

Guru99 Login page with 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();

    }

}

Guru99 Home Page with 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 with Page Factory concept

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 {

    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage;

    @BeforeTest

    public void setup(){

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

    }

}

Complete Project Structure will look like the diagram:

AjaxElementLocatorFactory

One of the key advantage of using Page Factory pattern is AjaxElementLocatorFactory Class.

It is working on lazy loading concept, i.e. a timeout for a WebElement will be assigned to the Object page class with the help of AjaxElementLocatorFactory .

Here, when an operation is performed on an element the wait for its visibility starts from that moment only. If the element is not found in the given time interval, test case execution will throw 'NoSuchElementException' exception.

Summary

  1. Page Object Model is an Object repository design pattern in Selenium WebDriver.
  2. POM creates our testing code maintainable, reusable.
  3. Page Factory is an optimized way to create object repository in POM concept.
  4. AjaxElementLocatorFactory is a lazy load concept in Page Factory pattern to identify WebElements only when they are used in any operation.

selenium page object model的更多相关文章

  1. Selenium的PO模式(Page Object Model)[python版]

     Page Object Model 简称POM  普通的测试用例代码: .... #测试用例 def test_login_mail(self): driver = self.driver driv ...

  2. Selenium的PO模式(Page Object Model)|(Selenium Webdriver For Python)

            研究Selenium + python 自动化测试有近两个月了,不能说非常熟练,起码对selenium自动化的执行有了深入的认识. 从最初无结构的代码,到类的使用,方法封装,从原始函数 ...

  3. Page Object Model (Selenium, Python)

    时间 2015-06-15 00:11:56  Qxf2 blog 原文  http://qxf2.com/blog/page-object-model-selenium-python/ 主题 Sel ...

  4. Python+Selenium框架设计--- Page Object Model

    POM(Page Object Model):页面对象模型,POM是一种最近几年非常流行的自动化测试模型,或者思想,POM不是一个框架,就是一个解决问题的思想.采用POM的目的,是为了解决前端中UI变 ...

  5. Selenium Page object Pattern usage

    使用Selenium的framework,大家免不了要使用他的page object pattern来开发适合自己的framework,原因很简单,page object 可以将测试的对象抽象成一个个 ...

  6. selenium page object模式

    页面对象模式将测试代码和被测试页面的元素及操作进行分离,以降低页面元素的变化对测试代码的影响.每个被测试的页面都会被定义一个类,类中会定位元素和操作. 如果不使用page object模式,则相同的操 ...

  7. Selenium Page Object(PO)设计模式

    Webdriver UI自动化测试火了好几年了,具体怎么设计自动化测试测试工程,组织测试用例完全凭借着自己的经验和习惯. 最近忽然听说了Page Object(简称PO)火了起来,也有面试的时候被问到 ...

  8. web端自动化——selenium Page Object设计模式

    Page Object设计模式的优点如下: ①    减少代码的重复. ②    提高测试用例的可读性. ③    提高测试用例的可维护性,特别是针对UI频繁变化的项目. 当为Web页面编写测试时,需 ...

  9. Appium+Python之PO模型(Page object Model)

    思考:我们进行自动化测试时,如果把代码都写在一个脚本中,代码的可读性会变差,且后期代码维护也麻烦,最好的想法就是测试对象和测试用例可以分离,可以很快定位问题,代码可读性高,也比较容易理解.这里推荐大家 ...

随机推荐

  1. MySQL(12):windows下解决mysql忘记密码

    mysql有时候忘记密码了怎么办?我给出案例和说明!一下就解决了!    Windows下的实际操作如下 : 1. 关闭正在运行的MySQL.  2. 打开DOS窗口,转到mysql\bin目录. 3 ...

  2. 洛谷 P1412 经营与开发

    /* 粘一下开始写的暴力吧 虽然没啥价值 */ #include<iostream> #include<cstdio> #include<cstring> #inc ...

  3. Linux中命令行编译java接口总是提示找不到符号的疑难杂症的解决

    今天学习java的接口,在linux的命令行下写代码练练手吧,啪啪啪一顿猛敲,写了一个接口UsbInserface,UDisk继承UsbInterface,写完了那就编译到bin目录呗. 当时写程序的 ...

  4. OD: SEHOP

    SEHOP,Structed Exception Handling Overwrite Protection,一种比 SafeSEH 更严厉的保护机制.Windows Vista SP1 开始支持 S ...

  5. 如何安装Oracle Database 11g数据库

    先选择你适合你的系统版本,32位系统的请选择32位的,64位系统可以使用32位也可以使用64位,建议采用64位的! 适用于 Microsoft Windows(32 位)的 Oracle Databa ...

  6. ngrok内网穿透(微信调试:只试用于微信测试账号)

    一.简介 ngrok:https://ngrok.com 功能:就是把外网地址映射到本地的内网地址 缺点: 1.免费版生成的域名是随机的(由于我是用于调试,就没什么关系,如果是正式生产环境可能需要一个 ...

  7. oracle 使用 ALTER 操作列

    使用 ALTER TABLE 语句追加, 修改, 或删除列的语法

  8. js鼠标右键操作

    一个页面中,BODY中用oncontextmenu='return false'来取消鼠标右键: 在JS中设置oncontextmenu='return true'用window.document. ...

  9. C# 解析User-Agent工具

    分享一个解析User-Agent的程序集: Neget程序集名称:UAParser Github下载地址:https://github.com/qiailu/uap-csharp 扩展程序集:UAPa ...

  10. Input File 表单上传按钮美化

    HTML <div class="input-file-button"> 上传图片<input type="file" class=" ...