538de50bb1
- Prisma User 模型新增 username 字段(唯一索引) - 注册先查重复再创建,返回友好中文提示(非 500) - 登录支持用户名/手机号/邮箱三种方式 - 前端注册表单增加用户名输入框,预校验 2-20 位格式 - 新增 scripts/deploy.sh:一键构建并部署主站+镜像站+重启后端+重载 Nginx - 镜像站 www.yuzhiran.com.cn Nginx 配置与主站同步 - AI 助手架构升级:用户端/管理后台均采用完整 Tool Calling 架构 - 新增 UserAiAssistantService(18 工具)+ AiAssistantController - admin 助手新增 search + mark-all-notifications-read 工具 - 修复注册 500 错误:catch Prisma P2002 → BadRequestException - Baidu Analytics Script 注入 root layout
120 lines
3.7 KiB
TypeScript
Executable File
120 lines
3.7 KiB
TypeScript
Executable File
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('功能页面', () => {
|
|
test.describe('沙盒 (/sandbox)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/sandbox');
|
|
});
|
|
|
|
test('页面渲染正常', async ({ page }) => {
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
|
|
test('模型选择器存在', async ({ page }) => {
|
|
const select = page.locator('select');
|
|
const count = await select.count();
|
|
expect(count).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
test('消息输入框存在', async ({ page }) => {
|
|
await expect(page.locator('textarea, input[type="text"]').first()).toBeVisible();
|
|
});
|
|
|
|
test('发送按钮存在', async ({ page }) => {
|
|
await expect(page.getByText('发送').first()).toBeVisible();
|
|
});
|
|
|
|
test('初始欢迎消息展示', async ({ page }) => {
|
|
await expect(page.getByText(/你好!我是宇之然 AI 助手/)).toBeVisible();
|
|
});
|
|
|
|
test('对比实验室链接存在', async ({ page }) => {
|
|
const compareLink = page.getByText('对比实验室').or(page.getByText('模型对比'));
|
|
const count = await page.getByText('对比实验室').count();
|
|
if (count > 0) {
|
|
const link = page.getByText('对比实验室').first();
|
|
await expect(link).toBeVisible();
|
|
const href = await link.getAttribute('href');
|
|
if (href) {
|
|
await expect(link).toHaveAttribute('href', /\/sandbox\/compare|\/compare/);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('对比实验室 (/sandbox/compare)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/sandbox/compare');
|
|
});
|
|
|
|
test('页面渲染正常', async ({ page }) => {
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('提示词工坊 (/prompts/workshop)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/prompts/workshop');
|
|
});
|
|
|
|
test('页面渲染正常', async ({ page }) => {
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('搜索 (/search)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/search');
|
|
});
|
|
|
|
test('搜索输入框存在', async ({ page }) => {
|
|
await expect(page.locator('input[type="text"], input[name="q"]').first()).toBeVisible();
|
|
});
|
|
|
|
test('搜索按钮存在', async ({ page }) => {
|
|
await expect(page.getByText('搜索').first()).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('发现页及子页', () => {
|
|
test('/discover 渲染', async ({ page }) => {
|
|
await page.goto('/discover');
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
const dailyLink = page.getByText('每日精选').first();
|
|
if (await dailyLink.isVisible()) {
|
|
await expect(dailyLink).toHaveAttribute('href', '/discover/daily');
|
|
}
|
|
});
|
|
|
|
test('/discover/daily 渲染', async ({ page }) => {
|
|
await page.goto('/discover/daily');
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
|
|
test('/discover/hot 渲染', async ({ page }) => {
|
|
await page.goto('/discover/hot');
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
|
|
test('/discover/tools 渲染', async ({ page }) => {
|
|
await page.goto('/discover/tools');
|
|
await expect(page.locator('h1')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('认证页 (/auth)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/auth');
|
|
});
|
|
|
|
test('登录表单可见', async ({ page }) => {
|
|
await expect(page.getByText('登录').first()).toBeVisible();
|
|
});
|
|
|
|
test('注册表单可切换', async ({ page }) => {
|
|
await page.goto('/auth?tab=register');
|
|
await expect(page.getByText('注册').first()).toBeVisible();
|
|
});
|
|
});
|
|
});
|