import { expect, test } from './fixtures'; // The quick-match flow drops the player straight into a game that is still waiting for an // opponent (status 'open'): the opponent card shows "searching for opponent" and resign is // disabled until the mock attaches a robot shortly after, which restores the game UI. Driven // entirely by the mock transport (no backend). test('quick game: enter immediately, wait for an opponent, then it joins', async ({ page }) => { await page.goto('/'); await page.getByRole('button', { name: /guest/i }).click(); await page.getByRole('button', { name: /New/ }).click(); // lobby tab bar -> auto-match // Pick a variant and start; the player lands in the game at once (no "searching" screen). await page.locator('.variant').first().click(); await page.getByRole('button', { name: /Start game/i }).click(); await expect(page.locator('[data-cell]').first()).toBeVisible(); // Still waiting for an opponent: the opponent card shows the placeholder, and resign (in the // history panel) is disabled. await expect(page.getByText(/Searching for opponent/)).toBeVisible(); await page.locator('.scoreboard').click(); // open the history panel await expect(page.getByRole('button', { name: 'Drop game' })).toBeDisabled(); // Attach the opponent deterministically (the mock otherwise joins on a timer). await page.evaluate(() => (window as unknown as { __mock: { joinOpponent(): void } }).__mock.joinOpponent()); // The opponent card shows its name, the placeholder is gone, and resign is enabled again. await expect(page.getByText('Robo')).toBeVisible(); await expect(page.getByText(/Searching for opponent/)).toHaveCount(0); await expect(page.getByRole('button', { name: 'Drop game' })).toBeEnabled(); });