merge: restore turn selector interaction parity
This commit is contained in:
@@ -514,7 +514,7 @@ const installRealtimeHarness = async (page: Page) => {
|
|||||||
|
|
||||||
const waitForMain = async (page: Page) => {
|
const waitForMain = async (page: Page) => {
|
||||||
await page.goto('./');
|
await page.goto('./');
|
||||||
await expect(page.getByRole('heading', { name: '전장 현황' })).toBeVisible();
|
await expect(page.locator('.game-shell__title')).toBeVisible();
|
||||||
await expect(page.locator('.main-global-menu').first()).toBeVisible();
|
await expect(page.locator('.main-global-menu').first()).toBeVisible();
|
||||||
await expect(page.locator('.main-nation-menu')).toBeVisible();
|
await expect(page.locator('.main-nation-menu')).toBeVisible();
|
||||||
await expect(page.locator('[data-navigation-id="npc-list"]')).toHaveCount(3);
|
await expect(page.locator('[data-navigation-id="npc-list"]')).toHaveCount(3);
|
||||||
@@ -567,8 +567,24 @@ const persistArtifact = async (page: Page, name: string) => {
|
|||||||
globalPopup: describe('#mobile-global-menu'),
|
globalPopup: describe('#mobile-global-menu'),
|
||||||
nationPopup: describe('#mobile-nation-menu'),
|
nationPopup: describe('#mobile-nation-menu'),
|
||||||
quickPopup: describe('#mobile-quick-menu'),
|
quickPopup: describe('#mobile-quick-menu'),
|
||||||
|
commandMenu: describe('.reserved-command-editor details[open] .menu-items'),
|
||||||
|
commandDividers: [...document.querySelectorAll<HTMLElement>('.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([
|
await Promise.all([
|
||||||
page.screenshot({ path: resolve(target, `${name}.png`), fullPage: true }),
|
page.screenshot({ path: resolve(target, `${name}.png`), fullPage: true }),
|
||||||
writeFile(resolve(target, `${name}.json`), `${JSON.stringify(geometry, null, 2)}\n`),
|
writeFile(resolve(target, `${name}.json`), `${JSON.stringify(geometry, null, 2)}\n`),
|
||||||
@@ -928,6 +944,10 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn
|
|||||||
await tenthTurnButton.click();
|
await tenthTurnButton.click();
|
||||||
const quickPicker = page.getByTestId('command-picker');
|
const quickPicker = page.getByTestId('command-picker');
|
||||||
await expect(quickPicker).toBeVisible();
|
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 quickPickerAlignment = await quickPicker.evaluate((element) => {
|
||||||
const row = element
|
const row = element
|
||||||
.closest('.reserved-command-editor')
|
.closest('.reserved-command-editor')
|
||||||
@@ -969,6 +989,30 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn
|
|||||||
expect(advancedControlGeometry.rangeTop).toBe(advancedControlGeometry.recentTop);
|
expect(advancedControlGeometry.rangeTop).toBe(advancedControlGeometry.recentTop);
|
||||||
expect(advancedControlGeometry.advancedTop).toBeGreaterThan(advancedControlGeometry.rangeTop);
|
expect(advancedControlGeometry.advancedTop).toBeGreaterThan(advancedControlGeometry.rangeTop);
|
||||||
expect(advancedControlGeometry.advancedBottom).toBeLessThanOrEqual(advancedControlGeometry.queueTop);
|
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();
|
await page.locator('[data-main-target="commands"] .select-command').click();
|
||||||
const picker = page.getByTestId('command-picker');
|
const picker = page.getByTestId('command-picker');
|
||||||
await expect(picker).toBeVisible();
|
await expect(picker).toBeVisible();
|
||||||
@@ -1157,6 +1201,11 @@ test('main cards and command input stay inside their Ref-sized grid slots', asyn
|
|||||||
expect(mobileGeometry.controlBoxes).toHaveLength(3);
|
expect(mobileGeometry.controlBoxes).toHaveLength(3);
|
||||||
expect(new Set(mobileGeometry.controlBoxes.map(({ y }) => y)).size).toBe(1);
|
expect(new Set(mobileGeometry.controlBoxes.map(({ y }) => y)).size).toBe(1);
|
||||||
await expect(page.locator('[data-main-target="commands"] .edit-column button')).toHaveCount(30);
|
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');
|
await captureProgress('mobile-500');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -149,6 +149,14 @@ const closePicker = () => {
|
|||||||
quickTarget.value = null;
|
quickTarget.value = null;
|
||||||
selectedCommand.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 selectCommand = (commandKey: string) => {
|
||||||
const command = props.commandTable?.[props.scope]
|
const command = props.commandTable?.[props.scope]
|
||||||
.flatMap((group) => group.values)
|
.flatMap((group) => group.values)
|
||||||
@@ -305,6 +313,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
>
|
>
|
||||||
짝수턴
|
짝수턴
|
||||||
</button>
|
</button>
|
||||||
|
<hr class="menu-divider" />
|
||||||
<template v-for="step in [3, 4, 5, 6, 7]" :key="step">
|
<template v-for="step in [3, 4, 5, 6, 7]" :key="step">
|
||||||
<small>{{ step }}턴 간격</small>
|
<small>{{ step }}턴 간격</small>
|
||||||
<div class="step-buttons">
|
<div class="step-buttons">
|
||||||
@@ -429,6 +438,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
>
|
>
|
||||||
붙여넣기
|
붙여넣기
|
||||||
</button>
|
</button>
|
||||||
|
<hr class="menu-divider" />
|
||||||
<button
|
<button
|
||||||
@click="
|
@click="
|
||||||
textCopy();
|
textCopy();
|
||||||
@@ -437,6 +447,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
>
|
>
|
||||||
텍스트 복사
|
텍스트 복사
|
||||||
</button>
|
</button>
|
||||||
|
<hr class="menu-divider" />
|
||||||
<button
|
<button
|
||||||
@click="
|
@click="
|
||||||
saveTemplate();
|
saveTemplate();
|
||||||
@@ -453,6 +464,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
>
|
>
|
||||||
반복하기
|
반복하기
|
||||||
</button>
|
</button>
|
||||||
|
<hr class="menu-divider" />
|
||||||
<button
|
<button
|
||||||
@click="
|
@click="
|
||||||
clearSelection();
|
clearSelection();
|
||||||
@@ -479,7 +491,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
<button type="button" class="select-command" @click="openPicker()">명령 선택 ▾</button>
|
<button type="button" class="select-command" @click="togglePicker()">명령 선택 ▾</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="queue-area">
|
<div class="queue-area">
|
||||||
@@ -542,7 +554,7 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
:key="row.index"
|
:key="row.index"
|
||||||
type="button"
|
type="button"
|
||||||
:aria-label="`${row.index + 1}턴 명령 입력`"
|
:aria-label="`${row.index + 1}턴 명령 입력`"
|
||||||
@click="openPicker(row.index)"
|
@click="togglePicker(row.index)"
|
||||||
>
|
>
|
||||||
✎
|
✎
|
||||||
</button>
|
</button>
|
||||||
@@ -708,6 +720,14 @@ const clickOutsideMenu = (event: Event) => {
|
|||||||
padding: 5px 8px;
|
padding: 5px 8px;
|
||||||
color: #bbb;
|
color: #bbb;
|
||||||
}
|
}
|
||||||
|
.menu-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
margin: 4px 0;
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #444;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
.step-buttons,
|
.step-buttons,
|
||||||
.template-row {
|
.template-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user