import { test, expect, type Page } from '@playwright/test'; // 桩后端:版本下拉 / 登录 / 用户列表(仅为标签挂载,不验列表内容)。不依赖真实后端起服。 async function stubBackend(page: Page) { await page.route('**/api/usr/companies', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 0, message: 'success', data: [{ id: 1, sCompanyName: '甲公司', sVersion: '标准版' }], }), }); }); await page.route('**/api/usr/login', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 0, message: 'success', data: { token: 'tk-e2e', user: { id: 1, sUserName: '朱子纯', sUserType: '超级管理员', sLanguage: '中文' }, }, }), }); }); await page.route('**/api/usr/users**', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 0, message: 'success', data: { records: [], total: 0, pageNum: 1, pageSize: 10 }, }), }); }); } async function login(page: Page) { await page.goto('/login'); await page.getByPlaceholder('请输入你的用户名').fill('admin'); await page.getByPlaceholder('请输入你的密码').fill('secret'); // 单一版本时 LoginPage 自动选中(spec § 6.3),无需手动展开下拉 await expect(page.getByText('甲公司(标准版)')).toBeVisible(); await page.getByRole('button', { name: /登\s*录/ }).click(); } test.describe('应用外壳关键旅程', () => { test('login then lands on home with topbar and KPI title', async ({ page }) => { await stubBackend(page); await login(page); await expect(page).toHaveURL(/\/$/); await expect(page.getByRole('button', { name: '全部导航' })).toBeVisible(); await expect(page.getByText('KPI监控')).toBeVisible(); }); test('open and close 全部导航 overlay', async ({ page }) => { await stubBackend(page); await login(page); await page.getByRole('button', { name: '全部导航' }).click(); await expect(page.getByTestId('nav-overlay')).toBeVisible(); await expect(page.getByText('期初设置')).toBeVisible(); await expect(page.getByText('API对接管理')).toBeVisible(); // Esc 关闭 await page.keyboard.press('Escape'); await expect(page.getByTestId('nav-overlay')).toHaveCount(0); }); test('open 用户列表 tab from common ops then close back to home', async ({ page }) => { await stubBackend(page); await login(page); // 常用操作卡内「用户列表」 await page.getByRole('button', { name: '用户列表' }).click(); await expect(page).toHaveURL(/\/usr\/users$/); await expect(page.getByTestId('tab-userlist')).toBeVisible(); // 关闭用户列表标签 → 回主页 await page.getByTestId('tab-close-userlist').click(); await expect(page).toHaveURL(/\/$/); await expect(page.getByTestId('tab-userlist')).toHaveCount(0); }); test('logout returns to /login', async ({ page }) => { await stubBackend(page); await login(page); await page.getByText('朱子纯(超级管理员)').click(); await page.getByText('退出登录').click(); await expect(page).toHaveURL(/\/login$/); await expect(page.getByText('已退出登录')).toBeVisible(); }); test('visiting / unauthenticated redirects to /login', async ({ page }) => { await stubBackend(page); // 不登录,清 token 后直接访问 / await page.goto('/login'); await page.evaluate(() => localStorage.removeItem('xly_erp_token')); await page.goto('/'); await expect(page).toHaveURL(/\/login$/); }); });