Bird
Raised Fist0
Testing Fundamentalstesting~8 mins

Page Object Model concept in Testing Fundamentals - Framework Patterns

Choose your learning style10 modes available
Framework Mode - Page Object Model concept
Folder Structure
project-root/
├── tests/
│   ├── login_tests.py
│   ├── cart_tests.py
│   └── checkout_tests.py
├── pages/
│   ├── base_page.py
│   ├── login_page.py
│   ├── home_page.py
│   └── cart_page.py
├── utils/
│   ├── driver_factory.py
│   └── helpers.py
├── config/
│   ├── config.yaml
│   └── credentials.yaml
└── conftest.py
Test Framework Layers
  • Driver Layer: Manages browser setup and teardown (e.g., driver_factory.py).
  • Page Objects: Classes representing pages or components with methods to interact with UI elements (e.g., login_page.py).
  • Tests: Test scripts that use page objects to perform actions and assertions (e.g., login_tests.py).
  • Utilities: Helper functions and reusable code (e.g., waits, data generators in helpers.py).
  • Configuration: Files storing environment settings and credentials (e.g., config.yaml).
Configuration Patterns
  • Use config.yaml to store environment URLs, browser types, and timeouts.
  • Keep sensitive data like usernames and passwords in credentials.yaml, excluded from version control.
  • Load configurations in conftest.py or setup scripts to initialize tests dynamically.
  • Allow switching environments (dev, staging, prod) by changing a single config value.
  • Use environment variables or command-line options to override defaults for flexibility.
Test Reporting and CI/CD Integration
  • Generate readable test reports using tools like pytest-html or built-in test runner reports.
  • Include screenshots on failure for easier debugging.
  • Integrate tests into CI/CD pipelines (e.g., GitHub Actions, Jenkins) to run tests automatically on code changes.
  • Fail builds if critical tests fail to ensure quality gates.
  • Store reports as artifacts for team review.
Best Practices for Page Object Model
  • Single Responsibility: Each page object class should represent one page or component only.
  • Encapsulation: Hide locator details inside page objects; tests should call methods, not access locators directly.
  • Reusable Methods: Create clear, reusable methods for common actions (e.g., login(), click_button()).
  • Maintainability: Keep locators and UI interaction code separate from test logic for easy updates.
  • Explicit Waits: Use waits inside page objects to handle dynamic page elements reliably.
Self Check

Where in this folder structure would you add a new page object class for the "Profile" page?

Key Result
Page Object Model organizes UI interactions into separate classes to keep tests clean and maintainable.

Practice

(1/5)
1. What is the main purpose of the Page Object Model in software testing?
easy
A. To combine multiple test cases into one large script
B. To write all test steps inside the test script without abstraction
C. To separate page structure from test logic for easier maintenance
D. To avoid using classes and methods in test automation

Solution

  1. Step 1: Understand the role of Page Object Model

    The Page Object Model (POM) is designed to separate the page details like locators and actions from the test scripts.
  2. Step 2: Identify the benefit of separation

    This separation makes tests easier to read, write, and maintain because changes in the UI only affect the page objects, not the test logic.
  3. Final Answer:

    To separate page structure from test logic for easier maintenance -> Option C
  4. Quick Check:

    Separation of concerns = A [OK]
Hint: POM separates page details from tests for easy updates [OK]
Common Mistakes:
  • Thinking POM combines all tests into one script
  • Believing POM avoids using classes and methods
  • Confusing POM with writing test steps directly in scripts
2. Which of the following is the correct way to define a page object class for a login page in Python?
easy
A. class LoginPage: def __init__(self, driver): self.driver = driver
B. def LoginPage(driver): self.driver = driver
C. class LoginPage: driver = driver
D. LoginPage = function(driver) { this.driver = driver; }

Solution

  1. Step 1: Check Python class syntax for page object

    In Python, a page object is a class with an __init__ method that accepts the driver and assigns it to self.driver.
  2. Step 2: Identify correct syntax

    class LoginPage: def __init__(self, driver): self.driver = driver correctly defines a class with __init__ and assigns driver properly. Options A, B, and D have syntax errors or misuse of class variables. LoginPage = function(driver) { this.driver = driver; } is JavaScript syntax, not Python.
  3. Final Answer:

    class LoginPage: def __init__(self, driver): self.driver = driver -> Option A
  4. Quick Check:

    Python class with __init__ = C [OK]
Hint: Python page objects use class with __init__ for driver [OK]
Common Mistakes:
  • Using function instead of class for page object
  • Assigning driver outside __init__ method
  • Mixing JavaScript syntax in Python code
3. Given this Python page object method, what will login_page.get_title() return if the page title is "Welcome"?
class LoginPage:
    def __init__(self, driver):
        self.driver = driver
    def get_title(self):
        return self.driver.title
medium
A. "Welcome"
B. self.driver
C. None
D. Error: method missing return

Solution

  1. Step 1: Understand the get_title method

    The method returns self.driver.title, which is the page title property from the driver object.
  2. Step 2: Determine the returned value

    If the page title is "Welcome", calling get_title() returns the string "Welcome".
  3. Final Answer:

    "Welcome" -> Option A
  4. Quick Check:

    Method returns driver.title = "Welcome" [OK]
Hint: Method returns driver.title property value [OK]
Common Mistakes:
  • Confusing method return with driver object itself
  • Assuming method returns None without explicit return
  • Thinking method causes error due to missing return
4. Identify the error in this page object method and select the fix:
class LoginPage:
    def __init__(self, driver):
        self.driver = driver
    def click_login(self):
        self.driver.find_element_by_id('loginBtn').click()
medium
A. Change method name to clickLogin
B. Use correct locator method: replace find_element_by_id with find_element(By.ID, 'loginBtn')
C. Remove self.driver assignment in __init__
D. Add return statement after click()

Solution

  1. Step 1: Check Selenium locator method usage

    In recent Selenium versions, find_element_by_id is deprecated. The correct usage is find_element(By.ID, 'loginBtn') with proper import.
  2. Step 2: Identify the fix

    Use correct locator method: replace find_element_by_id with find_element(By.ID, 'loginBtn') correctly updates the locator method. Other options do not fix the locator error or are unrelated.
  3. Final Answer:

    Use correct locator method: replace find_element_by_id with find_element(By.ID, 'loginBtn') -> Option B
  4. Quick Check:

    Update deprecated locator method = D [OK]
Hint: Use updated Selenium locators with By.ID [OK]
Common Mistakes:
  • Ignoring deprecated locator methods
  • Adding unnecessary return statements
  • Changing method names without reason
5. You want to create a page object for a search page that has a method to enter text and submit the search. Which design best follows the Page Object Model principles?
hard
A. class SearchPage: def __init__(self): self.driver = None def search(self, text): self.driver.find_element(By.ID, 'searchBox').send_keys(text)
B. class SearchPage: def search(self, text): input = driver.find_element(By.NAME, 'q') input.send_keys(text) input.submit()
C. def search(text): driver.find_element(By.NAME, 'q').send_keys(text) driver.find_element(By.NAME, 'q').submit()
D. class SearchPage: def __init__(self, driver): self.driver = driver def search(self, text): box = self.driver.find_element(By.NAME, 'q') box.clear() box.send_keys(text) box.submit()

Solution

  1. Step 1: Check for proper driver initialization

    class SearchPage: def __init__(self, driver): self.driver = driver def search(self, text): box = self.driver.find_element(By.NAME, 'q') box.clear() box.send_keys(text) box.submit() correctly initializes the driver in __init__, so the page object has access to it.
  2. Step 2: Verify method encapsulates actions

    The search method finds the input box, clears it, sends keys, and submits, all encapsulated in one method, following POM principles.
  3. Final Answer:

    class SearchPage: def __init__(self, driver): self.driver = driver def search(self, text): box = self.driver.find_element(By.NAME, 'q') box.clear() box.send_keys(text) box.submit() -> Option D
  4. Quick Check:

    Driver init + encapsulated method = A [OK]
Hint: Initialize driver in __init__ and encapsulate actions in methods [OK]
Common Mistakes:
  • Not initializing driver in constructor
  • Using global driver without passing it
  • Splitting one action into multiple unrelated methods
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard