fix(game-ui): 메인 턴과 장수 상태 표시를 보완
This commit is contained in:
@@ -946,7 +946,7 @@ const install = async (
|
||||
return requests;
|
||||
};
|
||||
|
||||
test('offers the Ref repeat range for general turns while keeping the chief range', async ({ page }) => {
|
||||
test('offers 12 repeat turns and six shift turns for general turns while keeping the chief range', async ({ page }) => {
|
||||
await install(page);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
await page.goto('/');
|
||||
@@ -957,6 +957,11 @@ test('offers the Ref repeat range for general turns while keeping the chief rang
|
||||
await expect(generalRepeat.locator('.menu-items > button')).toHaveText(
|
||||
Array.from({ length: 12 }, (_, index) => `${index + 1}턴`)
|
||||
);
|
||||
const generalPull = generalEditor.locator('.bottom-shift-menu').first();
|
||||
await generalPull.locator('summary').click();
|
||||
await expect(generalPull.locator('.menu-items > button')).toHaveText(
|
||||
Array.from({ length: 6 }, (_, index) => `${index + 1}턴`)
|
||||
);
|
||||
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
const mobileGeneralEditor = page.locator('[data-command-scope="general"]:visible');
|
||||
|
||||
@@ -1840,7 +1840,11 @@ test('tournament split main action follows recruitment, betting, finals, and tou
|
||||
const main = nationMenu.locator('[data-navigation-id="tournament"]');
|
||||
await expect(main).toHaveText(lifecycle.label);
|
||||
await expect(main).toHaveAttribute('href', `${basePath}${lifecycle.route}`);
|
||||
await expect(main).toHaveClass(/highlight/);
|
||||
if (lifecycle.stage === 1 || lifecycle.stage === 6) {
|
||||
await expect(main).toHaveClass(/highlight/);
|
||||
} else {
|
||||
await expect(main).not.toHaveClass(/highlight/);
|
||||
}
|
||||
|
||||
const toggle = nationMenu.locator('[data-menu-id="tournament-betting"]');
|
||||
await toggle.click();
|
||||
@@ -1851,9 +1855,12 @@ test('tournament split main action follows recruitment, betting, finals, and tou
|
||||
if (lifecycle.stage === 6) {
|
||||
await expect(tournamentItem).not.toHaveClass(/highlight/);
|
||||
await expect(bettingItem).toHaveClass(/highlight/);
|
||||
} else {
|
||||
} else if (lifecycle.stage === 1) {
|
||||
await expect(tournamentItem).toHaveClass(/highlight/);
|
||||
await expect(bettingItem).not.toHaveClass(/highlight/);
|
||||
} else {
|
||||
await expect(tournamentItem).not.toHaveClass(/highlight/);
|
||||
await expect(bettingItem).not.toHaveClass(/highlight/);
|
||||
}
|
||||
await page.keyboard.press('Escape');
|
||||
|
||||
@@ -1865,9 +1872,12 @@ test('tournament split main action follows recruitment, betting, finals, and tou
|
||||
if (lifecycle.stage === 6) {
|
||||
await expect(mobileTournament).not.toHaveClass(/highlight/);
|
||||
await expect(mobileBetting).toHaveClass(/highlight/);
|
||||
} else {
|
||||
} else if (lifecycle.stage === 1) {
|
||||
await expect(mobileTournament).toHaveClass(/highlight/);
|
||||
await expect(mobileBetting).not.toHaveClass(/highlight/);
|
||||
} else {
|
||||
await expect(mobileTournament).not.toHaveClass(/highlight/);
|
||||
await expect(mobileBetting).not.toHaveClass(/highlight/);
|
||||
}
|
||||
await page.keyboard.press('Escape');
|
||||
}
|
||||
@@ -2323,6 +2333,12 @@ test('main general card uses local turn time and command clock tracks corrected
|
||||
await expect(generalCard).toContainText('7분 남음');
|
||||
await expect(generalCard).toContainText('백마대');
|
||||
await expect(generalCard).toContainText('보통 120점(3)');
|
||||
const leadershipProgress = generalCard.locator('[data-rich-tooltip="stat-leadership"]');
|
||||
await leadershipProgress.hover();
|
||||
const statTooltip = page.locator('.tippy-box[data-theme~="sammo-rich"]');
|
||||
await expect(statTooltip).toBeVisible();
|
||||
await expect(statTooltip).toContainText('통솔 성장');
|
||||
await expect(statTooltip).toContainText('5 / 20');
|
||||
|
||||
const desktopGeometry = await title.evaluate((element) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
@@ -4239,6 +4255,18 @@ test('all main Lumen button families share the rounded pressed geometry', async
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
const generalPullMenu = page.locator('[data-main-target="commands"] .bottom-shift-menu').first();
|
||||
await generalPullMenu.locator('summary').click();
|
||||
await expect(generalPullMenu.locator('.menu-items > button')).toHaveText([
|
||||
'1턴',
|
||||
'2턴',
|
||||
'3턴',
|
||||
'4턴',
|
||||
'5턴',
|
||||
'6턴',
|
||||
]);
|
||||
await generalPullMenu.locator('summary').click();
|
||||
|
||||
state.permission = 0;
|
||||
await page.locator('.main-turn-controls').getByRole('button', { name: '갱 신' }).click();
|
||||
const disabledSecret = page.locator('.layout-desktop [data-navigation-id="secret-board"]');
|
||||
|
||||
@@ -32,6 +32,7 @@ const props = withDefaults(
|
||||
storageKey: string;
|
||||
editModeStorageKey?: string;
|
||||
maxPushTurn?: number;
|
||||
maxShiftTurn?: number;
|
||||
compact?: boolean;
|
||||
mobile?: boolean;
|
||||
title?: string;
|
||||
@@ -44,6 +45,7 @@ const props = withDefaults(
|
||||
{
|
||||
editModeStorageKey: undefined,
|
||||
maxPushTurn: 6,
|
||||
maxShiftTurn: 6,
|
||||
compact: false,
|
||||
mobile: false,
|
||||
title: '',
|
||||
@@ -498,7 +500,7 @@ const clickOutsideMenu = (event: Event) => {
|
||||
<summary>당기기</summary>
|
||||
<div class="menu-items">
|
||||
<button
|
||||
v-for="amount in props.maxPushTurn"
|
||||
v-for="amount in props.maxShiftTurn"
|
||||
:key="amount"
|
||||
@click="
|
||||
emit('shift', -amount);
|
||||
@@ -513,7 +515,7 @@ const clickOutsideMenu = (event: Event) => {
|
||||
<summary>미루기</summary>
|
||||
<div class="menu-items">
|
||||
<button
|
||||
v-for="amount in props.maxPushTurn"
|
||||
v-for="amount in props.maxShiftTurn"
|
||||
:key="amount"
|
||||
@click="
|
||||
emit('shift', amount);
|
||||
@@ -695,12 +697,38 @@ const clickOutsideMenu = (event: Event) => {
|
||||
</div>
|
||||
|
||||
<div v-if="!props.compact" class="bottom-actions">
|
||||
<button class="legacy-button legacy-button--secondary" type="button" @click="emit('shift', -1)">
|
||||
당기기
|
||||
</button>
|
||||
<button class="legacy-button legacy-button--secondary" type="button" @click="emit('shift', 1)">
|
||||
미루기
|
||||
</button>
|
||||
<details class="legacy-menu bottom-shift-menu">
|
||||
<summary class="legacy-button legacy-button--secondary" role="button">당기기</summary>
|
||||
<div class="menu-items">
|
||||
<button
|
||||
v-for="amount in props.maxShiftTurn"
|
||||
:key="amount"
|
||||
type="button"
|
||||
@click="
|
||||
emit('shift', -amount);
|
||||
clickOutsideMenu($event);
|
||||
"
|
||||
>
|
||||
{{ amount }}턴
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
<details class="legacy-menu bottom-shift-menu">
|
||||
<summary class="legacy-button legacy-button--secondary" role="button">미루기</summary>
|
||||
<div class="menu-items">
|
||||
<button
|
||||
v-for="amount in props.maxShiftTurn"
|
||||
:key="amount"
|
||||
type="button"
|
||||
@click="
|
||||
emit('shift', amount);
|
||||
clickOutsideMenu($event);
|
||||
"
|
||||
>
|
||||
{{ amount }}턴
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
<button class="legacy-button legacy-button--secondary" type="button" @click="expanded = !expanded">
|
||||
{{ expanded ? '접기' : '펼치기' }}
|
||||
</button>
|
||||
@@ -831,7 +859,8 @@ const clickOutsideMenu = (event: Event) => {
|
||||
}
|
||||
.control-pad > button,
|
||||
.clock,
|
||||
.legacy-menu > summary {
|
||||
.control-pad > .legacy-menu > summary,
|
||||
.advanced-actions .legacy-menu > summary {
|
||||
box-sizing: border-box;
|
||||
min-height: 34px;
|
||||
border: 0;
|
||||
|
||||
@@ -272,11 +272,19 @@ const specialText = computed(() => {
|
||||
<strong class="stat-value" :style="{ color: injuryInfo.color }">
|
||||
<span>{{ stat.value }}</span>
|
||||
<span v-if="stat.bonus > 0" class="leadership-bonus">+{{ stat.bonus }}</span>
|
||||
<span class="bar-cell" :data-stat-progress="stat.key">
|
||||
<LegacyProgressBar
|
||||
:percent="stat.percent"
|
||||
:label="`${stat.label} 성장 ${stat.accumulated} / ${stat.limit}`"
|
||||
/>
|
||||
<span class="bar-cell">
|
||||
<RichTooltip
|
||||
:title="`${stat.label} 성장`"
|
||||
:description="`${stat.accumulated} / ${stat.limit}`"
|
||||
:test-id="`stat-${stat.key}`"
|
||||
>
|
||||
<span :data-stat-progress="stat.key">
|
||||
<LegacyProgressBar
|
||||
:percent="stat.percent"
|
||||
:label="`${stat.label} 성장 ${stat.accumulated} / ${stat.limit}`"
|
||||
/>
|
||||
</span>
|
||||
</RichTooltip>
|
||||
</span>
|
||||
</strong>
|
||||
</template>
|
||||
@@ -539,6 +547,12 @@ const specialText = computed(() => {
|
||||
grid-column: 3;
|
||||
}
|
||||
|
||||
.bar-cell :deep(.rich-tooltip-trigger),
|
||||
.bar-cell [data-stat-progress] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bar-cell,
|
||||
.experience-bar {
|
||||
display: grid;
|
||||
|
||||
@@ -17,7 +17,7 @@ export const resolveTournamentMainPresentation = (
|
||||
tournamentStage: number,
|
||||
tournamentType: number | null
|
||||
): TournamentMainPresentation => {
|
||||
const active = tournamentStage > 0 || tournamentType !== null;
|
||||
const active = tournamentStage === 1 || tournamentStage === 6;
|
||||
const bettingActive = tournamentStage === 6;
|
||||
const tournamentLabel = tournamentType === null ? undefined : tournamentLabels[tournamentType];
|
||||
return {
|
||||
|
||||
@@ -3,14 +3,14 @@ import test from 'node:test';
|
||||
|
||||
import { resolveTournamentMainPresentation } from '../src/utils/tournamentNavigation.ts';
|
||||
|
||||
void test('routes every active tournament stage except betting to its type-specific tournament button', () => {
|
||||
void test('routes every non-betting stage to its type-specific tournament button and highlights only registration', () => {
|
||||
const expectedLabels = ['전력전', '통솔전', '일기토', '설전'];
|
||||
for (const [type, expectedLabel] of expectedLabels.entries()) {
|
||||
for (const stage of [1, 2, 3, 4, 5, 7, 8, 9, 10, 0]) {
|
||||
const presentation = resolveTournamentMainPresentation(stage, type);
|
||||
assert.equal(presentation.compactLabel, expectedLabel);
|
||||
assert.equal(presentation.to, '/tournament');
|
||||
assert.equal(presentation.active, true);
|
||||
assert.equal(presentation.active, stage === 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user