fix(game-ui): 전투 통계의 의미별 행을 맞춘다
승률·승리·패배와 살상률·사살·피살을 각각 같은 행에 두고 빈 slot을 명시적으로 유지한다. 실제 Chromium 좌표로 내정보와 감찰부 행 배치를 검증하고 지난 플레이의 소수 둘째 자리 기대값도 현재 공통 계약에 맞춘다.
This commit is contained in:
@@ -38,6 +38,18 @@ const readGeneralPanelImages = async (panel: Locator) =>
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const readGeneralSummaryRows = async (summary: Locator) =>
|
||||||
|
summary.evaluate((element) => {
|
||||||
|
const rows = new Map<number, string[]>();
|
||||||
|
for (const label of element.querySelectorAll<HTMLElement>(':scope > span')) {
|
||||||
|
const top = Math.round(label.getBoundingClientRect().top * 100) / 100;
|
||||||
|
const row = rows.get(top) ?? [];
|
||||||
|
row.push(label.textContent?.trim() ?? '');
|
||||||
|
rows.set(top, row);
|
||||||
|
}
|
||||||
|
return [...rows.values()];
|
||||||
|
});
|
||||||
|
|
||||||
type FixtureState = {
|
type FixtureState = {
|
||||||
permission: 'head' | 'member';
|
permission: 'head' | 'member';
|
||||||
myset: number;
|
myset: number;
|
||||||
@@ -1242,19 +1254,12 @@ test('내 정보&설정 keeps desktop density and becomes a 390px horizontal-ide
|
|||||||
await expect(page.locator('.battle-general-extra')).toContainText('피살6,789');
|
await expect(page.locator('.battle-general-extra')).toContainText('피살6,789');
|
||||||
await expect(page.locator('.battle-general-extra__recent-value')).toHaveText('01-01 00:00');
|
await expect(page.locator('.battle-general-extra__recent-value')).toHaveText('01-01 00:00');
|
||||||
await expect(page.locator('.legacy-general-details')).toHaveCount(0);
|
await expect(page.locator('.legacy-general-details')).toHaveCount(0);
|
||||||
await expect(page.locator('.battle-general-extra > span')).toHaveText([
|
expect(await readGeneralSummaryRows(page.locator('.battle-general-extra'))).toEqual([
|
||||||
'명성',
|
['명성', '계급', ''],
|
||||||
'계급',
|
['전투', '계략', '사관'],
|
||||||
'전투',
|
['승률', '승리', '패배'],
|
||||||
'승리',
|
['살상률', '사살', '피살'],
|
||||||
'패배',
|
['최근 전투'],
|
||||||
'계략',
|
|
||||||
'사관',
|
|
||||||
'사살',
|
|
||||||
'피살',
|
|
||||||
'승률',
|
|
||||||
'살상률',
|
|
||||||
'최근 전투',
|
|
||||||
]);
|
]);
|
||||||
await expect(page.locator('.item-group')).toContainText('명마');
|
await expect(page.locator('.item-group')).toContainText('명마');
|
||||||
await expect(page.locator('#container')).not.toContainText('che_');
|
await expect(page.locator('#container')).not.toContainText('che_');
|
||||||
@@ -2043,19 +2048,12 @@ test('감찰부 keeps the selector interaction and shows the permission error pa
|
|||||||
await expect(page.locator('.battle-general-extra')).toContainText('사관4년');
|
await expect(page.locator('.battle-general-extra')).toContainText('사관4년');
|
||||||
await expect(page.locator('.battle-general-extra')).toContainText('승률62.50%');
|
await expect(page.locator('.battle-general-extra')).toContainText('승률62.50%');
|
||||||
await expect(page.locator('.battle-general-extra')).toContainText('살상률181.84%');
|
await expect(page.locator('.battle-general-extra')).toContainText('살상률181.84%');
|
||||||
await expect(page.locator('.battle-general-extra > span')).toHaveText([
|
expect(await readGeneralSummaryRows(page.locator('.battle-general-extra'))).toEqual([
|
||||||
'명성',
|
['명성', '계급', ''],
|
||||||
'계급',
|
['전투', '계략', '사관'],
|
||||||
'전투',
|
['승률', '승리', '패배'],
|
||||||
'승리',
|
['살상률', '사살', '피살'],
|
||||||
'패배',
|
['최근 전투'],
|
||||||
'계략',
|
|
||||||
'사관',
|
|
||||||
'사살',
|
|
||||||
'피살',
|
|
||||||
'승률',
|
|
||||||
'살상률',
|
|
||||||
'최근 전투',
|
|
||||||
]);
|
]);
|
||||||
const battleImages = await readGeneralPanelImages(page.locator('.battle-general-card'));
|
const battleImages = await readGeneralPanelImages(page.locator('.battle-general-card'));
|
||||||
expect(battleImages).toHaveLength(2);
|
expect(battleImages).toHaveLength(2);
|
||||||
|
|||||||
@@ -278,8 +278,8 @@ test('past plays is available without a current general and preserves desktop in
|
|||||||
await expect(detailToggle).toHaveAttribute('aria-expanded', 'true');
|
await expect(detailToggle).toHaveAttribute('aria-expanded', 'true');
|
||||||
await expect(page.locator('.archive-general-card')).toHaveAttribute('data-general-basic-card', '');
|
await expect(page.locator('.archive-general-card')).toHaveAttribute('data-general-basic-card', '');
|
||||||
await expect(page.locator('.archive-general-card [role="progressbar"]')).toHaveCount(14);
|
await expect(page.locator('.archive-general-card [role="progressbar"]')).toHaveCount(14);
|
||||||
await expect(page.locator('[data-general-battle-summary]')).toContainText('승률62.5%');
|
await expect(page.locator('[data-general-battle-summary]')).toContainText('승률62.50%');
|
||||||
await expect(page.locator('[data-general-battle-summary]')).toContainText('살상률75.0%');
|
await expect(page.locator('[data-general-battle-summary]')).toContainText('살상률75.00%');
|
||||||
const hallBattle = page.locator('[data-hall-battle-record]');
|
const hallBattle = page.locator('[data-hall-battle-record]');
|
||||||
await expect(hallBattle).toContainText('명예의 전당 보존 기록');
|
await expect(hallBattle).toContainText('명예의 전당 보존 기록');
|
||||||
await expect(hallBattle).toContainText('항목별 기록 시점이 서로 다를 수 있습니다.');
|
await expect(hallBattle).toContainText('항목별 기록 시점이 서로 다를 수 있습니다.');
|
||||||
|
|||||||
@@ -61,11 +61,12 @@ const killRate = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span>명성</span><strong>{{ numberText(summary.experience) }}</strong> <span>계급</span
|
<span>명성</span><strong>{{ numberText(summary.experience) }}</strong> <span>계급</span
|
||||||
><strong>{{ summary.dedicationText || '-' }}</strong> <span>전투</span
|
><strong>{{ summary.dedicationText || '-' }}</strong>
|
||||||
|
<span class="battle-general-extra__empty" aria-hidden="true"></span>
|
||||||
|
<strong class="battle-general-extra__empty" aria-hidden="true"></strong>
|
||||||
|
<span>전투</span
|
||||||
><strong>{{ numberText(summary.warnum) }}<template v-if="summary.warnum != null">회</template></strong>
|
><strong>{{ numberText(summary.warnum) }}<template v-if="summary.warnum != null">회</template></strong>
|
||||||
<span>승리</span><strong>{{ numberText(summary.wins) }}</strong> <span>패배</span
|
<span>계략</span><strong>{{ numberText(summary.strategies) }}</strong>
|
||||||
><strong>{{ numberText(summary.losses) }}</strong> <span>계략</span
|
|
||||||
><strong>{{ numberText(summary.strategies) }}</strong>
|
|
||||||
<template v-if="summary.serviceYears !== undefined">
|
<template v-if="summary.serviceYears !== undefined">
|
||||||
<span>사관</span
|
<span>사관</span
|
||||||
><strong
|
><strong
|
||||||
@@ -73,11 +74,28 @@ const killRate = computed(() => {
|
|||||||
}}<template v-if="summary.serviceYears != null">년</template></strong
|
}}<template v-if="summary.serviceYears != null">년</template></strong
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="battle-general-extra__empty" aria-hidden="true"></span>
|
||||||
|
<strong class="battle-general-extra__empty" aria-hidden="true"></strong>
|
||||||
|
</template>
|
||||||
|
<template v-if="showWinRate">
|
||||||
|
<span>승률</span><strong>{{ winRate }}</strong>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="battle-general-extra__empty" aria-hidden="true"></span>
|
||||||
|
<strong class="battle-general-extra__empty" aria-hidden="true"></strong>
|
||||||
|
</template>
|
||||||
|
<span>승리</span><strong>{{ numberText(summary.wins) }}</strong> <span>패배</span
|
||||||
|
><strong>{{ numberText(summary.losses) }}</strong>
|
||||||
|
<template v-if="showWinRate">
|
||||||
|
<span>살상률</span><strong>{{ killRate }}</strong>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="battle-general-extra__empty" aria-hidden="true"></span>
|
||||||
|
<strong class="battle-general-extra__empty" aria-hidden="true"></strong>
|
||||||
|
</template>
|
||||||
<span>사살</span><strong>{{ numberText(summary.killCrew) }}</strong> <span>피살</span
|
<span>사살</span><strong>{{ numberText(summary.killCrew) }}</strong> <span>피살</span
|
||||||
><strong>{{ numberText(summary.deathCrew) }}</strong>
|
><strong>{{ numberText(summary.deathCrew) }}</strong>
|
||||||
<template v-if="showWinRate">
|
|
||||||
<span>승률</span><strong>{{ winRate }}</strong> <span>살상률</span><strong>{{ killRate }}</strong>
|
|
||||||
</template>
|
|
||||||
<span class="battle-general-extra__recent-label">최근 전투</span>
|
<span class="battle-general-extra__recent-label">최근 전투</span>
|
||||||
<strong class="battle-general-extra__recent-value">
|
<strong class="battle-general-extra__recent-value">
|
||||||
{{ formatServerDateTime(summary.recentWar, { format: 'monthDayTime', fallback: '-' }) }}
|
{{ formatServerDateTime(summary.recentWar, { format: 'monthDayTime', fallback: '-' }) }}
|
||||||
@@ -113,6 +131,10 @@ const killRate = computed(() => {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.battle-general-extra > .battle-general-extra__empty {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.battle-general-extra > .battle-general-extra__recent-label {
|
.battle-general-extra > .battle-general-extra__recent-label {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user