fix(game-ui): 고급 예턴 최근 명령 요약을 복원
고급 모드의 최근 실행 항목도 큐 행과 같은 예약 명령 formatter를 사용하게 한다. 데스크톱 hover와 모바일 focus·overflow를 production Chromium 회귀로 검증한다.
This commit is contained in:
@@ -2291,6 +2291,7 @@ test('keeps Ref command briefs and autonomous-action state after a turn mutation
|
|||||||
|
|
||||||
test('uses drag selection, clipboard paste, and a stored template in advanced mode', async ({ page }) => {
|
test('uses drag selection, clipboard paste, and a stored template in advanced mode', async ({ page }) => {
|
||||||
const requests = await install(page);
|
const requests = await install(page);
|
||||||
|
await page.setViewportSize({ width: 1200, height: 900 });
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
|
||||||
const editor = page.locator('[data-command-scope="general"]');
|
const editor = page.locator('[data-command-scope="general"]');
|
||||||
@@ -2318,6 +2319,41 @@ test('uses drag selection, clipboard paste, and a stored template in advanced mo
|
|||||||
await picker.getByRole('button', { name: '입력', exact: true }).click();
|
await picker.getByRole('button', { name: '입력', exact: true }).click();
|
||||||
await expect(editor.locator('.action-column > div').nth(2)).toHaveText('【허창】에 화계실행');
|
await expect(editor.locator('.action-column > div').nth(2)).toHaveText('【허창】에 화계실행');
|
||||||
|
|
||||||
|
const recentMenu = editor.locator('details').filter({ has: page.getByText('최근 실행', { exact: true }) });
|
||||||
|
await recentMenu.locator('summary').click();
|
||||||
|
const recentBriefButton = recentMenu.getByRole('button', { name: '【허창】에 화계실행', exact: true });
|
||||||
|
await expect(recentBriefButton).toBeVisible();
|
||||||
|
await recentBriefButton.hover();
|
||||||
|
await page.screenshot({
|
||||||
|
path: test.info().outputPath('advanced-recent-command-brief-desktop-1200.png'),
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
await recentMenu.locator('summary').click();
|
||||||
|
await page.setViewportSize({ width: 500, height: 900 });
|
||||||
|
await recentMenu.locator('summary').click();
|
||||||
|
await expect(recentBriefButton).toBeVisible();
|
||||||
|
await recentBriefButton.focus();
|
||||||
|
await expect(recentBriefButton).toBeFocused();
|
||||||
|
const mobileRecentGeometry = await editor.evaluate((element) => {
|
||||||
|
const menu = element.querySelector<HTMLElement>('details[open] .menu-items');
|
||||||
|
const recentButton = menu?.querySelector<HTMLElement>('button');
|
||||||
|
if (!menu || !recentButton) throw new Error('advanced recent command menu is missing');
|
||||||
|
return {
|
||||||
|
horizontalOverflow: element.scrollWidth - element.clientWidth,
|
||||||
|
menuRight: menu.getBoundingClientRect().right,
|
||||||
|
buttonRight: recentButton.getBoundingClientRect().right,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
expect(mobileRecentGeometry.horizontalOverflow).toBeLessThanOrEqual(0);
|
||||||
|
expect(mobileRecentGeometry.menuRight).toBeLessThanOrEqual(500);
|
||||||
|
expect(mobileRecentGeometry.buttonRight).toBeLessThanOrEqual(500);
|
||||||
|
await page.screenshot({
|
||||||
|
path: test.info().outputPath('advanced-recent-command-brief-mobile-500.png'),
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
await recentMenu.locator('summary').click();
|
||||||
|
await page.setViewportSize({ width: 1200, height: 900 });
|
||||||
|
|
||||||
await drag(0, 2);
|
await drag(0, 2);
|
||||||
await editor.locator('details.selected-menu > summary').click();
|
await editor.locator('details.selected-menu > summary').click();
|
||||||
await editor.getByRole('button', { name: '복사하기', exact: true }).click();
|
await editor.getByRole('button', { name: '복사하기', exact: true }).click();
|
||||||
|
|||||||
@@ -142,11 +142,12 @@ const isRecruitmentCommand = computed(
|
|||||||
() => selectedCommand.value?.key === 'che_징병' || selectedCommand.value?.key === 'che_모병'
|
() => selectedCommand.value?.key === 'che_징병' || selectedCommand.value?.key === 'che_모병'
|
||||||
);
|
);
|
||||||
const isRecruitmentOverlayOpen = computed(() => pickerOpen.value && isRecruitmentCommand.value);
|
const isRecruitmentOverlayOpen = computed(() => pickerOpen.value && isRecruitmentCommand.value);
|
||||||
const rowLabel = (row: ReservedCommandRow): string =>
|
const commandBrief = (entry: { action: string; args: unknown; label?: string }): string =>
|
||||||
formatReservedCommandBrief(props.scope, row.action, row.args, props.commandTable) ||
|
formatReservedCommandBrief(props.scope, entry.action, entry.args, props.commandTable) ||
|
||||||
row.label ||
|
entry.label ||
|
||||||
labelMap.value.get(row.action) ||
|
labelMap.value.get(entry.action) ||
|
||||||
row.action;
|
entry.action;
|
||||||
|
const rowLabel = (row: ReservedCommandRow): string => commandBrief(row);
|
||||||
const selectedIndices = () => normalizedSelection(selected.value, previousSelected.value, props.rows.length);
|
const selectedIndices = () => normalizedSelection(selected.value, previousSelected.value, props.rows.length);
|
||||||
const pattern = () => extractPattern(props.rows, selectedIndices());
|
const pattern = () => extractPattern(props.rows, selectedIndices());
|
||||||
const touchMenus = () => (menuRevision.value += 1);
|
const touchMenus = () => (menuRevision.value += 1);
|
||||||
@@ -467,7 +468,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
clickOutsideMenu($event);
|
clickOutsideMenu($event);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ entry.label ?? labelMap.get(entry.action) ?? entry.action }}
|
{{ commandBrief(entry) }}
|
||||||
</button>
|
</button>
|
||||||
<span v-if="!storage?.recent.size" class="empty-menu">비어 있음</span>
|
<span v-if="!storage?.recent.size" class="empty-menu">비어 있음</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user