feat: 지난 플레이 액션을 오른쪽에 분리

내 정보와 설정 상단에서 돌아가기와 새로고침은 왼쪽 탐색 그룹으로 유지하고 지난 플레이 링크는 같은 행 오른쪽에 독립 배치한다. 데스크톱과 모바일 Chromium geometry, focus, hover 및 prefix 경로 이동을 회귀 테스트로 고정한다.
This commit is contained in:
2026-08-19 13:58:18 +00:00
parent daf98722de
commit e17859e9ed
2 changed files with 77 additions and 3 deletions
+60
View File
@@ -1099,6 +1099,66 @@ test('내 정보&설정 keeps desktop density and becomes a 390px horizontal-ide
await persistParityArtifact(page, 'core-my-page-mobile', mobile); await persistParityArtifact(page, 'core-my-page-mobile', mobile);
}); });
test('내 정보&설정의 지난 플레이는 기본 탐색과 분리되어 오른쪽에 정렬된다', async ({ page }) => {
const state: FixtureState = { permission: 'head', myset: 3, settingMutations: [], accessPages: [] };
await install(page, state);
for (const viewport of [
{ name: 'desktop', width: 1000, height: 900 },
{ name: 'mobile', width: 390, height: 844 },
] as const) {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.goto('my-page');
const pastPlaysLink = page.getByRole('link', { name: '지난 플레이' });
await expect(pastPlaysLink).toHaveAttribute('href', `${gameBasePath}/past-plays`);
await pastPlaysLink.hover();
await pastPlaysLink.focus();
await expect(pastPlaysLink).toBeFocused();
const geometry = await page.locator('.title-row').evaluate((element) => {
const title = element.getBoundingClientRect();
const actions = element.querySelector<HTMLElement>('.title-actions')!.getBoundingClientRect();
const navigation = element.querySelector<HTMLElement>('.navigation-actions')!.getBoundingClientRect();
const back = element.querySelector<HTMLAnchorElement>('.navigation-actions a')!.getBoundingClientRect();
const refresh = element.querySelector<HTMLButtonElement>('.navigation-actions button')!.getBoundingClientRect();
const past = element.querySelector<HTMLAnchorElement>('.past-plays-link')!.getBoundingClientRect();
const pastStyle = getComputedStyle(element.querySelector<HTMLAnchorElement>('.past-plays-link')!);
return {
title: { left: title.left, right: title.right },
actions: { left: actions.left, right: actions.right },
navigation: { left: navigation.left, right: navigation.right },
back: { top: back.top, right: back.right },
refresh: { top: refresh.top, right: refresh.right },
past: { top: past.top, left: past.left, right: past.right },
pastStyle: {
cursor: pastStyle.cursor,
minHeight: pastStyle.minHeight,
backgroundColor: pastStyle.backgroundColor,
},
scrollWidth: document.documentElement.scrollWidth,
};
});
expect(geometry.actions.left).toBeCloseTo(geometry.title.left + 1, 0);
expect(geometry.actions.right).toBeCloseTo(geometry.title.right - 1, 0);
expect(geometry.navigation.left).toBeCloseTo(geometry.actions.left, 0);
expect(geometry.past.right).toBeCloseTo(geometry.actions.right, 0);
expect(geometry.past.left).toBeGreaterThan(geometry.navigation.right);
expect(geometry.back.top).toBeCloseTo(geometry.past.top, 0);
expect(geometry.refresh.top).toBeCloseTo(geometry.past.top, 0);
expect(geometry.pastStyle).toEqual({
cursor: 'pointer',
minHeight: '34px',
backgroundColor: 'rgb(49, 95, 134)',
});
expect(geometry.scrollWidth).toBe(viewport.width);
await persistParityArtifact(page, `core-my-page-past-plays-${viewport.name}`, geometry);
await pastPlaysLink.click();
await expect(page).toHaveURL(new RegExp(`${gameBasePath}/past-plays$`, 'u'));
}
});
for (const [label, failure] of [ for (const [label, failure] of [
['daemon timeout', 'TIMEOUT'], ['daemon timeout', 'TIMEOUT'],
['engine transaction 오류', 'INTERNAL_SERVER_ERROR'], ['engine transaction 오류', 'INTERNAL_SERVER_ERROR'],
+15 -1
View File
@@ -365,10 +365,14 @@ onMounted(() => {
<main id="container" class="legacy-page bg0 responsive-settings-page" :class="`screen-${screenMode}`"> <main id="container" class="legacy-page bg0 responsive-settings-page" :class="`screen-${screenMode}`">
<div class="title-row"> <div class="title-row">
<span> </span> <span> </span>
<RouterLink class="legacy-button" to="/past-plays">지난 플레이</RouterLink> <div class="title-actions">
<div class="navigation-actions">
<RouterLink class="legacy-button" to="/">돌아가기</RouterLink> <RouterLink class="legacy-button" to="/">돌아가기</RouterLink>
<button class="legacy-button" type="button" @click="() => loadPage()">새로고침</button> <button class="legacy-button" type="button" @click="() => loadPage()">새로고침</button>
</div> </div>
<RouterLink class="legacy-button past-plays-link" to="/past-plays">지난 플레이</RouterLink>
</div>
</div>
<div v-if="error" class="error-row">{{ error }}</div> <div v-if="error" class="error-row">{{ error }}</div>
<div class="status-row">{{ statusLine }}</div> <div class="status-row">{{ statusLine }}</div>
@@ -675,6 +679,16 @@ onMounted(() => {
height: 18px; height: 18px;
letter-spacing: 0; letter-spacing: 0;
} }
.title-actions {
display: flex;
width: 100%;
align-items: flex-start;
justify-content: space-between;
}
.navigation-actions {
display: flex;
gap: 4px;
}
.legacy-button, .legacy-button,
button, button,
select, select,