From 37e3c4acfc11a4dd1d45f80b886d76fbbbed2890 Mon Sep 17 00:00:00 2001 From: hided62 Date: Fri, 21 Aug 2026 16:04:25 +0000 Subject: [PATCH] =?UTF-8?q?fix(game-ui):=20=EC=82=AC=EB=A0=B9=EB=B6=80=20?= =?UTF-8?q?=EA=B3=A0=EA=B8=89=EB=AA=A8=EB=93=9C=20=EC=A0=9C=EC=96=B4?= =?UTF-8?q?=ED=96=89=20=EA=B2=B9=EC=B9=A8=EC=9D=84=20=ED=95=B4=EC=86=8C?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 고급 작업행을 정상 문서 흐름으로 옮기고 하단 당기기·미루기 행을 Ref와 같은 2등분으로 맞춘다. Chromium 회귀에서 일반 모드 버튼 hit-test와 실제 복귀 동작을 검증한다. --- .../e2e/commandArguments.spec.ts | 64 +++++++++++++++++++ .../command/ReservedCommandEditor.vue | 23 ++++--- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/app/game-frontend/e2e/commandArguments.spec.ts b/app/game-frontend/e2e/commandArguments.spec.ts index 068bb584..d2718582 100644 --- a/app/game-frontend/e2e/commandArguments.spec.ts +++ b/app/game-frontend/e2e/commandArguments.spec.ts @@ -1398,6 +1398,70 @@ test('shows all 12 advanced chief turns before the actions and uses the full mob await page.screenshot({ path: test.info().outputPath('chief-advanced-mobile-500.png'), fullPage: true }); }); +test('keeps the advanced chief return control visible and fills the two-cell bottom row', async ({ page }) => { + await install(page); + await page.setViewportSize({ width: 1200, height: 900 }); + await page.goto('/che/chief-center'); + + const editor = page.locator('[data-command-scope="nation"]:visible'); + await editor.getByRole('button', { name: '고급 모드', exact: true }).click(); + const modeButton = editor.getByRole('button', { name: '일반 모드', exact: true }); + await expect(modeButton).toBeVisible(); + + const geometry = await editor.evaluate((element) => { + const queue = element.querySelector('.queue-area')!; + const actions = element.querySelector('.advanced-actions')!; + const controls = element.querySelector('.control-pad')!; + const mode = [...controls.querySelectorAll(':scope > button')].find( + (item) => item.textContent?.trim() === '일반 모드' + )!; + const clock = controls.querySelector(':scope > .clock')!; + const summary = (label: string) => + [...controls.querySelectorAll(':scope > details > summary')].find( + (item) => item.textContent?.trim() === label + )!; + const repeat = summary('반복'); + const range = summary('범위'); + const storage = summary('보관함'); + const recent = summary('최근'); + const pull = summary('당기기').closest('details')!; + const push = summary('미루기').closest('details')!; + const rect = (item: HTMLElement) => { + const box = item.getBoundingClientRect(); + return { left: box.left, right: box.right, top: box.top, bottom: box.bottom, width: box.width }; + }; + const modeRect = mode.getBoundingClientRect(); + const hit = document.elementFromPoint(modeRect.left + modeRect.width / 2, modeRect.top + modeRect.height / 2); + return { + queue: rect(queue), + actions: rect(actions), + controls: rect(controls), + mode: rect(mode), + firstRow: [rect(mode), rect(clock), rect(repeat)], + secondRow: [rect(range), rect(storage), rect(recent)], + bottomRow: [rect(pull), rect(push)], + modeReceivesPointer: Boolean(hit && mode.contains(hit)), + documentOverflow: document.documentElement.scrollWidth - document.documentElement.clientWidth, + }; + }); + + expect(geometry.queue.bottom).toBeLessThanOrEqual(geometry.actions.top); + expect(geometry.actions.bottom).toBeLessThanOrEqual(geometry.controls.top); + expect(geometry.modeReceivesPointer).toBe(true); + expect(new Set(geometry.firstRow.map(({ top }) => top)).size).toBe(1); + expect(new Set(geometry.secondRow.map(({ top }) => top)).size).toBe(1); + expect(geometry.bottomRow[0]?.top).toBe(geometry.bottomRow[1]?.top); + expect(geometry.bottomRow[0]?.left).toBeCloseTo(geometry.controls.left, 1); + expect(geometry.bottomRow[1]?.right).toBeCloseTo(geometry.controls.right, 1); + expect(geometry.bottomRow[0]?.width).toBeCloseTo(geometry.bottomRow[1]?.width ?? 0, 1); + expect(geometry.documentOverflow).toBeLessThanOrEqual(0); + + await page.screenshot({ path: test.info().outputPath('chief-advanced-controls-desktop-1200.png'), fullPage: true }); + await modeButton.click(); + await expect(editor.locator('.advanced-actions')).toHaveCount(0); + await expect(editor.getByRole('button', { name: '고급 모드', exact: true })).toBeVisible(); +}); + test('enters general and nation command arguments and sends exact values', async ({ page }) => { const requests = await install(page); await page.setViewportSize({ width: 1200, height: 900 }); diff --git a/app/game-frontend/src/components/command/ReservedCommandEditor.vue b/app/game-frontend/src/components/command/ReservedCommandEditor.vue index d46f5791..0fc29698 100644 --- a/app/game-frontend/src/components/command/ReservedCommandEditor.vue +++ b/app/game-frontend/src/components/command/ReservedCommandEditor.vue @@ -475,7 +475,7 @@ const clickOutsideMenu = (event: Event) => { -
+
당기기
-
+
미루기