Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions .github/workflows/visactor-trusted-ci.yml

This file was deleted.

46 changes: 0 additions & 46 deletions common/config/flow-ci.json

This file was deleted.

35 changes: 0 additions & 35 deletions common/scripts/flow-ci-dispatch.mjs

This file was deleted.

46 changes: 0 additions & 46 deletions common/scripts/flow-ci-dispatch.test.mjs

This file was deleted.

77 changes: 1 addition & 76 deletions packages/vtable/__tests__/visual/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 准备

在仓库根目录使用 Node.js 22。VTable 与 VChart 统一固定 Playwright 1.63.0,安装 Rush 依赖和锁文件对应的 Chromium;两仓继续使用各自的执行配置与基线:
在仓库根目录使用 Node.js 22,安装 Rush 依赖和锁文件对应的 Chromium:

```sh
node common/scripts/install-run-rush.js install --ignore-hooks
Expand Down Expand Up @@ -32,85 +32,10 @@ node packages/vtable/scripts/visual-test.mjs --baseline <完整的40位commit-sh

正常结束、失败或 Ctrl+C 后,工具会回收本轮测试子进程、浏览器、HTTP 服务和临时基线 worktree。SIGKILL/断电后,先确认进程已结束,再检查 `git worktree list` 和 `.vtable-visual/running.lock`;不要删除其他任务的 worktree。

## 冻结套件导出

平台接入和归档可以复用同一个命令导出完整用例与当前构建,不需要 BugServer 登录:

```sh
node packages/vtable/scripts/visual-test.mjs --export-suite .vtable-visual/suites/current
node packages/vtable/scripts/visual-test.mjs --export-suite .vtable-visual/suites/next --previous-suite .vtable-visual/suites/current/suite-manifest.json
```

导出目录必须是新目录,位于工作区外或 Git 忽略目录;已有目录不会被覆盖。此模式不能与单例、目录、基线、列举或环境预检选项混用。它使用既有构建链生成所需的 `current-<resource>.js`,冻结原格式用例、页面、Playwright 运行器和辅助文件,并保存包版本与依赖锁文件。完整清单包含实际使用的 editors、gantt、plugins、sheet 和锁定 VChart 资源;VChart 版本来自已安装包,不使用 latest 或 CDN。此模式不下载官方基线、不运行截图、不接受视觉差异。

`suite-manifest.json` 使用 `schemaVersion=1`、`contractVersion=1.0`、`kind=suite_manifest`。所有文件记录相对路径、字节大小和 SHA-256;`suiteDigest` 标识规范化完整清单,`filesDigest` 标识冻结文件集合,`bundleDigest` 标识实际产品资源。`caseDigest` 包含用例、相对导入、公共运行器和使用的资源,截图键固定为 `final`,对应现有单例最终截图。历史 BugServer IDs 仅记录来源,不用于覆盖 Photo 用例,也不会写回源码。命令的 JSON 输出包含清单位置及按稳定 case ID 识别的 add/update/archive;归档只表示清单差异,不删除平台数据。

导出时校验唯一 ID/模块、完整资源、导入路径、符号链接及构建期工作区变化;失败退出 `2`,回收本次子进程,保留日志和 export-failure.json,移除不可消费的成功清单;重试使用新目录。套件列举和导入会执行 JavaScript:平台须把导出/发现放入隔离 worker,不能在有内网或业务凭据的控制进程执行。清单中的环境要求固定 Node 22、实际 Playwright 版本和现有截图设置;完整镜像、浏览器、字体和网络隔离仍由平台环境验收负责,导出成功不表示视觉测试或隔离验收通过。

确定性和非法输入检查:

```sh
node --test packages/vtable/scripts/visual-suite.test.mjs
```

## 冻结候选与指定只读基准

同一用例还可以验证冻结构建并与平台提供的 PNG 集合比较,不重新构建或采集基准:

```sh
node packages/vtable/scripts/visual-test.mjs --run-suite .vtable-visual/suites/current --run-request /path/to/run-request.json --baseline-set /path/to/baselines
# 可选 --output <新目录>;默认输出到 .vtable-visual/runs/<run-id>
```

三个输入必须配套,不能混用 `--case`、`--dir`、`--baseline`、`--self-compare` 或导出选项。输出须是新目录,位于工作区外或 Git 忽略目录,不能包含或覆盖输入;已有目录不会被覆盖。`suite-manifest.json` 需要 `adapterVersion=1.1.0`,增加实际提交的 `sourceParents` 与 `sourceDirty`;旧导出须重新生成。

`run-request.json` 使用公共接口契约 v1 的 `run_request`:固定仓库、产品、被测提交与源摘要、suite/bundle/policy 摘要、环境 ID、assetRevision、selection 和 executionKey。仅支持 `engines=["playwright"]`,Photo 的 suite/environment 为 `null`,截图键为 `final`。`full` 必须包含冻结清单全部用例;`targeted` 必须逐项列出 ID,不扩展为全量。选择摘要为规范化 items 的 SHA-256,执行键为规范化 `{identity, engines, selectionDigest, rerunSequence}` 的 SHA-256。`pr_head` 必须测试 head;`pr_merge` 必须绑定实际父提交 `[baseSha, headSha]`。本机 `local_workspace` 可包含 dirty 修改,但属于辅助证据,不能替代可信 CI 结果。

基准目录提供 `baseline-manifest.json`:

```json
{
"schemaVersion": 1,
"contractVersion": "1.0",
"kind": "baseline_manifest",
"artifactId": "selected-baselines",
"repository": "VisActor/VTable",
"productKey": "VTable",
"environmentId": "trusted-worker-environment-id",
"assetRevision": null,
"renderer": null,
"entries": [
{"caseId": "list-basic", "screenshotId": "final", "baselineExpected": false, "path": null, "digest": null}
]
}
```

此示例只声明一个首次基准项。请求目标 `identity.baseRef` 必须为 `develop`;`inputArtifacts` 必须包含该 artifactId、清单**原始文件字节**的 SHA-256、`mediaType=application/json` 和 `visibility=public|restricted`。可见性元信息不赋予执行器服务权限。环境 ID 和 assetRevision 必须与请求一致,所有选中截图均须有唯一条目;路径使用普通相对 POSIX 文件路径,禁止符号链接、越界和内容摘要不符。既有 PNG 填写 `baselineExpected=true`、相对 `path` 与 PNG 的 SHA-256;既有基准意外丢失仍声明 `true`,不得改成首次基准。只要使用既有 PNG,`renderer` 必须精确记录其实际 `{node, platform, arch, playwright, browser, settings}`,并与运行时实测一致。平台环境 ID 的完整镜像、字体、权限、内核和网络约束仍由可信控制器验收,本入口不建立操作系统隔离。

基准只复制到结果目录后用于原生 `toMatchSnapshot`,不开启基准更新;运行前后校验输入和副本不变。用例继续执行原有 mount、exercise/verify、有效绘制、连续稳定截图和 release。交互后再次检查绘制,空白、资源错误或语义断言失败不能发布候选图。

机器结果读取 `run-result.json`(`kind=run_result`、contractVersion=1.0)。逐截图保留三项检查、七类状态 `matched` / `different` / `no_baseline` / `assertion_failed` / `execution_error` / `skipped` / `cancelled`、图像摘要与证据路径;`complete` 仅表示全部选中截图具有终态报告,不表示比较通过。首次基准项经断言和稳定性验证可输出 `role=candidate` 的 PNG,但状态仍为 `no_baseline`、rawOutcome=failed、退出 `2`;意外缺基准另带 `MISSING_BASELINE`。只有完整的原生比较证据可返回 `different` 和退出 `1`;全部匹配返回 `0`;缺图、不完整、执行或清理错误返回 `2`。标准基准的接受、写回与服务接入另由协调流程负责,本入口没有同步或接受命令。

`summary.json`、`agent-summary.md` 和三图 HTML 是同次结果的查看入口;其中“完整比较”仍仅表示所选截图均完成有基准的比较。不要用首次候选已验证推断比较通过,也不要把指定基准或自比较称为官方 develop 通过。

```sh
# 先完成构建或套件导出,随后运行真实浏览器及失败路径专项
node --test packages/vtable/scripts/visual-candidate.test.mjs
```

## 用例维护

目录说明及来源 ID 规则见 [用例指南](./cases/README.md)。开发完成后运行相关目录;提交 PR 前运行默认全量比较并检查差异。新功能或缺陷修复可以加独立用例。不得用放宽截图阈值、跳过语义断言或接受差异代替修复不稳定用例。工具自检:

```sh
node --test packages/vtable/scripts/visual-test.test.mjs
```


## 本地比较的机器输出

`node packages/vtable/scripts/visual-test.mjs --json` 保留默认全量和官方 develop 比较;也可附带现有 `--case`、`--dir`、`--baseline` 或 `--self-compare`。此选项仅用于本地比较,不与列举、单独预检、套件导出或冻结候选模式混用。

stdout 只有一个 `schemaVersion=1`、`kind=local_visual_result` 对象,进度写入 stderr。对象保留真实 `exitCode`、`status`、`complete`、精确 `selection`、结果 `counts`、源码 `source.before/after`、实际 `baseline`、环境和三份报告绝对路径。退出码仍为通过 `0`、差异 `1`、错误 `2`;准备失败时未取得的范围、源码或基线为 null,不推断成功。源码摘要覆盖 HEAD、未提交和未跟踪源码,检查完成并清理后再次核对;发生变化记为 `WORKSPACE_CHANGED`、退出 `2`。目录或单例完成仅表示所选用例完成,`--self-compare` 只表示本地稳定性,均不代表官方全量、CI 或合入资格。

依赖及浏览器继续由原生预检负责,不自动安装或修复。报告只位于本次返回的运行目录;取消或清理失败保留错误证据。机器契约专项:`node --test packages/vtable/scripts/visual-json.test.mjs`。可安装的公共 `visactor-flow check` 复用此入口,不另行实现截图比较。
6 changes: 0 additions & 6 deletions packages/vtable/__tests__/visual/cases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,3 @@
从 BugServer 迁移来源时,缺少 `interactions` 字段仅表示没有附加录制动作;仍须检查源码中的事件、定时器、异步调用、后续 API 更新及资源。保留目标配置、数据边界、动作顺序和最终状态。不得复制业务原文、内部地址、凭证、原始数据或截图到公开仓库;来源不明时先在仓库外私有目录复核。

新增或修改后先运行单例 `--self-compare --case <id>`,再运行对应目录;提交前运行默认全量比较。若用例在官方基线不支持,报告为执行错误,应如实说明,不能把自比较当作双侧通过。

## 指定基准与首次候选

冻结套件执行仍使用同一份显式清单和原用例格式,步骤见 [工具说明](../README.md#冻结候选与指定只读基准)。新增用例保留稳定 ID、真实语义断言和交互状态验证;首次基准由输入清单明确声明 `baselineExpected=false`,不跳过绘制或稳定性检查。通过这些检查的 PNG 只进入运行结果暂存,`no_baseline` 不表示比较通过,也不自动变为正式基准。缺少既有基准、空白、缺图或断言失败必须保留错误。

运行器的故障注入和协议反例放在 `scripts/visual-candidate.test.mjs` 的独立副本中,不登记到产品截图清单、不提交破坏性 case。修改公共运行器后仍需执行相关测试和 PR 前官方 develop 全量比较。
2 changes: 0 additions & 2 deletions packages/vtable/__tests__/visual/playwright.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { settings } from './settings.mjs';
const runDir = process.env.VISUAL_RUN_DIR;
const phase = process.env.VISUAL_PHASE;
if (!runDir || !['baseline', 'current'].includes(phase)) throw new Error('请通过 visual-test.mjs 运行');
if (process.env.VISUAL_EXTERNAL_BASELINE === '1' && phase !== 'current')
throw new Error('指定基准模式只运行候选侧,不允许更新基准');

export default defineConfig({
testDir: '.',
Expand Down
Loading
Loading