Thesis: End-to-end login coverage can stay in the same Given/When/Then style as the rest of the suite. Playwright is the driver, not a second test framework.
What we shipped first
Unit tests could not see a broken Google client id or a wrong authorize redirect. The login button looked fine. A human had to click Continue with Google and notice invalid_client or a dead hop.
We already wrote API sagas as Given / When / Then in pytest. A separate Playwright project would have split the vocabulary. Operators would learn two runners for one product.
The working shape
Keep the saga in pytest. Skip cleanly when Playwright is not installed. Install browsers through a make target that is not an asdf plugin. Assert the browser lands on Google Sign-in for the expected host — not a token dump.
# Given / When / Then — still pytest, browser via Playwright
Given the login surface is open
When the operator chooses Continue with Google
Then the browser reaches Google Sign-in (not invalid_client)
$ make install-e2e
$ make test-e2e-auth
Checklist
- Run make install-e2e once per machine after Python is ready.
- Run make test-e2e-auth for the Google Continue saga.
- Keep assertions on the public handoff (Sign-in page / client acceptance), not on secrets or tokens.
- Leave the rest of the suite as ordinary pytest — same language, same CI story.
Related: a retry has to return the first answer. How we deliver: methodology.
Engineering commentary only — not audit, legal, or certification advice.