From 8ceea028757904ce40d380c5ceba799a013591af Mon Sep 17 00:00:00 2001 From: Senrokai Date: Fri, 21 Aug 2026 15:20:00 +0200 Subject: [PATCH] Wait for the boot as long as the boot takes The specs added over this series each opened with an untimed check that the canvas was there, which gives it Playwright's default five seconds. That is the one wait in this suite that cannot be made faster: eight workers share a software rasterizer, and what they are all waiting on is the same first paint. Under a full parallel run five seconds is a coin toss, and it came up wrong on the route-plotting spec. Thirty, like every other wait in here that crosses a camera flight. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi --- e2e/bookmarks.spec.ts | 5 ++++- e2e/galaxy-view.spec.ts | 7 +++++-- e2e/plan-view.spec.ts | 7 +++++-- e2e/route-plotting.spec.ts | 7 +++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/e2e/bookmarks.spec.ts b/e2e/bookmarks.spec.ts index ad5d801..209eba8 100644 --- a/e2e/bookmarks.spec.ts +++ b/e2e/bookmarks.spec.ts @@ -14,7 +14,10 @@ test.describe('Bookmarks', () => { // A later visit, on a different page: kept places outlive the one they were kept from. await page.goto('/'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + // Generously timed on purpose: this suite shares one software rasterizer, and the boot + // it waits on is the slowest thing in it. The default five seconds is a coin toss + // under a full parallel run. + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await page.getByRole('tab', { name: 'Bookmarks' }).click(); const kept = page.locator('#dock-panel-bookmarks li').filter({ hasText: 'Earth' }); diff --git a/e2e/galaxy-view.spec.ts b/e2e/galaxy-view.spec.ts index b9e31c9..7ef7238 100644 --- a/e2e/galaxy-view.spec.ts +++ b/e2e/galaxy-view.spec.ts @@ -9,7 +9,10 @@ test.describe('Galaxy view', () => { test('boots the app, initializes the 3D scene, and starts in the galaxy overview (no system controls shown)', async ({ page }) => { await page.goto('/?stars=4000'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + // Generously timed on purpose: this suite shares one software rasterizer, and the boot + // it waits on is the slowest thing in it. The default five seconds is a coin toss + // under a full parallel run. + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); // The dock's tab strip is up before the scene finishes booting; the search is one tab in it. await expect(page.getByRole('tab', { name: 'Search' })).toBeVisible(); await expect(backButtonLocator(page)).toHaveCount(0); @@ -23,7 +26,7 @@ test.describe('Galaxy view', () => { // up to more than the default per-test budget. test.setTimeout(90_000); await page.goto('/?stars=4000'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await page.getByRole('button', { name: 'Milky Way' }).click(); diff --git a/e2e/plan-view.spec.ts b/e2e/plan-view.spec.ts index 79626c1..42a26e4 100644 --- a/e2e/plan-view.spec.ts +++ b/e2e/plan-view.spec.ts @@ -34,7 +34,10 @@ test.describe('Plan view', () => { await expect(plan).toHaveAttribute('aria-pressed', 'true'); // The scene survives the swap: it is still this system, still labelled, still readable. - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + // Generously timed on purpose: this suite shares one software rasterizer, and the boot + // it waits on is the slowest thing in it. The default five seconds is a coin toss + // under a full parallel run. + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await expect.poll(spread, { timeout: 30_000 }).toBeGreaterThan(2); await page.getByRole('tab', { name: 'Readout' }).click(); await expect(page.getByTestId('hud-title')).toHaveText('Sol'); @@ -48,7 +51,7 @@ test.describe('Plan view', () => { test('keeps the scale ladder honest about how far out the view is', async ({ page }) => { test.setTimeout(90_000); await page.goto('/?stars=4000'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await expect(page.getByTestId('hud-current-level')).toHaveText('Solar Neighbourhood', { timeout: 30_000 }); await page.getByRole('tab', { name: 'Display' }).click(); diff --git a/e2e/route-plotting.spec.ts b/e2e/route-plotting.spec.ts index d308d06..ab0737a 100644 --- a/e2e/route-plotting.spec.ts +++ b/e2e/route-plotting.spec.ts @@ -4,7 +4,10 @@ test.describe('Route plotting', () => { test('chains one star to another through the crossings a chosen range allows', async ({ page }) => { test.setTimeout(90_000); await page.goto('/?stars=4000'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + // Generously timed on purpose: this suite shares one software rasterizer, and the boot + // it waits on is the slowest thing in it. The default five seconds is a coin toss + // under a full parallel run. + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await page.getByRole('tab', { name: 'Routes' }).click(); @@ -32,7 +35,7 @@ test.describe('Route plotting', () => { test('says what range a crossing would need, rather than only that there is none', async ({ page }) => { test.setTimeout(90_000); await page.goto('/?stars=4000'); - await expect(page.getByTestId('scene-canvas')).toBeVisible(); + await expect(page.getByTestId('scene-canvas')).toBeVisible({ timeout: 30_000 }); await page.getByRole('tab', { name: 'Routes' }).click(); await page.locator('#route-from').fill('Sol');