-
Notifications
You must be signed in to change notification settings - Fork 10
e2e
End-to-end tests live in e2e/ and run on Playwright. They drive the real frontend against a real backend per company.
Mandatory pattern: walk a flow via UI exactly once per workflow; API-seed all variants. See E2E State Pattern for the full rule + helpers. Audit of current duplicate walks: duplicate-walks audit. Coverage gaps: coverage-gaps.
- Test files:
e2e/tests/<company>/<workflow>/*.spec.ts - Page Object Models:
e2e/tests/poms/<company>/<workflow>.ts - Helpers:
e2e/helpers/(toast handling, CSV import, client fixups) - Playwright config:
e2e/playwright.config.ts - Operational notes & inventory:
e2e/README.md
How to design and name POM methods — dynamic getters, parametrization, locator priority, layering — is documented separately:
Specs compose POM primitives. Test-specific values (order IDs, weights, cities, counts) belong in the spec, not the POM.
RPC-triggering button clicks go through command(resource) (in specs: destructure command from the test fixture; in POMs: this.command(...)). The helper derives the button label and toast prefix from the same intl key the frontend renders, so a label rename breaks the test at the locator step instead of at a stale toast wait.
Fluent shortcuts: .via(locator) for non-button triggers, .thenConfirm() when the action opens a confirm dialog and the RPC fires on "Ja". For the case where the caller already opened the dialog elsewhere and "Ja" itself is the trigger, pass { label: "Ja" } to command(). Audit + rationale for handleToast / waitForResponse fallbacks: e2e-toast-wait-audit.md.
playwright.config.ts does not override timeout, expect.timeout, actionTimeout, navigationTimeout, or globalTimeout. Playwright defaults apply:
- Per-test timeout: 30 s
-
expect()timeout: 5 s
A handful of long workflow specs use test.slow(), which triples the per-test timeout to 90 s and tags the test as slow in reports. Current set lives in e2e/README.md ("Tests marked test.slow()").
Reach for test.slow() only after investigating why the test is slow. A test that runs close to 30 s is almost always doing more waiting than working. Common causes:
-
Unclosed toasts — clicking a button that fires a toast without awaiting it (via
command(rsc).click(),handleToast(...), oractButton(...)) means subsequent steps stack behind the still-visible toast. The default path iscommand(rsc).click(); reach forhandleToastonly for fill-trigger /waitForResponsefor silent toasts (see audit). -
Blind
waitForTimeout(...)— replace with locator-based waits (expect(locator).toBeVisible(),waitForResponse(...)). -
networkidlewaits on SPA pages —waitForURLdoes not wait for paint; pair it with an assertion on a stable element instead ofnetworkidle. -
Sequential
expect()polls that could be one assertion — e.g. checking N rows individually instead of asserting on the list count once. - Auto-generated Vuetify IDs in locators that retry on every component-tree change — see POM Architecture for locator priority.
- Re-running fixtures or imports inside steps that should reuse state — import once per test, not per step.
If a test legitimately exercises a multi-stage workflow (pick → pack → closeout) and the wall-clock floor is dominated by real backend work, test.slow() is fine. Document why in a short comment next to the call.
Long per-test timeouts are most expensive when the test is already broken. If a click does nothing, or the action fails immediately, a blanket 90 s timeout just burns CI minutes waiting for a state change that will never arrive. Prefer waiting briefly for the German … wird ausgeführt in-progress toast, only then extending the timeout window, and stopping as soon as the terminal success or failure toast appears.
- Index
- Import Rules
- Resource & Controller Layout
- Command Pattern
- Command Input Validation
- Query Shape: List vs Get
- Database Query Guidelines
- List Layout
- Streams & Progress
- Vue Conventions
- E2E State Pattern
- E2E
- E2E Toast Wait Audit
- Flow Documentation
- (project-local — create
flows/when first workflow lands)