Page Object Model and Page Factory in Selenium Python
By Manish Saini, Community Contributor - June 2, 2022
Web automation testing is used to automate the testing process of a website or web application. It can be used to test functionalities and load times and can also be used in regression testing. Web automation testing is an important part of the software development life cycle (SDLC) because it reduces the time and resources needed to ensure that the site is operating as intended.
Automation testing can be done through programming languages such as:
Web automation testing has become increasingly important due to the growing size of web applications and websites. It can be more difficult to test each new feature manually with larger sites. In addition, manual testing can take a long time, especially if bugs need to be fixed. And when it comes to automated web application testing, the first thing which will come to our mind is Selenium.
Learn More: Selenium with Python Automation Tutorial
Selenium is the most used tool that automates web browsers. This article will demonstrate the Page Object Model used in Selenium using Python as a programming language. It supports multiple browsers to test your website.
- What is Page Object Model (POM)?
- What is Page Factory?
- Page Object Model in Selenium with Python using selenium-page-factory
- Extended WebElements Methods in selenium-page-factory
- Sample Project Structure for Page Object Model & Page Factory in Selenium Python
- Run Tests on Multiple Browsers & Real Devices with BrowserStack
What is Page Object Model (POM)?
One way to help write clean and well-tested code is to create a Page Object Model. A Page Object Model (POM) is a set of classes designed to represent one or more web pages. It is a way of using objects to represent elements on the page. This enables you to write code that is simple and easy to understand. It also helps you to keep your tests well-structured and understandable.
There are many benefits to creating a POM such as:
- Testing Quality – The POM helps you write tests that are easy to understand and maintain. This can help improve the quality of your testing process to improve the readability and reliability of the scripts.
- Site Maintenance – It is easier to maintain the site over time. Suppose if something got changed on any page, we could easily find the functions and locators that need to be changed by that page class.
- Team Collaboration – The POM can help with collaboration between team members and improve the efficiency of your team significantly.
- Overall Productivity – The POM can make it easier for new team members to get up to speed and boost overall team productivity.
- Reusing Code – Using POM, we can reuse our functions in different Test Scripts by importing them from Page Class. It doesn’t require writing the same functions in different test cases.
With all of these benefits, it is clear that a POM can be a valuable tool for any organization. By creating one, you can help improve the quality of your software testing process and team collaboration.
What is Page Factory?
Page Factory is a method of implementing a Page Object Model. To support the Page Object pattern. In Java, we use @findBy, here, we will declare all web elements in a dictionary. Dictionary keys become WebElement or class member variables with having all extended WebElement methods.
Page Factory initializes all the web elements declared in Point at a time. All WebElements methods are re-defined to add extra features eg- the click method is extended to have an explicit wait for the element to be clickable.
Page Object Model in Selenium with Python using selenium-page-factory
It is easy implement page factory in Selenium with Python by using the selenium-page-factory package. Install it by using
pip install selenium-page-factory
To use selenium-page-factory every Page in the Page Object Model should have a WebDriver object as a class member as shown below:
class PageClass(PageFactory): def __init__(self, driver): self.driver = driver
Extended WebElements Methods in selenium-page-factory
set_text | get_text |
clear_text | click_button |
double_click | get_list_item_count |
select_element_by_text | select_element_by_index |
select_element_by_value | get_all_list_item |
get_list_selected_item | highlight |
is_Enabled | is_Checked |
getAttribute | hover |
visibility_of_element_located | invisibility_of_element_located |
element_to_be_clickable | execute_script |
context_click | text_to_be_present_in_element |
click_and_hold |
Sample Project Structure for Page Object Model & Page Factory in Selenium Python
Pre-requisites:
- IDE – PyCharm
- Python – 3.4 or higher
- Framework Used – Pytest
- Package Used – Selenium, selenium-page-factory, pytest
To install packages we can use pip.
pip install selenium-page-factory
Setup:
- Create a Python project in Pycharm.
- Add 2 Python Package src and test.
- Add Page Classes under src.pages package.
- Add test scripts under test package.
Project Structure:
In POM structure we have a package for all the pages. This package consists of class files related to every page. In these page classes, we have methods related to those pages.
Page Class
Code Snippet:
from seleniumpagefactory.Pagefactory import PageFactory class SignInPage(PageFactory): def __init__(self, driver): self.driver = driver locators = { 'user_name': ('CSS', "#username input"), 'password': ('CSS', '#password input'), 'login_btn': ('ID', 'login-btn') } def select_username(self): self.user_name.set_text('demouser\n') def select_password(self): self.password.set_text('testingisfun99\n') def click_login(self): self.login_btn.click()
This is the Page Class for the Sign In Page. Here we are importing the PageFactory Class from its module. After that, we made a class named SignInPage which inherits the PageFactory Class. Every page class must initialize the driver in the init method. Locators are saved in a dictionary with the locator name as a key and a tuple having its locator type and value as its value.
locators = { 'user_name': ('CSS', "#username input"), 'password': ('CSS', '#password input'), 'login_btn': ('ID', 'login-btn') }
After that, we write all the functions which need to be performed on that page. For example Entering the user name, password, etc. Syntax to write those functions is :
self.locator_name.function()
We write all our page classes in a similar manner. Here is another page class for the home page.
Code Snippet:
from seleniumpagefactory.Pagefactory import PageFactory class Homepage(PageFactory): def __init__(self, driver): self.driver = driver locators = { "sign_in": ("ID", "signin"), "user_name": ("CSS", ".username") } def click_sign_in(self): self.sign_in.click() def get_username(self): retrieved_username = self.user_name.get_text() assert retrieved_username == "demouser"
Test Case
Here is the code snippet for test_browserstack.py
from selenium import webdriver from src.pages.homepage import Homepage from src.pages.sign_in_page import SignInPage def test_browserstack(): driver = webdriver.Chrome() driver.get("https://bstackdemo.com/") homepage = Homepage(driver) sign_in_page = SignInPage(driver) homepage.click_sign_in() sign_in_page.select_username() sign_in_page.select_password() sign_in_page.click_login() homepage.get_username() driver.quit()
In this test case, we have used all the methods written inside our page classes.
- First, we need to import those page classes.
- Create a function for your test case.
- Initialize the driver for the chrome web driver.
- Make objects for the page classes.
- Call functions using the objects.
In this way, we can run our test cases by using the page object model. All the methods written inside the page classes can be reused in multiple test cases.
The pytest framework is used here, so to run our test case we need to execute a pytest command.
pytest -v
Here is the video of our test run.
Run Tests on Multiple Browsers & Real Devices with BrowserStack
BrowserStack gives you instant access to Selenium Grid of 3000+ real devices and desktop browsers. Running your Selenium tests with Python on BrowserStack is simple yet effective, always.
We need to replace browser = webdriver.Chrome() to
desired_cap = { 'os_version': '11', 'resolution': '1920x1080', 'browser': 'Chrome', 'browser_version': 'latest', 'os': 'Windows', 'name': 'BStack-[Python] Sample Test', # test name 'build': 'BStack Build Number 1' # CI/CD job or build name } driver = webdriver.Remote( command_executor='https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub', desired_capabilities=desired_cap)
It will start running your test cases on the BrowserStack cloud.
Conclusion
Page Object Model is a great way to organize your code and make it more reusable and understandable. It helps a lot when you need to do maintenance with your test scripts. In Automation Testing, our code often breaks due to changes in selectors which need to be fixed many times in the code. Page Factory helps debug that change and organize code in such a way that we can easily change our selectors.
Run your test cases in parallel on multiple browsers using BrowserStack Automate as it’s difficult to test your Web App on multiple browsers with their different versions locally. But, BrowserStack provides you with 3000+ real devices and web browsers to test your application using Selenium. You can also test that in parallel to accelerate CI/CD pipelines.
Pro Tip: Want to dive deeper into BrowserStack automation with free interactive courses and exercises? Visit Test University