Files
chorus/admin-ui/tests/e2e/system-management.spec.ts
T

93 lines
4.7 KiB
TypeScript

import { expect, test } from '@playwright/test'
const baseURL = process.env.ADMIN_UI_URL || 'http://127.0.0.1:9528'
const group = (title: string, path: string, children: object[]) => ({
menuName: path.split('/').pop(),
title,
icon: 'ri:settings-3-line',
path,
component: 'Layout',
visible: '0',
children
})
const page = (title: string, path: string, component: string) => ({
menuName: path.split('/').pop(), title, path, component, visible: '0', children: []
})
const navigation = [
group('生成配置', '/chorus/configuration', [
page('上游服务商', '/chorus/providers', 'chorus/providers/index'),
page('模型配置', '/chorus/models', 'chorus/models/index'),
page('路由策略', '/chorus/routes', 'chorus/routes/index'),
page('提示词模板', '/chorus/templates', 'chorus/templates/index')
]),
group('运行监控', '/chorus/monitoring', [
page('上游健康', '/chorus/health', 'chorus/health/index'),
page('生成记录', '/chorus/generations', 'chorus/generations/index')
]),
group('用户与访问', '/chorus/access', [
page('终端用户', '/chorus/users', 'chorus/users/index'),
page('API 密钥', '/chorus/api-keys', 'chorus/api-keys/index')
]),
group('系统管理', '/chorus/system', [
page('管理员账号', '/chorus/system/admins', 'admin/sys-user/index'),
page('角色权限', '/chorus/system/roles', 'admin/sys-role/index'),
page('菜单结构', '/chorus/system/menus', 'admin/sys-menu/index'),
page('接口清单', '/chorus/system/apis', 'admin/sys-api/index'),
page('登录日志', '/chorus/system/login-logs', 'admin/sys-login-log/index')
])
]
test.beforeEach(async ({ context, page: browserPage }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'test-token', domain: '127.0.0.1', path: '/' }])
await browserPage.route('**/api/v1/**', async route => {
const url = new URL(route.request().url())
let data: unknown = {}
if (url.pathname.endsWith('/getinfo')) {
data = { roles: ['admin'], permissions: ['*:*:*'], name: '本地管理员', avatar: '', introduction: '', userId: 1 }
} else if (url.pathname.endsWith('/menurole')) {
data = navigation
} else if (url.pathname.endsWith('/sys-user')) {
data = { list: [{ userId: 1, username: 'local-admin', nickName: '本地管理员', roleId: 1, status: '2' }], count: 1 }
} else if (url.pathname.endsWith('/role')) {
data = { list: [{ roleId: 1, roleName: 'Chorus Operator', roleKey: 'chorus_operator', roleSort: 100, status: '2' }], count: 1 }
} else if (url.pathname.endsWith('/menu')) {
data = navigation
} else if (url.pathname.endsWith('/sys-api') || url.pathname.endsWith('/sys-login-log')) {
data = { list: [], count: 0 }
}
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 200, data }) })
})
})
test('renders four groups and all thirteen confirmed entries', async ({ page: browserPage }) => {
await browserPage.goto(`${baseURL}/#/chorus/system/admins`)
await expect(browserPage.getByRole('heading', { name: '管理员账号' })).toBeVisible()
for (const title of ['生成配置', '运行监控', '用户与访问', '系统管理']) {
await expect(browserPage.getByText(title, { exact: true }).first()).toBeVisible()
}
for (const title of navigation.flatMap(item => item.children.map(child => child.title))) {
await expect(browserPage.getByText(title, { exact: true }).first()).toBeAttached()
}
await expect(browserPage.getByText('当前账号', { exact: true }).first()).toBeVisible()
await browserPage.screenshot({ path: 'test-results/system-admin-desktop.png', fullPage: true })
})
test('keeps system inventory pages read-only on desktop and narrow screens', async ({ page: browserPage }) => {
for (const [path, heading] of [['menus', '菜单结构'], ['apis', '接口清单'], ['login-logs', '登录日志']]) {
await browserPage.goto(`${baseURL}/#/chorus/system/${path}`)
await expect(browserPage.getByRole('heading', { name: heading })).toBeVisible()
await expect(browserPage.getByText('只读', { exact: true })).toBeVisible()
await expect(browserPage.getByRole('button', { name: /新增|编辑|删除/ })).toHaveCount(0)
}
await browserPage.setViewportSize({ width: 390, height: 844 })
await browserPage.goto(`${baseURL}/#/chorus/system/admins`)
await expect(browserPage.getByRole('heading', { name: '管理员账号' })).toBeVisible()
const overflow = await browserPage.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth)
expect(overflow).toBeFalsy()
await browserPage.screenshot({ path: 'test-results/system-admin-narrow.png', fullPage: true })
})