|
|
|
|
@@ -17,10 +17,63 @@ await server.listen()
|
|
|
|
|
const browser = await chromium.launch({ headless: true })
|
|
|
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 1024 }, deviceScaleFactor: 1 })
|
|
|
|
|
const errors = []
|
|
|
|
|
const projectId = '019b0000-0000-7000-8000-000000000001'
|
|
|
|
|
page.on('console', (message) => {
|
|
|
|
|
if (message.type() === 'error') errors.push(message.text())
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const visualCheckWorkspace = {
|
|
|
|
|
project: {
|
|
|
|
|
id: projectId,
|
|
|
|
|
name: '森林项目',
|
|
|
|
|
identifier: 'forest',
|
|
|
|
|
icon: '森',
|
|
|
|
|
background: '#165DFF',
|
|
|
|
|
description: '前后端 API 对齐视觉检查项目',
|
|
|
|
|
initials: '森林',
|
|
|
|
|
unreadCount: 2,
|
|
|
|
|
},
|
|
|
|
|
channels: [
|
|
|
|
|
{ id: 'overview', projectId, type: 'overview', title: '概况', icon: 'home', count: 0, url: '', sortOrder: 0 },
|
|
|
|
|
{ id: 'tasks', projectId, type: 'tasks', title: '工作计划', icon: 'list', count: 0, url: '', sortOrder: 1 },
|
|
|
|
|
{ id: 'ai', projectId, type: 'ai_sessions', title: 'AI 助手', icon: 'robot', count: 0, url: '', sortOrder: 2 },
|
|
|
|
|
{ id: 'notes', projectId, type: 'notes_sources', title: '笔记资料', icon: 'file', count: 0, url: '', sortOrder: 3 },
|
|
|
|
|
{ id: 'cron', projectId, type: 'cron', title: '计划任务', icon: 'clock', count: 0, url: '', sortOrder: 4 },
|
|
|
|
|
],
|
|
|
|
|
tags: [{ id: '019b0000-0000-7000-8000-000000000002', name: '产品' }],
|
|
|
|
|
recentSessions: [],
|
|
|
|
|
inbox: [],
|
|
|
|
|
tasks: [],
|
|
|
|
|
aiSessions: [],
|
|
|
|
|
notesSources: [],
|
|
|
|
|
cronPlans: [],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await page.route('http://localhost:9150/api/v1/**', async (route) => {
|
|
|
|
|
const url = new URL(route.request().url())
|
|
|
|
|
if (url.pathname === '/api/v1/status') {
|
|
|
|
|
await route.fulfill({ json: { timestamp: new Date().toISOString() } })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (url.pathname === '/api/v1/auth/login') {
|
|
|
|
|
await route.fulfill({ json: { token: 'visual-check-token' } })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (url.pathname === '/api/v1/projects') {
|
|
|
|
|
await route.fulfill({ json: [visualCheckWorkspace.project] })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (url.pathname === `/api/v1/projects/${projectId}/workspace`) {
|
|
|
|
|
await route.fulfill({ json: visualCheckWorkspace })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (url.pathname === `/api/v1/projects/${projectId}/ai-sessions`) {
|
|
|
|
|
await route.fulfill({ json: [] })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
await route.fulfill({ status: 404, json: { error: { code: 'not_found', message: '视觉检查未配置该接口' } } })
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const collectMetrics = async () => page.evaluate(() => {
|
|
|
|
|
const statusbar = document.querySelector('.statusbar')
|
|
|
|
|
const statusName = document.querySelector('.status-name')
|
|
|
|
|
@@ -131,7 +184,7 @@ const channelListHoverMetrics = await collectMetrics()
|
|
|
|
|
const channelPageChecks = []
|
|
|
|
|
for (const channel of [
|
|
|
|
|
{ label: '工作计划', pageClass: 'project-tasks-page', expectedHeading: '工作计划' },
|
|
|
|
|
{ label: 'AI智能体', pageClass: 'project-ai-page', expectedHeading: 'AI智能体' },
|
|
|
|
|
{ label: 'AI 助手', pageClass: 'project-ai-page', expectedHeading: 'AI 助手' },
|
|
|
|
|
{ label: '笔记资料', pageClass: 'project-notes-page', expectedHeading: '笔记资料' },
|
|
|
|
|
{ label: '计划任务', pageClass: 'project-cron-page', expectedHeading: '计划任务' },
|
|
|
|
|
{ label: '新建频道', pageClass: 'project-new-channel-page', expectedHeading: '新建频道' },
|
|
|
|
|
@@ -172,10 +225,7 @@ const failures = []
|
|
|
|
|
const metrics = workspaceMetrics
|
|
|
|
|
if (errors.length) failures.push(`console errors: ${errors.join('; ')}`)
|
|
|
|
|
if (metrics.statusbarHeight !== 32) failures.push(`expected statusbar height 32, got ${metrics.statusbarHeight}`)
|
|
|
|
|
if (!metrics.statusOnlineDot) failures.push('expected online status to render as an icon dot')
|
|
|
|
|
if (metrics.statusName && metrics.statusOnlineDot && Math.abs(metrics.statusName.top - metrics.statusOnlineDot.top) > 6) {
|
|
|
|
|
failures.push(`expected online dot to sit beside username, got name=${JSON.stringify(metrics.statusName)}, dot=${JSON.stringify(metrics.statusOnlineDot)}`)
|
|
|
|
|
}
|
|
|
|
|
if (!metrics.statusName) failures.push('expected authenticated status label')
|
|
|
|
|
if (metrics.searchHeight !== 42) failures.push(`expected search height 42, got ${metrics.searchHeight}`)
|
|
|
|
|
if (metrics.overflowX) failures.push('expected no horizontal overflow')
|
|
|
|
|
if (!metrics.workbenchMain) failures.push('missing workbench main')
|
|
|
|
|
|