From 99a831b25191756f991dea797a2139ede9ca050a Mon Sep 17 00:00:00 2001 From: hided62 Date: Wed, 23 Sep 2026 04:27:08 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9E=A5=EC=88=98=20=EC=97=B4=EC=A0=84?= =?UTF-8?q?=20=EC=9D=B4=EC=A0=84=20=EB=A1=9C=EA=B7=B8=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/game-frontend/e2e/inGameMenus.spec.ts | 53 ++++++++++++++++++++++ app/game-frontend/src/views/MyPageView.vue | 3 +- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/app/game-frontend/e2e/inGameMenus.spec.ts b/app/game-frontend/e2e/inGameMenus.spec.ts index 1a5dbe28..5097bc8e 100644 --- a/app/game-frontend/e2e/inGameMenus.spec.ts +++ b/app/game-frontend/e2e/inGameMenus.spec.ts @@ -79,6 +79,8 @@ type FixtureState = { generalMeFailure?: boolean; canChangeIcon?: boolean; generalLogQueries?: number; + myLogInputs?: Array>; + pagedMyLogs?: boolean; ensurePrestartQueries?: number; ensurePrestartFailure?: 'TIMEOUT' | 'INTERNAL_SERVER_ERROR'; nationNoticeInput?: string; @@ -583,6 +585,24 @@ const install = async (page: Page, state: FixtureState) => { }); if (operation === 'general.getMyLog') { state.generalLogQueries = (state.generalLogQueries ?? 0) + 1; + if (state.pagedMyLogs) { + state.myLogInputs?.push(jsonInput); + const type = jsonInput.type; + if (type === 'generalHistory') { + return response({ + type, + logs: Array.from({ length: 25 }, (_, index) => ({ id: 100 - index, text: `열전-${index}` })), + }); + } + if (type === 'generalAction') { + const firstPage = Array.from({ length: 24 }, (_, index) => ({ id: 50 - index, text: `행동-${index}` })); + return response({ + type, + logs: jsonInput.beforeId ? [{ id: 26, text: '이전 행동' }] : firstPage, + }); + } + return response({ type, logs: [] }); + } return response({ type: 'generalAction', logs: [{ id: 1, text: state.hiddenSeedLogText ?? '기록' }], @@ -1364,6 +1384,39 @@ test('접속량정보 keeps the legacy public 1016px chart geometry', async ({ p expect(mobileWidth).toBe(1016); }); +test('내 정보 열전은 전체 표시 후 종료하고 행동 기록만 다음 페이지를 요청한다', async ({ page }) => { + const state: FixtureState = { + permission: 'head', myset: 3, settingMutations: [], accessPages: [], pagedMyLogs: true, myLogInputs: [], + }; + await install(page, state); + await page.goto('my-page'); + + const history = page.locator('.log-panel').filter({ has: page.getByRole('heading', { name: '장수 열전' }) }); + const action = page.locator('.log-panel').filter({ has: page.getByRole('heading', { name: '개인 기록' }) }); + await expect(history.locator('.log-line')).toHaveCount(25); + await expect(history.getByRole('button', { name: '이전 로그 불러오기' })).toHaveCount(0); + await expect(action.locator('.log-line')).toHaveCount(24); + await waitForVisualAssets(page); + for (const width of [1000, 390]) { + await page.setViewportSize({ width, height: 900 }); + const geometry = await history.evaluate((element) => { + const rect = element.getBoundingClientRect(); + const style = getComputedStyle(element); + return { width: rect.width, height: rect.height, fontSize: style.fontSize, display: style.display }; + }); + expect(geometry.width).toBeGreaterThan(0); + expect(geometry.height).toBeGreaterThan(0); + await persistParityArtifact(page, `core-my-page-full-history-${width}`, geometry); + } + await action.getByRole('button', { name: '이전 로그 불러오기' }).click(); + await expect(action.locator('.log-line')).toHaveCount(25); + await expect(action.getByRole('button', { name: '이전 로그 불러오기' })).toHaveCount(0); + expect(state.myLogInputs?.filter((input) => input.type === 'generalHistory')).toHaveLength(1); + expect(state.myLogInputs?.filter((input) => input.type === 'generalAction')).toEqual([ + { type: 'generalAction' }, { type: 'generalAction', beforeId: 27 }, + ]); +}); + test('내 정보&설정 keeps desktop density and becomes a 390px horizontal-identity layout', async ({ page }) => { const state: FixtureState = { permission: 'head', myset: 3, settingMutations: [], accessPages: [] }; await install(page, state); diff --git a/app/game-frontend/src/views/MyPageView.vue b/app/game-frontend/src/views/MyPageView.vue index fffe3eee..7fd4f709 100644 --- a/app/game-frontend/src/views/MyPageView.vue +++ b/app/game-frontend/src/views/MyPageView.vue @@ -213,7 +213,8 @@ const loadLog = async (type: LogType, beforeId?: number) => { const response = await trpc.general.getMyLog.query({ type, beforeId }); const next = response.logs.map((entry) => ({ id: entry.id, html: formatLog(entry.text) })); logs[type] = beforeId ? [...logs[type], ...next] : next; - logHasMore[type] = next.length >= 24; + // 장수 열전은 첫 요청에 전체를 받으며 서버도 열전의 beforeId를 적용하지 않는다. + logHasMore[type] = type !== 'generalHistory' && next.length >= 24; } catch (cause) { error.value = errorText(cause); } finally {