import type { Locator, Page, Route } from '@playwright/test' import { expect, test } from './fixtures' type RoleRecord = { id: string code: string name: string shortName: string description: string enabled: boolean builtIn: boolean isSuperAdmin: boolean dataScopeCode: string departmentScopeIds: string[] linkedUserCount: number permissionCount: number sortOrder: number version: number } const json = (route: Route, data: unknown) => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 0, message: '成功', data, timestamp: Date.now(), requestId: 'role-form-regression' }), }) const fillFormItem = (dialog: Locator, label: string, value: string) => dialog .locator('.el-form-item') .filter({ hasText: label }) .first() .locator('input, textarea') .first() .fill(value) async function mockRoleApi(page: Page, submitted: Array>) { const roles: RoleRecord[] = [{ id: '1', code: 'admin', name: '管理员', shortName: '管', description: '系统管理员', enabled: true, builtIn: true, isSuperAdmin: true, dataScopeCode: 'ALL', departmentScopeIds: [], linkedUserCount: 1, permissionCount: 30, sortOrder: 10, version: 1, }] await page.route(/\/api\/(?:auth|tran)\//, async (route) => { const url = new URL(route.request().url()) const path = url.pathname const method = route.request().method() if (path.endsWith('/auth/me')) return json(route, { userId: '1', username: 'admin', displayName: '系统管理员', departmentId: '100', departmentName: '数字车间', activeRoleId: '1', roles, authorizationMode: 'SINGLE_ACTIVE', mustChangePassword: false, permissions: ['system.roles', 'system.roles.create', 'system.roles.update', 'system.roles.delete'], }) if (path.endsWith('/roles/all')) return json(route, roles) if (path.endsWith('/roles/stats')) return json(route, { total: roles.length, enabled: roles.filter((role) => role.enabled).length, builtIn: roles.filter((role) => role.builtIn).length, assignedUsers: roles.reduce((total, role) => total + role.linkedUserCount, 0), }) if (path.endsWith('/departments/tree')) return json(route, []) if (path.endsWith('/roles') && method === 'POST') { const body = route.request().postDataJSON() as Record submitted.push(body) const created: RoleRecord = { id: '2', code: String(body.code), name: String(body.name), shortName: String(body.shortName ?? ''), description: String(body.description ?? ''), enabled: true, builtIn: false, isSuperAdmin: false, dataScopeCode: String(body.dataScope), departmentScopeIds: [], linkedUserCount: 0, permissionCount: 0, sortOrder: Number(body.sortOrder), version: 1, } roles.push(created) return json(route, created) } if (/\/roles\/2$/.test(path) && method === 'PUT') { const body = route.request().postDataJSON() as Record submitted.push(body) Object.assign(roles[1]!, { name: String(body.name), shortName: String(body.shortName ?? ''), description: String(body.description ?? ''), dataScopeCode: String(body.dataScope), version: roles[1]!.version + 1, }) return json(route, roles[1]) } if (path.endsWith('/system-config/public')) return json(route, { systemName: '数字车间' }) if (path.endsWith('/auth/ping')) return json(route, { service: 'ut-auth', status: 'UP' }) if (path.endsWith('/tran/ping')) return json(route, { service: 'ut-tran', status: 'UP' }) return json(route, {}) }) await page.addInitScript(() => { window.sessionStorage.setItem('unreal-tran:web:access-token:v1', 'role-form-regression-token') }) } test('角色表单保留空简称、提供清晰提示,并在校验失败时提示用户', async ({ page }) => { const submitted: Array> = [] await mockRoleApi(page, submitted) await page.goto('/system/roles') await page.getByRole('button', { name: '新增角色', exact: true }).click() let dialog = page.locator('.el-dialog:visible') const shortInput = dialog.getByPlaceholder('请输入界面简称,如:审核') await expect(shortInput).toBeVisible() await fillFormItem(dialog, '角色名称', '测试角色') await fillFormItem(dialog, '角色编码', `a${'1'.repeat(48)}`) await dialog.getByRole('button', { name: '创建角色' }).click() await expect(page.locator('.el-message').filter({ hasText: '请检查表单中的错误项' })).toBeVisible() expect(submitted).toHaveLength(0) await fillFormItem(dialog, '角色编码', 'test_role') await dialog.getByRole('button', { name: '创建角色' }).click() await expect(dialog).toBeHidden() expect(submitted[0]).toMatchObject({ name: '测试角色', code: 'test_role', shortName: '' }) const createdRow = page.locator('.roles-table .el-table__row').filter({ hasText: '测试角色' }) await createdRow.getByRole('button', { name: '编辑' }).click() dialog = page.locator('.el-dialog:visible') await expect(dialog.getByPlaceholder('请输入界面简称,如:审核')).toHaveValue('') await dialog.getByRole('button', { name: '保存修改' }).click() await expect(dialog).toBeHidden() expect(submitted[1]).toMatchObject({ name: '测试角色', code: 'test_role', shortName: '' }) })