From 9c2b8d78d0f40e55913a840f8fb24ef79bcc1f4d Mon Sep 17 00:00:00 2001 From: hided62 Date: Mon, 17 Aug 2026 14:18:38 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9E=90=EC=9C=A8=20=ED=96=89=EB=8F=99?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=EB=A5=BC=20=ED=96=89=20=ED=88=B4=ED=8C=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../e2e/commandArguments.spec.ts | 65 ++++++++++++---- .../command/ReservedCommandEditor.vue | 74 ++++++++++++++----- 2 files changed, 106 insertions(+), 33 deletions(-) diff --git a/app/game-frontend/e2e/commandArguments.spec.ts b/app/game-frontend/e2e/commandArguments.spec.ts index be6a88dc..b1b03475 100644 --- a/app/game-frontend/e2e/commandArguments.spec.ts +++ b/app/game-frontend/e2e/commandArguments.spec.ts @@ -1300,18 +1300,36 @@ test('keeps the entered command visible and reports a server validation error', await expect(page.getByTestId('command-argument-form').locator('select')).toHaveValue('2'); }); -test('keeps Ref command briefs and autonomous-action state after a turn mutation', async ({ page }) => { +test('keeps Ref command briefs and autonomous-action state after a turn mutation', async ({ page, context }) => { await install(page); await page.setViewportSize({ width: 1200, height: 900 }); await page.goto('/'); const editor = page.locator('[data-command-scope="general"]'); - const status = editor.locator('[data-command-autorun-status]'); const firstRow = editor.locator('.action-column > div').first(); - await expect(status).toHaveText(/자율 행동: 200年 3月 · \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}까지/u); + await expect(editor.locator('[data-command-autorun-status]')).toHaveCount(0); await expect(firstRow).toContainText('휴식(자율 행동)'); + await expect(firstRow).toHaveAttribute( + 'data-autorun-tooltip', + /자율 행동: 200年 3月 · \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}까지/u + ); expect(await firstRow.evaluate((element) => getComputedStyle(element).color)).toBe('rgb(170, 255, 255)'); + const tooltipStyle = () => + firstRow.evaluate((element) => { + const style = getComputedStyle(element, '::after'); + return { content: style.content, opacity: style.opacity, visibility: style.visibility }; + }); + expect((await tooltipStyle()).visibility).toBe('hidden'); + const heightBeforeHover = await editor.evaluate((element) => element.getBoundingClientRect().height); + await firstRow.hover(); + await expect.poll(async () => (await tooltipStyle()).visibility).toBe('visible'); + expect((await tooltipStyle()).content).toContain('자율 행동: 200年 3月'); + expect(await editor.evaluate((element) => element.getBoundingClientRect().height)).toBe(heightBeforeHover); + await page.screenshot({ path: test.info().outputPath('command-brief-autorun-hover-desktop-1200.png'), fullPage: true }); + await page.mouse.move(0, 0); + await expect.poll(async () => (await tooltipStyle()).visibility).toBe('hidden'); + await page.getByRole('button', { name: '1턴 명령 입력', exact: true }).click(); const picker = page.getByTestId('command-picker'); await picker.getByRole('button', { name: '군사', exact: true }).click(); @@ -1320,31 +1338,46 @@ test('keeps Ref command briefs and autonomous-action state after a turn mutation await picker.getByRole('button', { name: '입력', exact: true }).click(); await expect(firstRow).toHaveText('【단양】으로 출병'); - await expect(firstRow).toHaveAttribute('title', /자율 행동/u); + await expect(firstRow).toHaveAttribute('data-autorun-tooltip', /자율 행동: 200年 3月 · .*까지/u); expect(await firstRow.evaluate((element) => getComputedStyle(element).color)).toBe('rgb(170, 255, 255)'); - await expect(status).toHaveText(/자율 행동: 200年 3月 · .*까지/u); + await firstRow.focus(); + await expect.poll(async () => (await tooltipStyle()).visibility).toBe('visible'); + await expect(firstRow).toBeFocused(); const desktopGeometry = await editor.evaluate((element) => { - const statusElement = element.querySelector('[data-command-autorun-status]'); + const layout = element.querySelector('.editor-layout'); + const controlPad = element.querySelector('.control-pad'); const row = element.querySelector('.action-column > div'); - if (!statusElement || !row) throw new Error('autonomous command geometry is missing'); + if (!layout || !controlPad || !row) throw new Error('autonomous command geometry is missing'); return { horizontalOverflow: element.scrollWidth - element.clientWidth, - statusWidth: statusElement.getBoundingClientRect().width, - editorWidth: element.getBoundingClientRect().width, + controlPadOffset: controlPad.getBoundingClientRect().top - layout.getBoundingClientRect().top, rowHeight: row.getBoundingClientRect().height, }; }); expect(desktopGeometry.horizontalOverflow).toBeLessThanOrEqual(0); - expect(desktopGeometry.statusWidth).toBeLessThanOrEqual(desktopGeometry.editorWidth); + expect(desktopGeometry.controlPadOffset).toBe(0); expect(desktopGeometry.rowHeight).toBeGreaterThanOrEqual(20); - await page.screenshot({ path: test.info().outputPath('command-brief-autorun-desktop-1200.png'), fullPage: true }); + await page.screenshot({ path: test.info().outputPath('command-brief-autorun-focus-desktop-1200.png'), fullPage: true }); - await page.setViewportSize({ width: 500, height: 900 }); - await expect(firstRow).toHaveText('【단양】으로 출병'); - await expect(status).toBeVisible(); - expect(await editor.evaluate((element) => element.scrollWidth - element.clientWidth)).toBeLessThanOrEqual(0); - await page.screenshot({ path: test.info().outputPath('command-brief-autorun-mobile-500.png'), fullPage: true }); + const mobilePage = await context.newPage(); + await install(mobilePage); + await mobilePage.setViewportSize({ width: 500, height: 900 }); + await mobilePage.goto('/'); + const mobileEditor = mobilePage.locator('[data-command-scope="general"]'); + const mobileFirstRow = mobileEditor.locator('.action-column > div').first(); + await expect(mobileFirstRow).toContainText('휴식(자율 행동)'); + await expect(mobileFirstRow).toHaveAttribute('data-autorun-tooltip', /자율 행동: 200年 3月 · .*까지/u); + await mobileFirstRow.focus(); + await expect + .poll(() => mobileFirstRow.evaluate((element) => getComputedStyle(element, '::after').visibility)) + .toBe('visible'); + expect(await mobileEditor.evaluate((element) => element.scrollWidth - element.clientWidth)).toBeLessThanOrEqual(0); + await mobilePage.screenshot({ + path: test.info().outputPath('command-brief-autorun-focus-mobile-500.png'), + fullPage: true, + }); + await mobilePage.close(); }); test('uses drag selection, clipboard paste, and a stored template in advanced mode', async ({ page }) => { diff --git a/app/game-frontend/src/components/command/ReservedCommandEditor.vue b/app/game-frontend/src/components/command/ReservedCommandEditor.vue index 9b43cd7b..e29f6183 100644 --- a/app/game-frontend/src/components/command/ReservedCommandEditor.vue +++ b/app/game-frontend/src/components/command/ReservedCommandEditor.vue @@ -348,10 +348,6 @@ const clickOutsideMenu = (event: Event) => { {{ props.title }} :{{ props.name ?? '-' }} -
- 자율 행동: {{ props.autonomousUntil }} -
-