0
0
Selenium Pythontesting~15 mins

Page factory pattern in Selenium Python - Deep Dive

Choose your learning style9 modes available
Overview - Page factory pattern
What is it?
The Page Factory pattern is a way to organize web page elements and actions in Selenium tests. It helps create a clear structure by separating the page's elements and the test logic. This pattern uses special annotations to find and store web elements efficiently. It makes tests easier to read, write, and maintain.
Why it matters
Without the Page Factory pattern, tests can become messy and hard to manage because element locators and test steps mix together. This leads to duplicated code and fragile tests that break easily when the web page changes. Using this pattern saves time and reduces errors, making automated tests more reliable and faster to update.
Where it fits
Before learning Page Factory, you should understand basic Selenium concepts like locating elements and writing simple tests. After mastering Page Factory, you can explore advanced test design patterns, test frameworks integration, and parallel test execution.
Mental Model
Core Idea
Page Factory organizes web elements as reusable objects to keep tests clean and maintainable.
Think of it like...
It's like having a labeled toolbox where each tool (web element) is stored in a specific spot, so you can quickly grab and use it without searching every time.
Page Object Class
┌───────────────────────────────┐
│  @FindBy(locator)              │
│  WebElement elementName       │
│                               │
│  Methods to interact with     │
│  elements (click, input, etc) │
└───────────────────────────────┘

Test Class
┌───────────────────────────────┐
│  Create Page Object instance   │
│  Call methods on elements      │
│  Assert results                │
└───────────────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding Selenium Web Elements
🤔
Concept: Learn what web elements are and how Selenium finds them.
In Selenium, web elements are parts of a web page like buttons, text boxes, or links. You find them using locators such as ID, name, or XPath. For example, driver.find_element(By.ID, 'submit') finds the submit button.
Result
You can interact with web elements, like clicking a button or typing text.
Knowing how Selenium locates elements is the base for organizing them better with patterns.
2
FoundationIntroduction to Page Object Model
🤔
Concept: Separate page structure from test logic using classes.
Page Object Model means creating a class for each web page. This class holds locators and methods to interact with the page. Tests then use these classes instead of raw locators.
Result
Tests become cleaner and easier to maintain because page details are in one place.
Separating page details from tests reduces duplication and makes updates simpler.
3
IntermediateUsing Page Factory for Element Initialization
🤔Before reading on: do you think Page Factory finds elements immediately or only when used? Commit to your answer.
Concept: Page Factory initializes web elements lazily using annotations.
Page Factory uses @FindBy annotations to declare elements. It initializes them only when the test uses them, saving time and avoiding errors if elements are not present immediately. In Python, you use selenium.webdriver.support.page_factory with decorators.
Result
Elements are ready to use without manual find_element calls, improving code clarity.
Lazy initialization avoids unnecessary searches and speeds up test setup.
4
IntermediateBest Practices for Locators in Page Factory
🤔Before reading on: is it better to use complex XPath or simple IDs for locators? Commit to your answer.
Concept: Choosing stable and fast locators improves test reliability.
Use unique IDs or names when possible because they are fast and stable. Avoid brittle XPath that breaks with small page changes. Page Factory works best with simple, clear locators.
Result
Tests break less often and are easier to fix when locators are well chosen.
Good locators are the foundation of stable automated tests.
5
AdvancedHandling Dynamic Elements with Page Factory
🤔Before reading on: do you think Page Factory can handle elements that appear after page load automatically? Commit to your answer.
Concept: Use waits and custom element initialization for dynamic content.
Dynamic elements may not be present immediately. Combine Page Factory with explicit waits to wait for elements before interacting. You can write methods that wait for elements inside the page object class.
Result
Tests become more robust and less flaky when handling dynamic pages.
Combining Page Factory with waits handles real-world web page behavior effectively.
6
ExpertCustom Decorators and Extending Page Factory
🤔Before reading on: can you extend Page Factory to add logging or error handling automatically? Commit to your answer.
Concept: You can create custom decorators to enhance element behavior.
In Python, decorators can wrap element access to add features like logging, screenshots on failure, or retries. This extends Page Factory beyond simple element storage to smarter test helpers.
Result
Tests gain extra power and diagnostics without cluttering test code.
Extending Page Factory with custom decorators unlocks advanced test capabilities.
Under the Hood
Page Factory uses a proxy pattern where element locators are stored but actual element lookup happens only when the element is used. This lazy loading reduces initial overhead and avoids errors if elements are not immediately present. The framework uses reflection or decorators to bind locators to variables automatically.
Why designed this way?
It was designed to improve test code readability and maintainability by separating element definitions from test logic. Early Selenium tests mixed locators and actions, causing duplication and fragile tests. Page Factory automates element initialization and supports lazy loading to handle dynamic pages better.
Test Code
  │
  ▼
Page Object Class
  ├─ @FindBy locators stored
  ├─ Methods to interact
  │
  ▼
Proxy Element
  ├─ On first use: find_element called
  ├─ Element cached
  │
  ▼
WebDriver
  ├─ Executes find_element
  └─ Returns WebElement
Myth Busters - 4 Common Misconceptions
Quick: Does Page Factory find all elements immediately when the page object is created? Commit to yes or no.
Common Belief:Page Factory finds all elements as soon as the page object is created.
Tap to reveal reality
Reality:Page Factory initializes elements lazily, only when they are accessed in the test.
Why it matters:Assuming immediate lookup can cause confusion about test speed and errors if elements are not present yet.
Quick: Is it okay to use complex XPath locators with Page Factory for best results? Commit to yes or no.
Common Belief:Using complex XPath locators with Page Factory is fine and reliable.
Tap to reveal reality
Reality:Complex XPath locators are brittle and can break easily; simple locators like IDs are better.
Why it matters:Using brittle locators leads to flaky tests that break with minor page changes.
Quick: Can Page Factory alone handle waiting for elements that load dynamically? Commit to yes or no.
Common Belief:Page Factory automatically waits for elements to appear before interacting.
Tap to reveal reality
Reality:Page Factory does not handle waits; explicit waits must be added separately.
Why it matters:Without waits, tests may fail intermittently on dynamic pages.
Quick: Does using Page Factory guarantee your tests will never break? Commit to yes or no.
Common Belief:Using Page Factory makes tests completely stable and unbreakable.
Tap to reveal reality
Reality:Page Factory helps organize code but does not prevent all test failures due to page changes or timing issues.
Why it matters:Overreliance on Page Factory can lead to ignoring other important test design practices.
Expert Zone
1
Page Factory's lazy loading means element lookup errors happen at interaction time, not at page object creation, which affects debugging timing.
2
Custom decorators can wrap element access to add retries or logging, improving test resilience and diagnostics without cluttering test code.
3
Combining Page Factory with explicit waits is essential for handling modern dynamic web pages, but this is not built-in and requires careful design.
When NOT to use
Avoid Page Factory when testing very simple pages or scripts where overhead is unnecessary. For highly dynamic single-page applications, consider using explicit waits and direct element handling or frameworks designed for reactive content like Playwright or Cypress.
Production Patterns
In real projects, Page Factory is combined with test frameworks like pytest and continuous integration. Teams create base page classes with common methods and extend them for specific pages. Custom wrappers add logging, screenshots, and retries. Tests use dependency injection to manage page objects cleanly.
Connections
Object-Oriented Programming
Page Factory builds on OOP by encapsulating page elements as objects.
Understanding classes and objects helps grasp how Page Factory organizes web elements into reusable components.
Lazy Loading Pattern
Page Factory uses lazy loading to delay element lookup until needed.
Knowing lazy loading explains why Page Factory improves performance and handles dynamic content better.
Supply Chain Management
Both manage resources efficiently by delaying actions until necessary.
Just like supply chains avoid stockpiling by ordering parts only when needed, Page Factory delays finding elements until interaction, saving time and resources.
Common Pitfalls
#1Locating elements immediately in the constructor causing errors if elements are not present.
Wrong approach:class LoginPage: def __init__(self, driver): self.driver = driver self.username = driver.find_element(By.ID, 'username') # wrong: immediate lookup self.password = driver.find_element(By.ID, 'password')
Correct approach:from selenium.webdriver.support.page_factory import PageFactory class LoginPage: def __init__(self, driver): self.driver = driver self.username = None self.password = None PageFactory.init_elements(driver, self) # lazy initialization
Root cause:Misunderstanding that elements should be found only when used, not at object creation.
#2Using complex XPath locators that break easily when page structure changes.
Wrong approach:self.submit_button = driver.find_element(By.XPATH, '//div[3]/form/button[1]') # brittle XPath
Correct approach:self.submit_button = driver.find_element(By.ID, 'submit') # stable ID locator
Root cause:Not prioritizing stable, unique locators leads to fragile tests.
#3Not using explicit waits with Page Factory causing flaky tests on dynamic pages.
Wrong approach:self.login_button.click() # no wait, may fail if button not ready
Correct approach:from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) wait.until(EC.element_to_be_clickable((By.ID, 'login'))) self.login_button.click()
Root cause:Assuming Page Factory handles waits automatically.
Key Takeaways
Page Factory pattern organizes web elements into reusable objects, separating page structure from test logic.
It uses lazy loading to find elements only when needed, improving test speed and handling dynamic content better.
Choosing stable locators like IDs over complex XPath makes tests more reliable and easier to maintain.
Page Factory does not handle waits; combining it with explicit waits is essential for robust tests.
Advanced users can extend Page Factory with custom decorators to add logging, retries, and other features.