Skip to content

Repository files navigation

QA Practice Projects

Three tiny, self-contained Playwright projects that reproduce real bug patterns discussed in interview prep: lost UTM parameters, missing legal disclosure text, and flaky tests. No external services, no API keys, no real network calls. Everything runs against local HTML fixtures.

Setup

npm install
npx playwright install --with-deps chromium

Run everything

npm test

Run one project at a time

npm run test:utm          # Project 1
npm run test:disclosure   # Project 2
npm run test:flaky        # Project 3

Project 1: UTM redirect chain (tests/utm-redirect.spec.ts)

What it simulates: A campaign email link redirects through a tracking script before landing on the final offer page. Somewhere in that chain, one UTM parameter silently disappears.

What you'll see: The test fails. Open fixtures/redirect-buggy.html, read the bug comment, uncomment the missing line, save, and run npm run test:utm again. Watch it go from red to green.

What this teaches: How to follow a redirect with page.waitForURL(), how to parse query parameters out of the final URL with the built-in URL and URLSearchParams objects, and what it actually looks like when a test catches a real attribution-breaking bug.


Project 2: Disclosure language check (tests/disclosure-check.spec.ts)

What it simulates: A vacation ownership company sends a discounted package email that legally requires disclosure language about a mandatory sales presentation. A templating bug strips that disclosure block from one version of the email.

What you'll see: Two tests run. The "correct email" test passes. The "buggy email" test fails on purpose, demonstrating exactly how this kind of check would catch a real compliance risk before a campaign ships.

What this teaches: Text-content assertions with toContainText(), and how to think about QA checks that protect against legal exposure, not just broken buttons.


Project 3: Flaky test pattern (tests/flaky-fix.spec.ts)

What it simulates: A page where content loads after a 1.5 second delay, just like a real API call or network response.

What you'll see: The "BAD pattern" test uses an artificially short 100ms timeout and fails almost every time. The "GOOD pattern" test uses Playwright's default timeout, which polls and retries automatically, and passes reliably every time.

What this teaches: Why flaky tests happen (checking before the condition is true) and the actual fix (let Playwright's built-in retry behavior do the waiting instead of guessing a fixed delay).


Suggested learning order

Run Project 3 first. It's the easiest to understand at a glance and teaches the single most common interview topic: "tell me about a flaky test you've fixed."

Run Project 1 second. It directly mirrors the UTM tracking question from interview prep.

Run Project 2 last. It's the most specific to the HGV-style compliance angle and the most likely to set you apart from other candidates if it comes up.

Stretch goal

Once all three pass, try converting tests/flaky-fix.spec.ts to Python as a side exercise. The Playwright Python API is nearly a line-for-line translation:

from playwright.sync_api import Page, expect

def test_good_pattern_waits_for_the_actual_condition(page: Page):
    page.goto("file:///path/to/fixtures/async-loader.html")
    page.click("#loadBtn")
    expect(page.locator("#result")).to_have_text("Offer Details Loaded")

That's the whole gap between the two languages: camelCase becomes snake_case, semicolons disappear, and expect() comes from a different import. You don't need to relearn how testing works, just the syntax.

About

Self-contained Playwright projects demonstrating real QA bug patterns: lost UTM tracking, missing compliance disclosures, and flaky test fixes. CI runs on every push.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages