Skip to content

Commit 4d07bf3

Browse files
committed
Fix slug-read race in the billing trial-checkout scenario
The scenario landed on "/" with waitUntil networkidle and immediately read the org slug from the pathname. networkidle proves the network went quiet, not that the client-side canonicalization redirect ran: on a slow CI runner the pathname is still "/" at that point, so split("/").filter(Boolean)[0] is undefined and the test navigates to the literal /undefined/billing/plans. The billing fetches fire under that bogus slug and cache their failure (autumn-js staleTime 60s, no refetch on focus); the shell then canonicalizes the URL client-side but nothing refetches, so the plans grid stays empty and the "Start free trial" waitFor times out through every retry. The run artifacts show exactly this: timeline.json records the /undefined/billing/plans navigation and failure.png shows the plans page with an empty grid. Wait for the URL to canonicalize onto the slug pattern before reading it, the same barrier member-invite-seat-limit already uses.
1 parent 6834eb2 commit 4d07bf3

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

e2e/cloud/billing-trial-checkout-stale.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,17 @@ scenario(
4444
await step("A fresh org is offered the Team free trial", async () => {
4545
// Billing requests are org-scoped via the URL slug header, so reach the
4646
// plans page through the org-scoped URL (a bare /billing/plans would fire
47-
// the first fetch before the slug resolves and 401). Land on "/" to
48-
// canonicalize, then open the slug-scoped plans page.
47+
// the first fetch before the slug resolves and 401). Land on "/" and WAIT
48+
// for the shell to canonicalize onto the slug before reading it:
49+
// networkidle only proves the network went quiet, not that the client-side
50+
// redirect ran, and reading too early navigates to the literal
51+
// "/undefined/billing/plans" — the billing fetches fire under the bogus
52+
// slug, fail, and are never refetched (autumn-js staleTime 60s), leaving
53+
// the plans grid empty forever.
4954
await page.goto("/", { waitUntil: "networkidle" });
55+
await page.waitForURL((url) => /^\/[a-z0-9-]+\/?$/.test(url.pathname), {
56+
timeout: 30_000,
57+
});
5058
const slug = new URL(page.url()).pathname.split("/").filter(Boolean)[0];
5159
await page.goto(`/${slug}/billing/plans`, { waitUntil: "networkidle" });
5260
await page.getByRole("heading", { name: "Choose a plan" }).waitFor();

0 commit comments

Comments
 (0)