With the plan in place, this lesson walks through implementing the core framework components: the BasePage with shared methods, page objects for login, inventory, cart, and checkout, data builders for test data generation, API helper commands, and a reporting utility that captures screenshots on failure. Each component references the patterns taught throughout this series.
Implementing the Framework — Component by Component
Implementation follows the dependency order: config first, then driver management, then BasePage, then page objects, then tests.
# Implementation roadmap — build in this order
IMPLEMENTATION_ORDER = [
{
"component": "1. Configuration (config/settings.py)",
"references": "Chapter 42 — Five-Layer Architecture (Layer 1)",
"key_decisions": [
"Use environment variables for all configurable values",
"Support local and CI environments via env var overrides",
"Store secrets in .env (gitignored), not in code",
],
"code_sample": (
"import os\n"
"class Settings:\n"
" BASE_URL = os.getenv('BASE_URL', 'https://www.saucedemo.com')\n"
" BROWSER = os.getenv('BROWSER', 'chrome')\n"
" HEADLESS = os.getenv('HEADLESS', 'true') == 'true'\n"
" TIMEOUT = int(os.getenv('TIMEOUT', '10'))\n"
" GRID_URL = os.getenv('GRID_URL', None)"
),
},
{
"component": "2. Driver Factory (utils/driver_factory.py)",
"references": "Chapter 43 — DriverFactory pattern",
"key_decisions": [
"Support Chrome, Firefox, Edge via browser name parameter",
"Support local and Grid execution via GRID_URL",
"Headless mode configurable via environment variable",
],
},
{
"component": "3. BasePage (pages/base_page.py)",
"references": "Chapter 38 — BasePage pattern",
"key_decisions": [
"Wrap click, type_text, get_text with WebDriverWait",
"Add is_visible, take_screenshot, scroll_to_element utilities",
"All page objects inherit from BasePage",
],
},
{
"component": "4. Page Objects (pages/login_page.py, etc.)",
"references": "Chapter 38 — Page Object Model",
"key_decisions": [
"Locators as class-level tuple constants",
"Action methods return page object instances (model transitions)",
"No assertions in page objects — only in tests",
"Constructor verifies page loaded (wait for key element)",
],
},
{
"component": "5. Data Builders (utils/data_builder.py)",
"references": "Chapter 77 — Builder pattern + test data management",
"key_decisions": [
"UserBuilder with sensible defaults and .with_*() methods",
"Timestamp-based unique identifiers for parallel safety",
"External fixture files (JSON) for static test data",
],
},
{
"component": "6. Test Cases (tests/test_*.py)",
"references": "Chapters 38-42 — Test design, data-driven, POM",
"key_decisions": [
"One test file per feature area (login, cart, checkout)",
"Descriptive test names: test_valid_login_shows_inventory",
"Data-driven tests with @parametrize for login variants",
"API tests using cy.request() or requests library",
],
},
{
"component": "7. Reporting (utils/reporter.py + conftest hooks)",
"references": "Chapter 42 — Reporting, logging, screenshots",
"key_decisions": [
"Auto-capture screenshot on test failure",
"Generate HTML report (pytest-html or Allure)",
"Log meaningful actions (not every find_element call)",
],
},
{
"component": "8. Security + Accessibility (tests/test_security.py)",
"references": "Chapters 60, 79 — Security payloads, axe-core",
"key_decisions": [
"XSS payloads parameterised across input fields",
"Access control checks (IDOR via API ID manipulation)",
"cy.checkA11y() or axe-core integration in key tests",
],
},
]
# Quality checklist before submission
QUALITY_CHECKLIST = [
"All tests pass locally on Chrome and Firefox",
"CI pipeline runs green on GitHub Actions",
"No hardcoded credentials — all secrets via env vars",
"No time.sleep() or cy.wait(ms) without justification",
"Every page object inherits from BasePage",
"Every test is independent — can run alone, in parallel, in any order",
"Test data uses unique identifiers (timestamps/UUIDs)",
"README includes setup instructions and architecture overview",
"Linter configured and passing (flake8/eslint)",
".gitignore excludes reports/, node_modules/, .env, __pycache__/",
]
print("Implementation Order:")
for comp in IMPLEMENTATION_ORDER:
print(f"\n {comp['component']}")
print(f" References: {comp['references']}")
print("\n\nQuality Checklist:")
for item in QUALITY_CHECKLIST:
print(f" [ ] {item}")
Common Mistakes
Mistake 1 — Skipping BasePage and duplicating wait logic in every page object
❌ Wrong: Every page object has its own WebDriverWait instantiation and its own click/type/getText wrapper — 6 page objects with the same boilerplate.
✅ Correct: BasePage defines click(), type_text(), get_text() once. All page objects inherit these methods. Zero duplication.
Mistake 2 — Not including API tests alongside UI tests
❌ Wrong: Framework only has UI tests — misses the opportunity to demonstrate API testing skills.
✅ Correct: Include 5-10 API tests (product listing, CRUD operations, error responses) to demonstrate full-stack testing capability.