fix: 유산 설명의 줄바꿈을 복원

전투 특기와 유니크 경매 설명의 레거시 br 표기를 안전한 줄 단위 DOM으로 변환한다. Chromium 회귀로 실제 줄바꿈과 리터럴 태그 비노출을 검증한다.
This commit is contained in:
2026-08-27 18:17:15 +00:00
parent 4b06330753
commit 212c13bf16
2 changed files with 43 additions and 10 deletions
+16 -7
View File
@@ -203,9 +203,15 @@ const specialNameMap = computed(() => {
}
return map;
});
const splitLegacyLineBreaks = (value: string): string[] => value.split(/<br\s*\/?\s*>|\r?\n/giu);
const selectedSpecialWarInfo = computed(
() => status.value?.availableSpecialWar.find((entry) => entry.key === nextSpecialKey.value)?.info ?? ''
);
const selectedSpecialWarInfoLines = computed(() => splitLegacyLineBreaks(selectedSpecialWarInfo.value));
const selectedUniqueInfo = computed(
() => status.value?.availableUnique.find((item) => item.key === uniqueForm.itemId)?.info ?? ''
);
const selectedUniqueInfoLines = computed(() => splitLegacyLineBreaks(selectedUniqueInfo.value));
const availableUniqueGroups = computed(() =>
uniqueItemSlotOrder
.map((slot) => ({
@@ -513,9 +519,10 @@ onMounted(() => {
</select>
</div>
<small
><span v-if="selectedSpecialWarInfo" class="special-description">{{
selectedSpecialWarInfo
}}</span
><span v-if="selectedSpecialWarInfo" class="special-description"
><template v-for="(line, index) in selectedSpecialWarInfoLines" :key="index"
>{{ line
}}<br v-if="index < selectedSpecialWarInfoLines.length - 1" /></template></span
><br v-if="selectedSpecialWarInfo" />{{ specialNameMap.get(nextSpecialKey) }} 특기를 다음에
얻도록 지정합니다.<br /><b
>필요 포인트: {{ status.inheritConst.inheritSpecificSpecialPoint }}</b
@@ -553,10 +560,12 @@ onMounted(() => {
/>
</div>
<small
>얻고자 하는 유니크 아이템으로 경매를 시작합니다. 24 동안 진행됩니다.<br />{{
status.availableUnique.find((item) => item.key === uniqueForm.itemId)?.info
}}</small
>
>얻고자 하는 유니크 아이템으로 경매를 시작합니다. 24 동안 진행됩니다.<br /><span
v-if="selectedUniqueInfo"
class="unique-description"
><template v-for="(line, index) in selectedUniqueInfoLines" :key="index"
>{{ line }}<br v-if="index < selectedUniqueInfoLines.length - 1" /></template></span
></small>
<button
class="legacy-button legacy-button--primary buy-button"
:disabled="isUnited || actionBusy"
@@ -79,13 +79,19 @@ const statusFixture = {
},
resetCosts: { resetSpecialWar: 1000, resetTurnTime: 1000 },
resetLevels: { resetSpecialWar: 0, resetTurnTime: 0 },
availableSpecialWar: [{ key: 'che_선봉', name: '선봉', info: '공격에 유리합니다.' }],
availableSpecialWar: [
{
key: 'che_선봉',
name: '선봉',
info: '[군사] 선봉 효과입니다.<br>[전투] 공격에 유리합니다.<br />[기타] 기동력을 보완합니다.',
},
],
availableUnique: [
{
key: 'che_명마_07_백마',
name: '백마(+7)',
rawName: '백마',
info: '기동력을 올려주는 유니크 명마입니다.',
info: '기동력을 올려주는 유니크 명마입니다.<br>전투 이동을 돕습니다.',
slot: 'horse',
},
{
@@ -206,6 +212,22 @@ const installFixture = async (
};
test.describe('inheritance management legacy parity', () => {
test('renders legacy description breaks without exposing br markup', async ({ page }) => {
await installFixture(page);
await page.goto(gameUrl);
const specialDescription = page.locator('.special-description');
const uniqueDescription = page.locator('.unique-description');
await expect(specialDescription.locator('br')).toHaveCount(2);
await expect(uniqueDescription.locator('br')).toHaveCount(1);
expect(await specialDescription.innerText()).toBe(
'[군사] 선봉 효과입니다.\n[전투] 공격에 유리합니다.\n[기타] 기동력을 보완합니다.'
);
expect(await uniqueDescription.innerText()).toBe('기동력을 올려주는 유니크 명마입니다.\n전투 이동을 돕습니다.');
await expect(specialDescription).not.toContainText('<br>');
await expect(uniqueDescription).not.toContainText('<br>');
});
test('confirms and displays the Ref-compatible pending turn-time base', async ({ page }) => {
const fixture = await installFixture(page);
await page.setViewportSize({ width: 390, height: 844 });
@@ -383,7 +405,9 @@ test.describe('inheritance management legacy parity', () => {
expect(
await page.evaluate(() =>
Math.abs(
window.scrollY + window.innerHeight - (document.scrollingElement?.scrollHeight ?? window.innerHeight)
window.scrollY +
window.innerHeight -
(document.scrollingElement?.scrollHeight ?? window.innerHeight)
)
)
).toBeLessThanOrEqual(1);