vdi-cloud/console/e2e/console.spec.ts

103 lines
6.7 KiB
TypeScript

import { test, expect, type Page } from '@playwright/test'
async function login(page: Page, username = 'admin') {
await page.goto('/login')
await page.getByRole('textbox', { name: '用户名', exact: true }).fill(username)
await page.getByRole('textbox', { name: '密码', exact: true }).fill('Demo@2026')
await page.getByRole('button', { name: '登录', exact: true }).click()
await expect(page.getByRole('heading', { name: '运行总览' })).toBeVisible()
}
test.beforeAll(async ({ request }) => { const r = await request.get('/healthz'); expect(r.ok()).toBe(true); expect((await r.json()).mode).toBe('demo') })
test('登录失败、登录恢复与退出', async ({ page }) => {
await page.goto('/login')
await page.getByRole('textbox', { name: '用户名', exact: true }).fill('admin')
await page.getByRole('textbox', { name: '密码', exact: true }).fill('incorrect')
await page.getByRole('button', { name: '登录', exact: true }).click()
await expect(page.getByText('用户名或密码错误')).toBeVisible()
await page.getByRole('textbox', { name: '密码', exact: true }).fill('Demo@2026')
await page.getByRole('button', { name: '登录', exact: true }).click()
await expect(page.getByRole('heading', { name: '运行总览' })).toBeVisible()
await page.reload()
await expect(page.getByRole('heading', { name: '运行总览' })).toBeVisible()
await page.getByRole('button', { name: '退出登录' }).click()
await expect(page).toHaveURL(/\/login/)
})
test('桌面命令与最终任务结果', async ({ page }) => {
await login(page)
await page.getByRole('navigation').getByRole('link', { name: '桌面管理' }).click()
await page.getByRole('button', { name: '列表视图' }).click()
const row = page.getByRole('row').filter({ hasText: '国产办公桌面' })
await expect(row).toBeVisible()
const currentStopped = await row.getByText('已关机', { exact: true }).count()
const action = currentStopped ? '开机' : '关机'
await row.getByRole('button', { name: action, exact: true }).click()
await page.getByRole('button', { name: '确认提交', exact: true }).click()
await expect(page.getByText('任务已提交,请在任务与审计中查看最终结果')).toBeVisible()
await page.getByRole('navigation').getByRole('link', { name: '任务与审计' }).click()
const task = page.getByRole('row').filter({ hasText: '国产办公桌面' }).first()
await expect(task.getByText('成功', { exact: true })).toBeVisible()
await expect(task).toContainText('演示计算任务已完成')
})
test('创建用户、编辑多个桌面授权并持久化', async ({ page }) => {
await login(page)
await page.getByRole('navigation').getByRole('link', { name: '用户与授权' }).click()
await page.getByRole('button', { name: '新建用户', exact: true }).click()
const dialog = page.getByRole('dialog')
const name = `测试用户 ${Date.now()}`
await dialog.getByRole('textbox', { name: /姓名/ }).fill(name)
await dialog.getByRole('textbox', { name: /用户账号/ }).fill(`e2e.${Date.now()}`)
await dialog.getByRole('button', { name: '创建用户', exact: true }).click()
await page.getByRole('textbox', { name: '搜索用户' }).fill(name)
await page.getByRole('row').filter({ hasText: name }).getByRole('button', { name: '编辑授权' }).click()
await dialog.locator('label.el-checkbox').filter({ hasText: '设计专属桌面' }).click()
await expect(dialog.getByRole('checkbox', { name: /设计专属桌面/ })).toBeChecked()
await dialog.locator('label.el-checkbox').filter({ hasText: '研发办公桌面' }).click()
await dialog.getByRole('button', { name: '保存授权' }).click()
const row = page.getByRole('row').filter({ hasText: name })
await expect(row).toContainText('设计专属桌面')
await expect(row).toContainText('研发办公桌面')
await page.reload()
await page.getByRole('textbox', { name: '搜索用户' }).fill(name)
await expect(page.getByRole('row').filter({ hasText: name })).toContainText('设计专属桌面')
})
test('登记终端只显示一次激活密钥', async ({ page }) => {
await login(page)
await page.getByRole('navigation').getByRole('link', { name: '终端管理' }).click()
await page.getByRole('button', { name: '登记终端' }).click()
const dialog = page.getByRole('dialog')
const serial = `E2E-${Date.now()}`
await dialog.getByRole('textbox', { name: '设备 SN' }).fill(serial)
await dialog.getByRole('textbox', { name: '终端名称' }).fill('联调终端')
await dialog.getByRole('button', { name: '登记并生成激活信息' }).click()
await expect(page.getByTestId('activation-secret')).toContainText('activate_')
await page.getByRole('button', { name: '已保存,关闭' }).click()
await page.getByRole('textbox', { name: '搜索终端' }).fill(serial)
await expect(page.getByRole('row').filter({ hasText: serial })).toContainText('待激活')
})
for (const username of ['viewer', 'operator']) test(`${username} 权限边界`, async ({ page }) => {
await login(page, username)
await page.getByRole('navigation').getByRole('link', { name: '用户与授权' }).click()
await expect(page.getByRole('button', { name: '新建用户' })).toHaveCount(0)
await expect(page.getByRole('button', { name: '编辑授权' })).toHaveCount(0)
await page.goto('/settings')
await expect(page.getByText('无访问权限', { exact: true })).toBeVisible()
await page.goto('/desktops')
await expect(page.getByRole('heading', { name: '桌面管理' })).toBeVisible()
await page.getByRole('button', { name: '列表视图' }).click()
if (username === 'viewer') await expect(page.getByRole('button', { name: '关机', exact: true })).toHaveCount(0)
else await expect(page.getByRole('button', { name: '关机', exact: true }).first()).toBeVisible()
})
test('空列表、刷新异常及 401 处理', async ({ page }) => {
await login(page)
await page.getByRole('navigation').getByRole('link', { name: '桌面管理' }).click()
await page.getByRole('textbox', { name: '搜索桌面' }).fill('不存在的桌面')
await expect(page.getByText('暂无符合条件的桌面')).toBeVisible()
await page.route('**/api/v1/overview', route => route.fulfill({ status: 503, json: { code: 'unavailable', message: '测试服务暂不可用', requestId: 'test-offline' } }))
await page.getByRole('navigation').getByRole('link', { name: '云桌面总览', exact: true }).click()
await page.getByRole('button', { name: '刷新数据' }).click()
await expect(page.getByText('数据刷新失败,当前信息可能已过期')).toBeVisible()
await page.unroute('**/api/v1/overview')
await page.evaluate(() => sessionStorage.setItem('vdi.accessToken', 'invalid-token'))
await page.reload()
await expect(page).toHaveURL(/\/login/)
})