Sobes.tech
Middle

What is the Page Object pattern?

sobes.tech AI

Answer from AI

The Page Object (PO) pattern is a design pattern for automated testing of web interfaces, which represents web pages as classes. Each PO class encapsulates elements and actions performed by the user on a specific page.

Advantages of using:

  • Readability: Test code becomes more understandable as it interacts with pages and their elements through high-level methods.
  • Maintainability: When element locators on the page change, it is sufficient to make edits only in the corresponding Page Object class, rather than rewriting tests that use these elements.
  • Reusability: Methods and elements of the Page Object can be used in various test scenarios.
  • Separation of concerns: The logic for interacting with UI elements is separated from the test scenario logic.

Main components:

  • Page classes: Represent an abstraction of a specific web page.
  • Web elements: Defined within the page class using locators (XPath, CSS selectors, ID, etc.).
  • Methods: Represent actions that can be performed on the page (e.g., login(), addToCart(), search()). These methods interact with web elements.

Example structure:

# login_page.py
from selenium.webdriver.common.by import By

class LoginPage:

    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, "username")  # Locator for username input field
        self.password_input = (By.ID, "password")  # Locator for password input field
        self.login_button = (By.XPATH, "//button[contains(text(), 'Login')]") # Locator for login button
        self.error_message = (By.CSS_SELECTOR, ".error-message") # Locator for error message

    def open(self, url):
        self.driver.get(url) # Opens the page

    def enter_credentials(self, username, password):
        self.driver.find_element(*self.username_input).send_keys(username) # Enters username
        self.driver.find_element(*self.password_input).send_keys(password) # Enters password

    def click_login_button(self):
        self.driver.find_element(*self.login_button).click() # Clicks login button

    def get_error_message(self):
        return self.driver.find_element(*self.error_message).text # Gets error message text
# test_login.py
import unittest
from selenium import webdriver
from login_page import LoginPage # Import Page Object class

class LoginTests(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome() # Initialize driver
        self.login_page = LoginPage(self.driver) # Create Page Object instance

    def tearDown(self):
        self.driver.quit() # Quit driver

    def test_valid_login(self):
        self.login_page.open("http://example.com/login") # Open page
        self.login_page.enter_credentials("valid_user", "valid_password") # Enter data
        self.login_page.click_login_button() # Click button
        # Additional checks after successful login

    def test_invalid_login(self):
        self.login_page.open("http://example.com/login") # Open page
        self.login_page.enter_credentials("invalid_user", "wrong_password") # Enter data
        self.login_page.click_login_button() # Click button
        error_text = self.login_page.get_error_message() # Get error message text
        self.assertIn("Invalid credentials", error_text) # Check error message

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

In this example, LoginPage is a Page Object for the login page. Tests in test_login.py use methods of this class, abstracting away the details of interacting with elements.

The Page Object pattern is a de facto standard in web interface test automation due to its advantages in maintainability and readability.

What is the Page Object pattern? — QA / QA Automation - sobes.tech