From c27cb0a11ae9340d0b77807a298c69f9000e089b Mon Sep 17 00:00:00 2001 From: EJClaw Date: Tue, 6 Oct 2026 01:21:59 +0900 Subject: [PATCH] =?UTF-8?q?M8:=20=EB=A7=88=ED=94=BC=EC=95=84=20E2E=20?= =?UTF-8?q?=EB=B0=A4=20=EB=8B=A8=EA=B3=84=20=ED=94=8C=EB=A0=88=ED=82=A4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 밤은 행동을 다 해도 일찍 끝나지 않고 타이머로만 넘어가는데, E2E가 밤을 15초로 둬서 부하가 걸리면 채팅+지목 3번이 15초를 넘겨 타이머가 먼저 발동, 진행 중이던 지목의 aria-pressed 대기가 5초에서 실패했다. - 밤 시간 15초 → 45초(채팅+지목 3번에 충분한 여유) - 낮 토론 배너 대기 30초 → 60초(길어진 밤 커버) - 지목 확정·채팅 반영 대기 5초 → 15초(부하 시 왕복 지연 흡수) 검증: 마피아 E2E 단독 3회 + 8코어 전부 포화 상태 1회 모두 통과. Co-Authored-By: Claude Opus 4.8 --- e2e/games.e2e.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/e2e/games.e2e.ts b/e2e/games.e2e.ts index 922d9a5..81cf3f4 100644 --- a/e2e/games.e2e.ts +++ b/e2e/games.e2e.ts @@ -801,7 +801,7 @@ async function mafiaRoleOf(p: Page): Promise<'mafia' | 'police' | 'doctor' | 'ci async function mafiaPick(p: Page, nick: string) { const tile = p.locator('button.mf-tile[data-target="ok"]', { has: p.locator('.nm', { hasText: new RegExp(`^${nick}( \\(나\\))?$`) }) }); await tile.click(); - await p.locator('button.mf-tile[aria-pressed="true"]', { has: p.locator('.nm', { hasText: new RegExp(`^${nick}( \\(나\\))?$`) }) }).waitFor({ timeout: 5000 }); + await p.locator('button.mf-tile[aria-pressed="true"]', { has: p.locator('.nm', { hasText: new RegExp(`^${nick}( \\(나\\))?$`) }) }).waitFor({ timeout: 15_000 }); } /** 마피아: writes in the selected channel tab and waits until the line shows up. */ @@ -809,7 +809,7 @@ async function mafiaSay(p: Page, channel: '전체' | '마피아' | '죽은 사 await p.getByRole('tab', { name: new RegExp(`^${channel} 채팅`) }).click(); await p.getByLabel(`${channel} 채팅 메시지`).fill(text); await p.getByLabel(`${channel} 채팅 메시지`).press('Enter'); - await p.locator('.mf-msgs .mf-msg', { hasText: text }).waitFor({ timeout: 5000 }); + await p.locator('.mf-msgs .mf-msg', { hasText: text }).waitFor({ timeout: 15_000 }); } async function mafiaBanner(p: Page, phase: string, timeout = 40_000) { @@ -1890,13 +1890,14 @@ const PLANS: Record = { // Channel checks: mafia and dead messages never reach other screens; the room chat is closed during the game. players: 4, lobby: async (host) => { - await host.getByRole('group', { name: '밤 시간' }).getByRole('button', { name: '15초' }).click(); + // Night cannot end early (only its clock advances it), so give the night's chat+3 picks ample room under load. + await host.getByRole('group', { name: '밤 시간' }).getByRole('button', { name: '45초' }).click(); await host.getByRole('button', { name: '▼ 자세한 설정' }).click(); await host.getByRole('group', { name: '지목 투표 시간' }).getByRole('button', { name: '10초', exact: true }).click(); await host.getByRole('group', { name: '최후의 반론 시간' }).getByRole('button', { name: '10초', exact: true }).click(); await host.getByRole('group', { name: '찬반 투표 시간' }).getByRole('button', { name: '5초', exact: true }).click(); await host.getByRole('button', { name: '설정 저장' }).click(); - await host.getByText(/밤 15초 · 투표 10초/).first().waitFor(); + await host.getByText(/밤 45초 · 투표 10초/).first().waitFor(); }, drive: async (pages) => { const [host, phone] = pages as [Page, Page, Page, Page]; @@ -1914,7 +1915,7 @@ const PLANS: Record = { await mafiaBanner(host, '인사 시간'); await mafiaSay(phone, '전체', '안녕하세요 반가워요'); - for (const p of pages) await p.locator('.mf-msgs .mf-msg', { hasText: '안녕하세요 반가워요' }).waitFor({ timeout: 5000 }); + for (const p of pages) await p.locator('.mf-msgs .mf-msg', { hasText: '안녕하세요 반가워요' }).waitFor({ timeout: 15_000 }); for (const p of pages) await p.getByRole('button', { name: /^인사 끝내기/ }).click(); for (const p of pages) await mafiaBanner(p, '밤'); @@ -1939,7 +1940,7 @@ const PLANS: Record = { } await mafiaShots(pages, '2-night'); - for (const p of pages) await mafiaBanner(p, '낮 토론', 30_000); + for (const p of pages) await mafiaBanner(p, '낮 토론', 60_000); for (const p of pages) await p.locator('.mf-news', { hasText: '아침 발표' }).waitFor(); await pages[C]!.locator('.mf-news', { hasText: '탈락했어요' }).waitFor(); await pages[P]!.locator('.mf-results', { hasText: '마피아예요!' }).waitFor(); @@ -1965,7 +1966,7 @@ const PLANS: Record = { await pages[M]!.locator('.mf-news', { hasText: '지목 투표 결과' }).waitFor(); if (await pages[P]!.getByLabel('전체 채팅 메시지').count()) throw new Error('others can talk during the last defense'); await mafiaSay(pages[M]!, '전체', '저는 진짜 시민이에요'); - await pages[P]!.locator('.mf-msgs .mf-msg', { hasText: '저는 진짜 시민이에요' }).waitFor({ timeout: 5000 }); + await pages[P]!.locator('.mf-msgs .mf-msg', { hasText: '저는 진짜 시민이에요' }).waitFor({ timeout: 15_000 }); await mafiaShots(pages, '4-defense'); await mafiaBanner(pages[P]!, '찬반 투표', 20_000); await pages[P]!.getByRole('button', { name: '찬성 (탈락)' }).click();