AI Global Academy Join the waitlist

Courses / Optimise, automate, operate

Lesson 8.4 · 55 minAutomated tests

Duration~55 min in the lesson + ~30 min homework
PrerequisitesCheckpoint lesson-8.3.
Checkpointlesson-8.4

What you will have

The project has Playwright end-to-end tests for the lead path and the admin login. They run against a safe local copy wired to a separate test database, pass on a clean run, and fail when the form is deliberately broken.

Video

The video for this lesson is not recorded yet.

Prompts used in this lesson

Part 4 — The test environment and the tests

Prompt to Claude
Purpose: catch a broken lead form or admin login before visitors do. Write
end-to-end tests with Playwright for the two paths that matter most.

Context: Playwright is installed (playwright.config.ts, tests folder e2e/). I
created a second Supabase project for tests and a file .env.e2e. Read .env.local
for variable NAMES only and tell me which names .env.e2e must contain; I will
fill in the values myself. Never print values from either file.

Before writing code: read the current Playwright documentation for the webServer
option, for authentication with a setup project and storage state, and for
locators. Tell me which pages you read.

Safe target (most important):
1. Tests run only against a local server that Playwright starts itself on port
   3100 with the values from .env.e2e, and never reuse an already running server.
2. That server uses the test Supabase project. Apply all migrations in
   supabase/migrations/ to it and create the admin test user from the
   credentials in .env.e2e.
3. In the test environment these stay empty and the code must skip them without
   errors: email, Telegram, Meta Conversions API, Google Ads conversions, the
   Claude API key, the GTM container ID. Check each code path and tell me if any
   would still send something.
4. Turnstile uses Cloudflare's documented always-pass dummy keys.
5. A guard that stops the whole run before the first test if the base URL is not
   localhost, or if the Supabase URL equals the one in .env.local.
6. .env.e2e and Playwright's saved login state are in .gitignore.

Tests:
A. Lead path: open the landing page, fill the form with a unique test email,
   submit, arrive on /thank-you. Sign in to the admin, find that lead in
   /admin/leads, open its card, change its status to "contacted", and confirm
   the change appears in the status history.
B. Admin login: signed out, /admin redirects to /admin/login; a wrong password
   shows an error and does not sign in; the right password opens the admin.

Also: delete the example test; add npm scripts "test:e2e" and "test:e2e:ui";
add the commands and the rule "run test:e2e before pushing" to CLAUDE.md.

Constraints: do not change application behaviour to make a test pass. If the
rate limit or anything else in the app blocks the tests, stop and explain the
options to me. Find elements by their labels and roles, the way a visitor would.

Done when: you have run the tests three times in a row with all passing, shown
me the output, and confirmed by a row count that the production database
received nothing. Report anything you could not verify.

Part 5 — Break it on purpose

Prompt to Claude
The end-to-end test for the lead path fails. The output is in the terminal and
the report is in playwright-report/. Find the cause in the application and
explain it to me in one sentence before changing anything. Fix the cause, not
the test: do not edit files in e2e/, do not loosen an assertion, do not add
retries or waits. Then run the full test suite and show me the result.

Do along

Work on your own project and pause the video where a step says so.

  1. Pause after Part 2. Check node --version against Playwright's supported versions.
  2. Create a second Supabase project for tests. Create the admin test user's credentials (a new password).
  3. Pause after Part 3. Run npm init playwright@latest with the answers from Part 3, then npx playwright test and npx playwright show-report.
  4. Pause after Part 4. Run the prompt from Part 4. When Claude lists the variable names, create .env.e2e and fill in the test project's values yourself. If your form has different fields or your first pipeline stage after new has another name, say so in the prompt.
  5. Watch the lead-path test in UI mode.
  6. Pause after Part 5. Break the form by hand (misspell one field name), run the tests, read the report.
  7. Use the fix prompt from Part 5. Check that the diff does not touch e2e/.
  8. After Part 6, run npm run test:e2e once more, then commit and tag with the commands under "Recap and next".

Check your work

  1. Run npm run test:e2e. Expected: all tests pass.
  2. Open your production CRM. Expected: no new test lead; no test email or Telegram message arrived.
  3. Misspell a form field name, run the tests. Expected: the lead-path test fails. Undo with git restore on that file; run again: pass.

Common problems

  • The run stops at once with the guard's message → .env.e2e holds production values or is incomplete → correct the values; this is the guard doing its job.
  • The form test fails at the Turnstile step → real Turnstile keys are in the test file → use Cloudflare's dummy always-pass keys from its testing page.
  • A real email or Telegram message arrived during a test → a notification variable is set in .env.e2e or the code ignores an empty value → stop, tell Claude which message arrived, have it fix the skip and prove it.

Homework

About 30 minutes, on your own, after the lesson. Lesson 8.5 does not depend on it.

  1. Learn what your tests see. Break two more things by hand, one at a time: one inside the form (for example the visible label of a field) and one elsewhere on the page (for example a headline or a footer link). Before each run, write down whether you expect a test to fail. Run npm run test:e2e, then undo with git restore. Deliverable: a heading "Tests: covered and not covered" in docs/architecture.md with, for each break, what you changed, your prediction and the result. Done when: both entries are written, git status shows no leftover change from the drills, and the tests pass.
  2. One more test of your own. Decide what, after the lead path, would cost your business most if it broke unnoticed: for example, the form showing an error when a required field is empty, or a campaign page under /lp/ loading with its form. Ask Claude for one test of it, with the constraints from the Part 4 prompt: local test environment only, no change to application behaviour, elements found by labels and roles. Then break that thing by hand and watch the new test fail. Done when: the whole suite passes three times in a row and the new test fails on your deliberate break. If you cannot get it reliably green, delete the new test file; a test that fails at random is worse than none.

Commit without a tag: git add -A, git commit -m "Homework 8.4: test coverage notes and one more test", git push.

Save your work

git add -A
git commit -m "Lesson 8.4: Playwright end-to-end tests for lead path and admin login"
git tag lesson-8.4
git push
git push --tags