# Instructions

- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.

# Test info

- Name: logout.e2e.test.ts >> Esc menu >> Esc opens menu; Logout returns to LoginScene with cleared session cookies (D-34)
- Location: test/e2e/logout.e2e.test.ts:18:3

# Error details

```
Error: expect(locator).toBeVisible() failed

Locator: locator('form#login-form, #login-form, #username')
Expected: visible
Timeout: 5000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" with timeout 5000ms
  - waiting for locator('form#login-form, #login-form, #username')

```

# Page snapshot

```yaml
- generic [ref=e4] [cursor=pointer]: Disconnected — click to retry
```

# Test source

```ts
  1  | // apps/client/test/e2e/logout.e2e.test.ts
  2  | // [int->REQ-CLI-02] [int->REQ-CLI-03]
  3  | // Plan 06-11 — Playwright e2e for Esc menu logout flow (D-24 + D-34).
  4  | //
  5  | // Tests:
  6  | //   1. Esc opens the menu; Logout returns to LoginScene with cleared session
  7  | //      cookies — cookie assertion uses page.context().cookies() (Better-Auth
  8  | //      sets HttpOnly so document.cookie is always empty; page.context().cookies()
  9  | //      sees the full cookie jar). Shape is toHaveLength(0), NOT
  10 | //      every(c => !c.value) which passes spuriously when cookies are absent.
  11 | //   2. Canvas pointerdown opens the menu (D-24 secondary trigger).
  12 | //   3. Resume closes the menu without navigating away.
  13 | 
  14 | import { test, expect, loginAs, waitForGameReady } from './fixtures.js';
  15 | 
  16 | test.describe('Esc menu', () => {
  17 |   // Test 1: Esc → menu visible → Logout → LoginScene + cleared session cookies
  18 |   test('Esc opens menu; Logout returns to LoginScene with cleared session cookies (D-34)', async ({
  19 |     page,
  20 |     accountA,
  21 |     inviteSuffix,
  22 |   }) => {
  23 |     await loginAs(page, accountA, inviteSuffix);
  24 |     await waitForGameReady(page);
  25 | 
  26 |     // Open the Esc menu via keyboard
  27 |     await page.keyboard.press('Escape');
  28 | 
  29 |     // Menu should be visible
  30 |     await expect(page.locator('[data-testid="esc-menu"]')).toBeVisible({
  31 |       timeout: 5_000,
  32 |     });
  33 | 
  34 |     // Click Logout
  35 |     await page.locator('[data-testid="esc-menu-logout"]').click();
  36 | 
  37 |     // Should navigate back to LoginScene (login form heading visible)
> 38 |     await expect(page.locator('form#login-form, #login-form, #username')).toBeVisible({
     |                                                                           ^ Error: expect(locator).toBeVisible() failed
  39 |       timeout: 5_000,
  40 |     });
  41 | 
  42 |     // D-34 cookie assertion: use page.context().cookies() NOT document.cookie
  43 |     // (Better-Auth is HttpOnly so document.cookie would be empty regardless).
  44 |     // Assert session-cookie count is zero — toHaveLength(0), NOT every(c => !c.value).
  45 |     const cookies = await page.context().cookies();
  46 |     const sessionCookies = cookies.filter((c) => /better-auth|session/i.test(c.name));
  47 |     expect(sessionCookies).toHaveLength(0);
  48 |   });
  49 | 
  50 |   // Test 2: canvas pointerdown opens menu (D-24 secondary trigger)
  51 |   test('canvas click opens menu (D-24 secondary trigger)', async ({
  52 |     page,
  53 |     accountA,
  54 |     inviteSuffix,
  55 |   }) => {
  56 |     await loginAs(page, accountA, inviteSuffix);
  57 |     await waitForGameReady(page);
  58 | 
  59 |     // Click the canvas (not chat area — use coordinates away from any UI)
  60 |     await page.locator('canvas[data-game-ready="true"]').click({ position: { x: 100, y: 100 } });
  61 | 
  62 |     // Menu should be visible
  63 |     await expect(page.locator('[data-testid="esc-menu"]')).toBeVisible({
  64 |       timeout: 5_000,
  65 |     });
  66 |   });
  67 | 
  68 |   // Test 3: Resume closes the menu and does not navigate away
  69 |   test('Resume closes menu and re-engages movement without navigating', async ({
  70 |     page,
  71 |     accountA,
  72 |     inviteSuffix,
  73 |   }) => {
  74 |     await loginAs(page, accountA, inviteSuffix);
  75 |     await waitForGameReady(page);
  76 | 
  77 |     // Open via Escape
  78 |     await page.keyboard.press('Escape');
  79 |     await expect(page.locator('[data-testid="esc-menu"]')).toBeVisible({
  80 |       timeout: 5_000,
  81 |     });
  82 | 
  83 |     // Click Resume
  84 |     await page.locator('[data-testid="esc-menu-resume"]').click();
  85 | 
  86 |     // Menu should be hidden
  87 |     await expect(page.locator('[data-testid="esc-menu"]')).toBeHidden({
  88 |       timeout: 3_000,
  89 |     });
  90 | 
  91 |     // Should still be in GameScene (canvas still present)
  92 |     await expect(page.locator('canvas[data-game-ready="true"]')).toBeVisible();
  93 |   });
  94 | });
  95 | 
```