Commit 37315eca4c84fdf09b2a261dd5097747d03203e3

Authored by zichun
1 parent a787bf26

test(fe-shell): 应用外壳 E2E 关键旅程 REQ-USR-003

Showing 1 changed file with 103 additions and 0 deletions
frontend/tests/e2e/shell.spec.ts 0 → 100644
  1 +import { test, expect, type Page } from '@playwright/test';
  2 +
  3 +// 桩后端:版本下拉 / 登录 / 用户列表(仅为标签挂载,不验列表内容)。不依赖真实后端起服。
  4 +async function stubBackend(page: Page) {
  5 + await page.route('**/api/usr/companies', async (route) => {
  6 + await route.fulfill({
  7 + status: 200,
  8 + contentType: 'application/json',
  9 + body: JSON.stringify({
  10 + code: 0,
  11 + message: 'success',
  12 + data: [{ id: 1, sCompanyName: '甲公司', sVersion: '标准版' }],
  13 + }),
  14 + });
  15 + });
  16 + await page.route('**/api/usr/login', async (route) => {
  17 + await route.fulfill({
  18 + status: 200,
  19 + contentType: 'application/json',
  20 + body: JSON.stringify({
  21 + code: 0,
  22 + message: 'success',
  23 + data: {
  24 + token: 'tk-e2e',
  25 + user: { id: 1, sUserName: '朱子纯', sUserType: '超级管理员', sLanguage: '中文' },
  26 + },
  27 + }),
  28 + });
  29 + });
  30 + await page.route('**/api/usr/users**', async (route) => {
  31 + await route.fulfill({
  32 + status: 200,
  33 + contentType: 'application/json',
  34 + body: JSON.stringify({
  35 + code: 0,
  36 + message: 'success',
  37 + data: { records: [], total: 0, pageNum: 1, pageSize: 10 },
  38 + }),
  39 + });
  40 + });
  41 +}
  42 +
  43 +async function login(page: Page) {
  44 + await page.goto('/login');
  45 + await page.getByPlaceholder('请输入你的用户名').fill('admin');
  46 + await page.getByPlaceholder('请输入你的密码').fill('secret');
  47 + // 单一版本时 LoginPage 自动选中(spec § 6.3),无需手动展开下拉
  48 + await expect(page.getByText('甲公司(标准版)')).toBeVisible();
  49 + await page.getByRole('button', { name: /登\s*录/ }).click();
  50 +}
  51 +
  52 +test.describe('应用外壳关键旅程', () => {
  53 + test('login then lands on home with topbar and KPI title', async ({ page }) => {
  54 + await stubBackend(page);
  55 + await login(page);
  56 + await expect(page).toHaveURL(/\/$/);
  57 + await expect(page.getByRole('button', { name: '全部导航' })).toBeVisible();
  58 + await expect(page.getByText('KPI监控')).toBeVisible();
  59 + });
  60 +
  61 + test('open and close 全部导航 overlay', async ({ page }) => {
  62 + await stubBackend(page);
  63 + await login(page);
  64 + await page.getByRole('button', { name: '全部导航' }).click();
  65 + await expect(page.getByTestId('nav-overlay')).toBeVisible();
  66 + await expect(page.getByText('期初设置')).toBeVisible();
  67 + await expect(page.getByText('API对接管理')).toBeVisible();
  68 + // Esc 关闭
  69 + await page.keyboard.press('Escape');
  70 + await expect(page.getByTestId('nav-overlay')).toHaveCount(0);
  71 + });
  72 +
  73 + test('open 用户列表 tab from common ops then close back to home', async ({ page }) => {
  74 + await stubBackend(page);
  75 + await login(page);
  76 + // 常用操作卡内「用户列表」
  77 + await page.getByRole('button', { name: '用户列表' }).click();
  78 + await expect(page).toHaveURL(/\/usr\/users$/);
  79 + await expect(page.getByTestId('tab-userlist')).toBeVisible();
  80 + // 关闭用户列表标签 → 回主页
  81 + await page.getByTestId('tab-close-userlist').click();
  82 + await expect(page).toHaveURL(/\/$/);
  83 + await expect(page.getByTestId('tab-userlist')).toHaveCount(0);
  84 + });
  85 +
  86 + test('logout returns to /login', async ({ page }) => {
  87 + await stubBackend(page);
  88 + await login(page);
  89 + await page.getByText('朱子纯(超级管理员)').click();
  90 + await page.getByText('退出登录').click();
  91 + await expect(page).toHaveURL(/\/login$/);
  92 + await expect(page.getByText('已退出登录')).toBeVisible();
  93 + });
  94 +
  95 + test('visiting / unauthenticated redirects to /login', async ({ page }) => {
  96 + await stubBackend(page);
  97 + // 不登录,清 token 后直接访问 /
  98 + await page.goto('/login');
  99 + await page.evaluate(() => localStorage.removeItem('xly_erp_token'));
  100 + await page.goto('/');
  101 + await expect(page).toHaveURL(/\/login$/);
  102 + });
  103 +});
... ...