0
0
Selenium-pythonHow-ToBeginner · 4 min read

How to Implement Page Object Model in Python with Selenium

To implement the Page Object Model in Python with Selenium, create separate classes for each web page that contain locators and methods to interact with page elements. Then, write test scripts that use these classes to perform actions, keeping tests clean and easy to maintain.
📐

Syntax

The Page Object Model uses classes to represent web pages. Each class has:

  • Locators: Variables that find elements on the page.
  • Methods: Functions that perform actions on those elements.
  • Constructor: Initializes the WebDriver instance.

This separates page details from test logic.

python
from selenium.webdriver.common.by import By

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, 'username')
        self.password_input = (By.ID, 'password')
        self.login_button = (By.ID, 'loginBtn')

    def enter_username(self, username):
        self.driver.find_element(*self.username_input).send_keys(username)

    def enter_password(self, password):
        self.driver.find_element(*self.password_input).send_keys(password)

    def click_login(self):
        self.driver.find_element(*self.login_button).click()
💻

Example

This example shows a simple login page object and a test that uses it to perform a login action.

python
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, 'username')
        self.password_input = (By.ID, 'password')
        self.login_button = (By.ID, 'loginBtn')

    def enter_username(self, username):
        self.driver.find_element(*self.username_input).send_keys(username)

    def enter_password(self, password):
        self.driver.find_element(*self.password_input).send_keys(password)

    def click_login(self):
        self.driver.find_element(*self.login_button).click()

# Test script

driver = webdriver.Chrome()
driver.get('https://example.com/login')

login_page = LoginPage(driver)
login_page.enter_username('testuser')
login_page.enter_password('password123')
login_page.click_login()

# Wait to see result (not for real tests)
time.sleep(3)
driver.quit()
Output
Test runs opening the browser, entering credentials, clicking login, then closing browser after 3 seconds.
⚠️

Common Pitfalls

  • Hardcoding locators inside test scripts instead of page classes makes maintenance hard.
  • Not using * to unpack locator tuples causes errors in find_element.
  • Mixing test logic and page actions reduces readability.
  • Not waiting for elements to load can cause flaky tests.

Always keep locators and actions inside page classes and use explicit waits in real tests.

python
from selenium.webdriver.common.by import By

# Wrong: locator used directly without unpacking
class WrongPage:
    def __init__(self, driver):
        self.driver = driver
        self.button = (By.ID, 'btn')

    def click_button(self):
        # This will cause an error
        self.driver.find_element(self.button).click()

# Right: unpack locator tuple with *
class RightPage:
    def __init__(self, driver):
        self.driver = driver
        self.button = (By.ID, 'btn')

    def click_button(self):
        self.driver.find_element(*self.button).click()
📊

Quick Reference

  • Page Class: Represents a web page.
  • Locators: Store element selectors as tuples.
  • Methods: Perform actions on elements.
  • Tests: Use page classes to keep tests clean.
  • Use: find_element(*locator) to unpack locator tuples.

Key Takeaways

Create separate classes for each page with locators and methods to interact with elements.
Use locator tuples unpacked with * in find_element calls to avoid errors.
Keep test scripts clean by calling page class methods instead of direct Selenium commands.
Avoid mixing test logic and page details to improve maintainability.
Use explicit waits in real tests to handle dynamic page loading.