Architected by Abhishek Raj P
Senior SDET | Test Automation Architect | Quality Engineering
Hyderabad, India • LinkedIn • GitHub
This repository demonstrates a production-grade, hybrid Web UI and REST API Test Automation Framework built with Python, Playwright, and Pytest.
Designed to reflect 10+ years of quality engineering experience in enterprise and fintech ecosystems, this architecture emphasizes:
- Zero Flakiness Engineering: Complete elimination of arbitrary waits (
time.sleep) in favor of Playwright's native event-loop auto-waiting and web-first assertions. - Layered Architecture & Separation of Concerns: Strict boundary separation between Page Objects (
pages/), API Service Clients (api/), centralized Fixture & Triage Harness (tests/conftest.py), and Data Utilities (utilities/). - Shift-Left API Contract Validation: High-speed API test suite with JSON Schema contract verification, session authentication token management, and complete CRUD validation.
- Enterprise Observability & Triage: Automatic capture of full-page failure screenshots, Playwright execution trace archives (
.zip), video recordings, structured log streams, and unified HTML / Allure reports. - Scalable Execution: Thread-safe parallel execution (
pytest-xdist), multi-browser support (Chromium,Firefox,WebKit), and robust GitHub Actions CI/CD workflows.
flowchart TD
subgraph TestExecution ["Test Execution Layer (Pytest)"]
UI_Tests["UI Tests (tests/ui/)<br/>Auth, Registration, E2E Checkout"]
API_Tests["API Tests (tests/api/)<br/>CRUD Lifecycle, JSON Schema Contract"]
DDT_Tests["Data-Driven Tests (tests/datadriven/)<br/>Parametrized JSON, CSV, Excel"]
Unit_Tests["Unit Tests (tests/unit/)<br/>Utilities & Readers"]
end
subgraph FrameworkCore ["Framework Core & Abstractions"]
POM["Page Object Model (pages/)<br/>HomePage, ProductPage, CartPage, CheckoutPage"]
APIClient["API Client Layer (api/)<br/>BaseClient, BookingClient, AuthClient"]
Fixtures["Centralized Pytest Harness (tests/conftest.py)<br/>Multi-Browser, Contexts, Tracing, Screenshots"]
end
subgraph UtilitiesAndData ["Utilities & Test Data Layer"]
DataReaders["Data Readers (utilities/data_reader_util.py)<br/>JSON, CSV, Excel Parser"]
RandomUtil["Synthetic Data Generator (utilities/random_data_util.py)<br/>Faker, UUID, Strings"]
Logger["Centralized Logger (utilities/logger_util.py)<br/>Console & Rotating File Logs"]
TestDataFiles["Test Data Fixtures (testdata/)<br/>Datasets & API Schemas"]
end
subgraph ReportingCI ["Observability & CI/CD Layer"]
Allure["Allure & HTML Reports<br/>reports/allure-results, report.html"]
Artifacts["Failure Triage Artifacts<br/>Full-page Screenshots & Traces"]
GitHubActions["GitHub Actions CI/CD<br/>Linting, Matrix Testing, Smoke Gate"]
end
UI_Tests --> POM
UI_Tests --> Fixtures
API_Tests --> APIClient
API_Tests --> Fixtures
DDT_Tests --> POM
DDT_Tests --> DataReaders
POM --> Fixtures
APIClient --> Fixtures
Fixtures --> Logger
Fixtures --> Artifacts
TestExecution --> Allure
GitHubActions --> TestExecution
.
├── .github/
│ └── workflows/
│ ├── ci.yml # CI quality gate: lint, unit, API, headless UI smoke
│ └── delivery-verification.yml # On-demand staged delivery verification workflow
├── api_client/ # REST API Service Client Layer (Playwright APIRequestContext)
│ ├── __init__.py
│ ├── base_api_client.py # Reusable HTTP methods with logging and latency tracking
│ ├── auth_client.py # Authentication & token generation client
│ └── booking_client.py # Domain endpoints for RESTful Booker CRUD operations
├── pages/ # Page Object Model (POM) Layer
│ ├── home_page.py # Navigation, search, and account controls
│ ├── login_page.py # User credentials, login actions, error banners
│ ├── registration_page.py # User onboarding form, validations, privacy policy
│ ├── product_page.py # Product details, quantity selection, cart addition
│ ├── search_results_page.py # Search result listings, filtering, card selection
│ ├── shopping_cart_page.py # Cart item inspection, price verification, checkout entry
│ ├── checkout_page.py # Step-by-step guest/user checkout, shipping & payment
│ ├── my_account_page.py # Authenticated user dashboard and options
│ └── logout_page.py # Session termination and redirection confirmation
├── testdata/ # Fixtures and Contract Specifications
│ ├── api_schemas/
│ │ └── booking_schema.json # JSON Schema for REST API contract validation
│ ├── logindata.json # JSON test fixture for Data-Driven Testing (DDT)
│ ├── logindata.csv # CSV test fixture for Data-Driven Testing (DDT)
│ └── logindata.xlsx # Excel test fixture for Data-Driven Testing (DDT)
├── tests/ # Unified Pytest Test Suites
│ ├── conftest.py # Root fixtures: browsers, pages, API contexts, triage hooks
│ ├── ui/ # End-to-End & Functional UI Test Suite
│ │ ├── test_login.py # Positive login, negative invalid credentials, logout
│ │ ├── test_registration.py # Dynamic Faker user creation & validation errors
│ │ ├── test_search_catalog.py # Product search, catalog filtering, empty state
│ │ ├── test_e2e_checkout.py # Flagship complete E2E guest checkout flow
│ │ └── test_shadow_dom.py # Shadow DOM traversal without fragile driver switching
│ ├── api/ # REST API Automation Suite
│ │ ├── test_booking_lifecycle.py # Full CRUD integration (Create, Read, Update, Delete)
│ │ └── test_booking_contract.py # JSON Schema validation & HTTP header verification
│ ├── datadriven/ # Data-Driven Testing (DDT)
│ │ └── test_login_ddt.py # Parametrized authentication tests (JSON & CSV fixtures)
│ ├── e2e/ # Smoke & Deployment Checks
│ │ └── test_storefront_smoke.py # Fast health check for deployed environments
│ └── unit/ # Local Unit Tests
│ └── test_data_reader_util.py # Isolated verification of testdata parsers
├── utilities/ # Cross-Cutting Infrastructure Utilities
│ ├── data_reader_util.py # Generic loader for JSON, CSV, and Excel workbooks
│ ├── random_data_util.py # Faker wrapper for deterministic & pseudo-random test data
│ └── logger_util.py # Structured logging handler (console + file rotation)
├── config.py # Central environment and configuration settings
├── pyproject.toml # Pytest markers, default options, and Ruff linter config
├── requirements.txt # Pinned production test dependencies
└── README.md # Framework architecture and interview documentation
- Each page object encapsulates its own locators and behavior.
- Navigational methods return the next page object (e.g.,
home_page.search_for_product("MacBook") -> SearchResultsPage), allowing fluent test step composition while keeping tests clean and readable.
- No
time.sleep()calls anywhere in the framework. - Locators leverage Playwright's auto-waiting and actionability checks (visible, stable, enabled, editable).
- Assertions use
expect(locator).to_be_visible(), which retries assertions until the expectation is met or times out, eliminating race conditions on dynamic single-page and asynchronous applications.
- Built on top of Playwright's native
APIRequestContext, executing HTTP requests in milliseconds without spawning a browser process. - Contract Verification: Leverages
jsonschemato ensure API schema stability before UI layers consume services. - State Isolation: Independent CRUD lifecycle tests avoid global mutable variables (
global booking_id), ensuring tests remain thread-safe and capable of running in parallel.
- Automatic post-mortem triage hooks in
tests/conftest.py:- Full-page screenshot: Captured on failure and saved to
reports/screenshots/. - Playwright Trace Archive: Complete DOM snapshots, console logs, network waterfalls, and action timings saved to
reports/traces/<test_name>_trace.zip. - Video Recording: Automatically retained for failed runs in
reports/videos/. - Allure Integration: Test evidence automatically attached to Allure and HTML reports for executive reporting.
- Full-page screenshot: Captured on failure and saved to
- Python 3.9, 3.10, or 3.11
- Git
# 1. Clone the repository
git clone https://github.com/abhi41289/PWPythonDemo.git
cd PWPythonDemo
# 2. Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Install Playwright browser binaries
playwright install chromium firefox webkit# Run critical-path smoke tests (UI + API)
pytest -m smoke -v
# Run full UI regression suite
pytest -m "ui and regression" -v
# Run complete REST API automation suite
pytest -m api -v
# Run API contract & schema validation tests
pytest -m contract -v
# Run Data-Driven test suite (JSON & CSV fixtures)
pytest -m datadriven -v
# Run unit tests only (instant, no network or browser required)
pytest -m unit -v# Run UI tests across different browser engines
pytest -m ui --browser-name=chromium
pytest -m ui --browser-name=firefox
pytest -m ui --browser-name=webkit
# Run in headed mode (visible browser window for debugging)
pytest -m smoke --headed
# Override target Base URL for testing staging or QA environments
pytest -m smoke --base-url="https://tutorialsninja.com/demo"# Execute tests in parallel using all available CPU cores
pytest -m "api or datadriven" -n auto
# Execute with specific worker count
pytest -n 4# Automatically retry failed tests up to 2 times
pytest --reruns 2 --reruns-delay 1# Generate self-contained HTML report (reports/report.html)
pytest --html=reports/report.html --self-contained-html
# Generate and view Allure Report
pytest --alluredir=reports/allure-results
allure serve reports/allure-results
# Inspect a Playwright failure trace archive
playwright show-trace reports/traces/<test_name>_trace.zipThe framework is configured with a modern GitHub Actions Quality Gate (.github/workflows/ci.yml):
- Linting: Static code analysis with
ruffacross application config, page objects, API clients, utilities, and tests. - Fast Shift-Left Gate: Runs isolated Unit and API contract/lifecycle tests.
- Browser Automation Gate: Matrix execution of UI smoke tests in headless Chromium.
- Artifact Archiving: Automatically collects and uploads JUnit XML reports, self-contained HTML reports, Allure results, and failure screenshots/traces with a 14-day retention policy.
| Topic | Technical Defense & Architectural Rationale |
|---|---|
| Why Playwright over Selenium / Cypress? | Playwright operates directly via the Chrome DevTools / browser debugging protocol, eliminating WebDriver HTTP latency. It provides native multi-tab, multi-origin, iframe, and shadow DOM support out of the box, with built-in request interception and unified UI + API contexts in a single runtime. |
| How is flakiness prevented? | We enforce Playwright's web-first assertions (expect(locator).to_be_visible()) and auto-waiting instead of arbitrary delays (time.sleep). Selectors are anchored to user-facing roles and stable attributes rather than brittle XPath indices. |
| How does the framework scale across teams? | The layered architecture ensures page objects only model the UI, API clients model service contracts, and tests focus purely on business logic. New test engineers can write high-value tests using page-chaining methods and utility readers without re-implementing locator logic. |
| How do you handle test state in parallel execution? | We avoid global mutable variables (global booking_id). Every test dynamically provisions its own test data (via RandomDataUtil / Faker or isolated API POST setups) and cleans up in teardown, allowing zero-dependency parallel execution (pytest-xdist). |
| How is failure triage optimized for distributed teams? | When a test fails in CI, developers don't have to guess: the framework captures a full-page screenshot and a complete Playwright trace file (.zip). Running playwright show-trace allows engineers to step through actions, DOM snapshots, network payloads, and console logs frame by frame. |
To verify formatting and import standards across the entire repository:
ruff check config.py pages api utilities tests