diff --git a/e2e/CLAUDE.md b/e2e/CLAUDE.md index fbf1e794..ebbb70f2 100644 --- a/e2e/CLAUDE.md +++ b/e2e/CLAUDE.md @@ -308,10 +308,15 @@ something no cheaper tier can. `web/` states, enforced by construction rather than by mock resetting. A workspace slug is unique server-side, so two tests sharing one would fail on the second, exactly as two sharing an email would. -- **Workers are capped at four.** Every test's setup is three - cross-service round trips against one core and one postgres; past a - few workers the setup starts timing out, which reads as flaky tests - when it is only load. +- **Workers are capped at four locally and two on CI.** Every test's + setup is several cross-service round trips against one core and one + postgres; past a few workers the setup starts timing out, which reads + as flaky tests when it is only load — and a private-repo CI runner has + two vCPUs for the stack and the browsers together. For the same + reason the test budget is 60s (a 7s local test is a 40s test on that + runner), and the collaboration tests are marked slow, tripling theirs: + each one runs two signups, two verifications, an invitation and its + acceptance before the first assertion. - **No test depends on another's state or on execution order**, and no test cleans up after itself: the stack's database is thrown away wholesale, which is why it carries no volumes. diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 2b38be6f..17d893cf 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -8,7 +8,14 @@ export default defineConfig({ // workspace before it starts, and the stack answers all of them from // one core and one postgres. Past a few workers the setup itself // starts timing out, which reads as flaky tests when it is only load. - workers: 4, + // CI gets fewer still: a private-repo runner has two vCPUs for the + // whole stack and the browsers together. + workers: process.env.CI ? 2 : 4, + // the default 30s budget contradicts the suite's own waits — a login + // redirect is allowed 15s and an invite acceptance 30s, because they + // are cross-service chains that stretch under load. CI runs the whole + // stack on two cores, where a test that takes 7s locally takes 40. + timeout: 60_000, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, // github gives inline annotations on the PR; html is what the diff --git a/e2e/tests/collaboration.test.ts b/e2e/tests/collaboration.test.ts index 41f7671b..628de8f0 100644 --- a/e2e/tests/collaboration.test.ts +++ b/e2e/tests/collaboration.test.ts @@ -14,6 +14,13 @@ import { visit } from "../helpers/page" import { signUpWithWorkspace } from "../helpers/workspace" test.describe("collaboration", () => { + // the heaviest setup in the suite: every test runs two signups, two + // email verifications, an invitation and its acceptance before the + // first assertion. slow() triples the budget for exactly these tests. + test.beforeEach(() => { + test.slow() + }) + test("shows text typed by one user to the other", async ({ page, request,