From 838c240984f641cdadd973b5cff823455a39cc14 Mon Sep 17 00:00:00 2001 From: hided62 Date: Thu, 13 Aug 2026 17:30:18 +0000 Subject: [PATCH 1/3] fix(frontend): add main execution status --- app/game-frontend/e2e/mainNavigation.spec.ts | 35 +++++++++++++------ .../src/components/main/MainFrontStatus.vue | 28 +++++++++------ .../main-front-status.spec.ts | 16 +++++++-- .../reference-main-front-status.mjs | 3 ++ 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/app/game-frontend/e2e/mainNavigation.spec.ts b/app/game-frontend/e2e/mainNavigation.spec.ts index 1a63ce7a..32760799 100644 --- a/app/game-frontend/e2e/mainNavigation.spec.ts +++ b/app/game-frontend/e2e/mainNavigation.spec.ts @@ -35,6 +35,7 @@ type NavigationFixture = { currentYear?: number; currentMonth?: number; scenarioTitle?: string; + lastExecuted?: string | null; latestVote?: { id: number; title: string; hasVoted: boolean } | null; globalRecords?: Array<{ id: number; text: string }>; generalRecords?: Array<{ id: number; text: string }>; @@ -423,7 +424,7 @@ const installFixture = async (page: Page, state: NavigationFixture) => { onlineNations: '위(1)', onlineGenerals: '메뉴검증장수', nationNotice: '

국가 방침

', - lastExecuted: null, + lastExecuted: state.lastExecuted === undefined ? '2026-08-13T00:05:06.000Z' : state.lastExecuted, latestVote: state.latestVote === undefined ? { id: 9, title: '메뉴 설문', hasVoted: false } @@ -567,6 +568,10 @@ const persistArtifact = async (page: Page, name: string) => { globalPopup: describe('#mobile-global-menu'), nationPopup: describe('#mobile-nation-menu'), quickPopup: describe('#mobile-quick-menu'), + activityStatus: describe('.activity-status'), + executionStatus: describe('.execution-status'), + tournamentStatus: describe('.tournament-status'), + voteStatus: describe('.vote-status'), commandMenu: describe('.reserved-command-editor details[open] .menu-items'), commandDividers: [...document.querySelectorAll('.reserved-command-editor details[open] .menu-divider')].map( (element) => { @@ -599,6 +604,7 @@ test('desktop menus preserve ref columns, prefix-safe routes, and controlled dro stage: 1, npcMode: 1, scenarioTitle: '메인 화면 검증 시나리오', + lastExecuted: '2026-08-13T00:05:06.000Z', generalMeCalls: 0, operations: [], }; @@ -615,31 +621,35 @@ test('desktop menus preserve ref columns, prefix-safe routes, and controlled dro await expect(page.getByRole('heading', { name: '메인 화면 검증 시나리오', exact: true })).toHaveCount(1); await expect(page.locator('.game-shell__subtitle')).toHaveText('185년 1월 · 턴 10분'); await expect(page.locator('.game-shell__subtitle')).not.toContainText('메인 화면 검증 시나리오'); + await expect(page.locator('.execution-status')).toHaveText('동작 시각: 08-13 09:05'); await expect(page.locator('.tournament-status')).toHaveText('토너먼트: 참가 모집중'); await expect(page.locator('.vote-status')).toHaveText('설문: 메뉴 설문'); const headerStatusGeometry = await page.locator('.main-page').evaluate((element) => { const title = element.querySelector('.game-shell__title'); const subtitle = element.querySelector('.game-shell__subtitle'); const activity = element.querySelector('.activity-status'); + const execution = element.querySelector('.execution-status'); const tournament = element.querySelector('.tournament-status'); const survey = element.querySelector('.vote-status'); - if (!title || !subtitle || !activity || !tournament || !survey) { + if (!title || !subtitle || !activity || !execution || !tournament || !survey) { throw new Error('main header status geometry is incomplete'); } return { title: title.getBoundingClientRect().toJSON(), subtitle: subtitle.getBoundingClientRect().toJSON(), activity: activity.getBoundingClientRect().toJSON(), + execution: execution.getBoundingClientRect().toJSON(), tournament: tournament.getBoundingClientRect().toJSON(), survey: survey.getBoundingClientRect().toJSON(), activityColumns: getComputedStyle(activity).gridTemplateColumns, }; }); expect(headerStatusGeometry.subtitle.y).toBeGreaterThanOrEqual(headerStatusGeometry.title.bottom); - expect(headerStatusGeometry.activity.width).toBeCloseTo(666.67, 0); + expect(headerStatusGeometry.activity.width).toBeCloseTo(1000, 0); + expect(headerStatusGeometry.execution.width).toBeCloseTo(333.33, 0); expect(headerStatusGeometry.tournament.width).toBeCloseTo(333.33, 0); expect(headerStatusGeometry.survey.width).toBeCloseTo(333.33, 0); - expect(headerStatusGeometry.activityColumns.split(' ')).toHaveLength(2); + expect(headerStatusGeometry.activityColumns.split(' ')).toHaveLength(3); const tournamentStatusLink = page.locator('.tournament-status a'); const surveyStatusLink = page.locator('.vote-status a'); await tournamentStatusLink.hover(); @@ -1217,6 +1227,7 @@ test('the 939/940 boundary switches to the Ref-style 500px single document', asy stage: 6, npcMode: 1, scenarioTitle: '모바일 검증 시나리오', + lastExecuted: null, latestVote: null, generalMeCalls: 0, operations: [], @@ -1238,25 +1249,27 @@ test('the 939/940 boundary switches to the Ref-style 500px single document', asy await page.setViewportSize({ width: 500, height: 900 }); await expect(page.getByRole('heading', { name: '모바일 검증 시나리오', exact: true })).toHaveCount(1); await expect(page.locator('.game-shell__subtitle')).toHaveText('185년 1월 · 턴 10분'); + await expect(page.locator('.execution-status')).toHaveText('동작 시각: 기록 없음'); await expect(page.locator('.tournament-status')).toHaveText('토너먼트: 베팅 진행중'); await expect(page.locator('.vote-status')).toHaveText('설문: 진행 중인 설문 없음'); const activityGeometry = await page.locator('.activity-status').evaluate((element) => { + const execution = element.querySelector('.execution-status'); const tournament = element.querySelector('.tournament-status'); const survey = element.querySelector('.vote-status'); - if (!tournament || !survey) throw new Error('activity status is incomplete'); + if (!execution || !tournament || !survey) throw new Error('activity status is incomplete'); return { width: element.getBoundingClientRect().width, + executionWidth: execution.getBoundingClientRect().width, tournamentWidth: tournament.getBoundingClientRect().width, surveyWidth: survey.getBoundingClientRect().width, columns: getComputedStyle(element).gridTemplateColumns, }; }); - expect(activityGeometry).toMatchObject({ - width: 500, - tournamentWidth: 250, - surveyWidth: 250, - columns: '250px 250px', - }); + expect(activityGeometry.width).toBe(500); + expect(activityGeometry.executionWidth).toBeCloseTo(166.67, 0); + expect(activityGeometry.tournamentWidth).toBeCloseTo(166.67, 0); + expect(activityGeometry.surveyWidth).toBeCloseTo(166.67, 0); + expect(activityGeometry.columns.split(' ')).toHaveLength(3); await expect .poll(() => page diff --git a/app/game-frontend/src/components/main/MainFrontStatus.vue b/app/game-frontend/src/components/main/MainFrontStatus.vue index 5731e4e1..048c96b7 100644 --- a/app/game-frontend/src/components/main/MainFrontStatus.vue +++ b/app/game-frontend/src/components/main/MainFrontStatus.vue @@ -1,4 +1,5 @@