88 lines
5.1 KiB
JavaScript
88 lines
5.1 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFile } from 'node:fs/promises'
|
|
import { fileURLToPath } from 'node:url'
|
|
import path from 'node:path'
|
|
|
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url))
|
|
const sourceRoot = path.resolve(scriptDir, '../src')
|
|
const publicRoot = path.resolve(scriptDir, '../public')
|
|
const [headerSource, routerSource, guideSource, guideContentSource] = await Promise.all([
|
|
readFile(path.join(sourceRoot, 'components/AppHeader.vue'), 'utf8'),
|
|
readFile(path.join(sourceRoot, 'router/index.ts'), 'utf8'),
|
|
readFile(path.join(sourceRoot, 'views/guide/GuideView.vue'), 'utf8'),
|
|
readFile(path.join(sourceRoot, 'views/guide/guideContent.ts'), 'utf8'),
|
|
])
|
|
|
|
assert.match(headerSource, /fa-book/, '顶部栏缺少书状使用文档图标')
|
|
assert.match(headerSource, /window\.open\([\s\S]*?['"]_blank['"]/, '使用文档应在浏览器新标签页打开')
|
|
assert.match(headerSource, /aria-label=["']打开使用文档["']/, '使用文档图标缺少无障碍名称')
|
|
assert.match(routerSource, /path:\s*['"]\/guide['"][\s\S]*?GuideView\.vue/, '缺少独立使用文档路由')
|
|
assert.match(routerSource, /name:\s*['"]guide['"][\s\S]*?skipPermission:\s*true/, '使用文档应允许所有已登录用户访问')
|
|
assert.ok(routerSource.indexOf("path: '/guide'") < routerSource.indexOf("path: '/'"), '使用文档不应嵌入主应用布局')
|
|
assert.match(guideSource, /class="docs-shell"/, '使用文档缺少独立文档站布局')
|
|
assert.match(guideSource, /class="docs-sidebar"/, '使用文档缺少左侧分级导航')
|
|
assert.match(guideSource, /class="article-toc"/, '使用文档缺少右侧页内目录')
|
|
assert.match(guideSource, /v-model="searchQuery"/, '使用文档缺少全局搜索能力')
|
|
assert.match(guideSource, /scrollIntoView/, '使用文档目录缺少锚点导航能力')
|
|
assert.match(guideSource, /class="architecture-flow"/, '使用文档缺少架构或流程图')
|
|
assert.match(guideSource, /articlePresentation\.stepsTitle/, '文档步骤标题应根据页面类型动态展示')
|
|
assert.match(guideSource, /查看型页面/, '文档缺少查看型页面说明')
|
|
assert.match(guideSource, /排查型页面/, '文档缺少排查型页面说明')
|
|
assert.match(guideSource, /class="step-screenshot"/, '使用文档缺少步骤内联页面截图')
|
|
assert.match(guideSource, /loading="lazy"/, '页面截图应使用懒加载')
|
|
assert.match(guideSource, /class="image-preview-overlay"/, '页面截图缺少大图预览')
|
|
assert.match(guideSource, /aria-modal="true"/, '截图预览缺少无障碍对话框语义')
|
|
assert.match(guideSource, /:inert="previewImage \? true : undefined"/, '截图预览打开时应禁用背景交互')
|
|
assert.match(guideSource, /event\.key === 'Tab'/, '截图预览缺少键盘焦点循环')
|
|
assert.match(guideSource, /:width="step\.screenshot\.width"/, '页面截图应使用真实固有尺寸')
|
|
|
|
for (const moduleName of [
|
|
'服务看板',
|
|
'模型训练',
|
|
'模型评测',
|
|
'模型推理',
|
|
'模型管理',
|
|
'数据集管理',
|
|
'数据处理',
|
|
'数据类型转换',
|
|
'用户设置',
|
|
'平台性能',
|
|
'查看日志',
|
|
]) {
|
|
assert.ok(guideContentSource.includes(moduleName), `使用文档缺少模块:${moduleName}`)
|
|
}
|
|
|
|
assert.match(guideSource, /操作步骤/, '使用文档缺少分步骤教程')
|
|
assert.match(guideContentSource, /title:\s*'快速开始'/, '使用文档缺少完整快速开始教程')
|
|
assert.match(guideContentSource, /architecture:/, '使用文档内容缺少架构流程数据')
|
|
assert.match(guideContentSource, /steps:/, '使用文档内容缺少模块操作步骤')
|
|
assert.match(guideContentSource, /id:\s*'dashboard'[\s\S]*?mode:\s*'overview'/, '服务看板应标记为查看型页面')
|
|
assert.match(guideContentSource, /id:\s*'hardware'[\s\S]*?mode:\s*'overview'/, '平台性能应标记为查看型页面')
|
|
assert.match(guideContentSource, /id:\s*'logs'[\s\S]*?mode:\s*'troubleshooting'/, '查看日志应标记为排查型页面')
|
|
assert.match(guideContentSource, /screenshot:/, '使用文档步骤缺少真实页面截图引用')
|
|
assert.match(guideContentSource, /status:\s*'建设中'/, '使用文档应如实标记未开放功能')
|
|
assert.match(guideSource, /@media \(max-width: 900px\)/, '使用文档缺少窄屏响应式布局')
|
|
|
|
for (const screenshotName of [
|
|
'service-dashboard.png',
|
|
'fine-tune-create.jpg',
|
|
'training-detail.jpg',
|
|
'model-edit.jpg',
|
|
'data-process-create.jpg',
|
|
'data-process-preview.jpg',
|
|
]) {
|
|
const screenshotPath = path.join(publicRoot, 'guide/screenshots', screenshotName)
|
|
const screenshot = await readFile(screenshotPath)
|
|
assert.ok(screenshot.length > 10_000, `页面截图不存在或内容异常:${screenshotName}`)
|
|
const isValidSignature = screenshotName.endsWith('.png')
|
|
? screenshot.subarray(1, 4).toString() === 'PNG'
|
|
: screenshot[0] === 0xff && screenshot[1] === 0xd8 && screenshot[2] === 0xff
|
|
assert.ok(isValidSignature, `页面截图扩展名与文件格式不一致:${screenshotName}`)
|
|
assert.ok(
|
|
guideContentSource.includes(`/guide/screenshots/${screenshotName}`),
|
|
`使用文档未引用页面截图:${screenshotName}`,
|
|
)
|
|
}
|
|
|
|
console.log('使用文档回归检查通过')
|