diff --git a/packages/artplayer-plugin-danmuku-mask/ARCHITECTURE.md b/packages/artplayer-plugin-danmuku-mask/ARCHITECTURE.md index 8b1cbc269..8b05aa4d0 100644 --- a/packages/artplayer-plugin-danmuku-mask/ARCHITECTURE.md +++ b/packages/artplayer-plugin-danmuku-mask/ARCHITECTURE.md @@ -165,7 +165,10 @@ by its original player. Native shared TensorFlow backend state remains unverifie `yarn test:browser test/browser/danmuku-mask-native.spec.js --workers=1` now covers actual local model loading, bitmap alpha and owned canvas cleanup, new/old cores, real Danmuku delivery after model readiness, pause/seek and CSS web fullscreen. -Set ARTPLAYER_MASK_ARTIFACT to the legacy global build for the second format. +Both Mask and Danmuku compile from current source by default. Set +ARTPLAYER_MASK_ARTIFACT and ARTPLAYER_DANMUKU_ARTIFACT to explicit global builds +for artifact verification; attachments record both inputs and hashes. Missing +specified files are errors, not a source or dist fallback. Archive each report before another browser run. The startup timestamp diagnostic can still miss a row; do not interpret the post-ready assertions as losslessness. Native acceptance still needs source changes, multiple players, failure recovery, diff --git a/packages/artplayer-plugin-danmuku/ARCHITECTURE.md b/packages/artplayer-plugin-danmuku/ARCHITECTURE.md index 74e9a09b4..5df042aa6 100644 --- a/packages/artplayer-plugin-danmuku/ARCHITECTURE.md +++ b/packages/artplayer-plugin-danmuku/ARCHITECTURE.md @@ -1,5 +1,20 @@ # Danmuku maintenance map +`test/browser/danmuku-dpip.spec.js` exercises the candidate with old/current cores +in two sequential native Document PiP windows. It checks timestamp-delivered text, +adopted layer and heatmap nodes, stylesheet layout, one surviving track Worker, +close/native-close/destroy cleanup, and no retained scheduling operation. Native +API absence is reported separately; it does not simulate a popup or count as +playback evidence. This is not a background-throttling or device benchmark. +Set `ARTPLAYER_DANMUKU_ARTIFACT` and `ARTPLAYER_DPIP_ARTIFACT` together to check +the corresponding built formats; both loaded hashes appear in each attachment. + +The actual Mask/model combination in `danmuku-mask-native.spec.js` now compiles +both plugins from source by default. `ARTPLAYER_MASK_ARTIFACT` and +`ARTPLAYER_DANMUKU_ARTIFACT` override them independently and fail on missing files. +Do not substitute a stale dist file for source checks. Full old-plugin/core, +OS fullscreen, installation, performance and device acceptance remain task 08/09. + The compatibility reference is the actual npm 5.3.0 package. Its archive, historical declarations, earlier exports and failure evidence are indexed in `refactor/baselines/danmuku-release.json` and diff --git a/refactor/baselines/danmuku-combination-checkpoint.json b/refactor/baselines/danmuku-combination-checkpoint.json new file mode 100644 index 000000000..9a16ac765 --- /dev/null +++ b/refactor/baselines/danmuku-combination-checkpoint.json @@ -0,0 +1,4459 @@ +{ + "schemaVersion": 1, + "task": "PKG-DANMUKU-08", + "status": "doing", + "sourceHead": "88ce836f85aa61ffa9ccabc456b1803738551692", + "environment": { + "node": "24.21.0", + "yarn": "1.22.22", + "platform": "win32", + "remoteCI": false, + "physicalDevices": false + }, + "reports": [ + { + "directory": "refactor/.cache/danmuku08-dpip-first-report", + "reportSha256": "09d91e1753522ab2db6f285a2480df25149a2e6bad4dff02003f9f342380f5fc", + "result": { + "scope": "source", + "exitCode": 1, + "signal": null, + "args": [ + "test", + "--config=playwright.source.config.js", + "test/browser/danmuku-dpip.spec.js", + "--project=chromium", + "--workers=2" + ] + }, + "stats": { + "startTime": "2026-09-14T12:40:41.294Z", + "duration": 13558.078, + "expected": 4, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "browsers": [ + "153.0.8010.12" + ], + "cases": [ + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.435215, + "rowTime": 0.966179, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.654868, + "rowTime": 2.145704, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.406876, + "rowTime": 0.921645, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.627949, + "rowTime": 2.136451, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "failed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "incomplete", + "rounds": [ + { + "time": 1.421031, + "rowTime": 0.939968, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.607384, + "rowTime": 2.138844, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.419284, + "rowTime": 0.932283, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.61724, + "rowTime": 2.128995, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.390163, + "rowTime": 0.923458, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.595984, + "rowTime": 2.103801, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "failed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "incomplete", + "rounds": [ + { + "time": 1.434772, + "rowTime": 0.941113, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.62372, + "rowTime": 2.138908, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + } + ] + }, + { + "directory": "refactor/.cache/danmuku08-dpip-source-report", + "reportSha256": "02a1278018835cee8082c0a220a231d94ab64d01aba57403d8e8091a253e0150", + "result": { + "scope": "source", + "exitCode": 0, + "signal": null, + "args": [ + "test", + "--config=playwright.source.config.js", + "test/browser/danmuku-dpip.spec.js", + "--workers=2" + ] + }, + "stats": { + "startTime": "2026-09-14T12:42:11.819Z", + "duration": 29996.204999999998, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "browsers": [ + "153.0.8010.12", + "155.0", + "26.6" + ], + "cases": [ + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.445957, + "rowTime": 0.953052, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.690424, + "rowTime": 2.215201, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.43265, + "rowTime": 0.937979, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.632418, + "rowTime": 2.150428, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.417788, + "rowTime": 0.937489, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.617973, + "rowTime": 2.136396, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.416423, + "rowTime": 0.930878, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.66119, + "rowTime": 2.161417, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.427304, + "rowTime": 0.955005, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.641046, + "rowTime": 2.169035, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.416353, + "rowTime": 0.923541, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.593799, + "rowTime": 2.121174, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.585016, + "rowTime": 1.126636, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.961702, + "rowTime": 2.502664, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.627166, + "rowTime": 1.126482, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.045169, + "rowTime": 2.544339, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.502111, + "rowTime": 1.001469, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.878184, + "rowTime": 2.377739, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.418166, + "rowTime": 0.959635, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.847473, + "rowTime": 2.360287, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 0.876231, + "rowTime": 0.876231, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.286327, + "rowTime": 1.794029, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.083591, + "rowTime": 1.083591, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.503077, + "rowTime": 2.00229, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "dpip": { + "input": "candidate-source", + "sha256": "2daf44990a250f1122ce38481f3ed8c41d2f8c65a0d5ed99ab2633e46b703db1" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + } + ] + }, + { + "directory": "refactor/.cache/danmuku08-mask-source-report", + "reportSha256": "26e1c77f02b189791df924f8461de8e8344392c47fa283e69b72837172f3cb4f", + "result": { + "scope": "source", + "exitCode": 0, + "signal": null, + "args": [ + "test", + "--config=playwright.source.config.js", + "test/browser/danmuku-mask-native.spec.js", + "--grep", + "actual model and Danmuku", + "--workers=2" + ] + }, + "stats": { + "startTime": "2026-09-14T12:42:59.202Z", + "duration": 76161.96399999999, + "expected": 9, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "browsers": [ + "153.0.8010.12", + "155.0", + "26.6" + ], + "cases": [ + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with candidate core", + "project": "chromium", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 10.171764, + "outputs": 22, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 12.589617, + "outputs": 35, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 35, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 24.474152, + "outputs": 60, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published core", + "project": "chromium", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 9.278593, + "outputs": 24, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 11.231041, + "outputs": 37, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 37, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 23.791785, + "outputs": 63, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published-5.3.1-beta.1 core", + "project": "chromium", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 10.260373, + "outputs": 22, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 12.716265, + "outputs": 35, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 35, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 24.427409, + "outputs": 60, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with candidate core", + "project": "firefox", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 9.98156, + "outputs": 23, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 10.589032, + "outputs": 30, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 30, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.821848, + "outputs": 57, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.133331298828125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.133331298828125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published core", + "project": "firefox", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 9.058839, + "outputs": 25, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 9.706386, + "outputs": 33, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 33, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.69966, + "outputs": 58, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.133331298828125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.133331298828125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published-5.3.1-beta.1 core", + "project": "firefox", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 9.124328, + "outputs": 24, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 9.487631, + "outputs": 31, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 31, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.777108, + "outputs": 56, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.133331298828125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.133331298828125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with candidate core", + "project": "webkit", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 8.6547923, + "outputs": 19, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 9.2970632, + "outputs": 29, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 29, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.9371879, + "outputs": 41, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published core", + "project": "webkit", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 8.3106255, + "outputs": 17, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 8.9746048, + "outputs": 28, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 28, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.6071461, + "outputs": 40, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + }, + { + "title": "Mask actual model and Danmuku share the layer through pause, seek and web fullscreen with published-5.3.1-beta.1 core", + "project": "webkit", + "status": "passed", + "mask": { + "file": "source UMD", + "sha256": "2b4c117b0c2ccf52258877c697a3d83908a23fe3b5c8d698728b98de470c0045" + }, + "danmuku": { + "file": "source UMD", + "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66" + }, + "snapshots": [ + { + "phase": "playing", + "time": 8.7341464, + "outputs": 20, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "paused", + "time": 9.3471465, + "outputs": 30, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + }, + { + "phase": "fullscreen-paused", + "time": 20, + "outputs": 30, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 1280, + "height": 720, + "fullscreenWeb": true + }, + { + "phase": "restored", + "time": 21.6147712, + "outputs": 40, + "sameLayer": true, + "mask": true, + "mode": "alpha", + "width": 640, + "height": 360, + "fullscreenWeb": false + } + ], + "visible": [ + { + "text": "Ready mask combination", + "connected": true, + "inLayer": true, + "width": 275, + "height": 28.125, + "display": "block" + }, + { + "text": "After seek and visibility", + "connected": true, + "inLayer": true, + "width": 312.5, + "height": 28.125, + "display": "block" + } + ], + "unexpectedRequests": [], + "limitation": "Actual model, native media, timestamp-delivered Danmuku and CSS web fullscreen. No OS fullscreen, GPU completion or device coverage claim." + } + ] + }, + { + "directory": "refactor/.cache/danmuku08-dpip-main-report", + "reportSha256": "bb87090d3821e5fe531082bd3a870f99550cf1a851ec5c310bebb40e97cf3c05", + "result": { + "scope": "source", + "exitCode": 0, + "signal": null, + "args": [ + "test", + "--config=playwright.source.config.js", + "test/browser/danmuku-dpip.spec.js", + "--workers=2" + ] + }, + "stats": { + "startTime": "2026-09-14T12:45:05.405Z", + "duration": 29714.63, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "browsers": [ + "153.0.8010.12", + "155.0", + "26.6" + ], + "cases": [ + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.456489, + "rowTime": 0.954924, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.892963, + "rowTime": 2.385711, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.423795, + "rowTime": 0.940088, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.725758, + "rowTime": 2.237489, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.427241, + "rowTime": 0.937195, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.841129, + "rowTime": 2.335442, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.451135, + "rowTime": 0.954788, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.893012, + "rowTime": 2.385739, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.426194, + "rowTime": 0.923101, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.744991, + "rowTime": 2.236901, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.421234, + "rowTime": 0.938771, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.817074, + "rowTime": 2.336923, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.808849, + "rowTime": 1.278405, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.253587, + "rowTime": 2.753336, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.58524, + "rowTime": 1.126536, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.961857, + "rowTime": 2.459762, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.501859, + "rowTime": 1.001301, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.461329, + "rowTime": 2.419539, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.41842, + "rowTime": 0.917743, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.878461, + "rowTime": 2.335747, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.626924, + "rowTime": 1.126396, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.086827, + "rowTime": 2.584589, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.668728, + "rowTime": 1.168326, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.139533, + "rowTime": 2.649911, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + } + ] + }, + { + "directory": "refactor/.cache/danmuku08-dpip-legacy-report", + "reportSha256": "8eb447aa107d0888c0dae923e497a17d0accbc39a56416653c793e780a444be9", + "result": { + "scope": "source", + "exitCode": 0, + "signal": null, + "args": [ + "test", + "--config=playwright.source.config.js", + "test/browser/danmuku-dpip.spec.js", + "--workers=2" + ] + }, + "stats": { + "startTime": "2026-09-14T12:46:44.068Z", + "duration": 31132.126999999997, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "browsers": [ + "153.0.8010.12", + "155.0", + "26.6" + ], + "cases": [ + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.442985, + "rowTime": 0.951769, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.8731, + "rowTime": 2.366626, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.426777, + "rowTime": 0.938991, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.731402, + "rowTime": 2.236765, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.443372, + "rowTime": 0.941433, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.901485, + "rowTime": 2.419621, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.443549, + "rowTime": 0.956645, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.871602, + "rowTime": 2.350939, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.423645, + "rowTime": 0.923922, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.731974, + "rowTime": 2.237398, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "chromium", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.443734, + "rowTime": 0.938813, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.914678, + "rowTime": 2.417824, + "width": 112.5, + "height": 28.125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.502081, + "rowTime": 0.959733, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.961633, + "rowTime": 2.462608, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.668618, + "rowTime": 1.168426, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.211737, + "rowTime": 2.669546, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.627217, + "rowTime": 1.129422, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.128328, + "rowTime": 2.626561, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.460322, + "rowTime": 1.001558, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 2.961461, + "rowTime": 2.461057, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.668535, + "rowTime": 1.168362, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.097152, + "rowTime": 2.56743, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true, + false + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "firefox", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": true, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-playback-danmuku-and-cleanup-passed", + "rounds": [ + { + "time": 1.58527, + "rowTime": 1.084648, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 1 + } + ] + }, + { + "time": 3.042827, + "rowTime": 2.54439, + "width": 112.5, + "height": 28.133331298828125, + "adopted": true, + "inLayer": true, + "position": "absolute", + "player": true, + "heatmap": true, + "workers": [ + { + "terminated": 0, + "replies": 2 + } + ] + } + ], + "final": { + "active": false, + "workers": [ + { + "terminated": 1, + "replies": 2 + } + ], + "errors": [], + "events": [ + true, + false, + true + ], + "frame": null, + "operation": null, + "nodes": 0, + "settings": 0, + "placeholders": 0 + } + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "published: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "published", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP native-close", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "native-close", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + }, + { + "title": "candidate: Danmuku, heatmap and Worker survive native Document PiP destroy", + "project": "webkit", + "status": "passed", + "evidence": { + "core": "candidate", + "ending": "destroy", + "supported": false, + "danmuku": { + "input": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-danmuku\\dist\\artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + "dpip": { + "input": "candidate-artifact", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + "outcome": "native-document-pip-unavailable", + "rounds": [] + } + } + ] + } + ], + "artifacts": [ + { + "file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js", + "sha256": "133b7412e1a468b34f4f7ab3779958259f13899e037833029931f02b0833d088" + }, + { + "file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.legacy.js", + "sha256": "9f0cb9969419a7d0c02d54790c423353b83f775acd95fbdbaeeb29a7fc42c816" + }, + { + "file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.mjs", + "sha256": "356406cda2e3e47376a87c939b76fb7c55f86d7c3829127da625b01241c67a2f" + }, + { + "file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.js", + "sha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a" + }, + { + "file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.legacy.js", + "sha256": "67dd14de3cc16a04ae6c1938dcba61b1355f4a15e5fa06f62a41b18d14d4d356" + }, + { + "file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.mjs", + "sha256": "541b4ad6e1cbadd9156ee1f317559c97b9fddae37668ef32046f1fa47c392ec2" + } + ], + "source": [ + { + "file": "test/browser/danmuku-dpip.spec.js", + "sha256LF": "41da7b3a3db3d8237f80e22e74ad1608c675e830d95644ed2bd007667851bf5e" + }, + { + "file": "test/browser/danmuku-mask-native.spec.js", + "sha256LF": "a3a83684a28747e7e985b9b30b26d779589ba3fd94c4d8a8cf6977139d4e7126" + } + ], + "initialFailureResolution": "Both failures expected a public false event during destruction. Existing Canvas native-PiP test and Document PiP lifecycle contract suppress post-destroy events. Corrected expected sequence only; retained original reports and all cleanup assertions. No production change.", + "limitations": [ + "Six WebKit cases per PiP run report API unavailability, not native playback success", + "Two sequential native windows per live player; not repeated player mounting or background/physical-device performance evidence", + "Source PiP pass predates the extra visible-text assertion and screenshot; main and legacy include both", + "Mask source regression uses actual model with CSS web fullscreen; not OS fullscreen, GPU/WASM closure or full distribution proof", + "Old published Danmuku combinations, OS fullscreen, complete installation distribution and final performance comparison remain in task 08/09" + ] +} diff --git a/refactor/changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md b/refactor/changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md new file mode 100644 index 000000000..60592fdc1 --- /dev/null +++ b/refactor/changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md @@ -0,0 +1,68 @@ +# PKG-DANMUKU-08 原生画中画与 Mask 源码组合检查点 + +本任务仍 doing;这是组合覆盖的增量,不是完整弹幕或发布验收。 + +## 改变与原因 + +新增 `test/browser/danmuku-dpip.spec.js`,在新旧核心中让播放器先播放,再通过 +真实用户点击打开系统 Document PiP 窗口。每个播放器连续打开两次窗口,在窗口中 +按媒体时间投放弹幕,检查可见文本、实际尺寸、绝对定位、图层及热力图的 document +归属、真实 Worker 回复和复用。分别以插件关闭、原生关闭、播放器销毁结束。 +结束时核对 Worker 只终止一次、调度 RAF/operation 清空、设置/弹幕节点和占位 +清零;普通关闭后检查原父节点恢复且媒体时间继续前进。 + +没有用 iframe 模拟窗口。实际 API 不可用的场景单独输出 unavailable,不能计入 +播放通过数;本机 WebKit 如实保留该限制。此测试不声称浏览器后台节流或物理设备 +性能已经通过,也不把两次开窗当作两次播放器重新装卸。 + +`danmuku-mask-native.spec.js` 原默认读取 Mask 与 Danmuku 已有 dist,现在默认并行 +构建当前源码 UMD;显式 ARTPLAYER_MASK_ARTIFACT / ARTPLAYER_DANMUKU_ARTIFACT +可分别选择产物,文件不存在直接失败。附件记录两个实际输入与摘要。修正的是测试 +的输入来源,不修改生产逻辑,不宣称其他仍默认读取 dist 的测试都已完成来源审查。 + +包内 Danmuku 与 Mask 架构文档同步了入口、覆盖及限制。没有增加依赖、公开类型、 +运行时 API 或 DOM/CSS hook。两包正常生产构建重新执行后,产物与原跟踪内容相同。 + +## 实际验证 + +Node24.21.0、Yarn1.22.22、Windows,Chromium153.0.8010.12、Firefox155.0、WebKit26.6。 +报告指纹、逐例输入和回收结果见[机器证据](../baselines/danmuku-combination-checkpoint.json)。 + +| 范围 | 结果及含义 | +| --- | --- | +| 首轮 Chromium 原生 PiP | 4通过、2失败;失败为销毁事件的测试预期错误 | +| 更正后的源码 PiP | 18项退出0:12项原生窗口播放/清理,6项WebKit API不可用 | +| main 两插件构建产物 PiP | 18项退出0,同上;新增可见文本断言和窗口截图 | +| legacy 两插件构建产物 PiP | 18项退出0,同上;新增可见文本断言和窗口截图 | +| 当前 Mask + Danmuku 源码、真实本地模型 | 9项通过,三核心组合 × 三浏览器,含暂停/seek/网页全屏 | +| 新增/修改浏览器文件 ESLint | 通过 | +| Danmuku、Document PiP 正常三格式构建 | 通过;现有跟踪产物未变化 | + +三个 PiP 报告各有24次原生开窗,但不能叠加成独立播放器样本。没有跳过或重试。 +源码 PiP 报告在额外可见文本断言与截图之前;main/legacy包含这两项增强。 +已人工查看 main 的原生窗口截图,视频与顶部弹幕可见,发送栏和进度控件布局正常。 +截图在 `refactor/.cache/danmuku08-native-window.png`,原附件保留在 main 报告中。 + +首轮2个失败不能删除:原先预期 destroy 时还有最后一个 document-pip=false。 +现有 Canvas 原生 PiP 测试和 Document PiP 生命周期契约均规定销毁后不再发公开 +关闭事件;据此将销毁结尾明确断言为 [true,false,true],普通关闭仍严格断言 +[true,false,true,false]。资源释放检查全部保留,没有为了通过而增加合成事件。 + +真实模型检查继续保留启动期时间窗口的诊断。断言的是模型就绪之后按媒体时间 +显示的行,并非启动阶段完全不丢行,也不是私有 GPU/WASM 完整释放证明。 + +## 接续与重跑 + +PKG-DANMUKU-08仍需补旧发布插件/新旧核心组合、系统全屏、重复播放器装卸, +并结合07基线比较组合负载性能。09继续最终安装分发、示例、文档及 Worker 入口。 +与Mask、Document PiP关联的设备/后台/模型内部资源门槛不由本检查点关闭。 + +源码入口:`yarn test:browser:source test/browser/danmuku-dpip.spec.js --workers=2`; +模型组合:`yarn test:browser:source test/browser/danmuku-mask-native.spec.js +--grep 'actual model and Danmuku' --workers=2`。产物PiP运行同时指定 +ARTPLAYER_DANMUKU_ARTIFACT 和 ARTPLAYER_DPIP_ARTIFACT;每次运行前归档前一份报告。 +正常构建分别使用 `yarn build artplayer-plugin-danmuku` 与 +`yarn build artplayer-plugin-document-pip`。 + +本检查点独立本地commit,提交审计完成后再继续下一批;无push、部署或发布。 +回退本检查点即可恢复测试输入与覆盖,生产运行时没有变化。 diff --git a/refactor/plan.md b/refactor/plan.md index 20aab76f6..a1cffdfbb 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 261 项,范围 22 个包及工作区/示例。 -状态:todo 49 / doing 20 / blocked 0 / done 192 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 48 / doing 21 / blocked 0 / done 192 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -335,7 +335,7 @@ | PKG-DANMUKU-05 | artplayer-plugin-danmuku
整理 DOM 渲染、设置、热力图与 worker | PKG-DANMUKU-04, CORE-14, CORE-18 | renderer/setting/heatmap/worker 职责及资源归属 | mount/icons/设置和 worker 协议保持,销毁无后台工作 | H | done | | PKG-DANMUKU-06 | artplayer-plugin-danmuku
迁移 TS 与公开声明 | PKG-DANMUKU-05, ENG-04, ENG-06 | 自有模块、worker 消息、option/item/result 类型 | 旧参数、扩展字段和事件消费通过,vendored 边界清楚 | H | done | | PKG-DANMUKU-07 | artplayer-plugin-danmuku
弹幕能力稳定性验收 | PKG-DANMUKU-06, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | done | -| PKG-DANMUKU-08 | artplayer-plugin-danmuku
完成新旧核心与组合验收 | PKG-DANMUKU-07, CORE-22 | 最终核心/旧核心、mask/fullscreen/PiP 组合报告 | 性能无未解释退化,反复装卸无累计资源 | H | todo | +| PKG-DANMUKU-08 | artplayer-plugin-danmuku
完成新旧核心与组合验收 | PKG-DANMUKU-07, CORE-22 | 最终核心/旧核心、mask/fullscreen/PiP 组合报告 | 性能无未解释退化,反复装卸无累计资源 | H | doing | | PKG-DANMUKU-09 | artplayer-plugin-danmuku
完成分发、示例与文档 | PKG-DANMUKU-08, ENG-07 | danmuku.js、README、声明、worker 与产物 | tarball 和静态 icons 等旧调用通过,有独立回退版本 | H | todo | | PKG-DANMUKU-10 | artplayer-plugin-danmuku
修复 issue958 密集热力图过高与曲线裁平 | PKG-DANMUKU-05 | 自动密度缩放与曲线边界、历史自定义坐标兼容及真实浏览器红绿证据 | 16000条三种分布在两核心三引擎和source/main/legacy不遮挡;显式轴和自定义points保持旧解释,有单独commit | M | done | | PKG-DANMUKU-11 | artplayer-plugin-danmuku
修复 Worker 隐藏等待吞掉可见寿命 | PKG-DANMUKU-06 | 成功放置时的可见计时与延迟回复回归 | 真实 Worker 延迟下完整显示寿命;保留暂停/回收/取消和公开契约 | M | done | @@ -611,6 +611,7 @@ - PKG-DANMUKU-05: [记录](changes/2026-09-13-PKG-DANMUKU-05-resources.md) [记录](baselines/danmuku-resources-validation.json) - PKG-DANMUKU-06: [记录](changes/2026-09-13-PKG-DANMUKU-06-types.md) [记录](baselines/danmuku-types-validation.json) - PKG-DANMUKU-07: [记录](changes/2026-09-13-PKG-DANMUKU-07-stability.md) [记录](baselines/danmuku-stability-validation.json) [记录](danmuku-stability.md) +- PKG-DANMUKU-08: [记录](changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md) [记录](baselines/danmuku-combination-checkpoint.json) - PKG-CANVAS-01: [记录](changes/2026-09-12-PKG-CANVAS-01-contract.md) [记录](baselines/canvas-contract.md) [记录](baselines/canvas-release.json) [记录](canvas-validation.md) [记录](baselines/canvas-contract-validation.json) - PKG-CANVAS-02: [记录](changes/2026-09-12-PKG-CANVAS-02-tests.md) [记录](baselines/canvas-behavior-validation.json) [记录](canvas-validation.md) - PKG-CANVAS-03: [记录](changes/2026-09-12-PKG-CANVAS-03-lifecycle.md) [记录](baselines/canvas-lifecycle-validation.json) [记录](canvas-validation.md) diff --git a/refactor/progress.md b/refactor/progress.md index f9f09015b..74da16291 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,20 @@ # 进度与证据 +## PKG-DANMUKU-08 原生画中画与真实 Mask 组合检查点(仍 doing) + +新增新旧核心中的两次原生Document PiP开窗,按媒体时间显示弹幕,检查图层/热力图 +跨文档归属、Worker复用、播放继续及关闭/原生关闭/销毁后的RAF、operation、DOM回收。 +源码/main/legacy各18项退出0:每份12原生播放+6WebKit API不可用记录,不能混计。 +main/legacy另有可见文本断言及截图;已查看原生窗口视频、弹幕与发送栏布局。 +首轮4/2失败为错误要求destroy后的关闭事件,按已有DPiP/Canvas契约修正,资源断言保留。 + +真实Mask组合默认输入从已有dist改为当前Mask/Danmuku源码,保留两个显式产物覆盖。 +本地真实模型、三核心三引擎暂停/seek/网页全屏9项通过;两插件重新构建产物未变, +专项lint通过。见[记录](changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md)与 +[证据](baselines/danmuku-combination-checkpoint.json)。261项:192 done、21 doing、48 todo。 +旧插件完整组合、OS全屏、反复装卸/组合性能及最终安装分发仍待08/09接续,不标完成。 +本检查点独立本地提交并核验提交审计;无push/部署/发布。 + ## PKG-DASH-MENU-01 SDK 刷新设置子菜单修复完成 原legacy设置点击失败的trace显示根面板取代质量子菜单,setting仍显示。 diff --git a/refactor/tasks.json b/refactor/tasks.json index 527b1bfee..fd94ccb56 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -3556,11 +3556,14 @@ "PKG-DANMUKU-07", "CORE-22" ], - "status": "todo", + "status": "doing", "risk": "H", "deliverable": "最终核心/旧核心、mask/fullscreen/PiP 组合报告", "acceptance": "性能无未解释退化,反复装卸无累计资源", - "evidence": [] + "evidence": [ + "changes/2026-09-14-PKG-DANMUKU-08-native-combinations.md", + "baselines/danmuku-combination-checkpoint.json" + ] }, { "id": "PKG-DANMUKU-09", diff --git a/test/browser/danmuku-dpip.spec.js b/test/browser/danmuku-dpip.spec.js new file mode 100644 index 000000000..ae50d732f --- /dev/null +++ b/test/browser/danmuku-dpip.spec.js @@ -0,0 +1,161 @@ +import fs from 'node:fs' +import process from 'node:process' +import { hash } from '../../refactor/scripts/releases.mjs' +import { dpipCandidate } from '../helpers/dpip.js' +import { compilePackage } from '../helpers/load.js' +import { expect, test } from './fixtures.js' + +const dpip = await dpipCandidate() +let danmuku +test.beforeAll(async () => { + danmuku = process.env.ARTPLAYER_DANMUKU_ARTIFACT + ? fs.readFileSync(process.env.ARTPLAYER_DANMUKU_ARTIFACT, 'utf8') + : await compilePackage('artplayer-plugin-danmuku', 'umd') +}) + +for (const core of ['published', 'candidate']) { + for (const ending of ['close', 'native-close', 'destroy']) { + test(`${core}: Danmuku, heatmap and Worker survive native Document PiP ${ending}`, async ({ page, context }, testInfo) => { + await page.goto(`/test/player.html?core=${core}`) + const supported = await page.evaluate(() => typeof window.documentPictureInPicture?.requestWindow === 'function') + const evidence = { core, ending, supported, danmuku: { input: process.env.ARTPLAYER_DANMUKU_ARTIFACT || 'source UMD', sha256: hash(danmuku) }, dpip: { input: dpip.name, sha256: hash(dpip.code) }, outcome: 'incomplete', rounds: [] } + if (!supported) { + evidence.outcome = 'native-document-pip-unavailable' + await testInfo.attach('danmuku-dpip', { contentType: 'application/json', body: JSON.stringify(evidence) }) + return + } + await page.evaluate(() => { + window.combinationWorkers = [] + const NativeWorker = window.Worker + window.Worker = class extends NativeWorker { + constructor(...args) { + super(...args) + this.record = { terminated: 0, replies: 0 } + window.combinationWorkers.push(this.record) + this.addEventListener('message', () => this.record.replies++) + } + + terminate() { + this.record.terminated++ + return super.terminate() + } + } + }) + await page.addScriptTag({ content: danmuku }) + await page.addScriptTag({ content: `(() => { const module = { exports: {} }; const exports = module.exports; ${dpip.code}; window.dpipFactory = module.exports.default || module.exports; })();` }) + await page.evaluate(() => { + window.combinationVisible = [] + window.combinationErrors = [] + window.combinationEvents = [] + window.art = new window.Artplayer({ + container: '.player', + url: '/assets/sample/video.mp4', + muted: true, + plugins: [window.artplayerPluginDanmuku({ danmuku: [], heatmap: true, emitter: true, speed: 4 }), window.dpipFactory({ fallbackToVideoPiP: false })], + }) + window.danmuku = window.art.plugins.artplayerPluginDanmuku + window.danmukuOwner = window.danmuku.config({}) + window.pip = window.art.plugins.artplayerPluginDocumentPip + window.combinationPlayer = window.art.template.$player + window.combinationLayer = window.art.template.$danmuku + window.combinationParent = window.combinationPlayer.parentNode + window.art.on('document-pip', value => window.combinationEvents.push(value)) + window.art.on('artplayerPluginDanmuku:error', error => window.combinationErrors.push(String(error))) + window.art.on('artplayerPluginDanmuku:visible', row => window.combinationVisible.push({ text: row.text, ref: row.$ref, time: window.art.currentTime })) + document.querySelector('#play').onclick = () => window.art.play() + const open = document.createElement('button') + open.id = 'danmuku-open-pip' + open.textContent = 'Open Danmuku PiP' + open.onclick = () => { + window.openingDanmukuPip = window.pip.open() + } + document.body.append(open) + }) + try { + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.click('#play') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1) + for (let round = 0; round < 2; round++) { + const popupPromise = context.waitForEvent('page', { timeout: 8000 }) + await page.click('#danmuku-open-pip') + const popup = await popupPromise + await page.evaluate(() => window.openingDanmukuPip) + await expect(popup.locator('video.art-video')).toBeVisible() + await expect(popup.locator('.artplayer-plugin-danmuku')).toHaveCount(1) + const text = `PiP row ${round}` + await page.evaluate(async (text) => { + await window.danmuku.load([{ text, time: window.art.currentTime + 0.5, mode: 1 }]) + }, text) + await expect.poll(() => page.evaluate(text => window.combinationVisible.some(row => row.text === text), text)).toBe(true) + await expect(popup.getByText(text, { exact: true })).toBeVisible() + const snapshot = await page.evaluate((text) => { + const row = window.combinationVisible.find(row => row.text === text) + const rect = row.ref.getBoundingClientRect() + const popup = window.documentPictureInPicture.window + return { + time: window.art.currentTime, + rowTime: row.time, + width: rect.width, + height: rect.height, + adopted: row.ref.ownerDocument === popup.document && window.combinationLayer.ownerDocument === popup.document, + inLayer: window.combinationLayer.contains(row.ref), + position: popup.getComputedStyle(row.ref).position, + player: window.combinationPlayer.ownerDocument === popup.document, + heatmap: window.art.controls.heatmap.ownerDocument === popup.document && !!window.art.controls.heatmap.querySelector('svg'), + workers: window.combinationWorkers.map(worker => ({ ...worker })), + } + }, text) + evidence.rounds.push(snapshot) + expect(snapshot.adopted && snapshot.inLayer && snapshot.player && snapshot.heatmap).toBe(true) + expect(snapshot.width).toBeGreaterThan(0) + expect(snapshot.height).toBeGreaterThan(0) + expect(snapshot.position).toBe('absolute') + expect(snapshot.workers).toHaveLength(1) + expect(snapshot.workers[0].replies).toBeGreaterThan(0) + if (round === 0) + await testInfo.attach('native-danmuku-page', { contentType: 'image/png', body: await popup.screenshot() }) + if (round === 1 && ending === 'destroy') { + await page.evaluate(() => window.art.destroy(false)) + } + else { + await page.evaluate(ending => ending === 'native-close' ? window.documentPictureInPicture.window.close() : window.pip.close(), ending) + await expect.poll(() => page.evaluate(() => window.pip.isActive)).toBe(false) + expect(await page.evaluate(() => window.combinationPlayer.parentNode === window.combinationParent && window.combinationLayer.ownerDocument === document)).toBe(true) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(snapshot.time + 0.1) + } + } + if (ending !== 'destroy') + await page.evaluate(() => window.art.destroy(false)) + await expect.poll(() => page.evaluate(() => !window.documentPictureInPicture.window || window.documentPictureInPicture.window.closed)).toBe(true) + evidence.final = await page.evaluate(() => ({ + active: window.pip.isActive, + workers: window.combinationWorkers, + errors: window.combinationErrors, + events: window.combinationEvents, + frame: window.danmukuOwner.scheduler.frame, + operation: window.danmukuOwner.scheduler.operation, + nodes: window.combinationLayer.children.length, + settings: document.querySelectorAll('.artplayer-plugin-danmuku').length, + placeholders: document.querySelectorAll('.artplayer-document-pip-placeholder').length, + })) + expect(evidence.final.active).toBe(false) + expect(evidence.final.workers).toHaveLength(1) + expect(evidence.final.workers[0].terminated).toBe(1) + expect(evidence.final.errors).toEqual([]) + // Destroy suppresses further public events, as in the existing native PiP contract. + expect(evidence.final.events).toEqual(ending === 'destroy' ? [true, false, true] : [true, false, true, false]) + expect(evidence.final.frame).toBeNull() + expect(evidence.final.operation).toBeNull() + expect(evidence.final.nodes + evidence.final.settings + evidence.final.placeholders).toBe(0) + evidence.outcome = 'native-playback-danmuku-and-cleanup-passed' + } + finally { + await testInfo.attach('danmuku-dpip', { contentType: 'application/json', body: JSON.stringify(evidence) }) + await page.evaluate(() => { + if (window.art && !window.art.isDestroy) + window.art.destroy(false) + }) + } + }) + } +} diff --git a/test/browser/danmuku-mask-native.spec.js b/test/browser/danmuku-mask-native.spec.js index 6b8d53b9e..d6b46a4a3 100644 --- a/test/browser/danmuku-mask-native.spec.js +++ b/test/browser/danmuku-mask-native.spec.js @@ -2,10 +2,11 @@ import assert from 'node:assert/strict' import fs from 'node:fs' import process from 'node:process' import { hash } from '../../refactor/scripts/releases.mjs' +import { compilePackage } from '../helpers/load.js' import { expect, test } from './fixtures.js' -const artifact = process.env.ARTPLAYER_MASK_ARTIFACT || 'packages/artplayer-plugin-danmuku-mask/dist/artplayer-plugin-danmuku-mask.js' -const code = fs.readFileSync(artifact, 'utf8') +const artifact = process.env.ARTPLAYER_MASK_ARTIFACT || 'source UMD' +let code const baseline = JSON.parse(fs.readFileSync('refactor/baselines/danmuku-mask-release.json', 'utf8')) const assets = baseline.sdk.assets.map(({ file, sha256 }) => { const bytes = fs.readFileSync(file) @@ -17,8 +18,14 @@ const assets = baseline.sdk.assets.map(({ file, sha256 }) => { return { file, sha256: actual, baselineSha256: sha256, normalizedLF } }) const media = 'docs/assets/sample/steve-jobs.mp4' -const danmukuFile = 'packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js' -const danmukuCode = fs.readFileSync(danmukuFile, 'utf8') +const danmukuFile = process.env.ARTPLAYER_DANMUKU_ARTIFACT || 'source UMD' +let danmukuCode +test.beforeAll(async () => { + ;[code, danmukuCode] = await Promise.all([ + process.env.ARTPLAYER_MASK_ARTIFACT ? fs.readFileSync(artifact, 'utf8') : compilePackage('artplayer-plugin-danmuku-mask', 'umd'), + process.env.ARTPLAYER_DANMUKU_ARTIFACT ? fs.readFileSync(danmukuFile, 'utf8') : compilePackage('artplayer-plugin-danmuku', 'umd'), + ]) +}) for (const core of ['candidate', 'published', 'published-5.3.1-beta.1']) { test(`Mask actual local MediaPipe model renders, stops and restarts with ${core} core`, async ({ page }, testInfo) => {