import { test, expect } from '@playwright/test' import { clearDatabase } from './fixtures' 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[placeholder="sk-..."]'), baseUrl: dialog.locator('input[placeholder="例如: https://api.openai.com/v1"]'), protocol: dialog.locator('.t-select'), saveBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '保存' }), cancelBtn: dialog.locator('.t-dialog__footer').getByRole('button', { name: '取消' }), } } test.describe('供应商管理', () => { test.beforeEach(async ({ page, request }) => { await clearDatabase(request) 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.protocol.click() await page.waitForSelector('.t-select__dropdown', { timeout: 3000 }) await page.locator('.t-select__dropdown .t-select-option').first().click() await page.waitForSelector('.t-select__dropdown', { state: 'hidden', timeout: 3000 }) await inputs.saveBtn.click() await expect(page.locator('.t-table__body').getByText('Test Provider')).toBeVisible({ timeout: 10000 }) }) 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.protocol.click() await page.waitForSelector('.t-select__dropdown', { timeout: 3000 }) await page.locator('.t-select__dropdown .t-select-option').first().click() await page.waitForSelector('.t-select__dropdown', { state: 'hidden', timeout: 3000 }) const responsePromise = page.waitForResponse(resp => resp.url().includes('/api/providers') && resp.request().method() === 'POST') await inputs.saveBtn.click() await responsePromise await expect(page.locator('.t-table__body').getByText('Before Edit')).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') const updateResponsePromise = page.waitForResponse(resp => resp.url().includes('/api/providers') && resp.request().method() === 'PUT') await editInputs.saveBtn.click() await updateResponsePromise await expect(page.locator('.t-table__body').getByText('After Edit')).toBeVisible({ timeout: 5000 }) }) 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.protocol.click() await page.waitForSelector('.t-select__dropdown', { timeout: 3000 }) await page.locator('.t-select__dropdown .t-select-option').first().click() await page.waitForSelector('.t-select__dropdown', { state: 'hidden', timeout: 3000 }) await inputs.saveBtn.click() await expect(page.locator('.t-table__body').getByText('To Delete')).toBeVisible({ timeout: 10000 }) 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.locator('.t-table__body').getByText('To Delete')).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.protocol.click() await page.waitForSelector('.t-select__dropdown', { timeout: 3000 }) await page.locator('.t-select__dropdown .t-select-option').first().click() await page.waitForSelector('.t-select__dropdown', { state: 'hidden', timeout: 3000 }) await inputs.saveBtn.click() await expect(page.locator('.t-table__body').getByText('Mask Test')).toBeVisible({ timeout: 10000 }) await expect(page.locator('.t-table__body')).toContainText('sk_abcdefghijklmnopqrstuvwxyz') }) })