diff --git a/frontend/e2e/mobile-ui.spec.ts b/frontend/e2e/mobile-ui.spec.ts index 4c4c176..0735959 100644 --- a/frontend/e2e/mobile-ui.spec.ts +++ b/frontend/e2e/mobile-ui.spec.ts @@ -213,10 +213,37 @@ test('settings match the approved paper-ledger geometry and action hierarchy', a expect(logoutBox!.width).toBeGreaterThanOrEqual(88) expect(logoutBox!.height).toBeGreaterThanOrEqual(isMobileContract ? 44 : 40) allowExpectedError(page, 'requestfailed: POST http://127.0.0.1:5173/api/v1/auth/logout net::ERR_ABORTED') + await page.route('**/api/v1/auth/logout', route => route.fulfill({ status: 204 })) await logout.click() await expect(page.getByRole('button', { name: '登录', exact: true })).toBeVisible() - await expect(page.getByText('欢迎回来,继续把生活理顺。')).toBeVisible() - expect(await page.request.get('/api/v1/me')).not.toBeOK() + await expect(page.getByRole('heading', { name: '欢迎回来', exact: true })).toBeVisible() + await expect(page.getByText('登录后继续处理今天的事项。')).toBeVisible() + await expect(page.getByText('登录后继续你的清单')).toBeVisible() + const authGeometry = await page.locator('.auth-card').evaluate(element => { + const card = element as HTMLElement + const cardRect = card.getBoundingClientRect() + const inputRects = [...card.querySelectorAll('input')].map(input => input.getBoundingClientRect()) + const buttonRect = card.querySelector('button.primary')!.getBoundingClientRect() + return { + viewportWidth: innerWidth, + documentOverflow: document.documentElement.scrollWidth - document.documentElement.clientWidth, + card: { left: cardRect.left, right: cardRect.right, width: cardRect.width }, + brand: { + fontSize: getComputedStyle(card.querySelector('.auth-brand .brand')!).fontSize, + logoWidth: card.querySelector('.auth-brand .brand-logo')!.getBoundingClientRect().width, + }, + inputHeights: inputRects.map(rect => rect.height), + buttonHeight: buttonRect.height, + } + }) + expect(authGeometry.documentOverflow).toBe(0) + const expectedCardWidth = Math.min(400, authGeometry.viewportWidth - (isMobileContract ? 36 : 48)) + expect(authGeometry.card.width).toBeCloseTo(expectedCardWidth, 0) + expect(authGeometry.card.left).toBeCloseTo((authGeometry.viewportWidth - expectedCardWidth) / 2, 0) + expect(authGeometry.card.right).toBeCloseTo((authGeometry.viewportWidth + expectedCardWidth) / 2, 0) + expect(authGeometry.brand).toEqual({ fontSize: '28px', logoWidth: 34 }) + expect(authGeometry.inputHeights.every(height => height >= 46)).toBeTruthy() + expect(authGeometry.buttonHeight).toBeGreaterThanOrEqual(46) }) test('task, habit, countdown, memo, action and confirmation overlays share the modal contract', async ({ page }, testInfo) => { diff --git a/frontend/src/App.vue b/frontend/src/App.vue index b858163..2be075c 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1511,13 +1511,15 @@ onUnmounted(() => {