From f36b8c03dab2e8f862ce512563e3e0b16a760372 Mon Sep 17 00:00:00 2001 From: hided62 Date: Fri, 21 Aug 2026 15:38:27 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A9=94=EC=9D=B8=20=EA=B5=AD=EA=B0=80?= =?UTF-8?q?=C2=B7=EC=9E=A5=EC=88=98=20=EC=A0=95=EB=B3=B4=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 국가와 장수 카드의 본문 및 접근 가능한 이름은 유지하면서 데스크톱과 모바일의 중복 외곽 헤더만 숨긴다. 실제 Chromium 회귀로 두 viewport의 헤더 부재와 레이아웃을 검증한다. --- app/game-frontend/e2e/mainNavigation.spec.ts | 22 +++++++++++++++++++ .../src/components/ui/PanelCard.vue | 8 +++++-- app/game-frontend/src/views/MainView.vue | 8 +++---- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/game-frontend/e2e/mainNavigation.spec.ts b/app/game-frontend/e2e/mainNavigation.spec.ts index 641c7d6b..2f5f31ea 100644 --- a/app/game-frontend/e2e/mainNavigation.spec.ts +++ b/app/game-frontend/e2e/mainNavigation.spec.ts @@ -1136,6 +1136,7 @@ test('desktop menus preserve ref columns, prefix-safe routes, and controlled dro await installFixture(page, state); await page.setViewportSize({ width: 1200, height: 900 }); await waitForMain(page); + if (artifactRoot) await mkdir(resolve(artifactRoot), { recursive: true }); await expect(page.locator('.main-global-menu')).toHaveCount(3); @@ -1994,6 +1995,17 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn await page.setViewportSize({ width: 1200, height: 900 }); await waitForMain(page); + for (const [target, label] of [ + ['nation', '국가 정보'], + ['general', '장수 정보'], + ] as const) { + const panel = page.locator(`.layout-desktop [data-main-target="${target}"]`); + await expect(panel).toHaveAttribute('aria-label', label); + await expect(panel.locator(':scope > .panel-header')).toHaveCount(0); + await expect(panel.locator(':scope > .panel-body')).toBeVisible(); + } + await expect(page.locator('.layout-desktop [data-main-target="city"] > .panel-header')).toContainText('도시 정보'); + const cityBars = page.locator('[data-main-target="city"] [role="progressbar"]'); const statBars = page.locator('[data-stat-progress] [role="progressbar"]'); const experienceBar = page.locator('[data-experience-progress] [role="progressbar"]'); @@ -2321,6 +2333,16 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn await page.setViewportSize({ width: 500, height: 900 }); await expect(page.locator('.layout-mobile')).toBeVisible(); + for (const [target, label] of [ + ['nation', '국가 정보'], + ['general', '장수 정보'], + ] as const) { + const panel = page.locator(`.layout-mobile [data-main-target="${target}"]`); + await expect(panel).toHaveAttribute('aria-label', label); + await expect(panel.locator(':scope > .panel-header')).toHaveCount(0); + await expect(panel.locator(':scope > .panel-body')).toBeVisible(); + } + await expect(page.locator('.layout-mobile [data-main-target="city"] > .panel-header')).toContainText('도시 정보'); await page.locator('[data-main-target="commands"] .bottom-actions').getByRole('button', { name: '펼치기' }).click(); expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(500); await expect(page.locator('[data-main-target="city"] [role="progressbar"]')).toHaveCount(8); diff --git a/app/game-frontend/src/components/ui/PanelCard.vue b/app/game-frontend/src/components/ui/PanelCard.vue index ac59e85a..95393de4 100644 --- a/app/game-frontend/src/components/ui/PanelCard.vue +++ b/app/game-frontend/src/components/ui/PanelCard.vue @@ -2,14 +2,18 @@ interface Props { title: string; subtitle?: string; + hideHeader?: boolean; } -defineProps(); +withDefaults(defineProps(), { + subtitle: undefined, + hideHeader: false, +});