Page Object Model (POM)


Maintaining 100s of lines of code in a single or multiple class file is a difficult task and also it will increases the complexity. In order to maintain the project structure and efficient performance of the selenium scripts, it is necessary to use different pages for different tasks. This classes can be reused in all the scripts using that element. In future, if there is a change in the web element, we need to make the change in Page classes no need to touch/modify the script.

What is the Page Object Model?
Page Object Model is a design pattern in test automation to create an Object Repository for web UI elements. Every web page in the application should have a corresponding page class. This Page class will find the WebElements and also may contain page methods which perform operations on those WebElements.
The benefit is , if the page UI changes, then the tests need not to be changed, only the code within the page object needs to be changed. After that, all the changes that support new UI are located in one place. That’s why locators and test scripts are maintain separately.

Benefits of using page object pattern:
1.Creating reusable code that can be shared across multiple test cases
Reducing the amount of duplicated code.
2.If the user interface changes, the fix needs changes in only one place.

Two ways you can Implementation Page Object Model
1)   without PageFactory
2)   with PageFactory

How to implement POM without PageFactory.

Scenario:
you need to enter the valid credentials in the ‘automationpractice login’ Page in order to redirect to the ‘My account - My Store‘ Page and then log out from the account.

1.   Create a new project and name it as POM
2.   Create a New python file and name it as webDriver.py and copy the below code.

Below code is to create a web driver object and maximize the window etc.

from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
class Driver:

   
def __init__(self):
       
self.driver = webdriver.Chrome(ChromeDriverManager().install())
       
self.driver.maximize_window()

   
def driver_Session(self):
        driversession=
self.driver
       
return (driversession)

3. Create a package called “PageObjects” under POM project and create HomePageObjects.py and LoginPageObjects.py for storing the locators of Home and login pages.

Below code is for HomePageObjects.py 
from selenium.webdriver.common.by import By
class HomePageObj(object):
   
def __init__(self, driver):
       
self.driver = driver
       
self.signInLink = self.driver.find_element(By.XPATH, "//a[@title='Log in to your customer account']")
   
def clickSiginLink(self):
       
self.signInLink.click()

Below code is for LgoinPageObjects.py
from selenium.webdriver.common.by import By
class LoginPageObj(object):
   
def __init__(self,driver):
       
self.driver=driver
       
self.userName=driver.find_element(By.XPATH,"//input[@name='userName']")
       
self.passWord=driver.find_element(By.XPATH,"//input[@name='password']")
       
self.loginButton=driver.find_element(By.XPATH,"//input[@name='login' and @value='Login']")
   
def setUserName(self,Name):
       
self.userName.clear()
       
self.userName.send_keys(Name)
   
def setPassWord(self,passw):
       
self.passWord.clear()
       
self.passWord.send_keys(passw)
   
def clickLoginButton(self):
       
self.loginButton.click()

4.Create another Package called “PageKeywords” under POM project and create HomePageLeywords.py and LoginKeywords.py

Below code is for HomePageKeywords.py
from PageObjects.HomePageObjects import HomePageObj
from webDriver import Driver
class HomePageKeyword(object):
    
def __init__(self,driver):
         self.driver =driver
    
def ClickOnsignIN(self):
        HomePage = HomePageObj(
self.driver)
        HomePage.clickSiginLink()


Below code is for LoginPageKeywords.py
from PageObjects.LoginPageObjects import LoginPageObj
from webDriver import Driver
class LoginKeywords(object):
   
def __init__(self):
       
self.driver=driver
   
def LoinINTOapp(self,Name,password):
        lObj=LoginPageObj(self.driver)
        lObj.setUserName(Name)
        lObj.setPassWord(password)
        lObj.clickLoginButton()
 titleTxt=self.driver.title
 assert titleTxt=="My account - My Store","Title Should be My account - My Store"
 print(titleTxt)

5.Create a package called “TestScripts” under POM project and create TestScript for the above scenario and the file name as “Test_Script1.py”

import unittest
from PageKeywords.LoginKeywords import LoginKeywords
from PageKeywords.HomePageKeywords import HomePageKeyword
from webDriver import Driver

class Scenarios(unittest.TestCase):
   
def setUp(self):
       
self.driver = Driver().driver_Session()
        Url =
"http://automationpractice.com/"
       
self.driver.get(Url)
   
def test_Sc1(self):
        homepage = HomePageKeyword(
self.driver)
        homepage.ClickOnsignIN()
        login = LoginKeywords(
self.driver)
        login.LoinINTOapp(
"abc111@gmail.com","abcd1234")
if __name__=="__main__":
    unittest.main()

How to implement POM without PageFactory using Python Page Object Model  library

PyPOM, or Python Page Object Model, is a Python library that provides a base page object model for use with Selenium functional tests.

We need to install PyPOM package for implementation of PageObjectModel.

1.Driver 
PyPOM requires a driver object to be instantiated and supports multiple driver types.
Ex:
class Chrome(Page):
       pass
chromePath = "C:\\executables\\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromePath)
page = Chrome(driver).open()

2.OPEN
Open the page. 
page = Chrome(driver, base_url).open()

3.BaseURL
A base URL can be passed to a page object on instantiation. If no URL template is provided, then calling open()
Ex:
class Chrome(Page):
       pass
base_url = "http://automationpractice.com/"
chromePath = "C:\\executables\\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromePath)
page = Chrome(driver, base_url).open()

4.URL Templates
By setting a value for URL_TEMPLATE, pages can specify either an absolute URL or one that is relative to the base

class Chrome(Page):
       URL_TEMPLATE=’index.php’ 
base_url = "http://automationpractice.com/"
chromePath = "C:\\executables\\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromePath)
page = Chrome(driver, base_url).open()


5.Locators
Each driver has its own approach to locating elements. A suggested approach is to store your locators at the top of your page/region classes. Ideally these should be proceeded with a single underscore to indicate that they’re primarily
reserved for internal use. These attributes can be stored as a two item tuple containing both the strategy and locator,and can then be unpacked when passed to a method that requires the arguments to be separated.

6.Pages
Page objects are representations of web pages. They provide functions to allow simulating user actions, and providing properties that return state from the page. The Page class provided by PyPOM provides a simple implementation that
can be sub-classed to apply to your project.

from pypom import Page 
class Chrome(Page):
       pass
 
base_url = "http://automationpractice.com/"
chromePath = "C:\\executables\\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromePath)
page = Chrome(driver, base_url).open()

7.Region
Region objects represent one or more elements of a web page that are repeated multiple times on a page, or shared
between multiple web pages. They prevent duplication, and can improve the readability and maintainability of your
page objects.
 from pypom import Page,Region
 from selenium import webdriver 
class Chrome(Page):
   
#URL_TEMPLATE="http://automationpractice.com/"
   
@property
   
def loginPage(self):
       
return SiteLoginPages(self)

class SiteLoginPages(Region):
    LoginLink=(By.XPATH,
"//a[@title='Log in to your customer account']")
    UserName=(By.XPATH,
"//input[@id='email']")
    PassWord = (By.XPATH,
"//input[@name='passwd']")
    LoginBtn=(By.XPATH,
"//button[@type='submit' and @id='SubmitLogin']")

   
def Login_APP(self):
       
self.find_element(*self.LoginLink).click()
       
self.find_element(*self.UserName).send_keys("abc111@gmail.com")

        
self.find_element(*self.PassWord).send_keys("abcd1234")
       
self.find_element(*self.LoginBtn).click()

base_url="http://automationpractice.com/"
chromePath="C:\\executables\\chromedriver.exe"

driver=webdriver.Chrome(executable_path=chromePath)
page=Chrome(driver,base_url).open()
page.loginPage.Login_APP()

Scenario:
you need to enter the valid credentials in the ‘automationpractice login’ Page in order to redirect to the ‘My account - My Store‘ Page and then log out from the account.

Below is the complete script for the above scenario.

1.Create a Project called “POMPY”
2.Create Package called AppPages under POMPY project and create SiteLogin.py for storing Login Page Objects and Methods
3.Create HomePage.py under AppPages Package for Homepage Objects and Methods.

Script for SiteLogin.py
from pypom import Page,Region
from selenium.webdriver.common.by import By

class Login(Page):
   
@property
   
def loginPage(self):
       
return SiteLoginPages(self)
   
@property
   
def logoutpage(self):
       
return SitelogoutPage(self)

class SitelogoutPage(Region):
    logoutBtn=(By.XPATH,
"//a[@title='Log me out']")

   
def click_Logout(self):
       
self.find_element(*self.logoutBtn).click()

class SiteLoginPages(Region):
    UserName=(By.XPATH,
"//input[@id='email']")
    PassWord = (By.XPATH,
"//input[@name='passwd']")
    LoginBtn=(By.XPATH,
"//button[@type='submit' and @id='SubmitLogin']")

   
def Login_APP(self,userName,pwd):
       
self.find_element(*self.UserName).send_keys(userName)
       
self.find_element(*self.PassWord).send_keys(pwd)
       
self.find_element(*self.LoginBtn).click()

Script for HomePage.py
from pypom import Page,Region
from selenium.webdriver.common.by import By
class Home(Page):
   
@property
   
def homePage(self):
       
return SiteHomePages(self)

class SiteHomePages(Region):
    LoginLink=(By.XPATH,
"//a[@title='Log in to your customer account']")

   
def Login_Link(self):
       
return self.find_element(*self.LoginLink).click()

4.Create a package called TestScript and AppTestScript.py for Test Scenarios.

Script for AppTestsScript.py
from pypom import Page,Region
from AppPages.SiteLogin import Login
from AppPages.HomePage import Home
from selenium import webdriver
from BasePage.BasePage import Base
import unittest

class Chrome(Home,Login):
  
pass
class
Scenarios(unittest.TestCase):
   
def setUp(self):
        base_url =
"http://automationpractice.com/"
       
chromePath = "C:\\executables\\chromedriver.exe"
       
driver = webdriver.Chrome(executable_path=chromePath)
       
self.page = Chrome(driver, base_url).open()
       
# self.page.homePage.Login_Link()
       
print(self.page)

   
def test_sc1(self):
       
print(self.page)
       
self.page.homePage.Login_Link()
       
self.page.loginPage.Login_APP("abc111@gmail.com", "abcd1234")
       
self.page.logoutpage.click_Logout()


if __name__=="__main__":
    unittest.main()

Note : For Details Information about PyPOM - Python Page Object Model please go through the below URL

PageFactory
Page Factory is one way of implementing a Page Object Model. In order to support the Page Object pattern. Now we are implementing Page Factory in pythonic way.

Main Features:
Initialise all the webElements declared in Point at a time.
All WebElements methods are re-define to add extra features eg- click method extended to have explicit wait.
Note: we have to install “selenium-page-factory” module.

Script: 
from seleniumpagefactory.Pagefactory import PageFactory
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
import unittest
import pdb

class LoginPageLocators(PageFactory):
   
def __init__(self,driver):
       
self.driver=driver
       
locators={
         
"userName":('xpath',"//input[@id='email']"),
         
"passWord":('xpath',"//input[@name='passwd']"),
         
"LoginBtn":('xpath',"//button[@type='submit' and @id='SubmitLogin']"),
         
"SignInLink":('xpath',"//a[@title='Log in to your customer account']")
        }

   
def login(self):
        LoginPageLocators.SignInLink.click_button()
       
self.userName.set_text("fsdfsf")
       
self.passWord.set_text("fsdfsf")
       
self.LoginBtn.click_button()

class LoginTest(unittest.TestCase):

   
def test_Login(self):
        chromePath =
"C:\\executables\\chromedriver.exe"
       
driver = webdriver.Chrome(executable_path=chromePath)
        driver.maximize_window()
        driver.get(
"http://automationpractice.com/")
        pdb.set_trace()
        pglogin=LoginPageLocators(driver)
        pglogin.login()

if __name__=="__main__":
    unittest.main()

Note: Every Page in Page Object Model should have WebDriver object as class member same as above example.

Comments