fix: 빈 특기의 획득 예정 나이를 표시한다

메인 장수 read model에 내정·전투 특기 예정 나이를 투영하고, Ref와 같은 현재 나이 다음 해 하한을 적용한다. API 회귀와 Chromium 데스크톱·모바일 검증을 추가한다.
This commit is contained in:
2026-08-22 05:03:25 +00:00
parent 0c75b96908
commit b8e9e6b513
4 changed files with 94 additions and 6 deletions
+43
View File
@@ -77,6 +77,7 @@ type FixtureState = {
joinConfig?: Record<string, unknown>;
createGeneralInputs?: Array<Record<string, unknown>>;
mainTraits?: { personal: string; specialDomestic: string; specialWar: string };
mainTraitAges?: { specialDomestic: number; specialWar: number };
richMyInfo?: boolean;
hiddenSeedLogText?: string;
recentRecords?: {
@@ -130,6 +131,7 @@ const myGeneral = (state: FixtureState) => ({
}
: null,
traits: state.mainTraits ?? { personal: '-', specialDomestic: '-', specialWar: '-' },
traitAges: state.mainTraitAges ?? { specialDomestic: 31, specialWar: 31 },
traitInfo: state.richMyInfo
? {
personal: '부상당할 확률이 감소합니다.',
@@ -725,6 +727,47 @@ test('재야 메인은 국가 틀과 성격·특기 표기명을 Chromium에 표
await persistParityArtifact(page, 'main-neutral-trait-display', geometry);
});
test('메인 장수 정보는 없는 내정·전투 특기의 Ref 획득 나이를 Chromium에 표시한다', async ({ page }) => {
const state: FixtureState = {
permission: 'member',
myset: 0,
mainTraits: { personal: '안전', specialDomestic: '-', specialWar: '-' },
mainTraitAges: { specialDomestic: 35, specialWar: 29 },
settingMutations: [],
accessPages: [],
};
await install(page, state);
for (const viewport of [
{ width: 1000, height: 900 },
{ width: 390, height: 844 },
]) {
await page.setViewportSize(viewport);
await page.goto('');
const specialValue = page.locator('.general-card .special-value');
await expect(specialValue).toHaveText(/35\s*\/\s*31/u);
await expect(specialValue).toHaveAttribute('aria-label', '35세 / 31세');
const geometry = await specialValue.evaluate((element) => {
const rect = element.getBoundingClientRect();
const documentWidth = document.documentElement.scrollWidth;
return {
text: element.textContent?.replace(/\s+/gu, ' ').trim(),
left: rect.left,
right: rect.right,
width: rect.width,
documentWidth,
viewportWidth: window.innerWidth,
};
});
expect(geometry.width).toBeGreaterThan(0);
expect(geometry.left).toBeGreaterThanOrEqual(0);
expect(geometry.right).toBeLessThanOrEqual(geometry.documentWidth);
expect(geometry.documentWidth).toBe(Math.max(viewport.width, 500));
await persistParityArtifact(page, `main-speciality-age-${viewport.width}`, geometry);
}
});
test('메인 카드의 국가·수도·관직·계급·병종은 Ref 출력명으로 표시된다', async ({ page }) => {
const state: FixtureState = {
permission: 'head',