Skip to content

ramanwaliagithub/playwright-pytest-framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Playwright + Pytest Test Automation Framework

A production-ready UI + API test automation framework built with Playwright (Python) and pytest, featuring the Page Object Model, a Service Object layer for API testing, environment-driven configuration, structured logging, failure-artifact capture (screenshots + traces), Docker support, and GitHub Actions pipelines for both pull requests (fast smoke subset) and nightly full regression (cross-browser).

Every module includes docstrings explaining the production concept it demonstrates, not just what the code does — so this repo doubles as a learning reference.

Project structure

.
├── src/
│   ├── config/settings.py       # Environment-driven config (12-factor app)
│   ├── core/base_page.py        # Base Page Object (POM)
│   ├── pages/home_page.py       # Concrete Page Object example
│   ├── api/client.py            # Base HTTP client (requests.Session wrapper)
│   ├── api/posts_service.py     # Service Object for the Posts API
│   ├── api/schemas.py           # Response contract/schema validation
│   └── utils/logger.py          # Centralized structured logging
├── tests/
│   ├── conftest.py              # Fixtures + hooks (browser/context/page/api_client)
│   ├── ui/test_home_page.py     # UI tests (POM, parametrize, markers)
│   ├── api/test_posts_api.py    # API tests (CRUD, schema, negative testing)
│   └── test_hybrid_ui_api.py    # Hybrid UI+API test pattern
├── docker/
│   ├── Dockerfile               # Based on official Playwright Python image
│   └── docker-compose.yml
├── .github/workflows/
│   ├── pr-checks.yml            # Runs on every PR: lint + smoke tests
│   └── nightly.yml              # Runs nightly (cron) + manual: full suite, 3 browsers
├── pytest.ini                   # Pytest config: markers, reporting
├── pyproject.toml               # Ruff + mypy config
├── requirements.txt
├── Makefile                     # Convenience commands
└── .env.example                 # Documents every configurable env var

Key design concepts

Concept Where
Page Object Model src/core/base_page.py, src/pages/home_page.py
Service Object pattern (API) src/api/posts_service.py
Environment-driven config (12-factor) src/config/settings.py
Schema/contract validation src/api/schemas.py
Fixture scoping (session vs function) tests/conftest.py
Test isolation via browser contexts tests/conftest.py
Failure artifacts (screenshot + trace) via pytest hooks tests/conftest.py
Web-first / auto-retrying assertions tests/ui/test_home_page.py
Parametrized tests both tests/ui/ and tests/api/
Negative testing tests/api/test_posts_api.py
Tiered suites: smoke / regression / nightly markers everywhere
Hybrid UI+API pattern tests/test_hybrid_ui_api.py
CI: PR vs nightly split .github/workflows/
Containerized, reproducible runs docker/

Getting started locally

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

pip install -r requirements.txt
playwright install --with-deps   # downloads browser binaries

cp .env.example .env             # optional: customize locally

pytest -m smoke -v               # fast subset
pytest -m "smoke or regression" -v
pytest -m "smoke or regression or nightly" -n auto -v   # full suite, parallel

Or via make:

make install
make browsers
make smoke

Running in Docker

docker build -f docker/Dockerfile -t playwright-pytest-framework:local .
docker run --rm -e HEADLESS=true -v "$(pwd)/reports:/app/reports" \
  playwright-pytest-framework:local -m smoke

or with compose:

docker compose -f docker/docker-compose.yml run tests

Configuration

All configuration is environment-variable driven — see .env.example for the full list (BASE_URL, API_BASE_URL, BROWSER, HEADLESS, API_AUTH_TOKEN, etc.). Nothing environment-specific is hardcoded in test code, so the same image/pipeline can target dev, staging, or prod-like environments purely by changing env vars.

Test markers

Declared and enforced (via --strict-markers) in tests/conftest.py:

  • @pytest.mark.smoke — fast, critical-path checks. Run on every PR.
  • @pytest.mark.regression — broader functional coverage.
  • @pytest.mark.nightly — slow/expensive checks reserved for the nightly job.
  • @pytest.mark.ui / @pytest.mark.api — test type, for selective filtering.

CI/CD

  • .github/workflows/pr-checks.yml — triggers on every PR to main. Runs ruff + mypy, then pytest -m smoke against Chromium only, for fast feedback. Uploads the HTML/JUnit report and any failure screenshots/traces as build artifacts.
  • .github/workflows/nightly.yml — triggers on a cron schedule (02:00 UTC daily) and via manual workflow_dispatch. Runs the full suite (smoke or regression or nightly) across a Chromium/Firefox/Webkit matrix in parallel (pytest -n auto), uploading per-browser reports. Includes a failure-notification job stub (wire to Slack/Teams/email).

Debugging a failure

When a UI test fails (locally or in CI), tests/conftest.py's pytest_runtest_makereport hook automatically saves:

  • reports/screenshots/<test-id>.png
  • reports/traces/<test-id>.zip — open with:
    playwright show-trace reports/traces/<test-id>.zip
    for a full step-by-step, DOM-snapshot replay of exactly what happened.

Extending the framework

  • New UI page → add a class to src/pages/, inheriting BasePage.
  • New API resource → add a Service Object to src/api/, and a schema dataclass to src/api/schemas.py if you want contract validation.
  • New test tier → register the marker in pytest_configure() in tests/conftest.py, then reference it in the relevant workflow's -m expression

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors