tests/ ├── test_login.py ├── test_checkout.py page_objects/ ├── base_page.py ├── login_page.py ├── checkout_page.py utilities/ ├── browser_factory.py ├── config_reader.py ├── logger.py reports/ ├── html_reports/ │ └── report_2024_06_01.html ├── logs/ │ └── test_log_2024_06_01.log configs/ ├── config.yaml ├── environments.yaml conftest.py pytest.ini
Why advanced patterns solve real challenges in Selenium Python - Framework Benefits
- Driver Layer: Manages browser setup and teardown using
browser_factory.py. - Page Objects: Encapsulate page elements and actions in classes like
login_page.py. This hides Selenium details from tests. - Tests: Test scripts in
tests/use page objects to perform user actions and assertions. - Utilities: Helpers for configuration reading, logging, and browser management.
- Configuration: YAML files store environment URLs, credentials, and browser choices.
Use YAML files to separate environment data from code. For example, environments.yaml holds URLs for dev, staging, and production.
config_reader.py loads these settings. Tests select environment via command line or environment variables.
Browser choice is configurable to run tests on Chrome, Firefox, or headless modes.
Credentials are stored securely outside code, loaded at runtime.
Use Pytest's built-in reporting with plugins like pytest-html to generate readable HTML reports saved in reports/html_reports/.
Logs are captured by logger.py and saved in reports/logs/ for debugging.
CI/CD pipelines (e.g., GitHub Actions, Jenkins) run tests automatically on code changes, publishing reports and logs for team review.
- Page Object Model: Keeps tests clean by separating UI details from test logic.
- DRY (Don't Repeat Yourself): Reuse code in utilities and page objects to avoid duplication.
- Explicit Waits: Use Selenium waits to handle dynamic page elements reliably.
- Configurable Environments: Easily switch between dev, staging, and production without code changes.
- Clear Reporting: Provide readable reports and logs to quickly find test failures.
Where would you add a new page object for the "User Profile" page in this framework structure?
Practice
Solution
Step 1: Understand the purpose of advanced patterns
Advanced patterns are designed to improve test code by making it cleaner and easier to understand.Step 2: Connect patterns to real challenges
They help handle timing issues and complex user actions, making tests more reliable and maintainable.Final Answer:
They make tests easier to read and maintain -> Option CQuick Check:
Advanced patterns improve readability and maintenance [OK]
- Thinking patterns slow tests down
- Believing patterns remove locators
- Assuming patterns limit browser support
Solution
Step 1: Recall correct WebDriverWait syntax
The correct syntax uses WebDriverWait(driver, timeout).until(condition).Step 2: Check the expected condition usage
EC.element_to_be_clickable expects a locator tuple like (By.ID, 'submit').Final Answer:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'submit'))) -> Option AQuick Check:
Correct WebDriverWait syntax = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'submit'))) [OK]
- Using incorrect method names like wait_for_clickable
- Passing locator as separate arguments instead of tuple
- Misplacing driver or timeout parameters
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 5) element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.btn-primary'))) print(element.text)
Solution
Step 1: Understand WebDriverWait with presence_of_element_located
The wait.until waits up to 5 seconds for the element with CSS class 'btn-primary' to appear in the DOM.Step 2: Check what print(element.text) does
If found, element.text prints the visible text of that element.Final Answer:
Prints the text of the first element with class 'btn-primary' if found within 5 seconds -> Option BQuick Check:
Wait for presence then print text = Prints the text of the first element with class 'btn-primary' if found within 5 seconds [OK]
- Confusing presence_of_element_located with visibility
- Expecting count instead of element text
- Assuming immediate exception without wait
element = driver.find_element(By.ID, 'login') element.click()
Assume the element appears after some delay.
Solution
Step 1: Recognize timing issue in element interaction
The element may not be ready immediately, so clicking right away can cause errors.Step 2: Use WebDriverWait to wait for clickability
Waiting until the element is clickable ensures the element is ready for interaction.Final Answer:
Add WebDriverWait to wait until element is clickable before clicking -> Option DQuick Check:
Wait for clickable before click = Add WebDriverWait to wait until element is clickable before clicking [OK]
- Changing locator type without reason
- Removing click call disables test action
- Using find_elements returns list, not single element
Solution
Step 1: Identify need for reusable, reliable click action
Waiting for visibility and clicking is a common pattern that benefits from reuse.Step 2: Use a wrapper method to combine wait and click
A custom method hides complexity and improves test code readability and reliability.Final Answer:
Create a custom wrapper method combining WebDriverWait and click action -> Option AQuick Check:
Reusable wrapper method solves timing and reuse [OK]
- Using fixed sleep wastes time and is unreliable
- Skipping wait causes flaky tests
- Repeating wait and click code everywhere reduces maintainability
Ready to prove it?
Pass the test and this pattern moves unknown
