test(browser): ENG-05 add real playback projects and artifact mapping

This commit is contained in:
Harvey Zhao committed 2026-09-10 22:25:13 +08:00
1 parent 458bc3215d
commit 7318d33822
20 files changed
+1241 -9

No files matched your search

+1
View File
@@ -44,6 +44,7 @@
| [类型检查与迁移入口](typechecking.md) | 根/分包配置、当前/旧编译器、严格正反例和历史声明错误 |
| [JS/TS 构建与开发](build-development.md) | 非交互选包、开发重建、资源夹具和 AMD 全局修复 |
| [测试目录维护说明](../test/README.md) | 统一测试命令、JS/TS loader、受控媒体及新旧公共契约 |
| [真实浏览器入口](../test/browser/README.md) | 三浏览器、解码画面与媒体状态、Range/失败服务及候选文件映射 |
## 维护规则
+666
View File
@@ -0,0 +1,666 @@
{
"task": "ENG-05",
"capturedAt": "2026-09-10T14:21:28.353Z",
"node": "24.21.0",
"platform": "win32",
"playwright": "1.63.0",
"mode": "workspace-build",
"sourceHashAlgorithm": "sha256-lf",
"sourceHashes": {
"playwright.config.js": "df2384f5626252ec933725867e400ec22eb92bc5e6f04873059b32decf2f2d56",
"test/browser/server.mjs": "d9025f9585f941a3b9b1f5b6c1b7b297c1fde6f50266720cbcc66f1334976f4a",
"test/browser/player.html": "179c89abf50f7d69c9083a4c2951cb6cbcd624f61d3b417ead139506a6468eb7",
"test/browser/fixtures.js": "313414b8958eb5b03a2da8595fa0bbf6bfdc01484373898c6cb7179545df175d",
"test/browser/playback.spec.js": "f4d8f65f35bad9ceb68137e605881f2e799f94bc636c0fdbde07c49d3623d86c"
},
"manifest": {
"kind": "artplayer-browser-test",
"resources": {
"/candidate/artplayer.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "c6f564431e03a198c81fc026af75ead9f7c624e5c7f2f23cba5ce984ec045290",
"bytes": 220281
},
"/compiled/artplayer.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "c6f564431e03a198c81fc026af75ead9f7c624e5c7f2f23cba5ce984ec045290",
"bytes": 220281,
"aliasOf": "/candidate/artplayer.js"
},
"/uncompiled/artplayer/index.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "c6f564431e03a198c81fc026af75ead9f7c624e5c7f2f23cba5ce984ec045290",
"bytes": 220281,
"aliasOf": "/candidate/artplayer.js"
},
"/candidate/artplayer-plugin-chapter.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer-plugin-chapter\\src\\index.js"
},
"sha256": "833b81bf3334443531ed1822e28a38a241484056c6dbbdd50cd1ec093303ab94",
"bytes": 8178
},
"/compiled/artplayer-plugin-chapter.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer-plugin-chapter\\src\\index.js"
},
"sha256": "833b81bf3334443531ed1822e28a38a241484056c6dbbdd50cd1ec093303ab94",
"bytes": 8178,
"aliasOf": "/candidate/artplayer-plugin-chapter.js"
},
"/uncompiled/artplayer-plugin-chapter/index.js": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer-plugin-chapter\\src\\index.js"
},
"sha256": "833b81bf3334443531ed1822e28a38a241484056c6dbbdd50cd1ec093303ab94",
"bytes": 8178,
"aliasOf": "/candidate/artplayer-plugin-chapter.js"
},
"/published/artplayer.js": {
"source": {
"kind": "npm-release",
"version": "5.4.0",
"integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==",
"member": "package/dist/artplayer.js"
},
"sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f",
"bytes": 134037
},
"/published/artplayer-plugin-chapter.js": {
"source": {
"kind": "npm-release",
"version": "1.1.0",
"integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==",
"member": "package/dist/artplayer-plugin-chapter.js"
},
"sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
"bytes": 4973
},
"/test/pattern.mp4": {
"source": {
"kind": "generated-media",
"file": "test/browser/media/pattern.mp4"
},
"sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
"bytes": 251538
},
"/test/pattern.webm": {
"source": {
"kind": "generated-media",
"file": "test/browser/media/pattern.webm"
},
"sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f",
"bytes": 162073
},
"/assets/sample/video.mp4": {
"source": {
"kind": "docs-media",
"file": "docs/assets/sample/video.mp4"
},
"sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980",
"bytes": 5818706
}
}
},
"stats": {
"startTime": "2026-09-10T14:21:28.353Z",
"duration": 12894.75,
"expected": 12,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"tests": [
{
"project": "chromium",
"title": "published: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 1796,
"browser": "153.0.8010.12",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [
{
"url": "http://127.0.0.1:8084/test/pattern.mp4?case=b4ed495288f4b512a8ac-846a43d5c11f461bc706",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
},
{
"url": "http://127.0.0.1:8084/assets/sample/video.mp4?case=b4ed495288f4b512a8ac-846a43d5c11f461bc706",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
},
{
"url": "http://127.0.0.1:8084/assets/sample/video.mp4?case=b4ed495288f4b512a8ac-846a43d5c11f461bc706",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
}
],
"decodedFrame": {
"pixels": [
[
255,
255,
2,
255
],
[
0,
0,
253,
255
],
[
1,
255,
255,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
},
{
"path": "/test/pattern.mp4",
"range": "bytes=229376-",
"method": "GET"
}
]
}
},
{
"project": "chromium",
"title": "candidate: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 1727,
"browser": "153.0.8010.12",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [
{
"url": "http://127.0.0.1:8084/test/pattern.mp4?case=b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
},
{
"url": "http://127.0.0.1:8084/assets/sample/video.mp4?case=b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
},
{
"url": "http://127.0.0.1:8084/assets/sample/video.mp4?case=b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb",
"resourceType": "media",
"failure": {
"errorText": "net::ERR_ABORTED"
}
}
],
"decodedFrame": {
"pixels": [
[
255,
255,
2,
255
],
[
0,
0,
253,
255
],
[
1,
255,
255,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
},
{
"path": "/test/pattern.mp4",
"range": "bytes=229376-",
"method": "GET"
}
]
}
},
{
"project": "chromium",
"title": "controlled HTTP media failure emits a real video error",
"status": "passed",
"durationMs": 391,
"browser": "153.0.8010.12",
"events": [
"video:error",
"destroy"
],
"errors": [],
"consoleErrors": [
"Failed to load resource: the server responded with a status of 503 (Service Unavailable)"
],
"failedRequests": []
},
{
"project": "chromium",
"title": "Range, media identity and docs candidate routes",
"status": "passed",
"durationMs": 308,
"browser": "153.0.8010.12",
"errors": [],
"consoleErrors": [],
"failedRequests": []
},
{
"project": "firefox",
"title": "published: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 3064,
"browser": "155.0",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [],
"decodedFrame": {
"pixels": [
[
255,
241,
2,
255
],
[
0,
14,
253,
255
],
[
0,
230,
255,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
}
]
}
},
{
"project": "firefox",
"title": "candidate: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 3118,
"browser": "155.0",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [],
"decodedFrame": {
"pixels": [
[
255,
241,
2,
255
],
[
0,
14,
253,
255
],
[
0,
230,
255,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
}
]
}
},
{
"project": "firefox",
"title": "controlled HTTP media failure emits a real video error",
"status": "passed",
"durationMs": 2403,
"browser": "155.0",
"events": [
"video:error",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": []
},
{
"project": "firefox",
"title": "Range, media identity and docs candidate routes",
"status": "passed",
"durationMs": 543,
"browser": "155.0",
"errors": [],
"consoleErrors": [],
"failedRequests": []
},
{
"project": "webkit",
"title": "published: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 4626,
"browser": "26.6",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [],
"decodedFrame": {
"pixels": [
[
235,
236,
12,
255
],
[
16,
15,
239,
255
],
[
13,
237,
237,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
}
]
}
},
{
"project": "webkit",
"title": "candidate: real playback, pause, seek, switch and destroy",
"status": "passed",
"durationMs": 4628,
"browser": "26.6",
"events": [
"video:loadedmetadata",
"ready",
"video:playing",
"video:pause",
"video:seeked",
"video:loadedmetadata",
"video:seeked",
"video:playing",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": [],
"decodedFrame": {
"pixels": [
[
235,
236,
12,
255
],
[
16,
15,
239,
255
],
[
13,
237,
237,
255
]
],
"mediaRequests": [
{
"path": "/test/pattern.mp4",
"range": "bytes=0-",
"method": "GET"
}
]
}
},
{
"project": "webkit",
"title": "controlled HTTP media failure emits a real video error",
"status": "passed",
"durationMs": 719,
"browser": "26.6",
"events": [
"video:error",
"destroy"
],
"errors": [],
"consoleErrors": [],
"failedRequests": []
},
{
"project": "webkit",
"title": "Range, media identity and docs candidate routes",
"status": "passed",
"durationMs": 577,
"browser": "26.6",
"errors": [],
"consoleErrors": [],
"failedRequests": []
}
],
"artifactMode": {
"browser": "155.0",
"platform": "win32",
"stats": {
"startTime": "2026-09-10T14:22:28.949Z",
"duration": 5939.912,
"expected": 4,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"resources": {
"/candidate/artplayer.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer\\dist\\artplayer.js"
},
"sha256": "9ad044a601dafc24f449b690403fb1c343b40e99ffb31043272189fc3c1e7bfa",
"bytes": 134939
},
"/compiled/artplayer.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer\\dist\\artplayer.js"
},
"sha256": "9ad044a601dafc24f449b690403fb1c343b40e99ffb31043272189fc3c1e7bfa",
"bytes": 134939,
"aliasOf": "/candidate/artplayer.js"
},
"/uncompiled/artplayer/index.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer\\dist\\artplayer.js"
},
"sha256": "9ad044a601dafc24f449b690403fb1c343b40e99ffb31043272189fc3c1e7bfa",
"bytes": 134939,
"aliasOf": "/candidate/artplayer.js"
},
"/candidate/artplayer-plugin-chapter.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer-plugin-chapter\\dist\\artplayer-plugin-chapter.js"
},
"sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
"bytes": 4973
},
"/compiled/artplayer-plugin-chapter.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer-plugin-chapter\\dist\\artplayer-plugin-chapter.js"
},
"sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
"bytes": 4973,
"aliasOf": "/candidate/artplayer-plugin-chapter.js"
},
"/uncompiled/artplayer-plugin-chapter/index.js": {
"source": {
"kind": "artifact",
"file": "D:\\github\\ArtPlayer\\refactor\\.cache\\eng-06-build\\packages\\artplayer-plugin-chapter\\dist\\artplayer-plugin-chapter.js"
},
"sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
"bytes": 4973,
"aliasOf": "/candidate/artplayer-plugin-chapter.js"
},
"/published/artplayer.js": {
"source": {
"kind": "npm-release",
"version": "5.4.0",
"integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==",
"member": "package/dist/artplayer.js"
},
"sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f",
"bytes": 134037
},
"/published/artplayer-plugin-chapter.js": {
"source": {
"kind": "npm-release",
"version": "1.1.0",
"integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==",
"member": "package/dist/artplayer-plugin-chapter.js"
},
"sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
"bytes": 4973
},
"/test/pattern.mp4": {
"source": {
"kind": "generated-media",
"file": "test/browser/media/pattern.mp4"
},
"sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
"bytes": 251538
},
"/test/pattern.webm": {
"source": {
"kind": "generated-media",
"file": "test/browser/media/pattern.webm"
},
"sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f",
"bytes": 162073
},
"/assets/sample/video.mp4": {
"source": {
"kind": "docs-media",
"file": "docs/assets/sample/video.mp4"
},
"sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980",
"bytes": 5818706
}
},
"source": "ENG-06 isolated build output, not a newly packed npm candidate"
}
}
@@ -0,0 +1,53 @@
# ENG-05:可重复的真实浏览器入口
## 交付与结构
新增 [浏览器测试目录](../../test/browser/README.md) 和根 Playwright 配置。固定
`@playwright/test` 1.63.0(仅开发依赖;连同 playwright/playwright-core 更新 yarn.lock),
提供安装、执行和 HTML 报告脚本。原快速 Node 测试独立保留。
服务只绑定 loopback,独占 8084、拒绝复用已有服务;每次从当前 JS/TS 入口构建 core/chapter,
或明确读取指定候选文件。发布基线校验归档/member hash。候选文件缺失直接失败;不会偷偷
使用工作区或旧 docs 产物。docs 页面和样本沿用原路径,compiled/uncompiled 的核心和 chapter
别名映射到已记录 SHA-256 的候选文件。尚未映射的其他包资源拒绝加载。
媒体服务实现单段 Range/后缀 Range、HEAD、416、固定 503 和按用例隔离的请求记录。
新建两个自生成、无外部画面及音轨的短样本;播放用例还切换到既有 docs video.mp4。
没有改动核心/插件的生产源码、公开 API 或声明。
CI 新增 macOS 三浏览器 smoke 和 always 上传报告/失败截图/trace;所有操作使用既有固定
Action SHA。macOS 的选择用于更接近 Safari 的媒体栈;这不代表已经运行远端 CI 或真实 Safari。
## 实际验证
- Windows、Node 24.21.0、Yarn 1.22.22:冻结安装通过,21 个直接工具固定、1339 个依赖 selector。
- Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6:12 项全部通过,无跳过、无重试。
同组用例覆盖发布 core 5.4.0 / 当前 core 与当前 chapter;解码画面像素、服务端媒体请求、
时间推进、暂停、seek、切源、销毁、503 与 video:error 均有断言。
- 指定 ENG-06 隔离构建中的两个 UMD 文件后,Firefox 4 项通过;报告确认使用 artifact 来源。
空候选映射负例在启动前以退出码 1 拒绝。该模式验证映射能力,不代表 ENG-07 tarball 消费完成。
- `yarn ci:check`:原 54 项检查通过;actionlint 与 Git 差异检查通过。
- [精简运行证据](../baselines/browser-validation.json) 保存版本、实际资源哈希、测试源指纹、
各用例结果、事件与解码像素。完整本地报告/log 在忽略的 refactor/.cache 下。
首次 WebKit 用例用 videoWidth=320 和 page.waitForResponse 判定失败。隔离原生 video、
实际截图和解码像素后确认视频确实播放:该 Windows 构建的 videoWidth 随布局变化,媒体请求
不可靠地出现在 page 网络事件中。最终用解码像素、实际时长和服务端请求联合判定,未删掉
播放或失败断言。此尺寸差异保留为环境限制,不能据此宣称所有媒体元数据兼容均已验证。
首次 Chromium 把正常媒体 Range 取消当成错误。最终只允许当前用例两条已知媒体 URL、同源、
resourceType=media、精确 net::ERR_ABORTED;全部原始记录仍保存。其他错误与播放失败仍失败。
本机 Node 下载浏览器连接超时,curl 从 Playwright 官方 URL 下载相同归档,再经临时 loopback
镜像交给官方 installer 解包;未改依赖或浏览器文件、未关闭 TLS 检查。镜像和诊断服务均已停止。
Chromium 本机安装 headless shell,已验证 headless 项目;带界面模式需安装完整 Chromium。
## 剩余范围与回退
真实 Monaco Run/TS/存储与完整 docs 页面操作仍归 EX-03;本任务只验证 docs 路由可取及候选映射,
轻量页面不替代编辑器验收。WebM 尚未加入播放断言;音频、移动真机、SDK、全插件组合和其他
浏览器最低版本仍按原任务推进。CI-01/CI-04 负责更完整矩阵及远端运行证据;本地全绿不代表远端已绿。
API-01/04/05/07/09 的基础测试入口已经可供 chapter 迁移复用,完整契约覆盖继续随包任务补齐。
回退本任务提交可移除新增依赖、测试及 CI 作业,不影响生产运行代码。下一任务优先推进 chapter
契约与测试,再完成 ENG-07 候选消费并进入插件源码拆分/TS 迁移。
+2 -1
View File
@@ -12,6 +12,7 @@
| `yarn test:unit` | 原播放/DASH 回归、同夹具的新旧公共契约与 JS/TS loader 验证 |
| `yarn test:node` | test:unit 加工具链/文档构建回归,保留原 test:playback/test:dash-control 入口 |
| `yarn test` | 统一执行 Node 与基线测试,源码/夹具维护入口见仓库 test/README.md |
| `yarn test:browser` | 隔离服务执行 Chromium/Firefox/WebKit 真实播放;首次先运行 test:browser:install,详见 [入口](../test/browser/README.md) |
| `yarn test:imports` | 3 个既有包导入 smoke,构建后执行以使用新产物;不把 console 示例视为完整行为断言 |
| `yarn test:baseline` | 固定发布包完整性及本地 HTTP 基线测试;首次可能下载已固定归档到缓存 |
| `yarn ci:check` | 严格 Node/Yarn/锁检查、计划、只读 lint、类型、Node 和基线测试;允许写忽略缓存,不修改源码 |
@@ -26,7 +27,7 @@ scripts/build-docs.js 保留原 npm run build 子命令兼容入口,现在传
Actions 固定完整 SHA,Node 来自 .node-version,Yarn 固定 1.22.22;安装使用 frozen-lockfile。actionlint 1.7.12 从官方固定归档取得,先核对提交在 workflow 中的 SHA-256,再执行。没有执行 curl 管道脚本。日志在失败时也尽量上传,包含源码 SHA、工具版本、锁摘要和生成差异概览,保留 14 天。
本轮不缓存 node_modules;矩阵、下载缓存、覆盖率、浏览器 trace 和候选 tarball 汇总由 CI-01 等后续任务扩展。当前测试通过不代表尚未实现的类型消费者或浏览器矩阵通过。将来的稳定 required 汇总名称由 CI-01/CI-04 核实后设置,不把本地 YAML 当作分支保护已生效。
不缓存 node_modules。ENG-04 已接入类型消费者;ENG-05 新增 macOS 的 `Browser playback smoke` 作业,运行三个浏览器并 always 上传 HTML/JSON、失败截图和 trace。本地 Windows 三浏览器已验证,远端 macOS 作业尚未运行。完整生态矩阵、下载缓存、覆盖率和候选 tarball 汇总由 CI-01 等后续任务扩展。稳定 required 汇总名称由 CI-01/CI-04 核实后设置,不把本地 YAML 当作分支保护已生效。
## Pages 隔离与启用条件
+1 -1
View File
@@ -34,7 +34,7 @@ chapter 试点可使用 `http://localhost:8082/?libs=./uncompiled/artplayer-plug
在线编辑器兼容用例继续通过实际 Run、键盘和控件交互验证;大量核心状态回归可以复用同一示例和样本在轻量测试页面运行,避免每项测试都依赖 Monaco 初始化。两类用例均保留,不能用轻量页面通过替代编辑器验收。
发布阶段将相同页面/示例接到候选 tarball 的提取内容,使用明确的测试目录或服务路由映射保留相对路径,并记录映射及完整性。此能力待 ENG-05/ENG-07 实现;当前没有可用的新开关或命令。不能只检查开发 bundle 就批准 npm 发布。
ENG-05 已提供 `yarn test:browser`、8084 隔离服务和 `ARTPLAYER_BROWSER_ARTIFACTS` 文件映射,见 [浏览器入口](../test/browser/README.md)。当前支持 core/chapter 的 compiled/uncompiled 别名,未映射的构建资源明确失败;每次报告保存实际文件 SHA-256。ENG-07 继续负责生成及核验候选 tarball,不能只检查开发 bundle 就批准 npm 发布。
## 任务归属与验收
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
状态:todo 186 / doing 0 / blocked 0 / done 28 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 185 / doing 0 / blocked 0 / done 29 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -78,7 +78,7 @@
| ENG-02 | workspace<br>拆分只读检查并建立 PR CI | ENG-01, ENG-PM-01 | lint/lint:fix、PR 与主线检查、独立部署任务;遵循 github-ci-cd.md,PR/重构分支触发、最小权限及 workflow 静态检查 | 仓库内检查可执行且不改源码、不发布;required checks 的外部设置状态列入发布台账,不阻塞本地框架建设 | M | done |
| ENG-03 | workspace<br>建立公共行为与单元测试入口 | ENG-02, BASE-03 | 保留现有 node:test,测试目录/夹具/统一入口 | 已有 19 项回归保留,旧版与候选可用同一夹具运行 | M | done |
| ENG-04 | workspace<br>建立类型测试基础 | ENG-02, BASE-05 | 根与分包 tsconfig、显式 TS 依赖、正反例测试 | 核心/试点与迁移模块严格检查,未迁移第三方/包历史问题独立台账;明确最低/当前 TS 和各环境类型;复用 BASE-05 的四种消费模式,不以 skipLibCheck 掩盖 BASE-TYPE-01/03 | M | done |
| ENG-05 | workspace<br>建立真实浏览器测试服务 | ENG-03, BASE-04, BASE-08 | Playwright projects、本地 Range/失败媒体服务;复用 docs 页面/样本的状态隔离、错误采集与候选资源映射 | Chromium/Firefox/WebKit 的基础播放 smoke 和报告可执行;以媒体状态断言判定通过,区分轻量用例与真实编辑器交互 | M | todo |
| ENG-05 | workspace<br>建立真实浏览器测试服务 | ENG-03, BASE-04, BASE-08 | Playwright projects、本地 Range/失败媒体服务;复用 docs 页面/样本的状态隔离、错误采集与候选资源映射 | Chromium/Firefox/WebKit 的基础播放 smoke 和报告可执行;以媒体状态断言判定通过,区分轻量用例与真实编辑器交互 | M | done |
| ENG-06 | workspace<br>支持按包非交互与 JS/TS 构建 | ENG-02, BASE-05 | build/dev 入口解析、指定包参数、原交互保留 | 三种产物、Less/SVG/worker 和本地 8082 demo 正常;保持 BASE-05 的 AMD 同时写入全局行为及 i18n/legacy 入口 | H | done |
| ENG-07 | workspace<br>建立 tarball 消费与产物检查 | ENG-04, ENG-06 | 隔离 npm 消费 fixtures、API/声明/入口差分 | 不借 workspace 源码通过,能识别缺文件与默认导出变化 | H | todo |
| ENG-08 | workspace<br>增加覆盖率、资源与性能报告 | ENG-03, ENG-05, BASE-06 | 覆盖率基线、资源清理断言、性能报告与阈值 | 关键生命周期分支有门槛,报告不靠无意义断言堆数量;将 BASE-06 的同环境多组配对、计时/压缩审查阈值与资源异常分开接入候选,不把历史现象冻结成正常要求 | M | todo |
@@ -430,4 +430,5 @@
- ENG-02: [记录](changes/2026-09-10-ENG-02-readonly-ci.md) [记录](baselines/ci-validation.json)
- ENG-03: [记录](changes/2026-09-10-ENG-03-unit-entry.md)
- ENG-04: [记录](changes/2026-09-10-ENG-04-typechecking.md) [记录](typechecking.md)
- ENG-05: [记录](changes/2026-09-10-ENG-05-browser-tests.md) [记录](baselines/browser-validation.json)
- ENG-06: [记录](changes/2026-09-10-ENG-06-build-development.md) [记录](build-development.md) [记录](baselines/build-validation.json)
+4
View File
@@ -1,5 +1,9 @@
# 进度与证据
## 当前实施:ENG-05 真实浏览器入口完成
Playwright 三浏览器 12 项真实播放/失败/映射测试通过,指定候选 UMD 文件的 Firefox 4 项通过;新增 CI smoke、报告与自生成媒体。见 [ENG-05](changes/2026-09-10-ENG-05-browser-tests.md)。当前 214 项,29 完成、185 待办;生产源码 TS 迁移仍为零。已具备 chapter 试点所需浏览器入口,下一项 PKG-CHAPTER-01,接特有测试和 ENG-07,再迁移插件源码。远端 CI、完整编辑器及真机尚未验收。
## 当前实施:ENG-03 公共行为与单元入口完成
原 19 项播放/DASH 回归保留,JS/TS loader 与受控媒体夹具复用;同一份五组 Emitter 契约在发布 core 5.4.0、工作区和三格式候选上通过。统一 yarn test:unit/test 与 CI 入口已接入,见 [ENG-03](changes/2026-09-10-ENG-03-unit-entry.md)。当前 214 项,28 完成、186 待办;生产源码 TS 迁移仍为零。ENG-06 提交 b53461da,本任务独立提交,下一项 ENG-05 浏览器自动化。
+5 -2
View File
@@ -532,11 +532,14 @@
"BASE-04",
"BASE-08"
],
"status": "todo",
"status": "done",
"risk": "M",
"deliverable": "Playwright projects、本地 Range/失败媒体服务;复用 docs 页面/样本的状态隔离、错误采集与候选资源映射",
"acceptance": "Chromium/Firefox/WebKit 的基础播放 smoke 和报告可执行;以媒体状态断言判定通过,区分轻量用例与真实编辑器交互",
"evidence": []
"evidence": [
"changes/2026-09-10-ENG-05-browser-tests.md",
"baselines/browser-validation.json"
]
},
{
"id": "ENG-06",