- 将 playwright.config.ts 的 mkdtemp 替换为固定路径,解决主进程/worker 临时目录不一致问题 - 交换后端 WAL 与迁移执行顺序,确保 sql.js 能读取到完整 schema - 修复 models.spec.ts 断言使用 exact:true 避免统一模型 ID 列干扰 - 移除全部 10 个 test.skip,26 个 E2E 测试全部通过
132 lines
5.0 KiB
TypeScript
132 lines
5.0 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
import { API_BASE, clearDatabase } from './fixtures'
|
|
|
|
let uid = Date.now()
|
|
function nextId() {
|
|
return `mpw_${++uid}`
|
|
}
|
|
|
|
function modelFormInputs(page: import('@playwright/test').Page) {
|
|
const dialog = page.locator('.t-dialog:visible')
|
|
return {
|
|
modelName: dialog.locator('input[placeholder="例如: gpt-4o"]'),
|
|
providerSelect: dialog.locator('.t-select'),
|
|
saveBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '保存' }),
|
|
cancelBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '取消' }),
|
|
}
|
|
}
|
|
|
|
test.describe('模型管理', () => {
|
|
let providerId: string
|
|
|
|
test.beforeEach(async ({ page, request }) => {
|
|
await clearDatabase(request)
|
|
providerId = nextId()
|
|
await request.post(`${API_BASE}/api/providers`, {
|
|
data: {
|
|
id: providerId,
|
|
name: 'Model Test Provider',
|
|
api_key: 'sk_test_key',
|
|
base_url: 'https://api.example.com/v1',
|
|
protocol: 'openai',
|
|
enabled: true,
|
|
},
|
|
})
|
|
|
|
await page.goto('/providers')
|
|
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible()
|
|
})
|
|
|
|
test('应能展开供应商查看模型空状态', async ({ page }) => {
|
|
await page.locator('.t-table__expand-box').first().click()
|
|
await expect(page.locator('.t-table__expanded-row').first()).toBeVisible()
|
|
await expect(page.getByText('暂无模型,点击上方按钮添加')).toBeVisible()
|
|
})
|
|
|
|
test('应能为供应商添加模型', async ({ page }) => {
|
|
await page.locator('.t-table__expand-box').first().click()
|
|
await expect(page.locator('.t-table__expanded-row').first()).toBeVisible()
|
|
|
|
await page.locator('.t-dialog:visible').waitFor({ state: 'hidden', timeout: 3000 }).catch(() => {})
|
|
|
|
await page.locator('.t-table__expanded-row button:has-text("添加模型")').first().click()
|
|
await expect(page.locator('.t-dialog:visible')).toBeVisible()
|
|
|
|
const inputs = modelFormInputs(page)
|
|
await inputs.modelName.fill('gpt_4_turbo')
|
|
|
|
const responsePromise = page.waitForResponse(resp => resp.url().includes('/api/models') && resp.request().method() === 'POST')
|
|
await inputs.saveBtn.click()
|
|
await responsePromise
|
|
await expect(page.locator('.t-table__expanded-row').getByText('gpt_4_turbo', { exact: true })).toBeVisible({ timeout: 5000 })
|
|
})
|
|
|
|
test('应显示统一模型 ID', async ({ page, request }) => {
|
|
await request.post(`${API_BASE}/api/models`, {
|
|
data: {
|
|
provider_id: providerId,
|
|
model_name: 'claude_3',
|
|
enabled: true,
|
|
},
|
|
})
|
|
|
|
await page.reload()
|
|
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible()
|
|
|
|
await page.locator('.t-table__expand-box').first().click()
|
|
await expect(page.locator('.t-table__expanded-row').first()).toBeVisible()
|
|
|
|
await expect(page.locator('.t-table__expanded-row').getByText(`${providerId}/claude_3`)).toBeVisible()
|
|
})
|
|
|
|
test('应能编辑模型', async ({ page, request }) => {
|
|
await request.post(`${API_BASE}/api/models`, {
|
|
data: {
|
|
provider_id: providerId,
|
|
model_name: 'gpt_3_5',
|
|
enabled: true,
|
|
},
|
|
})
|
|
|
|
await page.reload()
|
|
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible()
|
|
|
|
await page.locator('.t-table__expand-box').first().click()
|
|
await expect(page.locator('.t-table__expanded-row').first()).toBeVisible()
|
|
|
|
await page.locator('.t-table__expanded-row button:has-text("编辑")').first().click()
|
|
await expect(page.locator('.t-dialog:visible')).toBeVisible()
|
|
|
|
const inputs = modelFormInputs(page)
|
|
await inputs.modelName.clear()
|
|
await inputs.modelName.fill('gpt_4o')
|
|
|
|
const responsePromise = page.waitForResponse(resp => resp.url().includes('/api/models') && resp.request().method() === 'PUT')
|
|
await inputs.saveBtn.click()
|
|
await responsePromise
|
|
await expect(page.locator('.t-table__expanded-row').getByText('gpt_4o', { exact: true })).toBeVisible({ timeout: 5000 })
|
|
})
|
|
|
|
test('应能删除模型', async ({ page, request }) => {
|
|
await request.post(`${API_BASE}/api/models`, {
|
|
data: {
|
|
provider_id: providerId,
|
|
model_name: 'to_delete_model',
|
|
enabled: true,
|
|
},
|
|
})
|
|
|
|
await page.reload()
|
|
await expect(page.getByRole('heading', { name: '供应商管理' })).toBeVisible()
|
|
|
|
await page.locator('.t-table__expand-box').first().click()
|
|
await expect(page.locator('.t-table__expanded-row').first()).toBeVisible()
|
|
await expect(page.locator('.t-table__expanded-row').getByText('to_delete_model', { exact: true })).toBeVisible()
|
|
|
|
await page.locator('.t-table__expanded-row button:has-text("删除")').first().click()
|
|
await expect(page.getByText(/确定要删除/)).toBeVisible()
|
|
await page.locator('.t-popconfirm').getByRole('button', { name: '确定' }).click()
|
|
await expect(page.locator('.t-table__expanded-row').getByText('to_delete_model', { exact: true })).not.toBeVisible({ timeout: 5000 })
|
|
})
|
|
})
|