1
0
Files
nex/frontend/e2e/providers.spec.ts
lanyuanxiaoyao 59179094ed feat: E2E 测试集成真实后端
- Playwright 双 webServer 模式自动启动 Go 后端 + Vite 前端
- 后端使用临时 SQLite 数据库隔离,固定端口 19026
- vite.config.ts proxy target 动态读取环境变量
- 新增 sql.js 依赖用于 SQLite 统计数据 seed
- 新增 e2e/fixtures.ts 共享工具模块(API seed + SQLite seed)
- 拆分测试文件 5→7(providers/models/stats/navigation/validation)
- 删除旧文件 crud.spec.ts/sidebar.spec.ts/stats-cards.spec.ts
- E2E 测试尚有部分用例需调试修复
2026-04-22 00:31:35 +08:00

104 lines
4.3 KiB
TypeScript

import { test, expect } from '@playwright/test'
let uid = Date.now()
function nextId() {
return `pw_${++uid}`
}
function formInputs(page: import('@playwright/test').Page) {
const dialog = page.locator('.t-dialog:visible')
return {
id: dialog.locator('input[placeholder="例如: openai"]'),
name: dialog.locator('input[placeholder="例如: OpenAI"]'),
apiKey: dialog.locator('input[type="password"]'),
baseUrl: dialog.locator('input[placeholder="例如: https://api.openai.com/v1"]'),
saveBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '保存' }),
cancelBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '取消' }),
}
}
test.describe('供应商管理', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/providers')
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible()
})
test('应能创建供应商并验证出现在表格中', async ({ page }) => {
const testId = nextId()
await page.getByRole('button', { name: '添加供应商' }).click()
await expect(page.locator('.t-dialog:visible')).toBeVisible()
const inputs = formInputs(page)
await inputs.id.fill(testId)
await inputs.name.fill('Test Provider')
await inputs.apiKey.fill('sk_test_key_12345')
await inputs.baseUrl.fill('https://api.openai.com/v1')
await inputs.saveBtn.click()
await expect(page.locator('.t-dialog:visible')).not.toBeVisible({ timeout: 5000 })
await expect(page.locator('.t-table__body td').getByText(testId)).toBeVisible()
await expect(page.locator('.t-table__body td').getByText('Test Provider')).toBeVisible()
})
test('应能编辑供应商并验证更新生效', async ({ page }) => {
const testId = nextId()
await page.getByRole('button', { name: '添加供应商' }).click()
await expect(page.locator('.t-dialog:visible')).toBeVisible()
const inputs = formInputs(page)
await inputs.id.fill(testId)
await inputs.name.fill('Before Edit')
await inputs.apiKey.fill('sk_key')
await inputs.baseUrl.fill('https://api.example.com/v1')
await inputs.saveBtn.click()
await expect(page.locator('.t-dialog:visible')).not.toBeVisible({ timeout: 5000 })
await page.locator('.t-table__body button:has-text("编辑")').first().click()
await expect(page.locator('.t-dialog:visible')).toBeVisible()
const editInputs = formInputs(page)
await editInputs.name.clear()
await editInputs.name.fill('After Edit')
await editInputs.saveBtn.click()
await expect(page.locator('.t-dialog:visible')).not.toBeVisible({ timeout: 5000 })
await expect(page.locator('.t-table__body td').getByText('After Edit')).toBeVisible()
})
test('应能删除供应商并验证消失', async ({ page }) => {
const testId = nextId()
await page.getByRole('button', { name: '添加供应商' }).click()
await expect(page.locator('.t-dialog:visible')).toBeVisible()
const inputs = formInputs(page)
await inputs.id.fill(testId)
await inputs.name.fill('To Delete')
await inputs.apiKey.fill('sk_key')
await inputs.baseUrl.fill('https://api.example.com/v1')
await inputs.saveBtn.click()
await expect(page.locator('.t-dialog:visible')).not.toBeVisible({ timeout: 5000 })
await page.locator('.t-table__body button:has-text("删除")').first().click()
await expect(page.getByText('确定要删除这个供应商吗?')).toBeVisible()
await page.locator('.t-popconfirm').getByRole('button', { name: '确定' }).click()
await expect(page.getByText('确定要删除这个供应商吗?')).not.toBeVisible({ timeout: 3000 })
await expect(page.locator('.t-table__body td').getByText(testId)).not.toBeVisible({ timeout: 5000 })
})
test('应正确脱敏显示 API Key', async ({ page }) => {
const testId = nextId()
await page.getByRole('button', { name: '添加供应商' }).click()
await expect(page.locator('.t-dialog:visible')).toBeVisible()
const inputs = formInputs(page)
await inputs.id.fill(testId)
await inputs.name.fill('Mask Test')
await inputs.apiKey.fill('sk_abcdefghijklmnopqrstuvwxyz')
await inputs.baseUrl.fill('https://api.example.com/v1')
await inputs.saveBtn.click()
await expect(page.locator('.t-dialog:visible')).not.toBeVisible({ timeout: 5000 })
await expect(page.locator('.t-table__body')).toContainText('***stuv')
})
})