From 814bdc11db3eac7c104343bf11d05b498e0126a8 Mon Sep 17 00:00:00 2001 From: Harvey Zhao Date: Mon, 14 Sep 2026 03:27:49 +0800 Subject: [PATCH] test(jassub): [PKG-JASSUB-09] verify composited subtitle screenshots --- package.json | 1 + .../baselines/jassub-display-validation.json | 5317 +++++++++++++++++ .../2026-09-14-PKG-JASSUB-09-display.md | 63 + refactor/plan.md | 2 +- refactor/progress.md | 14 + refactor/risks.json | 2 + refactor/tasks.json | 5 +- refactor/toolchain-setup.md | 4 + test/browser/README.md | 12 + test/browser/jassub-display.js | 34 + test/browser/jassub-native.spec.js | 64 +- yarn.lock | 5 + 12 files changed, 5509 insertions(+), 14 deletions(-) create mode 100644 refactor/baselines/jassub-display-validation.json create mode 100644 refactor/changes/2026-09-14-PKG-JASSUB-09-display.md create mode 100644 test/browser/jassub-display.js diff --git a/package.json b/package.json index 3a4eff9c4..781ef1f63 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,7 @@ "lerna": "8.2.4", "less": "4.5.1", "linkedom": "0.18.13", + "pngjs": "7.0.0", "prompts": "2.4.2", "semver": "7.7.4", "servor": "4.0.2", diff --git a/refactor/baselines/jassub-display-validation.json b/refactor/baselines/jassub-display-validation.json new file mode 100644 index 000000000..e802f9d1e --- /dev/null +++ b/refactor/baselines/jassub-display-validation.json @@ -0,0 +1,5317 @@ +{ + "task": "PKG-JASSUB-09", + "status": "doing", + "baselineCommit": "7ef605fba7e7009b4838ecf391969b17fd0e1315", + "productionChanges": false, + "node": "24.21.0", + "yarn": "1.22.22", + "dependency": { + "name": "pngjs", + "version": "7.0.0", + "scope": "root devDependency", + "purpose": "Node-side decoding of composited Playwright PNGs", + "runtimeDependencies": {} + }, + "checks": [ + "Yarn add --dev --exact --ignore-workspace-root-check pngjs@7.0.0", + "Yarn install --frozen-lockfile --non-interactive (existing workspace, not a clean installation)", + "Yarn check:toolchain --strict: 28 tools / 1394 selectors", + "ESLint native spec and display helper: passed", + "Node test/toolchain.test.js: 1 passed" + ], + "limitation": "Diagnostic screenshot mode is opt-in; canonical readback remains. Earlier red runs and the WebKit short-window flaw are retained, not waived. The final screenshot run proves its selected fixture/capability paths only, not a production fix or complete JASSUB acceptance. Automatic failure screenshots after cleanup are not pre-destroy playback evidence. Final source hashes do not describe intermediate spec versions. Named PNG bytes and raw reports remain local, their identities are retained here.", + "currentFiles": [ + { + "path": "package.json", + "sha256": "88e9a073965e77cabacfe50a918f10626ba2dec5dba6be1a16ba080e0fab454b" + }, + { + "path": "yarn.lock", + "sha256": "1aee91387e21b01515447bd21cdbf18d57e55d6449eee8abaf4ab27397aaa667" + }, + { + "path": "test/browser/jassub-native.spec.js", + "sha256": "3198fb4314a8ac3d379beb027aed79103905f23ab615d7e54a368c7a6763e105" + }, + { + "path": "test/browser/jassub-display.js", + "sha256": "8b63c5b519c2efbe16c290c288fdf323268b8aa3267e2b48ca643dffafb81db3" + }, + { + "path": "packages/artplayer-plugin-jassub/src/jassub.es.js", + "sha256": "60590f2fca6ffded74f96f8a6001a86c32eb38f5e1fae26338cbbb43e93fb70a" + }, + { + "path": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + } + ], + "reports": [ + { + "profile": "Initial green screenshot mode; short cue windows; incorrect baseline-white ASS hash/limitation in original report", + "reportPath": "refactor/.cache/jassub09-firefox-display.json", + "sha256": "2345a2b0e2d1b5fd95eb83f94c478206c82405c895e8db64c07ffb1b6e287024", + "resultsPath": "refactor/.cache/jassub09-firefox-display-results", + "stats": { + "startTime": "2026-09-13T19:17:14.163Z", + "duration": 43165.816999999995, + "expected": 2, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "cases": [ + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "failed", + "duration": 19620, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.650326, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 90, + "droppedFrames": 0, + "mozPresentedFrames": 90 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.248798, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 173, + "droppedFrames": 0, + "mozPresentedFrames": 173 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 158, + "delivered": 157, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 18214.64, + "height": 720, + "mediaTime": 23.36, + "presentationTime": 18214.64, + "presentedFrames": 532, + "width": 1280 + } + }, + "lastPixel": { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.248798, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 173, + "droppedFrames": 0, + "mozPresentedFrames": 173 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + "errors": [ + "Error: Timeout 7000ms exceeded while waiting on the predicate\n\n 192 | window.art.fullscreenWeb = true\n 193 | })\n> 194 | await expect.poll(async () => (await pixels(page)).cssWidth).toBeGreaterThan(before.cssWidth)\n | ^\n 195 | await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100)\n 196 | await pixels(page, 'fullscreen')\n 197 | if (screenshotReadback) {\n at D:\\github\\ArtPlayer\\test\\browser\\jassub-native.spec.js:194:68" + ], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "c1c70e3a349c57afab4f489e3d52544b98c4b2af236a29943bfae0f937d749d6", + "bytes": 26649 + }, + { + "name": "jassub-display-after-seek", + "sha256": "b96fe4f1d87fd4587f97a8242bbcf1a99df044f8894851e912670dd2a4435d55", + "bytes": 228999 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 9605, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.644191, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 90, + "droppedFrames": 0, + "mozPresentedFrames": 90 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.274188, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 174, + "droppedFrames": 0, + "mozPresentedFrames": 174 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.521551, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 180, + "droppedFrames": 0, + "mozPresentedFrames": 180 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602952, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602952, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 158, + "delivered": 157, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8385.1, + "height": 720, + "mediaTime": 13.6, + "presentationTime": 8385.1, + "presentedFrames": 287, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602952, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "c1c70e3a349c57afab4f489e3d52544b98c4b2af236a29943bfae0f937d749d6", + "bytes": 26649 + }, + { + "name": "jassub-display-after-seek", + "sha256": "b96fe4f1d87fd4587f97a8242bbcf1a99df044f8894851e912670dd2a4435d55", + "bytes": 228999 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "5fe9f99c505942ff6b5a73703b5f33a0943101466457db046ff50f70e0405cea", + "bytes": 588910 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "2d198838e78b2add051d427103fcb5e1f4b65e36cd18d09d6aa4287f7f97d41b", + "bytes": 569334 + }, + { + "name": "jassub-display-restored", + "sha256": "730685de35f722dfa661e101d07e037d10c67692565e94ec21daa61b0e0b8f02", + "bytes": 591920 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8593, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.358781, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 83, + "droppedFrames": 0, + "mozPresentedFrames": 83 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.246703, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 166, + "droppedFrames": 0, + "mozPresentedFrames": 166 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.610195, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 175, + "droppedFrames": 0, + "mozPresentedFrames": 175 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.69069, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.69069, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 166, + "delivered": 165, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 7942.16, + "height": 720, + "mediaTime": 13.68, + "presentationTime": 7925.5, + "presentedFrames": 275, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.69069, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "57e0ab0c8bc3cad61c5cb90474a5cfdf3bd8fa2d0046f4def3cf173c234c434f", + "bytes": 26661 + }, + { + "name": "jassub-display-after-seek", + "sha256": "d9268d84f12086f1fb9513cdeea91f00d150f72123e50ef39cd39d3bc0920958", + "bytes": 229344 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "f2b9457c53572ba11736323914ae2cc063feec627582d9906b43af4c0065f6eb", + "bytes": 589086 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "57c66260e377f68569f6025ff3916f48b38521c0e4c6f9aa408a0ce982cef6b1", + "bytes": 570044 + }, + { + "name": "jassub-display-restored", + "sha256": "55e89de57944a92f0b94944ec531aa5c0fd8d46cbcd4f326086ac42cc83b51f1", + "bytes": 592621 + } + ], + "attemptErrors": [] + } + ] + }, + { + "profile": "Added screenshot timing/operation errors; short windows; original report still used baseline-white ASS hash/limitation", + "reportPath": "refactor/.cache/jassub09-firefox-display-observed.json", + "sha256": "7b1c0f19dc0f3f686b804ab5014e0d595dc274176f5e5acae2ae7cfbc3b772d6", + "resultsPath": "refactor/.cache/jassub09-firefox-display-observed-results", + "stats": { + "startTime": "2026-09-13T19:19:06.304Z", + "duration": 33845.081999999995, + "expected": 2, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "cases": [ + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 9599, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.582906, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 89, + "droppedFrames": 0, + "mozPresentedFrames": 89 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 32, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.24094, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 172, + "droppedFrames": 0, + "mozPresentedFrames": 172 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 34, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.524122, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 79, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.604586, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 73, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.604586, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 79, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 157, + "delivered": 156, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8418.12, + "height": 720, + "mediaTime": 13.6, + "presentationTime": 8418.12, + "presentedFrames": 286, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.604586, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 79, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "9cb38aacfe45ed5855ba6ef1518adf1ac029d55d95041432d7e505e37fa75693", + "bytes": 26663 + }, + { + "name": "jassub-display-after-seek", + "sha256": "b96fe4f1d87fd4587f97a8242bbcf1a99df044f8894851e912670dd2a4435d55", + "bytes": 228999 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "5fe9f99c505942ff6b5a73703b5f33a0943101466457db046ff50f70e0405cea", + "bytes": 588910 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "2d198838e78b2add051d427103fcb5e1f4b65e36cd18d09d6aa4287f7f97d41b", + "bytes": 569334 + }, + { + "name": "jassub-display-restored", + "sha256": "30f142569045c947a36ddf7e266407c8ee543810616b9b606f51b4f1106884bf", + "bytes": 591803 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8797, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.574806, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 88, + "droppedFrames": 0, + "mozPresentedFrames": 88 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1018, + "signature": 842894512, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 29, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.200463, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 171, + "droppedFrames": 0, + "mozPresentedFrames": 171 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 34, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.605907, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 71, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.68764, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 184, + "droppedFrames": 0, + "mozPresentedFrames": 184 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 61, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.68764, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 184, + "droppedFrames": 0, + "mozPresentedFrames": 184 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 160, + "delivered": 159, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8167.12, + "height": 720, + "mediaTime": 13.68, + "presentationTime": 8167.12, + "presentedFrames": 287, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.68764, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 184, + "droppedFrames": 0, + "mozPresentedFrames": 184 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "39f740c0ff36f25d7e0c691c1e4e5a537943c38ac4ee4f4909075a27844aae75", + "bytes": 27425 + }, + { + "name": "jassub-display-after-seek", + "sha256": "d9268d84f12086f1fb9513cdeea91f00d150f72123e50ef39cd39d3bc0920958", + "bytes": 229344 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "0b9358c79b0c50fb8b536d76d0f20f9ebb49a93c9cd96d66da6ea13ec75689a2", + "bytes": 589077 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "8ede63ee8d1f25cbddd2dc70af5967326d0c6484004b61d8072d3a39195511cc", + "bytes": 570046 + }, + { + "name": "jassub-display-restored", + "sha256": "4e3e7f6ce02b755c2848535078dc2a3dddd4a95fb056651451a4fe3f6ebc5e12", + "bytes": 592664 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "failed", + "duration": 11524, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [], + "frames": { + "before": "function", + "registered": 3, + "delivered": 2, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 922.1, + "height": 720, + "mediaTime": 0.48, + "presentationTime": 905.42, + "presentedFrames": 13, + "width": 1280 + } + }, + "errors": [ + "Error: Timeout 7000ms exceeded while waiting on the predicate\n\n 175 | expect(offscreen.selected).toBe(defaultOffscreen && !customCanvas && offscreen.available)\n 176 | await page.locator('#play').click()\n> 177 | await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100)\n | ^\n 178 | const before = await pixels(page, 'before-seek')\n 179 | expect(before.connected).toBe(true)\n 180 | await page.locator('#pause').click()\n at D:\\github\\ArtPlayer\\test\\browser\\jassub-native.spec.js:177:67" + ], + "screenshots": [], + "attemptErrors": [] + } + ] + }, + { + "profile": "Added complete attempt error attachments; short windows; original report still used baseline-white ASS hash/limitation", + "reportPath": "refactor/.cache/jassub09-firefox-display-errors.json", + "sha256": "bd0766ef47a7f881adecdb8cf0c8c151befcf5a5e29ccab07b28743fa680375a", + "resultsPath": "refactor/.cache/jassub09-firefox-display-errors-results", + "stats": { + "startTime": "2026-09-13T19:20:22.823Z", + "duration": 30560.77, + "expected": 3, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 9732, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.603481, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 89, + "droppedFrames": 0, + "mozPresentedFrames": 89 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 34, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.23443, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 173, + "droppedFrames": 0, + "mozPresentedFrames": 173 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 33, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.481224, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 86, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602852, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 77, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602852, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 80, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 158, + "delivered": 157, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8467.64, + "height": 720, + "mediaTime": 13.6, + "presentationTime": 8467.64, + "presentedFrames": 287, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.602852, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 182, + "droppedFrames": 0, + "mozPresentedFrames": 182 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 80, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "c1c70e3a349c57afab4f489e3d52544b98c4b2af236a29943bfae0f937d749d6", + "bytes": 26649 + }, + { + "name": "jassub-display-after-seek", + "sha256": "d9268d84f12086f1fb9513cdeea91f00d150f72123e50ef39cd39d3bc0920958", + "bytes": 229344 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "5fe9f99c505942ff6b5a73703b5f33a0943101466457db046ff50f70e0405cea", + "bytes": 588910 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "2d198838e78b2add051d427103fcb5e1f4b65e36cd18d09d6aa4287f7f97d41b", + "bytes": 569334 + }, + { + "name": "jassub-display-restored", + "sha256": "30f142569045c947a36ddf7e266407c8ee543810616b9b606f51b4f1106884bf", + "bytes": 591803 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8679, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.593802, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 89, + "droppedFrames": 0, + "mozPresentedFrames": 89 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 35, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.235217, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 173, + "droppedFrames": 0, + "mozPresentedFrames": 173 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 35, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.482202, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7119, + "signature": 1900259656, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 70, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.563306, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 62, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.563306, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 68, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 157, + "delivered": 156, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8070.96, + "height": 720, + "mediaTime": 13.56, + "presentationTime": 8070.96, + "presentedFrames": 286, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.563306, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 181, + "droppedFrames": 0, + "mozPresentedFrames": 181 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 68, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "c1c70e3a349c57afab4f489e3d52544b98c4b2af236a29943bfae0f937d749d6", + "bytes": 26649 + }, + { + "name": "jassub-display-after-seek", + "sha256": "d9268d84f12086f1fb9513cdeea91f00d150f72123e50ef39cd39d3bc0920958", + "bytes": 229344 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "bc3f3b4cfb51688488598407d3b9cc0626bd71f2a9813dfe3da344fdcd14081b", + "bytes": 587128 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "3afd1bb8091f4a07779d119af706ea0eb720ba5d59fbd35cd45ea339222342ea", + "bytes": 568699 + }, + { + "name": "jassub-display-restored", + "sha256": "0c6852a139c3fc3cd215da98d455910ac9e4020bc9d4c1b105d1583b2a1d8e8f", + "bytes": 591242 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8665, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "12994d1b6a07c45fd9776cb8709afc37725a8003bd90e4e829b7cc44fbadc0ec", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.603969, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 89, + "droppedFrames": 0, + "mozPresentedFrames": 89 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 28, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.202683, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 171, + "droppedFrames": 0, + "mozPresentedFrames": 171 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 37, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.48489, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 71, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.567798, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 180, + "droppedFrames": 0, + "mozPresentedFrames": 180 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 65, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.567798, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 180, + "droppedFrames": 0, + "mozPresentedFrames": 180 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 151, + "delivered": 150, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8063.4, + "height": 720, + "mediaTime": 13.56, + "presentationTime": 8063.4, + "presentedFrames": 284, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.567798, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 180, + "droppedFrames": 0, + "mozPresentedFrames": 180 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1909994892, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "9cb38aacfe45ed5855ba6ef1518adf1ac029d55d95041432d7e505e37fa75693", + "bytes": 26663 + }, + { + "name": "jassub-display-after-seek", + "sha256": "d9268d84f12086f1fb9513cdeea91f00d150f72123e50ef39cd39d3bc0920958", + "bytes": 229344 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "57314a6566ade06a97501ecbbcae778bce392f01dec113d2cdb822bd9b978c6e", + "bytes": 588594 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "2919c127f041d9f3e19ab65c210c3db920653635e33b9b43ae77ab909de5b9be", + "bytes": 568711 + }, + { + "name": "jassub-display-restored", + "sha256": "fc4c3b4178ed9ef28e4aa83345ff8df399c43cc26baece7e172d82a5f1e6bc61", + "bytes": 591300 + } + ], + "attemptErrors": [] + } + ] + }, + { + "profile": "Chromium/WebKit short cue windows; metadata corrected; WebKit initial capture could be empty or already the second cue", + "reportPath": "refactor/.cache/jassub09-display-other-engines.json", + "sha256": "aae18d9e9b1bbc43d1bfca36b39283b17bcf7ef27f6ab9f54fe5c4e6be196995", + "resultsPath": "refactor/.cache/jassub09-display-other-engines-results", + "stats": { + "startTime": "2026-09-13T19:21:36.909Z", + "duration": 68959.875, + "expected": 4, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "cases": [ + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 9173, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.594855, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 93, + "droppedFrames": 0, + "decodedFrames": 93 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 42, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.461436, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 307, + "droppedFrames": 0, + "decodedFrames": 307 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 75, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.038394, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 321, + "droppedFrames": 0, + "decodedFrames": 321 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 128, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.182993, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 325, + "droppedFrames": 0, + "decodedFrames": 325 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 138, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.182993, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 325, + "droppedFrames": 0, + "decodedFrames": 325 + }, + "onDemand": true, + "phase": "restored", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 127, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 190, + "delivered": 189, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8417.8, + "height": 720, + "mediaTime": 14.16, + "presentationTime": 8402, + "presentedFrames": 197, + "processingDuration": 0.0507, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.182993, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 325, + "droppedFrames": 0, + "decodedFrames": 325 + }, + "onDemand": true, + "phase": "restored", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 127, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "664d33bbe6ff35c6d8977080653e7ecd2b961a0980f0164bdf4a0fb32fbb1e9a", + "bytes": 20850 + }, + { + "name": "jassub-display-after-seek", + "sha256": "746daea2c5bb64da112c89714824a8b904f464d50ec8949804f70cbdcef35559", + "bytes": 171883 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "1aa599747c3ddb668cc6883c2bef2fc9f93ec77161b9112ed7622fea9655818b", + "bytes": 433499 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "3886b002292d256bf63ea1c4b4159169ba2b55963b75c1697ab92b198957fe79", + "bytes": 417839 + }, + { + "name": "jassub-display-restored", + "sha256": "4c61ad316779dd5dc1aa02a0aa892fe62d02348bf259e77b6d2aac898054fa02", + "bytes": 436111 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 8867, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.586952, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 93, + "droppedFrames": 0, + "decodedFrames": 93 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 53, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.418583, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 306, + "droppedFrames": 0, + "decodedFrames": 306 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 77, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.802132, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 315, + "droppedFrames": 0, + "decodedFrames": 315 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 135, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.958987, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 319, + "droppedFrames": 0, + "decodedFrames": 319 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 123, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.958987, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 319, + "droppedFrames": 0, + "decodedFrames": 319 + }, + "onDemand": true, + "phase": "restored", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 135, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 185, + "delivered": 184, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8194, + "height": 720, + "mediaTime": 13.96, + "presentationTime": 8178.2, + "presentedFrames": 192, + "processingDuration": 0.0485, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.958987, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 319, + "droppedFrames": 0, + "decodedFrames": 319 + }, + "onDemand": true, + "phase": "restored", + "visible": 7120, + "signature": 1903585488, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 135, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "664d33bbe6ff35c6d8977080653e7ecd2b961a0980f0164bdf4a0fb32fbb1e9a", + "bytes": 20850 + }, + { + "name": "jassub-display-after-seek", + "sha256": "746daea2c5bb64da112c89714824a8b904f464d50ec8949804f70cbdcef35559", + "bytes": 171883 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "eee8ed83d1451b2d2d437439f6392dca0914d6d6bb99863458fc6d5ec8ec0d60", + "bytes": 433530 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "9aaca111bd10f5715925bd81034fafb9176f3776d8cab73aa76dac8889a214c7", + "bytes": 415819 + }, + { + "name": "jassub-display-restored", + "sha256": "363d620e77b781fcaeeef51a8c23a707fa953253a82cc7c5e426286719e8c980", + "bytes": 435481 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 9008, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.553176, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 92, + "droppedFrames": 0, + "decodedFrames": 92 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 52, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.41916, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 306, + "droppedFrames": 0, + "decodedFrames": 306 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 75, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 13.975889, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 320, + "droppedFrames": 0, + "decodedFrames": 320 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 7122, + "signature": 1910063588, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 122, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.116325, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 129, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.116325, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1910063588, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 139, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 188, + "delivered": 187, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8318.9, + "height": 720, + "mediaTime": 14.12, + "presentationTime": 8303.7, + "presentedFrames": 195, + "processingDuration": 0.0337, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.116325, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "restored", + "visible": 7122, + "signature": 1910063588, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 139, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "8a513bca933e6cd9cbd3915aa9bc2a490d6aba9961238ed179f76f2970f92d8f", + "bytes": 20832 + }, + { + "name": "jassub-display-after-seek", + "sha256": "746daea2c5bb64da112c89714824a8b904f464d50ec8949804f70cbdcef35559", + "bytes": 171883 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "e753963dd147b6b3b88da48ee2e14dd1508525dedf203537c23f27a3290aaddc", + "bytes": 433663 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "07f39bf85a1e4330bfdd0c31df9ba1751adb444299d9e7cc992cdeb4ec3fb320", + "bytes": 417889 + }, + { + "name": "jassub-display-restored", + "sha256": "2af4ad4d156c240a018cfb76d177c1ccfec56c7ac3c17695fd3924d75f2c33a2", + "bytes": 436264 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "failed", + "duration": 11852, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 5.3892925, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 108, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.180938, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 163, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 125, + "delivered": 124, + "after": "function", + "lastMetadata": { + "presentationTime": 11179, + "expectedDisplayTime": 11212, + "width": 640, + "height": 360, + "mediaTime": 13.3782506, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.180938, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 163, + "observation": "composited-png" + }, + "errors": [ + "Error: expect(received).not.toBe(expected) // Object.is equality\n\nExpected: not 3637463172\n\n 195 | const after = await pixels(page, 'after-seek')\n 196 | expect(after.time).toBeGreaterThanOrEqual(10)\n> 197 | expect(after.signature).not.toBe(before.signature)\n | ^\n 198 | await page.evaluate(() => {\n 199 | window.art.fullscreenWeb = true\n 200 | })\n at D:\\github\\ArtPlayer\\test\\browser\\jassub-native.spec.js:197:35" + ], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "f03181b04cf2427c7142f5326486cb727933602fc1683d434449f73c025a0b75", + "bytes": 131042 + }, + { + "name": "jassub-display-after-seek", + "sha256": "0bbc622d7c94114defd009640caadb9d38597aae701c183fcebd4e3d3372c32a", + "bytes": 472056 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "passed", + "duration": 14081, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 4.145959, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 100, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.231438, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 162, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 14.8457508, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 30295, + "signature": 2705561028, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 480, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 15.3447717, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 478, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 15.3447717, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 30295, + "signature": 2705561028, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 453, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 121, + "delivered": 120, + "after": "function", + "lastMetadata": { + "presentationTime": 12044, + "expectedDisplayTime": 12383, + "width": 640, + "height": 360, + "mediaTime": 15.3447717, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 15.3447717, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 30295, + "signature": 2705561028, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 453, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "271f70dc13f93616f5ae0c9318908cecc144f9631fa3a626f8f8356bc7897958", + "bytes": 43522 + }, + { + "name": "jassub-display-after-seek", + "sha256": "fee35c80256ad04d4f772e498b46542dae345db823dee431b6dfbcc9396488f4", + "bytes": 471887 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "3287ed097ce6c83bbd8277304143c1efa26c58b0d3b64e53ee4fbe775409405e", + "bytes": 1300468 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "94b76cd917355fb4d221a853c6409df7f3fc16354395a0a6e940f0d3c7573ab5", + "bytes": 1281566 + }, + { + "name": "jassub-display-restored", + "sha256": "53a0e7c6e096bad0bf447801d12a41ac2f5e34ca8393e9e843416765fea2a395", + "bytes": 1294363 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "failed", + "duration": 11642, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "f1bccac9797b459eba39875e7fa0f91c8453f3d83c7dd19893513736fea9dcba", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 5.4120634, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 102, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.0578755, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 159, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 119, + "delivered": 118, + "after": "function", + "lastMetadata": { + "presentationTime": 10959, + "expectedDisplayTime": 11098, + "width": 640, + "height": 360, + "mediaTime": 13.1895422, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 13.0578755, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 159, + "observation": "composited-png" + }, + "errors": [ + "Error: expect(received).not.toBe(expected) // Object.is equality\n\nExpected: not 3637463172\n\n 195 | const after = await pixels(page, 'after-seek')\n 196 | expect(after.time).toBeGreaterThanOrEqual(10)\n> 197 | expect(after.signature).not.toBe(before.signature)\n | ^\n 198 | await page.evaluate(() => {\n 199 | window.art.fullscreenWeb = true\n 200 | })\n at D:\\github\\ArtPlayer\\test\\browser\\jassub-native.spec.js:197:35" + ], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "d7d03ab758b038f0177f22ecc1e4f92abcc560b692987012293927e48e18fc05", + "bytes": 213865 + }, + { + "name": "jassub-display-after-seek", + "sha256": "7be26a82ab55777f0b1e1eac652de6dfedc43636d0d028bff4a579837184bf79", + "bytes": 471942 + } + ], + "attemptErrors": [] + } + ] + }, + { + "profile": "Final screenshot-specific 0-30s and 40-110s cues; seek50; asserts initial cue interval and pixels; no timeout increase", + "reportPath": "refactor/.cache/jassub09-display-final.json", + "sha256": "6c0b83d1d0f5672c9fb43d53c113432a08077fe0c01e057a408f08ad18c304db", + "resultsPath": "refactor/.cache/jassub09-display-final-results", + "stats": { + "startTime": "2026-09-13T19:24:05.556Z", + "duration": 101412.722, + "expected": 9, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 9055, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.581166, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 93, + "droppedFrames": 0, + "decodedFrames": 93 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 40, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.423873, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 282, + "droppedFrames": 0, + "decodedFrames": 282 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 70, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.975709, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 296, + "droppedFrames": 0, + "decodedFrames": 296 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6597, + "signature": 161483676, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 115, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.107292, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 299, + "droppedFrames": 0, + "decodedFrames": 299 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 119, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.107292, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 299, + "droppedFrames": 0, + "decodedFrames": 299 + }, + "onDemand": true, + "phase": "restored", + "visible": 6597, + "signature": 161483676, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 114, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 189, + "delivered": 188, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8370.4, + "height": 720, + "mediaTime": 54.12, + "presentationTime": 8354.1, + "presentedFrames": 196, + "processingDuration": 0.1999, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.107292, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 299, + "droppedFrames": 0, + "decodedFrames": 299 + }, + "onDemand": true, + "phase": "restored", + "visible": 6597, + "signature": 161483676, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 114, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "8a513bca933e6cd9cbd3915aa9bc2a490d6aba9961238ed179f76f2970f92d8f", + "bytes": 20832 + }, + { + "name": "jassub-display-after-seek", + "sha256": "6f2ef853233ed8cd2af29bc6ecc4bb0b9b503c128371461dcce111f5a0656f12", + "bytes": 161709 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "9a2c92fcb06e97c065209fc90ad57647525d44b2880eae2091479dc173ec260d", + "bytes": 383710 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "544d4be74b244b233f919a12a415bb721e1179ac2b0e34a8573d8f8bbfbc5248", + "bytes": 363588 + }, + { + "name": "jassub-display-restored", + "sha256": "b7cb6ce8024bed9e7a147da6fce38805207124512af37c9f14071d0dad47e56d", + "bytes": 383483 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 8820, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.611175, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 94, + "droppedFrames": 0, + "decodedFrames": 94 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 43, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.42054, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 283, + "droppedFrames": 0, + "decodedFrames": 283 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 73, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.800143, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 292, + "droppedFrames": 0, + "decodedFrames": 292 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6055, + "signature": 2649510240, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 132, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.953134, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 296, + "droppedFrames": 0, + "decodedFrames": 296 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 120, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.953134, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 296, + "droppedFrames": 0, + "decodedFrames": 296 + }, + "onDemand": true, + "phase": "restored", + "visible": 6055, + "signature": 2649510240, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 113, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 185, + "delivered": 184, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8172.9, + "height": 720, + "mediaTime": 53.96, + "presentationTime": 8157, + "presentedFrames": 192, + "processingDuration": 0.1969, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.953134, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 296, + "droppedFrames": 0, + "decodedFrames": 296 + }, + "onDemand": true, + "phase": "restored", + "visible": 6055, + "signature": 2649510240, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 113, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "664d33bbe6ff35c6d8977080653e7ecd2b961a0980f0164bdf4a0fb32fbb1e9a", + "bytes": 20850 + }, + { + "name": "jassub-display-after-seek", + "sha256": "6f2ef853233ed8cd2af29bc6ecc4bb0b9b503c128371461dcce111f5a0656f12", + "bytes": 161709 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "fd26382e22be0e55d237171b1bf25b1651b6fb25d912f09f011bfabb57498036", + "bytes": 384150 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "69087ca1d5cdafc4f3c4405f2031cae859894fe658755cf2796ab2c5ab3bc086", + "bytes": 362027 + }, + { + "name": "jassub-display-restored", + "sha256": "f6ba81cfac0b7fc78d4ba8d907a1add6117883dd930106ce4f6d12c628ffeaa9", + "bytes": 380205 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "chromium", + "status": "passed", + "duration": 9923, + "browser": "153.0.8010.12", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 4.594488, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 118, + "droppedFrames": 0, + "decodedFrames": 118 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 41, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.396202, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 306, + "droppedFrames": 0, + "decodedFrames": 306 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 68, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.923175, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 320, + "droppedFrames": 0, + "decodedFrames": 320 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6599, + "signature": 167961776, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 123, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.062477, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 126, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.062477, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "restored", + "visible": 6599, + "signature": 167961776, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 115, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 213, + "delivered": 212, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 9279, + "height": 720, + "mediaTime": 54.08, + "presentationTime": 9262.8, + "presentedFrames": 220, + "processingDuration": 0.0475, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.062477, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 323, + "droppedFrames": 0, + "decodedFrames": 323 + }, + "onDemand": true, + "phase": "restored", + "visible": 6599, + "signature": 167961776, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 115, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "8ba81febfee2a53925a195ce023ca0b86ac87af8f7c938b8d68e98774c83538f", + "bytes": 17115 + }, + { + "name": "jassub-display-after-seek", + "sha256": "71f5aa1d5c95a53be03b2b0738c71b2a9a39421f949d5ff6d93251e4785579d1", + "bytes": 162003 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "c5d4180047220186de32893f1bf8cfc7170f177506150972d0580b8c560ab716", + "bytes": 377722 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "6cc6ea0ac3c680acd69038adc262e990782245592e530a26eeec76037f0497ec", + "bytes": 368368 + }, + { + "name": "jassub-display-restored", + "sha256": "b8afb8a8e24ea204a8fd6ec6f5e4392799798202d2309194241b53f5818fc723", + "bytes": 386661 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 9775, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.642548, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 90, + "droppedFrames": 0, + "mozPresentedFrames": 90 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 30, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.246443, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 175, + "droppedFrames": 0, + "mozPresentedFrames": 175 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 34, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.689996, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 185, + "droppedFrames": 0, + "mozPresentedFrames": 185 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6615, + "signature": 221220536, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 76, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.770899, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 187, + "droppedFrames": 0, + "mozPresentedFrames": 187 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.770899, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 187, + "droppedFrames": 0, + "mozPresentedFrames": 187 + }, + "onDemand": true, + "phase": "restored", + "visible": 6607, + "signature": 194556840, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 72, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 165, + "delivered": 164, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 8556.18, + "height": 720, + "mediaTime": 53.76, + "presentationTime": 8556.18, + "presentedFrames": 293, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.770899, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 187, + "droppedFrames": 0, + "mozPresentedFrames": 187 + }, + "onDemand": true, + "phase": "restored", + "visible": 6607, + "signature": 194556840, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 72, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "c1c70e3a349c57afab4f489e3d52544b98c4b2af236a29943bfae0f937d749d6", + "bytes": 26649 + }, + { + "name": "jassub-display-after-seek", + "sha256": "18a06091d5f1a9c55f854da8394eecc2eb0853566e8edda337e80594c34fd4e6", + "bytes": 217412 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "fa36347e0760fc6ec42d71132286ff84f6614bc1bc5a176124646abbb1040292", + "bytes": 541290 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "7efe1ff1a099f1edf0de0926dc67ce47539f6be1ba54a5787bcf4e4fe4c190fa", + "bytes": 513668 + }, + { + "name": "jassub-display-restored", + "sha256": "ab696ff7ab4d93f0eb216e82fe604053d2d001baabe8da94c9169c7f453e5902", + "bytes": 536502 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8508, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.368996, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 83, + "droppedFrames": 0, + "mozPresentedFrames": 83 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1028, + "signature": 851219992, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 27, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.222194, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 166, + "droppedFrames": 0, + "mozPresentedFrames": 166 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 31, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.585994, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 176, + "droppedFrames": 0, + "mozPresentedFrames": 176 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6615, + "signature": 221220536, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 79, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.70728, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 56, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.70728, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "restored", + "visible": 6611, + "signature": 207888696, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 158, + "delivered": 157, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 7949.64, + "height": 720, + "mediaTime": 53.72, + "presentationTime": 7932.98, + "presentedFrames": 277, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.70728, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 178, + "droppedFrames": 0, + "mozPresentedFrames": 178 + }, + "onDemand": true, + "phase": "restored", + "visible": 6611, + "signature": 207888696, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 69, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "cf0857e7840e476d2a0411ad77a6fe99273095d8f16dea93f9a0af892cda5d37", + "bytes": 26658 + }, + { + "name": "jassub-display-after-seek", + "sha256": "380510726ece09376b5faf3ac661758df12a62d3b2f35cde5bd68e4886b6baa6", + "bytes": 217356 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "d8c6dd9525523ad202f5d09b23bcd6c6b7b65c0502d768a77044111be7b8bf9a", + "bytes": 547303 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "186eaa67716464ee807b9aa69a9c4288d4c5214dc23864b4193eb95ad25117ef", + "bytes": 520972 + }, + { + "name": "jassub-display-restored", + "sha256": "7aa6bcb1efd407e531a46269d2f536b2daa2eb61a2b6b2d9e1154c2d4ea9dff6", + "bytes": 543902 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "firefox", + "status": "passed", + "duration": 8513, + "browser": "155.0", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": true, + "selected": true + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 3.539741, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 88, + "droppedFrames": 0, + "mozPresentedFrames": 88 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 1027, + "signature": 850394300, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 26, + "observation": "composited-png" + }, + { + "width": 640, + "height": 360, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.24975, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 171, + "droppedFrames": 0, + "mozPresentedFrames": 171 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 2342, + "signature": 1938468104, + "screenshotWidth": 640, + "screenshotHeight": 360, + "screenshotElapsed": 33, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.451874, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 177, + "droppedFrames": 0, + "mozPresentedFrames": 177 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 6633, + "signature": 280828012, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 70, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.573164, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 60, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.573164, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "restored", + "visible": 6615, + "signature": 221220536, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 68, + "observation": "composited-png" + } + ], + "frames": { + "before": "function", + "registered": 158, + "delivered": 157, + "after": "function", + "lastMetadata": { + "expectedDisplayTime": 7906.56, + "height": 720, + "mediaTime": 53.56, + "presentationTime": 7889.88, + "presentedFrames": 282, + "width": 1280 + } + }, + "lastPixel": { + "width": 1280, + "height": 720, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 53.573164, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 179, + "droppedFrames": 0, + "mozPresentedFrames": 179 + }, + "onDemand": true, + "phase": "restored", + "visible": 6615, + "signature": 221220536, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 68, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "b2f4b840ba5e779edba0588678bc1375e0d18a4d72d51696acf135b67e8d9668", + "bytes": 27274 + }, + { + "name": "jassub-display-after-seek", + "sha256": "33afeefd99e079e2639837386e98c97083c67fce97735a8fe3b4b2fcb123ba27", + "bytes": 217259 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "18ebca3b42757fc126b841c1acc2e7788754ffa2a061ec626e083c4c120345f3", + "bytes": 549953 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "6a5fc65c423f55867ddf31a7dc8fca4ef298f964ca31faf860d767be4c79e510", + "bytes": 528838 + }, + { + "name": "jassub-display-restored", + "sha256": "3940dc69b7620c0e4afcac482e7c4f835ab6c8bef7b4ce236f20c67140186d40", + "bytes": 551355 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with candidate core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "passed", + "duration": 13904, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 4.1812715, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 4369, + "signature": 1588904296, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 81, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.2288547, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 130, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.4622925, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 27951, + "signature": 1535513192, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 471, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9518342, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 493, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9518342, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 437, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 115, + "delivered": 114, + "after": "function", + "lastMetadata": { + "presentationTime": 11821, + "expectedDisplayTime": 12161, + "width": 640, + "height": 360, + "mediaTime": 54.9518342, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9518342, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 437, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "0153d1d577015dce2964e2d215d2369097e18cf86a88ffde8a9d52c5aa80b5a3", + "bytes": 51584 + }, + { + "name": "jassub-display-after-seek", + "sha256": "53d6fd712b648176c3735d1c1c03f552a6e89e68aa25950613da5020fcd992ec", + "bytes": 432628 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "620e53c4c0e4e237f0a66e10989bb345b50f35dc1afb0e3eff9a218931e72a55", + "bytes": 1161255 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "3788c302d679a2b58079d20238aba2f6c0d7d9f2073d968617764e2f930acfc0", + "bytes": 1144616 + }, + { + "name": "jassub-display-restored", + "sha256": "28d15ee87bd2f7da76db28eb2532ea91d5be2406759ed1698cbe512404b842b8", + "bytes": 1180798 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "passed", + "duration": 14314, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 4.2338132, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 4369, + "signature": 1588904296, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 109, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.2135422, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 159, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.7810216, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 27903, + "signature": 895562312, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 483, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 55.2927093, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 482, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 55.2927093, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 459, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 119, + "delivered": 118, + "after": "function", + "lastMetadata": { + "presentationTime": 12294, + "expectedDisplayTime": 12635, + "width": 640, + "height": 360, + "mediaTime": 55.2927093, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 55.2927093, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 459, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "814ff8dfd73108ca2fc3b404e4f50147a191a4257917bdc396e28651c4603c67", + "bytes": 51348 + }, + { + "name": "jassub-display-after-seek", + "sha256": "53d6fd712b648176c3735d1c1c03f552a6e89e68aa25950613da5020fcd992ec", + "bytes": 432628 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "c97a620fba6ce7d3b900b8af3273449446d56da7612f7dcb7a49d5a59a8c33ec", + "bytes": 1168731 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "19e9ca490e96cc495b96b14aa7911eedd7a7d31c24b92375b5be320bc06ba55f", + "bytes": 1146721 + }, + { + "name": "jassub-display-restored", + "sha256": "698afe1cce7fc91a7ca4699182d39669a61381273357cc520d1d4e4b2cd34b9a", + "bytes": 1182649 + } + ], + "attemptErrors": [] + }, + { + "title": "JASSUB candidate artifact renders actual WASM subtitles through seek and layout with published-5.3.1-beta.1 core, customCanvas=false, defaultOffscreen=true", + "project": "webkit", + "status": "passed", + "duration": 13765, + "browser": "26.6", + "platform": "win32", + "source": { + "artifact": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js", + "sha256": "fb8cd8b7b6fb57a7866f929cfe20f7f582c86af96101f23c572dd79b4912dc9f" + }, + "subtitleSha256": "dd882fd3fe1914a3ba4260694360f223b3d74f75e360216221aa1f229ba54e7a", + "offscreen": { + "available": false, + "selected": false + }, + "screenshotReadback": true, + "snapshots": [ + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 4.0846257, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "before-seek", + "visible": 4369, + "signature": 1588904296, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 92, + "observation": "composited-png" + }, + { + "width": 1280, + "height": 720, + "cssWidth": 640, + "cssHeight": 360, + "clip": { + "x": 8, + "y": 8, + "width": 640, + "height": 360 + }, + "time": 53.1336881, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "after-seek", + "visible": 10180, + "signature": 3637463172, + "screenshotWidth": 1280, + "screenshotHeight": 720, + "screenshotElapsed": 156, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.4217091, + "connected": true, + "media": { + "paused": false, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "fullscreen", + "visible": 27967, + "signature": 1748829896, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 452, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9010008, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "hidden-negative-control", + "visible": 0, + "signature": 0, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 460, + "observation": "composited-png" + }, + { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9010008, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 504, + "observation": "composited-png" + } + ], + "frames": { + "before": "undefined", + "registered": 113, + "delivered": 112, + "after": "function", + "lastMetadata": { + "presentationTime": 11393, + "expectedDisplayTime": 11469, + "width": 640, + "height": 360, + "mediaTime": 54.9010008, + "presentedFrames": 0, + "processingDuration": 0 + } + }, + "lastPixel": { + "width": 2560, + "height": 1440, + "cssWidth": 1280, + "cssHeight": 720, + "clip": { + "x": 0, + "y": 0, + "width": 1280, + "height": 720 + }, + "time": 54.9010008, + "connected": true, + "media": { + "paused": true, + "readyState": 4, + "totalFrames": 0, + "droppedFrames": 0, + "decodedFrames": 0 + }, + "onDemand": true, + "phase": "restored", + "visible": 27887, + "signature": 682245096, + "screenshotWidth": 2560, + "screenshotHeight": 1440, + "screenshotElapsed": 504, + "observation": "composited-png" + }, + "errors": [], + "screenshots": [ + { + "name": "jassub-display-before-seek", + "sha256": "cd952d56d6f8bfc41f26386a3467f32a82aa50085e34aeec22acf2d115a47aa9", + "bytes": 56907 + }, + { + "name": "jassub-display-after-seek", + "sha256": "63b4cd4e9d3907e989dfd5c929182eff58e91e11969b2d5a752b7eb003feead6", + "bytes": 433047 + }, + { + "name": "jassub-display-fullscreen", + "sha256": "e39bc98ae903ad8533043e200306c8da980e1c2a5f1061964d37300f08044d0d", + "bytes": 1160996 + }, + { + "name": "jassub-display-hidden-negative-control", + "sha256": "5094ee2c518e77cd497cfb40d1324e07e291aa14cc85b197b8dadc702a456e40", + "bytes": 1141600 + }, + { + "name": "jassub-display-restored", + "sha256": "ecad5630cfc9b2b1849102eeca11bf2ec9f59b1af50c9c1d83d238add7d67ce5", + "bytes": 1177477 + } + ], + "attemptErrors": [] + } + ] + } + ] +} diff --git a/refactor/changes/2026-09-14-PKG-JASSUB-09-display.md b/refactor/changes/2026-09-14-PKG-JASSUB-09-display.md new file mode 100644 index 000000000..7df1b566a --- /dev/null +++ b/refactor/changes/2026-09-14-PKG-JASSUB-09-display.md @@ -0,0 +1,63 @@ +# PKG-JASSUB-09 合成截图验证检查点 + +接续 `7ef605fba7e7009b4838ecf391969b17fd0e1315`,任务仍为 doing。前一轮原生 +ImageBitmap 控制把停顿定位到异步创建与显示读取相关路径;本轮补充完全不复制 +转移画布的实际合成截图,检查是否只是原来的 canvas readback 引入了问题。 + +## 实际改动 + +`test/browser/jassub-display.js` 只负责 Node 端 PNG 解码及绿色字形计数;浏览器 +继续实际播放并运行 JASSUB Worker/WASM。原有 `jassub-native.spec.js` 默认流程 +保留;显式 `ARTPLAYER_JASSUB_SCREENSHOT=true` 才走截图诊断。页面几何与媒体状态 +由单独函数读取,避免几何检查间接触发复制画布。 + +截图用例使用可识别的绿色 ASS 字形,并在全屏后隐藏字幕验证绿色像素归零, +恢复后再次验证可见,防止把视频背景或播放器 UI 误认作字幕。同时检查 seek +前后字形签名、播放时间前进、布局尺寸及原有销毁/资源边界。没有屏蔽 Worker +错误,没有把默认 asyncRender/offscreenRender 改成 false,没有修改生产源码。 + +新增根 devDependency `pngjs@7.0.0`,只用于 Node 测试截图解码;MIT、无运行时 +依赖,API 来源为 [上游文档](https://github.com/pngjs/pngjs#sync-api)。根 manifest +和唯一 yarn.lock 仅增加此项。Node 24.21.0 / Yarn 1.22.22 正常安装、随后 frozen +安装和严格工具链检查通过,未使用 ignore-scripts/ignore-engines。没有新增发布 +依赖、提高播放器浏览器语法目标或重建无变化的发布产物。 + +## 保留的中间结果 + +- 首轮 Firefox 截图:2 通过 / 1 全屏失败;直接截图也未保证消除停顿,不能声称 + 问题只由原先的 drawImage 复制造成。 +- 增加截图耗时/调用错误记录后:2 通过 / 1 首次像素失败;随后加入完整尝试错误 + 附件的版本三项通过。添加观测不是生产修复,成功重跑不关闭原风险。 +- Chromium/WebKit 首轮:4 通过 / 2 失败。两个 WebKit 失败时 before-seek 已到 + 5.389/5.412 秒,采样的已是后一条字幕;甚至通过的 WebKit before-seek 为 + 4.146 秒、像素为零。说明第一版截图用例的短字幕窗口不可靠,不能把这组失败 + 报成 WebKit 的字幕显示缺陷,也不能将那个通过样本作为完整前后字形证明。 +- 修正仅作用于截图模式:第一条 0-30 秒、第二条 40-110 秒,seek 50 秒;明确 + before.time < 30 且 before.visible > 100。原非截图模式保持原 ASS 和 seek 10 + 秒,expect/test 超时均未扩大。这样保留有限等待检查,同时不依赖截图在四秒内 + 完成所有前置动作。最终三浏览器 × 三核心九项通过;Chromium/Firefox 使用真实 + offscreen 能力,Windows WebKit 无 transfer,验证实际主线程 fallback。最终结果 + 见机器记录。 + +初版报告中的 limitation/subtitleSha256 尚沿用白色 ASS 文字;在最终测试中已 +改为实际选中字幕的 hash 和截图模式描述。机器记录明确区分中间证据,不把旧 +报告错误元数据当作实际输入身份。浏览器 fixture 自动失败截图发生在 finally +销毁之后,不能用空白页面推断销毁前的播放状态。命名阶段 PNG 在销毁前采集。 + +## 复跑与边界 + +```powershell +$env:ARTPLAYER_JASSUB_ARTIFACT = 'packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js' +$env:ARTPLAYER_JASSUB_OFFSCREEN = 'default' +$env:ARTPLAYER_JASSUB_SCREENSHOT = 'true' +yarn test:browser test/browser/jassub-native.spec.js --workers=1 +``` + +保留 `jassub-hybrid.spec.js` 和原 readback 红序列,不用截图模式替代全部兼容验收。 +每轮先归档共享 report/results。原始截图、trace、报告保存在 `.cache/`,提交的 +[摘要](../baselines/jassub-display-validation.json)保存参数、hash、结果、失败及 +阶段像素/媒体状态,不能替代所有物理设备和持续 GPU 使用证据。 + +本轮不关闭 JASSUB-FIREFOX-OFFSCREEN-01、09 或 05;不宣称整包、完整浏览器组合、 +npm 准入、远程 CI 或三轮发布复盘完成。回退本检查点恢复原测试与锁文件;没有 +生产实现需要回退,也没有 push/publish。 diff --git a/refactor/plan.md b/refactor/plan.md index 9e76cd9ec..d8e557b16 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -605,4 +605,4 @@ - PKG-DANMUKU-11: [记录](changes/2026-09-13-PKG-DANMUKU-11-visible-lifetime.md) [记录](baselines/danmuku-lifetime-validation.json) - PKG-DANMUKU-12: [记录](changes/2026-09-13-PKG-DANMUKU-12-frame-sampling.md) [记录](baselines/danmuku-frame-sampling-validation.json) - PKG-JASSUB-08: [记录](changes/2026-09-14-PKG-JASSUB-08-offscreen.md) [记录](baselines/jassub-offscreen-validation.json) [记录](baselines/jassub-offscreen-patch.json) -- PKG-JASSUB-09: [记录](changes/2026-09-14-PKG-JASSUB-09-hybrid.md) [记录](baselines/jassub-hybrid-validation.json) [记录](baselines/jassub-hybrid-patch.json) +- PKG-JASSUB-09: [记录](changes/2026-09-14-PKG-JASSUB-09-hybrid.md) [记录](baselines/jassub-hybrid-validation.json) [记录](baselines/jassub-hybrid-patch.json) [记录](changes/2026-09-14-PKG-JASSUB-09-firefox-diagnostics.md) [记录](changes/2026-09-14-PKG-JASSUB-09-display.md) [记录](baselines/jassub-display-validation.json) diff --git a/refactor/progress.md b/refactor/progress.md index 5f1856af3..7d62186f8 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,19 @@ # 进度与证据 +## PKG-JASSUB-09 合成截图验证(doing) + +新增显式截图模式,由 Node pngjs@7.0.0 解码实际页面 PNG,不复制转移画布。 +绿色 ASS 字形有 seek 前后签名、播放推进、全屏、隐藏归零和恢复可见断言。 +修正截图用例短字幕窗口导致 WebKit 前置样本过期的问题后,三浏览器与三核心 +最终九项通过。默认 readback 和其红序列保留;早期截图模式也出现 Firefox +首次像素/全屏失败,不能把本轮全绿解释成停顿已修复。09/05 继续 doing。 +根测试依赖与唯一 Yarn 锁同次更新,frozen 安装、严格工具链、相关 ESLint 和 +工具链反例测试通过。生产源码/公共类型/分发产物未变。 +[变更与中间失败](changes/2026-09-14-PKG-JASSUB-09-display.md)及 +[截图阶段和运行摘要](baselines/jassub-display-validation.json)记录实际覆盖。 +下一步保留 Firefox 未关闭风险继续取证,同时推进其他可独立完成的插件迁移和 +组合验收;本问题尚不足以阻止整项重构的其他实施工作。 + ## PKG-JASSUB-09 Firefox 原生绘制诊断(doing) 新增不加载 JASSUB 的 Worker/ImageBitmap 控制,按新核心、已发布核心及无脚本的 diff --git a/refactor/risks.json b/refactor/risks.json index d58471ced..c35188fbc 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -5652,6 +5652,8 @@ "refactor/baselines/jassub-hybrid-validation.json", "refactor/changes/2026-09-14-PKG-JASSUB-09-firefox-diagnostics.md", "refactor/baselines/jassub-firefox-diagnostics.json", + "refactor/changes/2026-09-14-PKG-JASSUB-09-display.md", + "refactor/baselines/jassub-display-validation.json", "test/browser/jassub-platform.spec.js", "test/browser/jassub-native.spec.js", "test/browser/jassub-hybrid.spec.js" diff --git a/refactor/tasks.json b/refactor/tasks.json index f583e8e00..38867af69 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -4809,7 +4809,10 @@ "evidence": [ "changes/2026-09-14-PKG-JASSUB-09-hybrid.md", "baselines/jassub-hybrid-validation.json", - "baselines/jassub-hybrid-patch.json" + "baselines/jassub-hybrid-patch.json", + "changes/2026-09-14-PKG-JASSUB-09-firefox-diagnostics.md", + "changes/2026-09-14-PKG-JASSUB-09-display.md", + "baselines/jassub-display-validation.json" ] } ] diff --git a/refactor/toolchain-setup.md b/refactor/toolchain-setup.md index 9129f2bd7..6e9a596f3 100644 --- a/refactor/toolchain-setup.md +++ b/refactor/toolchain-setup.md @@ -19,6 +19,10 @@ CORE-25 默认选项缺陷已修复并通过相同三 Node 与严格打包检查 ## 锁文件和依赖维护 - 根构建工具固定精确版本并放在 devDependencies;发布包的 dependencies/peer 范围保持原样。 +- PKG-JASSUB-09 新增根 devDependency `pngjs@7.0.0`,在 Node 中解码 Playwright 截图, + 用实际合成画面与转移画布 readback 对照;不进入发布包。仅新增其精确 Yarn 锁条目, + 并验证固定 Node/Yarn 的 frozen 安装及严格工具链检查。上游 API 见 + [pngjs 文档](https://github.com/pngjs/pngjs#sync-api)。 - ENG-04 新增 typescript-compat(npm:typescript@4.3.5)作为旧编译器消费探针;源码继续使用 typescript 5.9.3。精确 npm alias 也由锁检查保护;实际覆盖与命令见 [类型检查说明](typechecking.md)。 - 添加根开发依赖使用 `yarn add --dev --exact --ignore-workspace-root-check @`,包级依赖使用 `yarn workspace add ...`;运行依赖升级需要独立兼容证据。 - manifest 和 yarn.lock 同次提交;不提交 package-lock.json、bun.lock 或第二份安装锁。旧 npm 锁及验证报告保留于 ENG-01 Git 历史,原本地 Yarn 锁也已在忽略缓存中备份。 diff --git a/test/browser/README.md b/test/browser/README.md index 97f6ee892..f70ab0410 100644 --- a/test/browser/README.md +++ b/test/browser/README.md @@ -205,3 +205,15 @@ transfer use main-thread fillRect and do not verify the Worker/ImageBitmap path. The report records these distinctions and never infers a JASSUB fix from a control pass. Preserve each raw report/results directory before the next browser command. See [the isolation record](../../refactor/changes/2026-09-14-PKG-JASSUB-09-firefox-diagnostics.md). + +`ARTPLAYER_JASSUB_SCREENSHOT=true` adds a separate observation path to the native +JASSUB spec. `jassub-display.js` decodes a clipped composited page PNG using the +pinned root-only pngjs development dependency; it never copies the transferred +canvas. This mode uses green ASS glyphs, distinct 0-30s and 40-110s cue windows, +and seeks to 50s. It checks the initial cue time, visible pixels, changed glyph +signature, playback advance, fullscreen geometry and a hidden/restored negative +control. Normal readback fixtures and timeouts stay unchanged. Reported subtitle +hashes identify the actual selected ASS, not the white baseline. Screenshots are +attached at named phases; errors from individual polling attempts are retained. +The fixture's automatic failure screenshot runs after cleanup and may show an +empty player; use the named pre-cleanup screenshots for visual claims. diff --git a/test/browser/jassub-display.js b/test/browser/jassub-display.js new file mode 100644 index 000000000..7234d4816 --- /dev/null +++ b/test/browser/jassub-display.js @@ -0,0 +1,34 @@ +import { PNG } from 'pngjs' + +// Read the browser's composited PNG in Node, without copying the transferred canvas. +export async function captureJassubDisplay(page, phase) { + const geometry = await page.evaluate(() => window.jassubGeometry()) + const started = Date.now() + let png + try { + png = await page.screenshot({ clip: geometry.clip }) + } + catch (error) { + await page.evaluate((failure) => { + (window.jassubNative.displayFailures ||= []).push(failure) + }, { message: error.message, elapsed: Date.now() - started, geometry }) + throw error + } + const { data, width, height } = PNG.sync.read(png) + let visible = 0 + let signature = 0 + for (let i = 0; i < data.length; i += 4) { + // The screenshot diagnostic ASS uses green glyphs; normal fixtures stay white. + if (data[i] < 70 && data[i + 1] > 180 && data[i + 2] < 70) { + visible++ + signature = (signature + i) >>> 0 + } + } + const state = { ...geometry, phase, visible, signature, screenshotWidth: width, screenshotHeight: height, screenshotElapsed: Date.now() - started, observation: 'composited-png' } + await page.evaluate((state) => { + window.jassubNative.lastPixel = state + if (state.phase) + window.jassubNative.snapshots.push(state) + }, state) + return { state, png } +} diff --git a/test/browser/jassub-native.spec.js b/test/browser/jassub-native.spec.js index ea631d718..b4b70943f 100644 --- a/test/browser/jassub-native.spec.js +++ b/test/browser/jassub-native.spec.js @@ -2,6 +2,7 @@ import fs from 'node:fs' import process from 'node:process' import { ensureArchive, hash, readMember } from '../../refactor/scripts/releases.mjs' import { expect, test } from './fixtures.js' +import { captureJassubDisplay } from './jassub-display.js' const baseline = JSON.parse(fs.readFileSync('refactor/baselines/jassub-release.json', 'utf8')) const release = baseline.release @@ -14,7 +15,21 @@ const onDemandRender = process.env.ARTPLAYER_JASSUB_ON_DEMAND !== 'false' const defaultOffscreen = process.env.ARTPLAYER_JASSUB_OFFSCREEN === 'default' const readbackFrame = process.env.ARTPLAYER_JASSUB_READBACK_FRAME === 'true' const synchronousRender = process.env.ARTPLAYER_JASSUB_ASYNC_RENDER === 'false' +const screenshotReadback = process.env.ARTPLAYER_JASSUB_SCREENSHOT === 'true' +const seekTime = screenshotReadback ? 50 : 10 async function pixels(page, phase) { + if (screenshotReadback) { + try { + const { state, png } = await captureJassubDisplay(page, phase) + if (phase) + await test.info().attach(`jassub-display-${phase}`, { body: png, contentType: 'image/png' }) + return state + } + catch (error) { + await test.info().attach('jassub-display-attempt-error', { body: error.stack || error.message, contentType: 'text/plain' }) + throw error + } + } return page.evaluate(async ({ phase, readbackFrame }) => { if (readbackFrame) await new Promise(requestAnimationFrame) @@ -30,9 +45,10 @@ Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, Style: Default,Liberation Sans,36,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,10,10,20,1 [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text -Dialogue: 0,0:00:00.00,0:00:04.00,Default,,0,0,0,,Before seek -Dialogue: 0,0:00:05.00,0:00:30.00,Default,,0,0,0,,After seek with actual WASM +Dialogue: 0,0:00:00.00,${screenshotReadback ? '0:00:30.00' : '0:00:04.00'},Default,,0,0,0,,Before seek +Dialogue: 0,${screenshotReadback ? '0:00:40.00,0:01:50.00' : '0:00:05.00,0:00:30.00'},Default,,0,0,0,,After seek with actual WASM ` +const testedSubtitles = screenshotReadback ? subtitles.replace('&H00FFFFFF', '&H0000FF00') : subtitles for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { test(`JASSUB ${artifact ? 'candidate artifact' : `published ${release.version}`} renders actual WASM subtitles through seek and layout with ${core} core, customCanvas=${customCanvas}, defaultOffscreen=${defaultOffscreen}`, async ({ page, context }, testInfo) => { @@ -133,9 +149,15 @@ for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { window.jassub.addEventListener('error', event => reject(event.error), { once: true }) }) const readback = document.createElement('canvas') - window.jassubPixels = (phase) => { + window.jassubGeometry = () => { const canvas = window.jassub._canvas const rect = canvas.getBoundingClientRect() + const video = window.art.video + const quality = video.getVideoPlaybackQuality?.() + return { width: canvas.width, height: canvas.height, cssWidth: rect.width, cssHeight: rect.height, clip: { x: rect.x, y: rect.y, width: rect.width, height: rect.height }, time: window.art.currentTime, connected: canvas.isConnected, media: { paused: video.paused, readyState: video.readyState, totalFrames: quality?.totalVideoFrames, droppedFrames: quality?.droppedVideoFrames, decodedFrames: video.webkitDecodedFrameCount, mozPresentedFrames: video.mozPresentedFrames }, onDemand: window.jassub._onDemandRender } + } + window.jassubPixels = (phase) => { + const canvas = window.jassub._canvas readback.width = canvas.width readback.height = canvas.height const context = readback.getContext('2d') @@ -149,32 +171,34 @@ for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { signature = (signature + i * pixels[i]) >>> 0 } } - const video = window.art.video - const quality = video.getVideoPlaybackQuality?.() - const state = { phase, visible, signature, width: canvas.width, height: canvas.height, cssWidth: rect.width, cssHeight: rect.height, time: window.art.currentTime, connected: canvas.isConnected, media: { paused: video.paused, readyState: video.readyState, totalFrames: quality?.totalVideoFrames, droppedFrames: quality?.droppedVideoFrames, decodedFrames: video.webkitDecodedFrameCount, mozPresentedFrames: video.mozPresentedFrames }, onDemand: window.jassub._onDemandRender } + const state = { phase, visible, signature, ...window.jassubGeometry() } window.jassubNative.lastPixel = state if (phase) window.jassubNative.snapshots.push(state) return state } - }, { subContent: subtitles, onDemandRender, customCanvas, defaultOffscreen, synchronousRender }) + }, { subContent: testedSubtitles, onDemandRender, customCanvas, defaultOffscreen, synchronousRender }) const offscreen = await page.evaluate(() => window.jassubNative.offscreen) expect(offscreen.selected).toBe(defaultOffscreen && !customCanvas && offscreen.available) await page.locator('#play').click() await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100) const before = await pixels(page, 'before-seek') expect(before.connected).toBe(true) + if (screenshotReadback) { + expect(before.time).toBeLessThan(30) + expect(before.visible).toBeGreaterThan(100) + } await page.locator('#pause').click() - await page.evaluate(async () => { + await page.evaluate(async (seekTime) => { const seeked = new Promise(resolve => window.art.video.addEventListener('seeked', resolve, { once: true })) - window.art.currentTime = 10 + window.art.currentTime = seekTime await seeked - }) + }, seekTime) await page.locator('#play').click() await expect.poll(async () => (await pixels(page)).signature).not.toBe(before.signature) await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100) const after = await pixels(page, 'after-seek') - expect(after.time).toBeGreaterThanOrEqual(10) + expect(after.time).toBeGreaterThanOrEqual(seekTime) expect(after.signature).not.toBe(before.signature) await page.evaluate(() => { window.art.fullscreenWeb = true @@ -182,6 +206,18 @@ for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { await expect.poll(async () => (await pixels(page)).cssWidth).toBeGreaterThan(before.cssWidth) await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100) await pixels(page, 'fullscreen') + if (screenshotReadback) { + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(after.time + 0.2) + await page.evaluate(() => { + window.art.pause() + window.jassub._canvas.style.visibility = 'hidden' + }) + const hidden = await pixels(page, 'hidden-negative-control') + expect(hidden.visible).toBe(0) + await page.evaluate(() => window.jassub._canvas.style.visibility = '') + await expect.poll(async () => (await pixels(page)).visible).toBeGreaterThan(100) + await pixels(page, 'restored') + } await testInfo.attach('actual-jassub-page', { body: await page.screenshot(), contentType: 'image/png' }) if (artifact) await page.evaluate(() => window.jassub.destroy()) @@ -199,7 +235,11 @@ for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { const state = await page.evaluate(() => window.jassubNative).catch(error => ({ unavailable: error.message })) state.readbackFrame = readbackFrame state.synchronousRender = synchronousRender - await testInfo.attach('actual-jassub-evidence', { body: JSON.stringify({ core, onDemandRender, customCanvas, defaultOffscreen, source: artifact ? { artifact, sha256: hash(code) } : { version: release.version, integrity: release.integrity, member, sha256: hash(code) }, subtitleSha256: hash(subtitles), resources, external, state, limitation: `Actual worker, WASM and local font; offscreen option ${defaultOffscreen ? 'omitted, actual capability/selection recorded' : 'explicitly false'}. Canvas pixels are read from a separate canvas copying the native display bitmap. No full failure recovery, sustained GPU/memory or physical-device acceptance; candidate adds direct-then-host destruction.` }, null, 2), contentType: 'application/json' }) + state.screenshotReadback = screenshotReadback + const observation = screenshotReadback + ? 'Composited page PNG decoded in Node; authored green ASS glyphs with hidden/restored negative control. No transferred-canvas copy.' + : 'Canvas pixels are read from a separate canvas copying the native display bitmap.' + await testInfo.attach('actual-jassub-evidence', { body: JSON.stringify({ core, onDemandRender, customCanvas, defaultOffscreen, source: artifact ? { artifact, sha256: hash(code) } : { version: release.version, integrity: release.integrity, member, sha256: hash(code) }, subtitleSha256: hash(testedSubtitles), resources, external, state, limitation: `Actual worker, WASM and local font; offscreen option ${defaultOffscreen ? 'omitted, actual capability/selection recorded' : 'explicitly false'}. ${observation} No full failure recovery, sustained GPU/memory or physical-device acceptance; candidate adds direct-then-host destruction.` }, null, 2), contentType: 'application/json' }) if (!page.isClosed()) { await page.evaluate(() => { if (window.art && !window.art.isDestroy) diff --git a/yarn.lock b/yarn.lock index f51582bb3..c74398cd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6747,6 +6747,11 @@ pluralize@^8.0.0: resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +pngjs@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" + integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== + pnpm-workspace-yaml@1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/pnpm-workspace-yaml/-/pnpm-workspace-yaml-1.5.0.tgz"