A production-ready test automation framework built with Selenium 4, pytest, and the Page Object Model (POM) pattern.
selenium_framework/
├── config/
│ ├── __init__.py
│ └── settings.py # Central config (reads from .env)
├── pages/
│ ├── base_page.py # Base POM class with reusable Selenium actions
│ ├── login_page.py # Login page locators & actions
│ ├── inventory_page.py # Products page
│ ├── cart_page.py # Cart page
│ └── checkout_page.py # Checkout flow
├── tests/
│ ├── ui/
│ │ ├── test_login.py # Login tests (smoke + regression)
│ │ ├── test_inventory.py# Inventory & sorting tests
│ │ └── test_checkout.py # End-to-end checkout tests
│ └── api/
│ └── test_api.py # API tests (no browser)
├── utils/
│ ├── driver_factory.py # WebDriver instantiation (Chrome/Firefox/Edge)
│ ├── wait_helper.py # Explicit-wait wrappers
│ ├── screenshot_helper.py # Auto-screenshot on failure
│ ├── logger.py # Rotating file + console logger
│ └── data_reader.py # Excel & JSON test-data readers
├── data/
│ └── test_data.json # Sample test data
├── reports/ # HTML reports & screenshots (auto-created)
├── logs/ # Rotating log files (auto-created)
├── conftest.py # pytest fixtures & hooks
├── pytest.ini # pytest configuration
├── requirements.txt # Python dependencies
└── .env.example # Environment variable template
cd selenium_frameworkpython -m venv venv
source venv/bin/activate # macOS / Linux
venv\Scripts\activate # Windowspip install -r requirements.txtcp .env.example .env
# Edit .env — set BROWSER, HEADLESS, credentials, etc.# All tests
pytest
# Only smoke tests (fast, critical-path)
pytest -m smoke
# Only API tests (no browser needed)
pytest -m api
# Only login tests
pytest -m login
# Run headless
HEADLESS=true pytest
# Run with Firefox
BROWSER=firefox pytest
# Parallel execution (4 workers)
pytest -n 4
# Retry flaky tests up to 2 times
pytest --reruns 2| Marker | Description |
|---|---|
smoke |
Critical-path tests — run on every commit |
regression |
Full regression suite |
login |
Login-related tests |
cart |
Shopping-cart tests |
checkout |
End-to-end checkout tests |
api |
API-layer tests (no browser) |
slow |
Tests that take > 30 seconds |
After every run, find the HTML report at:
reports/report.html # open in any browser
reports/screenshots/ # captured only on test failure
logs/automation.log # rotating log file
Set BROWSER in .env or as an env variable:
| Value | Driver |
|---|---|
chrome |
ChromeDriver (auto) |
firefox |
GeckoDriver (auto) |
edge |
EdgeDriver (auto) |
Drivers are downloaded automatically by webdriver-manager — no manual installation required.
| Variable | Default | Description |
|---|---|---|
BROWSER |
chrome |
Browser to use |
HEADLESS |
false |
Run without a visible window |
BASE_URL |
https://www.saucedemo.com |
Application under test |
API_BASE_URL |
https://reqres.in/api |
Base URL for API tests |
STANDARD_USER |
standard_user |
Login username |
APP_PASSWORD |
secret_sauce |
Login password |
IMPLICIT_WAIT |
10 |
Implicit wait in seconds |
EXPLICIT_WAIT |
20 |
Explicit wait timeout |
PAGE_LOAD_TIMEOUT |
30 |
Page load timeout |
SCREENSHOT_ON_FAIL |
true |
Auto-screenshot on test failure |
# pages/my_page.py
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
class MyPage(BasePage):
HEADING = (By.TAG_NAME, "h1")
def get_heading(self) -> str:
return self.get_text(self.HEADING)@pytest.fixture()
def my_page(driver):
return MyPage(driver)# tests/ui/test_my_feature.py
import pytest
@pytest.mark.smoke
class TestMyFeature:
def test_heading_is_visible(self, my_page):
my_page.open("/my-path")
assert my_page.get_heading() == "Expected Heading"JSON (for structured data):
from utils.data_reader import read_json
data = read_json("test_data.json")Excel (for data-driven / parametrised tests):
from utils.data_reader import read_excel
rows = read_excel("users.xlsx", sheet="LoginData")| Library | Purpose |
|---|---|
selenium |
Browser automation |
pytest |
Test runner & framework |
pytest-html |
HTML test reports |
pytest-xdist |
Parallel test execution |
pytest-rerunfailures |
Retry flaky tests |
webdriver-manager |
Auto-download browser drivers |
Faker |
Generate realistic fake test data |
python-dotenv |
Load config from .env files |
requests |
HTTP client for API tests |
openpyxl |
Read Excel test-data files |
allure-pytest |
Rich Allure reports (optional) |