Manuals / Playwright with Python / Ch 44

Part 7 · Real-World Project & Job ReadinessProfessional90 min read

33. Real-World Capstone Project

Playwright with Python · 244 pages source format

End-to-end framework build (login, CRUD flow, API validation) The capstone ties together nearly every prior chapter into one cohesive project rather than isolated exercises. A solid scope for a portfolio-worthy capstone: ● Login — using POM (Chapter 14), with a session-reuse fixture (Chapter 20) so login only happens once per run, not once per test.

What you'll learn

  • End-to-end framework build (login, CRUD flow, API validation)
  • Combining UI + API + auth + CI/CD in one suite
  • Code review and refactor pass

End-to-end framework build (login, CRUD flow, API validation)

The capstone ties together nearly every prior chapter into one cohesive project rather than isolated exercises. A solid scope for a portfolio-worthy capstone:

login only happens once per run, not once per test.

cover Create, Read, Update, Delete end-to-end through the UI.

correctly server-side, not just that the UI looked right.

tasks_page = TasksPage(authenticated_page)

response = request.get("/api/tasks?title=Finish QA report")

task_id = response.json()["tasks"][0]["id"]

follow_up = request.get(f"/api/tasks/{task_id}")

Pointers: The API-validation steps are what elevate this from "a UI clicker" to a genuine full-stack test — it's a detail interviewers specifically listen for, since it demonstrates you understand that UI success and data-layer success are two different things worth verifying independently.

  • Login — using POM (Chapter 14), with a session-reuse fixture (Chapter 20) so
  • CRUD flow — pick one feature (e.g., a "tasks" or "leave requests" module) and
  • API validation — for at least the Create and Delete steps, verify the result via a direct API call (Chapter 18) as well as the UI, proving the data actually persisted
assert response.json()["tasks"][0]["due_date"] == "2026-08-10"

# Update

tasks_page.edit_task("Finish QA report", new_title="Finish QA report v2")

expect(authenticated_page.get_by_text("Finish QA report v2")).to_be_visible()

# Delete

tasks_page.delete_task("Finish QA report v2")

expect(authenticated_page.get_by_text("Finish QA report v2")).not_to_be_visible()

# API validation of deletion

# Create

tasks_page.create_task("Finish QA report", due_date="2026-08-10")

expect(authenticated_page.get_by_text("Finish QA report")).to_be_visible()

# API validation of creation

# tests/test_task_crud.py

from pages.tasks_page import TasksPage

def test_create_read_update_delete_task(authenticated_page, request):
Interactive study board
End-to-end framework build (login, CRUD flow, API validation)Drag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Combining UI + API + auth + CI/CD in one suite

The full picture: conftest.py wires together the session-scoped auth fixture (Chapter

20), the request fixture for API calls (Chapter 18), and the whole thing runs automatically via a GitHub Actions workflow (Chapter 25) on every push, publishing an HTML or Allure report as an artifact (Chapter 26).

Pointers: Getting this pipeline green end-to-end — not just passing locally — is the real milestone. A huge amount of practical learning happens specifically in the friction of getting something to run correctly in CI that worked fine locally (missing --with-deps, environment variable differences, headless-only quirks) — don't skip actually pushing this to GitHub and watching Actions run it.

Interactive study board
Combining UI + API + auth + CI/CD in one suiteDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Code review and refactor pass

Once the capstone works, deliberately revisit it against Chapter 31's anti-patterns checklist:

Pointers: This refactor pass is itself a valuable, showable skill — if you're asked in an interview "tell me about a time you improved code quality," a concrete before/after from this exact refactor pass is a strong, specific answer.

  • Any hardcoded waits sneak in while you were focused on "just get it working"?
  • Any locators that should be role-based but ended up as brittle CSS?
  • Any test that secretly depends on another test's leftover data?
  • Is cleanup happening reliably via fixture teardown (Chapter 16), even on failure?
Interactive study board
Code review and refactor passDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Checklist