|
- import type { Page, Route } from '@playwright/test'
-
- import { captureScreenshot, expect, test } from './fixtures'
-
- test.use({ trace: 'off', video: 'off' })
-
- const loginContext = {
- defaultRoleCode: 'admin',
- roles: [
- { code: 'teacher', label: '教员', accountLabel: '教员账号', organizationMode: 'CASCADE', organizationLabels: ['教学系', '教研室'] },
- { code: 'admin', label: '管理员', accountLabel: '管理员账号', organizationMode: 'NONE', organizationLabels: [] },
- ],
- departments: [
- {
- id: '100', code: 'EQUIPMENT', name: '工程装备系', parentId: null,
- children: [{ id: '110', code: 'MAINTENANCE', name: '维修教研室', parentId: '100', children: [] }],
- },
- ],
- }
-
- const identities = [
- { id: '402', displayName: '杜晴', departmentId: '110', departmentName: '维修教研室' },
- ]
-
- const envelope = (data: unknown) => JSON.stringify({
- code: 200,
- message: '成功',
- data,
- timestamp: '2026-08-29T12:00:00+08:00',
- requestId: 'ape2e-login-identity-preference',
- })
-
- const fulfill = (route: Route, data: unknown) => route.fulfill({
- status: 200,
- contentType: 'application/json',
- body: envelope(data),
- })
-
- async function mockLoginDependencies(page: Page) {
- await page.route('**/api/auth/v1/**', async (route) => {
- const path = new URL(route.request().url()).pathname
- if (path.endsWith('/auth/login-context')) return fulfill(route, loginContext)
- if (path.endsWith('/auth/login-identities')) return fulfill(route, identities)
- if (path.endsWith('/auth/login')) {
- return fulfill(route, { accessToken: 'remember-access-token', refreshToken: 'remember-refresh-token', expiresIn: 3600 })
- }
- if (path.endsWith('/auth/me')) {
- return fulfill(route, {
- user: { id: '1', username: 'admin.saved', displayName: '系统管理员', mustChangePassword: true },
- activeRoleId: '1', roles: [{ id: '1', code: 'admin', name: '管理员', enabled: true }],
- permissions: [], authorizationMode: 'SINGLE_ACTIVE',
- })
- }
- if (path.endsWith('/system-config/public')) return fulfill(route, {})
- return fulfill(route, {})
- })
- }
-
- test('登录页恢复上次成功登录的部门和账号但不保存密码', async ({ page }, testInfo) => {
- await page.addInitScript(() => {
- window.localStorage.setItem('ai-person:web:login-identity-preference:v1', JSON.stringify({
- lastRoleCode: 'teacher',
- selections: {
- teacher: { departmentId: '110', userId: '402', username: '' },
- },
- }))
- })
- await mockLoginDependencies(page)
-
- await page.goto('/login')
-
- await expect(page.locator('[data-role-code="teacher"]')).toHaveAttribute('aria-pressed', 'true')
- const organizationSelects = page.locator('.login-role-fields .login-picker:not(.login-identity-picker)')
- await expect(organizationSelects.nth(0)).toContainText('工程装备系')
- await expect(organizationSelects.nth(1)).toContainText('维修教研室')
- await expect(page.locator('.login-identity-picker')).toContainText('杜晴')
- await expect(page.locator('input[name="password"]')).toHaveValue('')
- await expect(page.getByRole('button', { name: '登录' })).toBeDisabled()
- await captureScreenshot(page, testInfo, 'restored-login-identity-without-password')
- })
-
- test('按登录身份分别恢复记住的账号和密码', async ({ page }) => {
- await page.addInitScript(() => {
- window.localStorage.setItem('ai-person:web:login-identity-preference:v1', JSON.stringify({
- lastRoleCode: 'teacher',
- selections: {
- teacher: {
- departmentId: '110', userId: '402', username: '',
- password: 'Teacher-Remembered-1', remember: true,
- },
- admin: {
- departmentId: '', userId: '', username: 'admin.remembered',
- password: 'Admin-Remembered-2', remember: true,
- },
- },
- }))
- })
- await mockLoginDependencies(page)
-
- await page.goto('/login')
-
- await expect(page.locator('.login-identity-picker')).toContainText('杜晴')
- await expect(page.locator('input[name="password"]')).toHaveValue('Teacher-Remembered-1')
- await expect(page.locator('input[name="rememberMe"]')).toBeChecked()
-
- await page.locator('[data-role-code="admin"]').click()
- await expect(page.locator('input[name="username"]')).toHaveValue('admin.remembered')
- await expect(page.locator('input[name="password"]')).toHaveValue('Admin-Remembered-2')
- await expect(page.locator('input[name="rememberMe"]')).toBeChecked()
-
- await page.locator('[data-role-code="teacher"]').click()
- await expect(page.locator('.login-identity-picker')).toContainText('杜晴')
- await expect(page.locator('input[name="password"]')).toHaveValue('Teacher-Remembered-1')
- })
-
- test('成功登录后按勾选状态保存账号密码', async ({ page }) => {
- await mockLoginDependencies(page)
- await page.goto('/login')
- await page.locator('[data-role-code="admin"]').click()
-
- await page.locator('input[name="username"]').fill('admin.saved')
- await page.locator('input[name="password"]').fill('Saved-Password-3')
- await page.locator('input[name="rememberMe"]').check()
- await page.getByRole('button', { name: '登录' }).click()
-
- await expect.poll(() => page.evaluate(() => {
- const raw = window.localStorage.getItem('ai-person:web:login-identity-preference:v1') || '{}'
- return JSON.parse(raw).selections?.admin
- })).toEqual({
- departmentId: '', userId: '', username: 'admin.saved',
- password: 'Saved-Password-3', remember: true,
- })
- })
-
- test('已删除的部门或账号不会被本地偏好错误回填', async ({ page }) => {
- await page.addInitScript(() => {
- window.localStorage.setItem('ai-person:web:login-identity-preference:v1', JSON.stringify({
- lastRoleCode: 'teacher',
- selections: {
- teacher: { departmentId: '999', userId: '999', username: '' },
- },
- }))
- })
- await mockLoginDependencies(page)
-
- await page.goto('/login')
-
- await expect(page.locator('[data-role-code="teacher"]')).toHaveAttribute('aria-pressed', 'true')
- const organizationSelects = page.locator('.login-role-fields .login-picker:not(.login-identity-picker)')
- await expect(organizationSelects.nth(0).locator('.el-select__placeholder').first()).toContainText('请选择教学系')
- await expect(organizationSelects.nth(1).getByRole('combobox')).toBeDisabled()
- await expect(page.locator('.login-identity-picker').getByRole('combobox')).toBeDisabled()
- await expect(page.locator('input[name="password"]')).toHaveValue('')
- })
|