Introduction
As automation testing projects grow, maintaining test scripts becomes increasingly challenging. A small application may have only a few test cases, but an enterprise application can contain hundreds or thousands of test scenarios.
If locators and browser interactions are written directly inside every test case, even a minor application change can require updates across multiple scripts.
The Page Object Model (POM) is a design pattern that helps solve this problem. It separates web page locators and interactions from test execution logic, making automation frameworks easier to maintain, reuse and scale.
Selenium Python with PyTest and Page Object Model is a popular combination for developing structured web automation frameworks.
In this tutorial, we will learn how to implement POM using Selenium Python with practical examples.
1. What Is Page Object Model?
Page Object Model is a design pattern used in test automation. Each application page is represented by a separate Python class.
The page class contains:
Web element locators.
Methods for interacting with elements.
Reusable page-level operations.
Navigation or page-specific functionality.
Test classes use these page objects to perform application workflows and validate results.
For example, an e-commerce application may contain:
| Application Page | Page Object Class |
|---|---|
| Login page | LoginPage |
| Home page | HomePage |
| Product page | ProductPage |
| Shopping cart | CartPage |
| Checkout page | CheckoutPage |
Instead of writing login locators repeatedly in different tests, testers can create one reusable LoginPage class.
2. Why Use Page Object Model in Selenium Python?
POM offers several advantages.
1. Code reusability
Common actions such as login, search and navigation can be implemented once and reused.
2. Easy maintenance
When an element's locator changes, the update can usually be made in its page class rather than across multiple test cases.
3. Improved readability
Test cases describe business workflows instead of containing long sequences of low-level browser commands.
4. Better scalability
POM helps organise large automation projects into manageable components.
5. Separation of responsibilities
Page objects manage page interactions, while test scripts focus on test scenarios and assertions.
3. Tools Required for Selenium Python POM
Before creating the framework, install the required tools:
Python.
Selenium WebDriver.
PyTest.
VS Code or PyCharm.
Chrome, Firefox or another supported browser.
Install Selenium and PyTest:
python -m pip install selenium pytestFor HTML reporting, you can also install:
python -m pip install pytest-htmlUse a virtual environment for project dependencies. Selenium Manager can manage compatible browser drivers automatically in many current setups.
4. Creating the Selenium Python POM Project Structure
Create a project directory named selenium_pom_project.
A recommended structure is:
selenium_pom_project/
│
├── pages/
│ ├── __init__.py
│ ├── base_page.py
│ ├── login_page.py
│ └── home_page.py
│
├── tests/
│ ├── __init__.py
│ └── test_login.py
│
├── conftest.py
├── pytest.ini
└── requirements.txtPurpose of the folders and files:
pages/: Stores page object classes.base_page.py: Contains reusable browser interaction methods.login_page.py: Contains login page locators and actions.home_page.py: Contains home page interactions.tests/: Stores PyTest test cases.conftest.py: Provides browser fixtures.pytest.ini: Contains test configuration.requirements.txt: Stores dependency information.
This structure can be expanded as the application and test suite grow.
5. Creating a Base Page Class
A Base Page class contains reusable methods that can be inherited by other page classes.
Create pages/base_page.py:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
def click(self, locator):
element = self.wait.until(
EC.element_to_be_clickable(locator)
)
element.click()
def enter_text(self, locator, text):
element = self.wait.until(
EC.visibility_of_element_located(locator)
)
element.clear()
element.send_keys(text)
def get_text(self, locator):
element = self.wait.until(
EC.visibility_of_element_located(locator)
)
return element.text
def is_visible(self, locator):
return self.wait.until(
EC.visibility_of_element_located(locator)
).is_displayed()This class provides reusable methods for clicking, entering text, retrieving text and checking element visibility.
Page-specific classes can inherit these methods instead of implementing the same functionality repeatedly.
6. Creating the Login Page Class
Now create a separate page object for the application's login page.
Create pages/login_page.py:
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
class LoginPage(BasePage):
USERNAME = (By.ID, "username")
PASSWORD = (By.ID, "password")
LOGIN_BUTTON = (By.ID, "login")
def enter_username(self, username):
self.enter_text(self.USERNAME, username)
def enter_password(self, password):
self.enter_text(self.PASSWORD, password)
def click_login(self):
self.click(self.LOGIN_BUTTON)
def login(self, username, password):
self.enter_username(username)
self.enter_password(password)
self.click_login()The class contains the locators and actions required for the login page.
The login() method combines several smaller methods into one reusable workflow.
The example uses illustrative element IDs. Replace them with the actual locators from your practice application.
7. Creating the Home Page Class
After successful login, the application may display a home page.
Create pages/home_page.py:
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
class HomePage(BasePage):
PAGE_HEADING = (By.TAG_NAME, "h1")
def get_heading(self):
return self.get_text(self.PAGE_HEADING)
def is_homepage_displayed(self):
return self.is_visible(self.PAGE_HEADING)This class provides methods to retrieve the page heading and verify that the expected page element is visible.
For a real application, the heading locator and expected page state should match the actual application design.
8. Creating the Browser Fixture in conftest.py
PyTest fixtures help manage browser setup and cleanup.
Create conftest.py in the project root:
import pytest
from selenium import webdriver
@pytest.fixture
def driver():
browser = webdriver.Chrome()
browser.maximize_window()
yield browser
browser.quit()The browser is created before the test and closed after the test finishes, including when the test fails.
Function-scoped browser sessions are a useful default because they help keep tests independent.
9. Creating the Login Test Case
Now the page objects can be used inside the test script.
Create tests/test_login.py:
from pages.login_page import LoginPage
from pages.home_page import HomePage
def test_valid_login(driver):
driver.get("https://example.com/login")
login_page = LoginPage(driver)
login_page.login(
"testuser",
"testpassword"
)
home_page = HomePage(driver)
assert home_page.is_homepage_displayed()This test demonstrates the separation between browser interaction and test validation.
The test does not need to know the individual locators used by the login page. It simply calls the login() method.
The URL, credentials and page elements are placeholders. Use a dedicated test environment and valid test data when implementing this example.
10. Executing the Selenium Python POM Test
Open the terminal from the project directory.
Run all test cases:
pytestRun with detailed output:
pytest -vRun a particular test file:
pytest tests/test_login.py -vGenerate an HTML report:
pytest --html=report.html --self-contained-htmlThese commands help execute the automation suite and review test results.
11. POM with Parameterized Test Cases
A good automation framework should support multiple test scenarios.
PyTest parameterization allows the same test to execute with different credentials.
import pytest
from pages.login_page import LoginPage
@pytest.mark.parametrize(
"username,password",
[
("validuser", "validpassword"),
("invaliduser", "wrongpassword"),
("", "validpassword")
]
)
def test_login_scenarios(
driver, username, password
):
driver.get("https://example.com/login")
login_page = LoginPage(driver)
login_page.login(username, password)For a complete implementation, each data set should have an expected outcome and a corresponding assertion, such as successful navigation or an invalid-credentials message.
This approach supports positive and negative testing without duplicating the entire test function.
12. Page Object Model vs Page Factory
Page Object Model and Page Factory are related concepts, but they are not identical.
| Page Object Model | Page Factory |
|---|---|
| A design pattern | A technique or implementation approach |
| Organises page-specific code | Provides a way to initialise page elements |
| Can use normal Selenium locators | Often uses annotation-based element declarations in frameworks that support them |
| Does not require a specific library | Depends on the language and framework implementation |
In Python Selenium projects, developers commonly implement POM using normal locator tuples and methods. They do not need a Java-style Page Factory implementation to benefit from POM.
13. Best Practices for Selenium Python POM
Follow these recommendations when building a maintainable framework:
Create a separate page class for each major application page.
Keep locators inside their relevant page classes.
Use a Base Page for genuinely reusable interactions.
Use explicit waits for dynamic elements.
Keep test assertions in test files where practical.
Avoid placing application-specific business rules in generic utility methods.
Use meaningful method names such as
login()andadd_to_cart().Store environment settings and test data separately.
Avoid hardcoding sensitive credentials.
Keep test cases independent and suitable for parallel execution.
A well-designed POM framework should simplify maintenance rather than introduce unnecessary layers of abstraction.
14. Career Opportunities in Selenium Python Framework Development
Knowledge of Page Object Model is important for automation testers who want to progress beyond basic Selenium scripting.
Relevant career skills include:
Python programming.
Selenium WebDriver.
PyTest framework.
Page Object Model.
Data-driven testing.
API automation.
Git and GitHub.
Jenkins and CI/CD.
Playwright automation.
Debugging and framework maintenance.
Practical framework development experience can help candidates demonstrate their technical capabilities during automation testing interviews.
Learn Selenium Python Automation Testing with Palium Skills
Palium Skills provides practical Automation Testing training for freshers, graduates, manual testers and working professionals.
The Selenium Python training pathway can include:
Python programming fundamentals.
Selenium WebDriver automation.
Locators and web element handling.
Explicit waits and dynamic web elements.
PyTest framework.
Page Object Model implementation.
Data-driven automation testing.
Framework development from scratch.
Practical automation projects.
Interview preparation.
Training modes include classroom sessions at South Kolkata and Salt Lake, Kolkata, and instructor-led live online sessions for learners across India.
Contact Palium Skills
Website: www.paliumskills.com
Call: 8420594969 / 7044871915
WhatsApp: 9903130500
Email: info@paliumskills.com
South Kolkata Centre: 1st Floor, Sheeba Bhavan, 1/22 Poddar Nagar, Near South City Mall, Kolkata – 700068.
Salt Lake Centre: 5th Floor, RDB Boulevard, Block GP, Salt Lake Electronic Complex, Kolkata – 700091.
Frequently Asked Questions
1. What is Page Object Model in Selenium Python?
Page Object Model is a design pattern that represents application pages as Python classes containing locators and reusable interaction methods.
2. Why is POM used in automation testing?
POM improves code reusability, readability, maintainability and organisation of automation scripts.
3. Can we use Page Object Model with PyTest?
Yes. Selenium Python, PyTest and POM work together to create structured and scalable automation frameworks.
4. What is a Base Page class?
A Base Page class contains common browser interaction methods that can be reused by individual page classes through inheritance.
5. Is Page Factory required for Selenium Python?
No. A Python Selenium framework can implement the Page Object Model using ordinary classes, locator tuples and methods.
6. Can POM be used for large automation projects?
Yes. POM is particularly useful for large applications with multiple pages, reusable workflows and extensive test suites.
7. What should I learn after Selenium Python POM?
You can progress to data-driven testing, API automation, advanced PyTest features, reporting, CI/CD integration and Playwright.