Friday, 1 April 2016

Page Object Model Using Selenium Python: Complete Tutorial with Practical Examples

 

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 PagePage Object Class
Login pageLoginPage
Home pageHomePage
Product pageProductPage
Shopping cartCartPage
Checkout pageCheckoutPage

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 pytest

For HTML reporting, you can also install:

python -m pip install pytest-html

Use 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.txt

Purpose 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:

pytest

Run with detailed output:

pytest -v

Run a particular test file:

pytest tests/test_login.py -v

Generate an HTML report:

pytest --html=report.html --self-contained-html

These 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 ModelPage Factory
A design patternA technique or implementation approach
Organises page-specific codeProvides a way to initialise page elements
Can use normal Selenium locatorsOften uses annotation-based element declarations in frameworks that support them
Does not require a specific libraryDepends 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:

  1. Create a separate page class for each major application page.

  2. Keep locators inside their relevant page classes.

  3. Use a Base Page for genuinely reusable interactions.

  4. Use explicit waits for dynamic elements.

  5. Keep test assertions in test files where practical.

  6. Avoid placing application-specific business rules in generic utility methods.

  7. Use meaningful method names such as login() and add_to_cart().

  8. Store environment settings and test data separately.

  9. Avoid hardcoding sensitive credentials.

  10. 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

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.

TDS on Salary: A Practical Guide for HR and Payroll Professionals

  TDS on Salary: A Complete Guide for HR and Payroll Professionals Learn how TDS on salary works in India , the role of employers, employee...