From 5e196c07d27f5badf0396eaca4f5d83b1d1496eb Mon Sep 17 00:00:00 2001 From: hided62 Date: Fri, 21 Aug 2026 16:46:34 +0000 Subject: [PATCH] =?UTF-8?q?fix(game-ui):=20=EC=A0=84=ED=88=AC=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=EC=9D=98=20=EC=9D=98=EB=AF=B8=EB=B3=84=20=ED=96=89?= =?UTF-8?q?=EC=9D=84=20=EB=A7=9E=EC=B6=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 승률·승리·패배와 살상률·사살·피살을 각각 같은 행에 두고 빈 slot을 명시적으로 유지한다. 실제 Chromium 좌표로 내정보와 감찰부 행 배치를 검증하고 지난 플레이의 소수 둘째 자리 기대값도 현재 공통 계약에 맞춘다. --- app/game-frontend/e2e/inGameMenus.spec.ts | 50 +++++++++---------- app/game-frontend/e2e/pastPlays.spec.ts | 4 +- .../components/main/GeneralBattleSummary.vue | 36 ++++++++++--- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/app/game-frontend/e2e/inGameMenus.spec.ts b/app/game-frontend/e2e/inGameMenus.spec.ts index 3ed880fc..cb5265b8 100644 --- a/app/game-frontend/e2e/inGameMenus.spec.ts +++ b/app/game-frontend/e2e/inGameMenus.spec.ts @@ -38,6 +38,18 @@ const readGeneralPanelImages = async (panel: Locator) => }) ); +const readGeneralSummaryRows = async (summary: Locator) => + summary.evaluate((element) => { + const rows = new Map(); + for (const label of element.querySelectorAll(':scope > span')) { + const top = Math.round(label.getBoundingClientRect().top * 100) / 100; + const row = rows.get(top) ?? []; + row.push(label.textContent?.trim() ?? ''); + rows.set(top, row); + } + return [...rows.values()]; + }); + type FixtureState = { permission: 'head' | 'member'; myset: number; @@ -1242,19 +1254,12 @@ test('내 정보&설정 keeps desktop density and becomes a 390px horizontal-ide await expect(page.locator('.battle-general-extra')).toContainText('피살6,789'); await expect(page.locator('.battle-general-extra__recent-value')).toHaveText('01-01 00:00'); await expect(page.locator('.legacy-general-details')).toHaveCount(0); - await expect(page.locator('.battle-general-extra > span')).toHaveText([ - '명성', - '계급', - '전투', - '승리', - '패배', - '계략', - '사관', - '사살', - '피살', - '승률', - '살상률', - '최근 전투', + expect(await readGeneralSummaryRows(page.locator('.battle-general-extra'))).toEqual([ + ['명성', '계급', ''], + ['전투', '계략', '사관'], + ['승률', '승리', '패배'], + ['살상률', '사살', '피살'], + ['최근 전투'], ]); await expect(page.locator('.item-group')).toContainText('명마'); await expect(page.locator('#container')).not.toContainText('che_'); @@ -2043,19 +2048,12 @@ test('감찰부 keeps the selector interaction and shows the permission error pa await expect(page.locator('.battle-general-extra')).toContainText('사관4년'); await expect(page.locator('.battle-general-extra')).toContainText('승률62.50%'); await expect(page.locator('.battle-general-extra')).toContainText('살상률181.84%'); - await expect(page.locator('.battle-general-extra > span')).toHaveText([ - '명성', - '계급', - '전투', - '승리', - '패배', - '계략', - '사관', - '사살', - '피살', - '승률', - '살상률', - '최근 전투', + expect(await readGeneralSummaryRows(page.locator('.battle-general-extra'))).toEqual([ + ['명성', '계급', ''], + ['전투', '계략', '사관'], + ['승률', '승리', '패배'], + ['살상률', '사살', '피살'], + ['최근 전투'], ]); const battleImages = await readGeneralPanelImages(page.locator('.battle-general-card')); expect(battleImages).toHaveLength(2); diff --git a/app/game-frontend/e2e/pastPlays.spec.ts b/app/game-frontend/e2e/pastPlays.spec.ts index 5ee95071..be294422 100644 --- a/app/game-frontend/e2e/pastPlays.spec.ts +++ b/app/game-frontend/e2e/pastPlays.spec.ts @@ -278,8 +278,8 @@ test('past plays is available without a current general and preserves desktop in await expect(detailToggle).toHaveAttribute('aria-expanded', 'true'); await expect(page.locator('.archive-general-card')).toHaveAttribute('data-general-basic-card', ''); await expect(page.locator('.archive-general-card [role="progressbar"]')).toHaveCount(14); - await expect(page.locator('[data-general-battle-summary]')).toContainText('승률62.5%'); - await expect(page.locator('[data-general-battle-summary]')).toContainText('살상률75.0%'); + await expect(page.locator('[data-general-battle-summary]')).toContainText('승률62.50%'); + await expect(page.locator('[data-general-battle-summary]')).toContainText('살상률75.00%'); const hallBattle = page.locator('[data-hall-battle-record]'); await expect(hallBattle).toContainText('명예의 전당 보존 기록'); await expect(hallBattle).toContainText('항목별 기록 시점이 서로 다를 수 있습니다.'); diff --git a/app/game-frontend/src/components/main/GeneralBattleSummary.vue b/app/game-frontend/src/components/main/GeneralBattleSummary.vue index 982bd647..7b2ec503 100644 --- a/app/game-frontend/src/components/main/GeneralBattleSummary.vue +++ b/app/game-frontend/src/components/main/GeneralBattleSummary.vue @@ -61,11 +61,12 @@ const killRate = computed(() => {