From d695c0e2c82017d8be51e1ce10dc5a485d0077b0 Mon Sep 17 00:00:00 2001 From: hided62 Date: Thu, 13 Aug 2026 15:33:30 +0000 Subject: [PATCH 1/3] fix(game-ui): toggle turn picker and restore menu dividers --- app/game-frontend/e2e/mainNavigation.spec.ts | 49 +++++++++++++++++++ .../command/ReservedCommandEditor.vue | 24 ++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/app/game-frontend/e2e/mainNavigation.spec.ts b/app/game-frontend/e2e/mainNavigation.spec.ts index 0a2e49e3..9f55ddb2 100644 --- a/app/game-frontend/e2e/mainNavigation.spec.ts +++ b/app/game-frontend/e2e/mainNavigation.spec.ts @@ -561,8 +561,24 @@ const persistArtifact = async (page: Page, name: string) => { globalPopup: describe('#mobile-global-menu'), nationPopup: describe('#mobile-nation-menu'), quickPopup: describe('#mobile-quick-menu'), + commandMenu: describe('.reserved-command-editor details[open] .menu-items'), + commandDividers: [...document.querySelectorAll('.reserved-command-editor details[open] .menu-divider')].map( + (element) => { + const rect = element.getBoundingClientRect(); + const style = getComputedStyle(element); + return { + rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height }, + borderTop: style.borderTop, + margin: style.margin, + }; + } + ), }; }); + const commandMenu = page.locator('.reserved-command-editor details[open] .menu-items').first(); + if (await commandMenu.isVisible()) { + await commandMenu.screenshot({ path: resolve(target, `${name}-menu.png`) }); + } await Promise.all([ page.screenshot({ path: resolve(target, `${name}.png`), fullPage: true }), writeFile(resolve(target, `${name}.json`), `${JSON.stringify(geometry, null, 2)}\n`), @@ -882,6 +898,10 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn await tenthTurnButton.click(); const quickPicker = page.getByTestId('command-picker'); await expect(quickPicker).toBeVisible(); + await tenthTurnButton.click(); + await expect(quickPicker).toBeHidden(); + await tenthTurnButton.click(); + await expect(quickPicker).toBeVisible(); const quickPickerAlignment = await quickPicker.evaluate((element) => { const row = element .closest('.reserved-command-editor') @@ -923,6 +943,30 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn expect(advancedControlGeometry.rangeTop).toBe(advancedControlGeometry.recentTop); expect(advancedControlGeometry.advancedTop).toBeGreaterThan(advancedControlGeometry.rangeTop); expect(advancedControlGeometry.advancedBottom).toBeLessThanOrEqual(advancedControlGeometry.queueTop); + const rangeMenu = page.locator('[data-main-target="commands"] .range-menu'); + await rangeMenu.locator('summary').click(); + const rangeDividers = rangeMenu.locator('.menu-divider'); + await expect(rangeDividers).toHaveCount(1); + await expect(rangeDividers.first()).toBeVisible(); + expect(await rangeDividers.first().evaluate((element) => getComputedStyle(element).borderTop)).toBe( + '1px solid rgb(68, 68, 68)' + ); + await persistArtifact(page, `${basePath.slice(1)}-command-range-divider-desktop-1200`); + await rangeMenu.evaluate((element) => ((element as HTMLDetailsElement).open = false)); + await expect(rangeMenu).not.toHaveAttribute('open', ''); + + const selectedMenu = page.locator('[data-main-target="commands"] .selected-menu'); + await selectedMenu.locator('summary').click(); + const selectedMenuDividers = selectedMenu.locator('.menu-divider'); + await expect(selectedMenuDividers).toHaveCount(3); + await expect(selectedMenuDividers.first()).toBeVisible(); + expect(await selectedMenuDividers.first().evaluate((element) => getComputedStyle(element).borderTop)).toBe( + '1px solid rgb(68, 68, 68)' + ); + await persistArtifact(page, `${basePath.slice(1)}-command-selected-dividers-desktop-1200`); + await selectedMenu.evaluate((element) => ((element as HTMLDetailsElement).open = false)); + await expect(selectedMenu).not.toHaveAttribute('open', ''); + await page.locator('[data-main-target="commands"] .select-command').click(); const picker = page.getByTestId('command-picker'); await expect(picker).toBeVisible(); @@ -1111,6 +1155,11 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn expect(mobileGeometry.controlBoxes).toHaveLength(3); expect(new Set(mobileGeometry.controlBoxes.map(({ y }) => y)).size).toBe(1); await expect(page.locator('[data-main-target="commands"] .edit-column button')).toHaveCount(30); + const mobileTurnButton = page.getByRole('button', { name: '10턴 명령 입력' }); + await mobileTurnButton.click(); + await expect(page.getByTestId('command-picker')).toBeVisible(); + await mobileTurnButton.click(); + await expect(page.getByTestId('command-picker')).toBeHidden(); await captureProgress('mobile-500'); }); diff --git a/app/game-frontend/src/components/command/ReservedCommandEditor.vue b/app/game-frontend/src/components/command/ReservedCommandEditor.vue index 44f462de..a88229b1 100644 --- a/app/game-frontend/src/components/command/ReservedCommandEditor.vue +++ b/app/game-frontend/src/components/command/ReservedCommandEditor.vue @@ -149,6 +149,14 @@ const closePicker = () => { quickTarget.value = null; selectedCommand.value = null; }; +const togglePicker = (turnIndex?: number) => { + const target = turnIndex ?? null; + if (pickerOpen.value && quickTarget.value === target) { + closePicker(); + return; + } + openPicker(turnIndex); +}; const selectCommand = (commandKey: string) => { const command = props.commandTable?.[props.scope] .flatMap((group) => group.values) @@ -305,6 +313,7 @@ const clickOutsideMenu = (event: Event) => { > 짝수턴 +