1
0
Files
nex/frontend/e2e/providers.spec.ts
lanyuanxiaoyao 870004af23 feat: 现代化 UI 布局,实现侧边栏导航和统计仪表盘
- 重构 AppLayout 为可折叠侧边栏导航布局
- 实现统计仪表盘:统计摘要卡片 + 请求趋势图表
- Provider 页面使用 Card 包裹优化视觉层次
- 主题切换按钮移至侧边栏底部,支持折叠态
- Header 适配暗色主题,添加分隔线优化视觉过渡
- 添加全局样式重置(SCSS)
- 完善组件测试和 E2E 测试覆盖
- 同步 OpenSpec 规范到主 specs
2026-04-16 19:24:02 +08:00

137 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
// 辅助在对话框内定位输入框Ant Design 6 的 Modal + Form
function formInputs(page: import('@playwright/test').Page) {
const dialog = page.getByRole('dialog');
return {
id: dialog.getByRole('textbox', { name: /ID/ }),
name: dialog.getByRole('textbox', { name: /名称/ }),
apiKey: dialog.locator('input[type="password"]'),
baseUrl: dialog.getByRole('textbox', { name: /Base URL/ }),
// Ant Design 6 按钮文字带空格:"保 存"、"取 消"
saveBtn: dialog.locator('.ant-modal-footer').getByRole('button').last(),
cancelBtn: dialog.locator('.ant-modal-footer').getByRole('button').first(),
};
}
test.describe('供应商管理', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/providers');
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible();
});
test('应显示供应商管理页面', async ({ page }) => {
await expect(page.getByText('供应商列表')).toBeVisible();
});
test('应显示添加供应商按钮', async ({ page }) => {
await expect(page.getByRole('button', { name: '添加供应商' })).toBeVisible();
});
test('应通过侧边栏导航切换页面', async ({ page }) => {
await page.locator('.ant-layout-sider').getByText('用量统计').click();
await expect(page.getByRole('heading', { name: '用量统计' })).toBeVisible();
await page.locator('.ant-layout-sider').getByText('供应商管理').click();
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible();
});
test('应能打开添加供应商对话框', async ({ page }) => {
await page.getByRole('button', { name: '添加供应商' }).click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByText('添加供应商')).toBeVisible();
await expect(formInputs(page).id).toBeVisible();
await expect(formInputs(page).name).toBeVisible();
await expect(formInputs(page).apiKey).toBeVisible();
await expect(formInputs(page).baseUrl).toBeVisible();
});
test('应验证供应商表单必填字段', async ({ page }) => {
await page.getByRole('button', { name: '添加供应商' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await formInputs(page).saveBtn.click();
await expect(page.getByText('请输入供应商 ID')).toBeVisible();
await expect(page.getByText('请输入名称')).toBeVisible();
await expect(page.getByText('请输入 API Key')).toBeVisible();
await expect(page.getByText('请输入 Base URL')).toBeVisible();
});
test('应验证URL格式', async ({ page }) => {
await page.getByRole('button', { name: '添加供应商' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
const inputs = formInputs(page);
await inputs.id.fill('test-provider');
await inputs.name.fill('Test Provider');
await inputs.apiKey.fill('sk-test-key');
await inputs.baseUrl.fill('invalid-url');
await inputs.saveBtn.click();
await expect(page.getByText('请输入有效的 URL')).toBeVisible();
});
test('应能取消添加供应商', async ({ page }) => {
await page.getByRole('button', { name: '添加供应商' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await formInputs(page).id.fill('test-provider');
await formInputs(page).cancelBtn.click();
await expect(page.getByRole('dialog')).not.toBeVisible();
});
test('应显示供应商列表中的信息', async ({ page }) => {
await expect(page.locator('.ant-table')).toBeVisible();
const tableHeaders = page.locator('.ant-table-thead th');
const count = await tableHeaders.count();
expect(count).toBeGreaterThanOrEqual(3);
});
test('应能展开供应商查看模型列表', async ({ page }) => {
const expandBtns = page.locator('.ant-table-row-expand-icon');
const count = await expandBtns.count();
if (count > 0) {
await expandBtns.first().click();
await expect(page.locator('.ant-table-expanded-row').first()).toBeVisible();
} else {
test.skip();
}
});
test('应能打开编辑供应商对话框', async ({ page }) => {
const editBtns = page.locator('.ant-table-tbody button:has-text("编辑")');
const count = await editBtns.count();
if (count > 0) {
await editBtns.first().click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByText('编辑供应商')).toBeVisible();
await expect(formInputs(page).id).toBeDisabled();
} else {
test.skip();
}
});
test('应显示删除确认对话框', async ({ page }) => {
const deleteBtns = page.locator('.ant-table-tbody button:has-text("删除")');
const count = await deleteBtns.count();
if (count > 0) {
await deleteBtns.first().click();
await expect(page.getByText('确定要删除这个供应商吗?')).toBeVisible();
// Popconfirm 按钮也带空格:"确 定"、"取 消"
await page.locator('.ant-popconfirm-buttons').getByRole('button').first().click();
} else {
test.skip();
}
});
});