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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
65 lines
3.0 KiB
TypeScript
65 lines
3.0 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
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');
|
|
// 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();
|
|
|
|
// Sirius is 2.64 pc from the Sun, so the default 3 pc range crosses it in one.
|
|
await page.locator('#route-from').fill('Sol');
|
|
const departure = page.locator('#dock-panel-routes ul li button').first();
|
|
await expect(departure).toBeVisible({ timeout: 30_000 });
|
|
await departure.click();
|
|
|
|
await page.locator('#route-to').fill('Sirius');
|
|
const destination = page.locator('#dock-panel-routes ul li button').first();
|
|
await expect(destination).toBeVisible();
|
|
await destination.click();
|
|
|
|
await page.getByRole('button', { name: 'Plot route' }).click();
|
|
|
|
await expect(page.getByTestId('route-summary')).toHaveText(/1 jump · 2\.6\d pc/);
|
|
// The chain itself, departure first, each step a way to fly there.
|
|
const steps = page.getByTestId('route-steps').getByRole('button');
|
|
await expect(steps).toHaveCount(2);
|
|
await expect(steps.first()).toContainText('Sol');
|
|
await expect(steps.last()).toContainText('Sirius');
|
|
});
|
|
|
|
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({ timeout: 30_000 });
|
|
|
|
await page.getByRole('tab', { name: 'Routes' }).click();
|
|
await page.locator('#route-from').fill('Sol');
|
|
const departure = page.locator('#dock-panel-routes ul li button').first();
|
|
await expect(departure).toBeVisible({ timeout: 30_000 });
|
|
await departure.click();
|
|
|
|
// Narrowed until nothing the catalogue holds is within reach of the Sun: its nearest
|
|
// neighbour is 1.30 pc away, so half a parsec strands it.
|
|
await page.locator('#route-range').fill('0.5');
|
|
await page.locator('#route-to').fill('Sirius');
|
|
const destination = page.locator('#dock-panel-routes ul li button').first();
|
|
await expect(destination).toBeVisible();
|
|
await destination.click();
|
|
await page.getByRole('button', { name: 'Plot route' }).click();
|
|
|
|
const summary = page.getByTestId('route-summary');
|
|
await expect(summary).toContainText('No route at this range', { timeout: 30_000 });
|
|
// And the answer, not just the refusal: the range that would open one, offered as a control.
|
|
const raise = summary.getByRole('button');
|
|
await expect(raise).toContainText(/pc would reach/);
|
|
await raise.click();
|
|
|
|
await expect(page.getByTestId('route-summary')).toContainText(/jump/, { timeout: 30_000 });
|
|
});
|
|
});
|