e2e: CREW tab renders real roster cards with both traits; roster survives container restart
This commit is contained in:
+21
-1
@@ -7,7 +7,8 @@ interface PlanetDto { id: number; name: string; type: string; hazard: boolean; e
|
|||||||
interface InventoryItemDto { kind: string; name: string; qty: number }
|
interface InventoryItemDto { kind: string; name: string; qty: number }
|
||||||
interface SystemState { systemId: number; systemName: string; planets: PlanetDto[]; inventory: InventoryItemDto[]; turn: number }
|
interface SystemState { systemId: number; systemName: string; planets: PlanetDto[]; inventory: InventoryItemDto[]; turn: number }
|
||||||
interface FoundItem { kind: string; name: string; qty: number }
|
interface FoundItem { kind: string; name: string; qty: number }
|
||||||
interface ExploreResult extends SystemState { outcome: FoundItem[] }
|
interface ExploreResult extends SystemState { outcome: FoundItem[]; crewFound: unknown }
|
||||||
|
interface CrewDto { id: number; name: string; role: string; traitGood: string; traitBad: string; origin: string }
|
||||||
|
|
||||||
test('landing page loads with the SpaceWanderer title', async ({ page }) => {
|
test('landing page loads with the SpaceWanderer title', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
@@ -119,6 +120,25 @@ test('exploration yields finds that accumulate in the inventory', async ({ page
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('CREW tab renders real roster cards, each showing both traits and an origin', async ({ page }) => {
|
||||||
|
const roster = (await (await page.request.get('/api/crew')).json()) as CrewDto[];
|
||||||
|
expect(roster.length).toBeGreaterThanOrEqual(2); // starting crew is always seeded
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
await page.getByRole('tab', { name: 'CREW' }).click();
|
||||||
|
|
||||||
|
for (const member of roster) {
|
||||||
|
const heading = page.getByRole('heading', { name: member.name });
|
||||||
|
await expect(heading).toBeVisible();
|
||||||
|
// The card is the third div ancestor of the title (flex row → CardHeader → Card).
|
||||||
|
const card = heading.locator('xpath=ancestor::div[3]');
|
||||||
|
await expect(card.getByText(member.role)).toBeVisible();
|
||||||
|
await expect(card.getByText(member.traitGood)).toBeVisible();
|
||||||
|
await expect(card.getByText(member.traitBad)).toBeVisible();
|
||||||
|
await expect(card.getByText(`ORIGIN // ${member.origin.toUpperCase()}`)).toBeVisible();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('GET /api/version reports the app version as JSON', async ({ page }) => {
|
test('GET /api/version reports the app version as JSON', async ({ page }) => {
|
||||||
const res = await page.request.get('/api/version');
|
const res = await page.request.get('/api/version');
|
||||||
expect(res.status()).toBe(200);
|
expect(res.status()).toBe(200);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface WorldSystemDto { id: number; name: string; x: number; y: number; disco
|
|||||||
interface WorldState { systems: WorldSystemDto[]; edges: [number, number][]; turn: number }
|
interface WorldState { systems: WorldSystemDto[]; edges: [number, number][]; turn: number }
|
||||||
interface PlanetDto { id: number; name: string; type: string; hazard: boolean; explored: boolean; parent: number | null }
|
interface PlanetDto { id: number; name: string; type: string; hazard: boolean; explored: boolean; parent: number | null }
|
||||||
interface SystemState { systemId: number; systemName: string; planets: PlanetDto[]; inventory: { kind: string; name: string; qty: number }[]; turn: number }
|
interface SystemState { systemId: number; systemName: string; planets: PlanetDto[]; inventory: { kind: string; name: string; qty: number }[]; turn: number }
|
||||||
|
interface CrewDto { id: number; name: string; role: string; traitGood: string; traitBad: string; origin: string }
|
||||||
|
|
||||||
test('app survives a container restart (stack + volume persistence)', async ({ page }) => {
|
test('app survives a container restart (stack + volume persistence)', async ({ page }) => {
|
||||||
test.setTimeout(180_000);
|
test.setTimeout(180_000);
|
||||||
@@ -47,6 +48,10 @@ test('app survives a container restart (stack + volume persistence)', async ({ p
|
|||||||
expect(exploreRes.status()).toBe(200);
|
expect(exploreRes.status()).toBe(200);
|
||||||
const sysExplored = (await exploreRes.json()) as SystemState;
|
const sysExplored = (await exploreRes.json()) as SystemState;
|
||||||
|
|
||||||
|
// Crew baseline: the roster (starting crew + any finds so far) must survive too.
|
||||||
|
const crewBefore = (await (await page.request.get('/api/crew')).json()) as CrewDto[];
|
||||||
|
expect(crewBefore.length).toBeGreaterThanOrEqual(2); // starting crew is always seeded
|
||||||
|
|
||||||
// Restart the app container mid-run — the named DB volume must survive it.
|
// Restart the app container mid-run — the named DB volume must survive it.
|
||||||
execSync(`docker compose ${composeArgs} restart space-wanderer`, { cwd: repoRoot, stdio: 'pipe' });
|
execSync(`docker compose ${composeArgs} restart space-wanderer`, { cwd: repoRoot, stdio: 'pipe' });
|
||||||
|
|
||||||
@@ -77,6 +82,10 @@ test('app survives a container restart (stack + volume persistence)', async ({ p
|
|||||||
expect(sysAfter.turn).toBe(sysExplored.turn);
|
expect(sysAfter.turn).toBe(sysExplored.turn);
|
||||||
expect(sysAfter.planets.find((p) => p.id === targetPlanet.id)?.explored).toBe(true);
|
expect(sysAfter.planets.find((p) => p.id === targetPlanet.id)?.explored).toBe(true);
|
||||||
|
|
||||||
|
// Crew roster survived too: same members, traits and origins (no re-seed on restart).
|
||||||
|
const crewAfter = (await (await page.request.get('/api/crew')).json()) as CrewDto[];
|
||||||
|
expect(crewAfter).toEqual(crewBefore);
|
||||||
|
|
||||||
// The page itself serves again with the landing title.
|
// The page itself serves again with the landing title.
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
await expect(page.getByRole('heading', { name: 'SpaceWanderer' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'SpaceWanderer' })).toBeVisible();
|
||||||
|
|||||||
Reference in New Issue
Block a user