mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 17:02:28 +00:00
land: area/playback-qa 48999ca22e (playback-qa)
This commit is contained in:
commit
4de357e4a7
10 files changed
+1841
-8
No files matched your search
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"id": "playback-qa-3",
|
||||
"area": "playback-qa",
|
||||
"status": "open",
|
||||
"title": "Diagnose Firefox deterministic CI failure at fb54cea3",
|
||||
"blockedOn": null,
|
||||
"addedOn": "2026-10-22",
|
||||
"filedAt": "fb54cea3a2ba99b4860421724a5050af6b97c293",
|
||||
"brief": "docs/agents/CAMPAIGN-2026-10-22.md"
|
||||
"id": "playback-qa-3",
|
||||
"area": "playback-qa",
|
||||
"status": "blocked",
|
||||
"title": "Diagnose Firefox deterministic CI failure at fb54cea3",
|
||||
"blockedOn": "CI-equivalent failing execution evidence unavailable: public logs403, no Playwright artifact; exact terminal assertions identified but controlled local Firefox runs pass. Await new actionable CI evidence; no further reruns routed.",
|
||||
"addedOn": "2026-10-22",
|
||||
"filedAt": "fb54cea3a2ba99b4860421724a5050af6b97c293",
|
||||
"brief": "docs/agents/CAMPAIGN-2026-10-22.md",
|
||||
"evidence": "docs/testing/playback-qa-3-investigation.md",
|
||||
"checkpoint": "Public CI184passed/2failed/3flaky preserved; local exact Playwright3passed/0failed/0flaky/0skipped,workers1,retries0,naturalexit0; not fixed or done."
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"mirrorHits": 3,
|
||||
"started": "2026-10-22T14:16:24.113Z",
|
||||
"sha": "c5b678f7c9d0b92fbf786b16ae831f1be1d0b899",
|
||||
"cases": [
|
||||
{
|
||||
"mode": "app-ready",
|
||||
"name": "exercises for-you view empty-state and hashtag action",
|
||||
"ready": {
|
||||
"harness": true,
|
||||
"videoLists": 1,
|
||||
"heading": "Trending"
|
||||
},
|
||||
"result": {
|
||||
"ok": true,
|
||||
"profileShows": [
|
||||
"hashtags"
|
||||
],
|
||||
"forYouInitialEmpty": true,
|
||||
"forYouLoadingEmpty": false,
|
||||
"forYouVideoEmpty": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"mode": "app-ready",
|
||||
"name": "exercises explore view empty-state transitions",
|
||||
"ready": {
|
||||
"harness": true,
|
||||
"videoLists": 1,
|
||||
"heading": "Trending"
|
||||
},
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"mode": "app-ready",
|
||||
"name": "exercises kids view empty-state transitions",
|
||||
"ready": {
|
||||
"harness": true,
|
||||
"videoLists": 1,
|
||||
"heading": "Trending"
|
||||
},
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"mode": "isolated",
|
||||
"name": "exercises for-you view empty-state and hashtag action",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"profileShows": [
|
||||
"hashtags"
|
||||
],
|
||||
"forYouInitialEmpty": true,
|
||||
"forYouLoadingEmpty": false,
|
||||
"forYouVideoEmpty": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"mode": "isolated",
|
||||
"name": "exercises explore view empty-state transitions",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"mode": "isolated",
|
||||
"name": "exercises kids view empty-state transitions",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
}
|
||||
],
|
||||
"blocked": [
|
||||
"https://esm.sh/@aws-sdk/[email protected]",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]/nip44",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.snort.social/",
|
||||
"https://esm.sh/@aws-sdk/[email protected]",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]/nip44",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.snort.social/",
|
||||
"https://esm.sh/@aws-sdk/[email protected]",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]",
|
||||
"https://esm.sh/[email protected]/nip44",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.primal.net/",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/lib/nostr.bundle.min.js",
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://relay.primal.net/",
|
||||
"wss://relay.snort.social/"
|
||||
],
|
||||
"pageErrors": [],
|
||||
"browser": "146.0.1",
|
||||
"ended": "2026-10-22T14:16:35.031Z",
|
||||
"resourcesClosed": true
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"bytes": 65331,
|
||||
"sha256": "2f1f8730af8c9fb08068a41c9c18356b9f48f21635fe5deed6d17fc6b9b97be7",
|
||||
"esbuild": "0.27.3",
|
||||
"sanityPassed": 6,
|
||||
"historicalMatch": false,
|
||||
"inputs": [
|
||||
"../../../../../tmp/playback-qa-3-assets/node_modules/base64-js/index.js",
|
||||
"../../../../../tmp/playback-qa-3-assets/node_modules/ieee754/index.js",
|
||||
"../../../../../tmp/playback-qa-3-assets/node_modules/buffer/index.js",
|
||||
"../../../../../tmp/playback-qa-3-assets/entry.mjs"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"name": "buffer",
|
||||
"version": "6.0.3",
|
||||
"key": "make-fetch-happen:request-cache:https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"sha256": "555b6f49224afcf6b2c5a9aea7cd34a7f443f395b10532bc5580022d57aa51f5",
|
||||
"bytes": 23108
|
||||
},
|
||||
{
|
||||
"name": "base64-js",
|
||||
"version": "1.5.1",
|
||||
"key": "make-fetch-happen:request-cache:https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"sha256": "b1b7a945b52685269083425216d6597e33d97bf21699d656e92fdb3eb5210a85",
|
||||
"bytes": 4109
|
||||
},
|
||||
{
|
||||
"name": "ieee754",
|
||||
"version": "1.2.1",
|
||||
"key": "make-fetch-happen:request-cache:https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"sha256": "8ef14b9b397e339db89db97881fb714f49319d8f0eb1275901f45567b28f9dac",
|
||||
"bytes": 2886
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,156 @@
|
||||
# QA3 scratch diagnostic drivers
|
||||
|
||||
Exact first driver; no retained test added.
|
||||
|
||||
```js
|
||||
const fs=require('node:fs/promises');
|
||||
const http=require('node:http');
|
||||
const path=require('node:path');
|
||||
const vm=require('node:vm');
|
||||
const dep='/home/user/Documents/GitHub/bitvid-dispatch/node_modules/';
|
||||
const {firefox}=require(dep+'playwright');
|
||||
const {expect}=require(dep+'@playwright/test');
|
||||
const {transformHook}=require(dep+'playwright/lib/transform/transform.js');
|
||||
const root='/home/user/Documents/GitHub/bitvid-playback-qa';
|
||||
const report={started:new Date().toISOString(),sha:'c5b678f7c9d0b92fbf786b16ae831f1be1d0b899',cases:[],blocked:[],pageErrors:[]};
|
||||
let browser,server;
|
||||
(async()=>{
|
||||
const source=await fs.readFile(root+'/tests/e2e/runtime-coverage-expansion.spec.ts','utf8');
|
||||
const tests=[];const test=(name,fn)=>tests.push({name,fn});test.describe=(_,fn)=>fn();
|
||||
const code=transformHook(source.replace('import { expect, test } from "./helpers/instrumentedTest";',''),'/tmp/playback-qa-3-original.ts').code;
|
||||
vm.runInNewContext(code,{test,expect,exports:{},require});
|
||||
server=http.createServer(async(req,res)=>{let p=new URL(req.url,'http://localhost').pathname;if(p==='/')p='/index.html';const file=path.resolve(root,'.'+p);if(!file.startsWith(root+'/')){res.writeHead(403);res.end();return;}try{const bytes=await fs.readFile(file);res.setHeader('Content-Type',({'.js':'text/javascript','.html':'text/html','.css':'text/css','.json':'application/json','.svg':'image/svg+xml'})[path.extname(file)]||'application/octet-stream');res.end(bytes);}catch{res.writeHead(404);res.end();}});
|
||||
await new Promise(ok=>server.listen(31857,'127.0.0.1',ok));
|
||||
browser=await firefox.launch({headless:true});report.browser=browser.version();
|
||||
for(const t of tests.slice(0,3)){
|
||||
const context=await browser.newContext({serviceWorkers:'block'});
|
||||
await context.route('**/*',r=>{const u=new URL(r.request().url());if(u.origin==='http://127.0.0.1:31857')return r.continue();report.blocked.push(u.origin+u.pathname);return r.abort('blockedbyclient');});
|
||||
await context.routeWebSocket('**/*',r=>{report.blocked.push(r.url());r.close();});
|
||||
const page=await context.newPage();page.on('pageerror',e=>report.pageErrors.push(e.message));
|
||||
const proxy={goto:(url,opts)=>page.goto('http://127.0.0.1:31857'+url,opts),evaluate:async(...args)=>{const result=await page.evaluate(...args);report.cases.at(-1).result=result;return result;}};
|
||||
const item={name:t.name};report.cases.push(item);
|
||||
try{await t.fn({page:proxy});item.pass=true;}catch(e){item.pass=false;item.error=e.message;}
|
||||
await context.close();
|
||||
}
|
||||
})().catch(e=>{report.blocker=e.stack;process.exitCode=1;}).finally(async()=>{if(browser)await browser.close();if(server)await new Promise(ok=>server.close(ok));report.ended=new Date().toISOString();report.resourcesClosed=true;await fs.writeFile('/tmp/playback-qa-3-local.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report,null,2));});
|
||||
|
||||
```
|
||||
|
||||
App-ready plus isolated-control driver; readiness deliberately differs from CI networkidle-only setup.
|
||||
|
||||
```js
|
||||
const fs=require('node:fs/promises');
|
||||
const http=require('node:http');
|
||||
const path=require('node:path');
|
||||
const vm=require('node:vm');
|
||||
const dep='/home/user/Documents/GitHub/bitvid-dispatch/node_modules/';
|
||||
const {firefox}=require(dep+'playwright');
|
||||
const {expect}=require(dep+'@playwright/test');
|
||||
const {transformHook}=require(dep+'playwright/lib/transform/transform.js');
|
||||
const root='/home/user/Documents/GitHub/bitvid-playback-qa';
|
||||
const report={mirrorHits:0,started:new Date().toISOString(),sha:'c5b678f7c9d0b92fbf786b16ae831f1be1d0b899',cases:[],blocked:[],pageErrors:[]};
|
||||
let browser,server;
|
||||
(async()=>{
|
||||
const source=await fs.readFile(root+'/tests/e2e/runtime-coverage-expansion.spec.ts','utf8');
|
||||
const tests=[];const test=(name,fn)=>tests.push({name,fn});test.describe=(_,fn)=>fn();
|
||||
const code=transformHook(source.replace('import { expect, test } from "./helpers/instrumentedTest";',''),'/tmp/playback-qa-3-original.ts').code;
|
||||
vm.runInNewContext(code,{test,expect,exports:{},require});
|
||||
server=http.createServer(async(req,res)=>{let p=new URL(req.url,'http://localhost').pathname;if(p==='/')p='/index.html';const file=path.resolve(root,'.'+p);if(!file.startsWith(root+'/')){res.writeHead(403);res.end();return;}try{const bytes=await fs.readFile(file);res.setHeader('Content-Type',({'.js':'text/javascript','.html':'text/html','.css':'text/css','.json':'application/json','.svg':'image/svg+xml'})[path.extname(file)]||'application/octet-stream');res.end(bytes);}catch{res.writeHead(404);res.end();}});
|
||||
await new Promise(ok=>server.listen(31857,'127.0.0.1',ok));
|
||||
browser=await firefox.launch({headless:true});report.browser=browser.version();
|
||||
const mirror=await fs.readFile('/tmp/playback-qa-3-assets/buffer.mjs');
|
||||
for(const mode of ['app-ready','isolated']) for(const t of tests.slice(0,3)){
|
||||
const context=await browser.newContext({serviceWorkers:'block'});
|
||||
await context.route('**/*',r=>{const u=new URL(r.request().url());if(u.href==='https://cdn.jsdelivr.net/npm/[email protected]/+esm'){report.mirrorHits++;return r.fulfill({body:mirror,contentType:'text/javascript',headers:{'Access-Control-Allow-Origin':'*'}});}if(mode==='isolated' && u.origin==='http://127.0.0.1:31857' && u.pathname==='/')return r.fulfill({body:'<!doctype html><html><body></body></html>',contentType:'text/html'});if(u.origin==='http://127.0.0.1:31857')return r.continue();report.blocked.push(u.origin+u.pathname);return r.abort('blockedbyclient');});
|
||||
await context.routeWebSocket('**/*',r=>{report.blocked.push(r.url());r.close();});
|
||||
const page=await context.newPage();page.on('pageerror',e=>report.pageErrors.push(e.message));
|
||||
const proxy={goto:async(url,opts)=>{await page.goto('http://127.0.0.1:31857'+url,opts);if(mode==='app-ready'){await page.waitForFunction(async()=>{const m=await import('/js/applicationContext.js');await m.getApplicationReady();return !!m.getApplication() && !!window.__bitvidTest__ && !!document.getElementById('videoList');},null,{timeout:15000});item.ready=await page.evaluate(()=>({harness:!!window.__bitvidTest__,videoLists:document.querySelectorAll('#videoList').length,heading:document.querySelector('h1,h2')?.textContent}));}return;},evaluate:async(...args)=>{const result=await page.evaluate(...args);report.cases.at(-1).result=result;return result;}};
|
||||
const item={mode,name:t.name};report.cases.push(item);
|
||||
try{await t.fn({page:proxy});item.pass=true;}catch(e){item.pass=false;item.error=e.message;if(!item.ready && mode==='app-ready')throw new Error('actual-app readiness blocked: '+e.message);}
|
||||
await context.close();
|
||||
}
|
||||
})().catch(e=>{report.blocker=e.stack;process.exitCode=1;}).finally(async()=>{if(browser)await browser.close();if(server)await new Promise(ok=>server.close(ok));report.ended=new Date().toISOString();report.resourcesClosed=true;await fs.writeFile('/tmp/playback-qa-3-app-ready-result.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report,null,2));});
|
||||
|
||||
```
|
||||
|
||||
Original-timing passive DOM trace driver; exact original callbacks/expectations, no readiness wait.
|
||||
|
||||
```js
|
||||
const fs=require('node:fs/promises');
|
||||
const http=require('node:http');
|
||||
const path=require('node:path');
|
||||
const vm=require('node:vm');
|
||||
const dep='/home/user/Documents/GitHub/bitvid-dispatch/node_modules/';
|
||||
const {firefox}=require(dep+'playwright');
|
||||
const {expect}=require(dep+'@playwright/test');
|
||||
const {transformHook}=require(dep+'playwright/lib/transform/transform.js');
|
||||
const root='/home/user/Documents/GitHub/bitvid-playback-qa';
|
||||
const report={mirrorHits:0,started:new Date().toISOString(),sha:'c5b678f7c9d0b92fbf786b16ae831f1be1d0b899',cases:[],blocked:[],pageErrors:[]};
|
||||
let browser,server;
|
||||
(async()=>{
|
||||
const source=await fs.readFile(root+'/tests/e2e/runtime-coverage-expansion.spec.ts','utf8');
|
||||
const tests=[];const test=(name,fn)=>tests.push({name,fn});test.describe=(_,fn)=>fn();
|
||||
const code=transformHook(source.replace('import { expect, test } from "./helpers/instrumentedTest";',''),'/tmp/playback-qa-3-original.ts').code;
|
||||
vm.runInNewContext(code,{test,expect,exports:{},require});
|
||||
server=http.createServer(async(req,res)=>{let p=new URL(req.url,'http://localhost').pathname;if(p==='/')p='/index.html';const file=path.resolve(root,'.'+p);if(!file.startsWith(root+'/')){res.writeHead(403);res.end();return;}try{const bytes=await fs.readFile(file);res.setHeader('Content-Type',({'.js':'text/javascript','.html':'text/html','.css':'text/css','.json':'application/json','.svg':'image/svg+xml'})[path.extname(file)]||'application/octet-stream');res.end(bytes);}catch{res.writeHead(404);res.end();}});
|
||||
await new Promise(ok=>server.listen(31857,'127.0.0.1',ok));
|
||||
browser=await firefox.launch({headless:true});report.browser=browser.version();
|
||||
const mirror=await fs.readFile('/tmp/playback-qa-3-assets/buffer.mjs');
|
||||
for(const t of tests.slice(0,3)){
|
||||
const context=await browser.newContext({serviceWorkers:'block'});
|
||||
await context.route('**/*',r=>{const u=new URL(r.request().url());if(u.href==='https://cdn.jsdelivr.net/npm/[email protected]/+esm'){report.mirrorHits++;return r.fulfill({body:mirror,contentType:'text/javascript',headers:{'Access-Control-Allow-Origin':'*'}});}if(u.origin==='http://127.0.0.1:31857')return r.continue();report.blocked.push(u.origin+u.pathname);return r.abort('blockedbyclient');});
|
||||
await context.routeWebSocket('**/*',r=>{report.blocked.push(r.url());r.close();});
|
||||
await context.addInitScript(()=>{
|
||||
const ids=new WeakMap();let next=0;const id=n=>n?(ids.has(n)?ids.get(n):(ids.set(n,++next),next)):null;
|
||||
const trace=[];window.__qaTrace=trace;
|
||||
const get=Document.prototype.getElementById;
|
||||
const snap=(type,node)=>{if(trace.length>=300)return;trace.push({type,at:performance.now(),node:id(node),connected:node?.isConnected,videoList:id(get.call(document,'videoList')),body:id(document.body),harness:!!window.__bitvidTest__,stack:new Error().stack?.split('\n').slice(1,5)});};
|
||||
Document.prototype.getElementById=function(name){const r=get.call(this,name);if(name==='videoList')snap('getElementById-videoList',r);return r;};
|
||||
const desc=Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');
|
||||
Object.defineProperty(Element.prototype,'innerHTML',{...desc,set(value){const watch=this===document.body||this.id==='videoList';if(watch)snap('before-innerHTML',this);desc.set.call(this,value);if(watch)snap('after-innerHTML',this);}});
|
||||
new MutationObserver(records=>{if(records.some(r=>[...r.addedNodes,...r.removedNodes].some(n=>n.nodeType===1&&(n.id==='videoList'||n.querySelector?.('#videoList')))))snap('mutation-videoList',get.call(document,'videoList'));}).observe(document,{childList:true,subtree:true});
|
||||
});
|
||||
const page=await context.newPage();page.on('pageerror',e=>report.pageErrors.push(e.message));
|
||||
const proxy={goto:(url,opts)=>page.goto('http://127.0.0.1:31857'+url,opts),evaluate:async(...args)=>{const result=await page.evaluate(...args);report.cases.at(-1).result=result;report.cases.at(-1).trace=await page.evaluate(()=>window.__qaTrace);report.cases.at(-1).postResultState=await page.evaluate(async()=>{const m=await import('/js/applicationContext.js');return {application:!!m.getApplication(),harness:!!window.__bitvidTest__,videoLists:document.querySelectorAll('#videoList').length};});return result;}};
|
||||
const item={name:t.name};report.cases.push(item);
|
||||
try{await t.fn({page:proxy});item.pass=true;}catch(e){item.pass=false;item.error=e.message;}
|
||||
await context.close();
|
||||
}
|
||||
})().catch(e=>{report.blocker=e.stack;process.exitCode=1;}).finally(async()=>{if(browser)await browser.close();if(server)await new Promise(ok=>server.close(ok));report.ended=new Date().toISOString();report.resourcesClosed=true;await fs.writeFile('/tmp/playback-qa-3-causal-result.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report,null,2));});
|
||||
|
||||
```
|
||||
|
||||
Exact Playwright runner scratch overlay and network-only auto fixture. Spec is original source with only registration import changed to ../guard.
|
||||
|
||||
playwright.config.ts
|
||||
|
||||
```js
|
||||
import original from '/home/user/Documents/GitHub/bitvid-playback-qa/playwright.config';
|
||||
export default {...original,testDir:'/tmp/playback-qa-3-runner',globalSetup:'/home/user/Documents/GitHub/bitvid-playback-qa/tests/e2e/helpers/playwrightCoverageGlobalSetup.ts',outputDir:'/tmp/playback-qa-3-runner/results',reporter:[['list'],['json',{outputFile:'/tmp/playback-qa-3-runner/report.json'}]],use:{...original.use,baseURL:'http://127.0.0.1:31857',serviceWorkers:'block'},projects:original.projects.filter(p=>p.name==='e2e-firefox'),webServer:{...original.webServer,command:'node /tmp/playback-qa-3-runner/server.cjs',url:'http://127.0.0.1:31857/docs/kitchen-sink.html',reuseExistingServer:false}};
|
||||
|
||||
```
|
||||
|
||||
guard.ts
|
||||
|
||||
```js
|
||||
import {test as base,expect} from '/home/user/Documents/GitHub/bitvid-playback-qa/tests/e2e/helpers/instrumentedTest';
|
||||
import fs from 'node:fs/promises';
|
||||
const mirror=fs.readFile('/tmp/playback-qa-3-assets/buffer.mjs');
|
||||
export const test=base.extend({_offlineGuard:[async({context},use,testInfo)=>{
|
||||
const blocked:string[]=[];let mirrorHits=0;
|
||||
await context.route('**/*',async r=>{const u=new URL(r.request().url());if(u.href==='https://cdn.jsdelivr.net/npm/[email protected]/+esm'){mirrorHits++;return r.fulfill({body:await mirror,contentType:'text/javascript',headers:{'Access-Control-Allow-Origin':'*'}});}if(u.origin==='http://127.0.0.1:31857')return r.continue();blocked.push(u.origin+u.pathname);return r.abort('blockedbyclient');});
|
||||
await context.routeWebSocket('**/*',r=>{blocked.push(r.url());r.close();});
|
||||
try{await use();}finally{await testInfo.attach('offline-boundary',{body:JSON.stringify({mirrorHits,blocked}),contentType:'application/json'});}
|
||||
},{auto:true}]});
|
||||
export {expect};
|
||||
|
||||
```
|
||||
|
||||
server.cjs
|
||||
|
||||
```js
|
||||
const fs=require('node:fs/promises'),http=require('node:http'),path=require('node:path');const root='/home/user/Documents/GitHub/bitvid-playback-qa';let server;
|
||||
server=http.createServer(async(req,res)=>{let p=new URL(req.url,'http://localhost').pathname;if(p==='/')p='/index.html';const file=path.resolve(root,'.'+p);if(!file.startsWith(root+'/')){res.writeHead(403);res.end();return;}try{const bytes=await fs.readFile(file);res.setHeader('Content-Type',({'.js':'text/javascript','.html':'text/html','.css':'text/css','.json':'application/json','.svg':'image/svg+xml'})[path.extname(file)]||'application/octet-stream');res.end(bytes);}catch{res.writeHead(404);res.end();}});
|
||||
server.listen(31857,'127.0.0.1');
|
||||
|
||||
```
|
||||
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"config": {
|
||||
"configFile": "/tmp/playback-qa-3-runner/playwright.config.ts",
|
||||
"rootDir": "/tmp/playback-qa-3-runner",
|
||||
"forbidOnly": false,
|
||||
"fullyParallel": false,
|
||||
"globalSetup": "/home/user/Documents/GitHub/bitvid-playback-qa/tests/e2e/helpers/playwrightCoverageGlobalSetup.ts",
|
||||
"globalTeardown": null,
|
||||
"globalTimeout": 0,
|
||||
"grep": {},
|
||||
"grepInvert": null,
|
||||
"maxFailures": 0,
|
||||
"metadata": {
|
||||
"actualWorkers": 1
|
||||
},
|
||||
"preserveOutput": "always",
|
||||
"projects": [
|
||||
{
|
||||
"outputDir": "/tmp/playback-qa-3-runner/results",
|
||||
"repeatEach": 1,
|
||||
"retries": 0,
|
||||
"metadata": {
|
||||
"actualWorkers": 1
|
||||
},
|
||||
"id": "e2e-firefox",
|
||||
"name": "e2e-firefox",
|
||||
"testDir": "/tmp/playback-qa-3-runner",
|
||||
"testIgnore": [],
|
||||
"testMatch": [
|
||||
"e2e/**/*.spec.ts"
|
||||
],
|
||||
"timeout": 120000
|
||||
}
|
||||
],
|
||||
"quiet": false,
|
||||
"reporter": [
|
||||
[
|
||||
"list",
|
||||
null
|
||||
],
|
||||
[
|
||||
"json",
|
||||
{
|
||||
"outputFile": "/tmp/playback-qa-3-runner/report.json"
|
||||
}
|
||||
]
|
||||
],
|
||||
"reportSlowTests": {
|
||||
"max": 5,
|
||||
"threshold": 300000
|
||||
},
|
||||
"runAgents": "none",
|
||||
"shard": null,
|
||||
"tags": [],
|
||||
"updateSnapshots": "missing",
|
||||
"updateSourceMethod": "patch",
|
||||
"version": "1.58.2",
|
||||
"workers": 1,
|
||||
"webServer": {
|
||||
"command": "node /tmp/playback-qa-3-runner/server.cjs",
|
||||
"url": "http://127.0.0.1:31857/docs/kitchen-sink.html",
|
||||
"reuseExistingServer": false,
|
||||
"timeout": 120000
|
||||
}
|
||||
},
|
||||
"suites": [
|
||||
{
|
||||
"title": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"file": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"column": 0,
|
||||
"line": 0,
|
||||
"specs": [],
|
||||
"suites": [
|
||||
{
|
||||
"title": "runtime coverage expansion",
|
||||
"file": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"line": 3,
|
||||
"column": 6,
|
||||
"specs": [
|
||||
{
|
||||
"title": "exercises for-you view empty-state and hashtag action",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 120000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "e2e-firefox",
|
||||
"projectName": "e2e-firefox",
|
||||
"results": [
|
||||
{
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 3135,
|
||||
"errors": [],
|
||||
"stdout": [],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-10-22T14:22:02.653Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "offline-boundary",
|
||||
"contentType": "application/json",
|
||||
"body": "eyJtaXJyb3JIaXRzIjoxLCJibG9ja2VkIjpbImh0dHBzOi8vZXNtLnNoL0Bhd3Mtc2RrL2NsaWVudC1zM0AzLjYzNy4wIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvK2VzbSIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMC9uaXA0NCIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vcmVsYXkuZGFtdXMuaW8vIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5zbm9ydC5zb2NpYWwvIiwid3NzOi8vcmVsYXkucHJpbWFsLm5ldC8iLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9ub3MubG9sLyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvbGliL25vc3RyLmJ1bmRsZS5taW4uanMiLCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL25vc3RyLXRvb2xzQDIuMTcuMC9saWIvbm9zdHIuYnVuZGxlLm1pbi5qcyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvbGliL25vc3RyLmJ1bmRsZS5taW4uanMiLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9ub3MubG9sLyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iXX0="
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "392e8fc2af458905b98f-9ff48298987f061c177a",
|
||||
"file": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"line": 4,
|
||||
"column": 7
|
||||
},
|
||||
{
|
||||
"title": "exercises explore view empty-state transitions",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 120000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "e2e-firefox",
|
||||
"projectName": "e2e-firefox",
|
||||
"results": [
|
||||
{
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 2267,
|
||||
"errors": [],
|
||||
"stdout": [],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-10-22T14:22:06.278Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "offline-boundary",
|
||||
"contentType": "application/json",
|
||||
"body": "eyJtaXJyb3JIaXRzIjoxLCJibG9ja2VkIjpbImh0dHBzOi8vZXNtLnNoL0Bhd3Mtc2RrL2NsaWVudC1zM0AzLjYzNy4wIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvK2VzbSIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMC9uaXA0NCIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vcmVsYXkuZGFtdXMuaW8vIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5zbm9ydC5zb2NpYWwvIiwid3NzOi8vcmVsYXkucHJpbWFsLm5ldC8iLCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL25vc3RyLXRvb2xzQDIuMTcuMC9saWIvbm9zdHIuYnVuZGxlLm1pbi5qcyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwid3NzOi8vcmVsYXkuZGFtdXMuaW8vIiwid3NzOi8vbm9zLmxvbC8iLCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL25vc3RyLXRvb2xzQDIuMTcuMC9saWIvbm9zdHIuYnVuZGxlLm1pbi5qcyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvbGliL25vc3RyLmJ1bmRsZS5taW4uanMiLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9ub3MubG9sLyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iXX0="
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "392e8fc2af458905b98f-44c51fdca915cc6d7a20",
|
||||
"file": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"line": 79,
|
||||
"column": 7
|
||||
},
|
||||
{
|
||||
"title": "exercises kids view empty-state transitions",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 120000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "e2e-firefox",
|
||||
"projectName": "e2e-firefox",
|
||||
"results": [
|
||||
{
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 2209,
|
||||
"errors": [],
|
||||
"stdout": [],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-10-22T14:22:08.564Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "offline-boundary",
|
||||
"contentType": "application/json",
|
||||
"body": "eyJtaXJyb3JIaXRzIjoxLCJibG9ja2VkIjpbImh0dHBzOi8vZXNtLnNoL0Bhd3Mtc2RrL2NsaWVudC1zM0AzLjYzNy4wIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvK2VzbSIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMCIsImh0dHBzOi8vZXNtLnNoL25vc3RyLXRvb2xzQDIuMTcuMC9uaXA0NCIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vcmVsYXkuZGFtdXMuaW8vIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5zbm9ydC5zb2NpYWwvIiwid3NzOi8vcmVsYXkucHJpbWFsLm5ldC8iLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9ub3MubG9sLyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvbGliL25vc3RyLmJ1bmRsZS5taW4uanMiLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9ub3MubG9sLyIsImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbm9zdHItdG9vbHNAMi4xNy4wL2xpYi9ub3N0ci5idW5kbGUubWluLmpzIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ub3N0ci10b29sc0AyLjE3LjAvbGliL25vc3RyLmJ1bmRsZS5taW4uanMiLCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL25vc3RyLXRvb2xzQDIuMTcuMC9saWIvbm9zdHIuYnVuZGxlLm1pbi5qcyIsIndzczovL3JlbGF5LmRhbXVzLmlvLyIsIndzczovL25vcy5sb2wvIiwid3NzOi8vcmVsYXkuc25vcnQuc29jaWFsLyIsIndzczovL3JlbGF5LnByaW1hbC5uZXQvIiwid3NzOi8vbm9zLmxvbC8iLCJ3c3M6Ly9yZWxheS5kYW11cy5pby8iLCJ3c3M6Ly9yZWxheS5wcmltYWwubmV0LyIsIndzczovL3JlbGF5LnNub3J0LnNvY2lhbC8iXX0="
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "392e8fc2af458905b98f-079002fdea00236f7003",
|
||||
"file": "e2e/runtime-coverage-expansion.spec.ts",
|
||||
"line": 120,
|
||||
"column": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"errors": [],
|
||||
"stats": {
|
||||
"startTime": "2026-10-22T14:22:01.436Z",
|
||||
"duration": 9955.026,
|
||||
"expected": 3,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
"flaky": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
Running 3 tests using 1 worker
|
||||
|
||||
(node:141920) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
(node:141920) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
✓ 1 [e2e-firefox] › ../../../../../tmp/playback-qa-3-runner/e2e/runtime-coverage-expansion.spec.ts:4:7 › runtime coverage expansion › exercises for-you view empty-state and hashtag action (3.1s)
|
||||
✓ 2 [e2e-firefox] › ../../../../../tmp/playback-qa-3-runner/e2e/runtime-coverage-expansion.spec.ts:79:7 › runtime coverage expansion › exercises explore view empty-state transitions (2.3s)
|
||||
✓ 3 [e2e-firefox] › ../../../../../tmp/playback-qa-3-runner/e2e/runtime-coverage-expansion.spec.ts:120:7 › runtime coverage expansion › exercises kids view empty-state transitions (2.2s)
|
||||
|
||||
3 passed (10.0s)
|
||||
@@ -0,0 +1,76 @@
|
||||
# QA3 Firefox CI investigation — first checkpoint
|
||||
|
||||
**Disposition:** blocked, not fixed/done. Dispatch20261022T142307 accepted this bounded checkpoint and stopped further Firefox reruns. Public CI184passed/2failed/3flaky remains open; actual serial local runner3/3 passed without retry. No causal defect was established. Need new actionable CI-equivalent failure evidence; public logs403 and no E2E artifact limit investigation. Evidence-only checkpoint approved for normal docs queue; no product gate or new browser work is implied.
|
||||
|
||||
2026-10-22. Current HEAD `c5b678f7c9d0b92fbf786b16ae831f1be1d0b899`; filed CI SHA `fb54cea3a2ba99b4860421724a5050af6b97c293`. Own clean branch fast-forwarded to unstable, no unique commits discarded. Relevant original view modules and runtime-coverage spec have zero diff between these SHAs. QA3 claimed; implementation remains unrouted.
|
||||
|
||||
Plan: identify exact CI failures through public metadata; inspect original scenario and view wiring; run one narrow Firefox diagnostic with all external traffic denied; preserve first result and release resources; route any further environment preparation or demonstrated fix through dispatch. Product, existing tests, helpers, and configuration remain read-only.
|
||||
|
||||
## Public CI evidence
|
||||
|
||||
Unauthenticated GET job119013565277 in run39536282396 succeeds. Head SHA matches filedAt. Job `e2e-tests (22, e2e-firefox)` failed at step9, `Run deterministic E2E suite (e2e-firefox)`; build and browser install passed. Workflow command is `npx playwright test tests/e2e --project=${{ matrix.project }}`. Current config enables one CI retry; no local retry was used.
|
||||
|
||||
Public check annotations endpoint returned13 entries. Summary:184 passed,2 failed,3 flaky in15.8minutes. Terminal failures, including their original attempts and CI retry:
|
||||
|
||||
- `runtime-coverage-expansion.spec.ts:73`: For You `profileShows` expected to contain `hashtags`, received `[]`.
|
||||
- Same file line156: Kids `emptyInitial` expected true, received false.
|
||||
|
||||
Three flaky tests had `browserContext.newPage`/page setup120000ms timeouts: notification-system line84, profile-management line49 and line126. These are distinct from terminal assertion failures. The known feed hydration flake is not established as the cause.
|
||||
|
||||
Logs endpoint returned HTTP403 (curl exit22). Artifact listing returned one artifact, `dist-hashes-current`; no retained Playwright trace/report artifact was listed. Check output summary/text are null, but annotations provide the assertions above. No credentials, rerun, or remote write used. Initial sandbox DNS failure was resolved by approved read-only network escalation.
|
||||
|
||||
## First local controlled result
|
||||
|
||||
Command `node /tmp/playback-qa-3-run.cjs`; Node22.23.1, existing read-only Playwright1.58.2 dependencies, Firefox146.0.1. Scratch HTTP server private31857 serves this worktree. Existing spec imported through Playwright's TypeScript transformer with only its test registration import replaced by a collector; exact first three test callbacks/assertions execute against fresh Firefox contexts. Coverage/console fixture is not executed; no full-run concurrency, build or CI environment equivalence claimed.
|
||||
|
||||
Initial sandbox bind failed EPERM before browser start; approved escalation then executed once. Measured run14:11:11.923→14:11:17.342UTC:3/3 original view scenarios passed (For You, Explore control, Kids). Node exited naturally0. All owned browser/context/server resources closed in finally; preview3000 untouched. Driver contains no retries, sleeps, assertion weakening or forced exit.
|
||||
|
||||
Three external requests, all exact Buffer CDN import, were blocked. No external HTTP/WebSocket allowed. No pageerror events recorded. This prevents the full application module graph from booting, so these results establish only the original view scenarios with blocked bootstrap. They do not reproduce, fix or clear the CI failures, and are not actual-app qualification. Original CI failures remain open. Exact first result is retained in `playback-qa-3-local-first-result.json`.
|
||||
|
||||
## Blocker and next boundary
|
||||
|
||||
Dispatch notified CI assertions and resource release. Further browser work awaits routing/resource grant for genuine offline dependency preparation and app/DOM interference measurement. No fake Buffer, substituted product behavior, public fixture traffic, real signer/relay/media/cloud, product/test/helper/config edits, full suite or build used. CI browser version, full logs, concurrency/resource conditions, cause and actual-app behavior remain unverified. No new retained test was added, so no mutant claim is made.
|
||||
|
||||
## Authorized cached-artifact preparation: missing bundle
|
||||
|
||||
Dispatch message20261022T141235 authorized reuse of the genuine cached Buffer artifact only, matching prior QA provenance/hash, followed by app readiness and isolated-view controls. It explicitly requires reporting a blocker if the artifact is missing. No new browser was started.
|
||||
|
||||
Prior durable `playback-qa-2-assets-plan.md` and `playback-qa-2-second-pass.md` identify a65405-byte locally bundled genuine npm Buffer6.0.3 artifact, SHA256 `507a593508c51d1397a9a5818ad0b8dbf7e3ad810feaa87cabff87ff56cf3984`. Its old QA scratch directories (`/tmp/bitvid-playback-qa-2-assets`, `-snapshot`, `-integrated`, `-final`) are absent. Filename inventory of `/tmp`, fleet state and relevant repository paths found no reusable Buffer bundle. Existing source polyfill files reference the remote CDN; they are not the bundle.
|
||||
|
||||
`npm cache ls buffer base64-js ieee754` exited0 and lists the three original versioned tarball cache keys. These are source packages, not the approved built artifact; no extraction, install, rebundle, substitute, external fetch or browser execution followed. Dispatch was asked to identify a surviving exact-hash prepared artifact or route offline reconstruction separately. The conditional browser grant has not been consumed; browser/expensive resources remain released. Actual app readiness, original CI assertion reproduction and root cause remain unverified.
|
||||
|
||||
## Separately authorized offline reconstruction and readiness controls
|
||||
|
||||
Dispatch20261022T141453 explicitly authorized offline reconstruction from the three exact cached upstream packages. Cache SHA512 matched cached registry metadata and cache integrity for3/3; historical tarball and index.js SHA256 pins matched3/3. Safe extraction admitted regular package files only, rejecting traversal and links. Existing read-only esbuild0.27.3 bundled precisely buffer6.0.3/base64-js1.5.1/ieee7541.2.1 plus the scratch entry, with no fetch/install scripts/product changes. New output65331bytes SHA256 `2f1f8730af8c9fb08068a41c9c18356b9f48f21635fe5deed6d17fc6b9b97be7` differs from historical65405bytes/507a; no byte-equivalence claim. Native-Node comparisons/API probes passed6/6: exports, UTF8, base64, shared subarray backing, float64 bytes, typed-array hex. Provenance and output report retained beside this note.
|
||||
|
||||
Granted command `node /tmp/playback-qa-3-ready-run.cjs` ran14:16:24.113→14:16:35.031UTC at the same QA HEAD. Firefox146.0.1, private31857, fresh contexts. Exact CDN Buffer import was fulfilled3 times with the verified reconstructed artifact; all other public HTTP/WebSocket attempts denied. Node exited naturally0; all owned resources closed, RELEASE sent. No pageerrors recorded. No broad/full suite/build or test retry used.
|
||||
|
||||
With explicit `getApplicationReady()` resolution, actual application object, harness and videoList readiness required before the original callbacks, all three scenarios passed3/3. Each observed Trending heading and one videoList before DOM replacement. Separate inert-document isolated-view controls passed3/3. Original assertions unchanged; exact drivers and result JSON retained. This adds app-readiness timing relative to original CI `networkidle` only, so it does not prove CI equivalence or root cause and does not erase either terminal CI failure. No control establishes real relay, signer, cloud, playback, CDN or production behavior.
|
||||
|
||||
Next proposed causal measurement sent to dispatch: retain original networkidle-only timing with verified Buffer, passively trace document/container replacement and application-context identity while executing original callbacks. This would distinguish app-bootstrap interference from view behavior without weakening assertions or adding readiness waits. It has not yet run; browser resources remain released pending routing. CI concurrency, exact browser version and logs remain unavailable/unverified.
|
||||
|
||||
## Approved original-timing causal diagnostic
|
||||
|
||||
Dispatch20261022T141750 granted the original networkidle-only timing with passive DOM/application traces. Command `node /tmp/playback-qa-3-causal-run.cjs > /tmp/playback-qa-3-causal-stdout.json` ran14:18:54.853→14:19:02.503UTC, exit0, Firefox146.0.1, same HEAD/verified Buffer/private31857/public-deny boundary. No readiness waits, sleeps, retries or original callback/assertion edits. All3 scenarios passed3/3; CI terminal failures remain unreproduced. Browser/context/server closed naturally; RELEASE sent.
|
||||
|
||||
Passive traces assign identity1 to app videoList, identity2 to body, identity3 to replacement fixture videoList. Each original callback replaces the body's content; each view initializer then resolves connected fixture node3. All initial empty states are observed and all expected actions/transitions pass. App feed loading/render writes occurred before fixture replacement; no app-driven videoList/root replacement during the measured callbacks is observed. No evidence yet supports a causal race fix. Instrumentation wrappers preserve getter/setter values but their execution overhead remains an environmental difference.
|
||||
|
||||
Post-result application-context sampling is not exact-assertion sampling: For You has application false because its original callback explicitly calls setApplication(null); Explore/Kids application true. Harness is present and one videoList remains in all3. This cannot rule out unobserved context changes at other times and must not be presented as proof of CI app identity. Buffer fulfillment3, pageerrors0; all other public attempts denied.
|
||||
|
||||
Inspected original instrumentedTest: Firefox does not start JS coverage; console/pageerror capture requires environment flags; no additional readiness waits or before-test app setup is supplied. Scratch VM registration still differs from actual Playwright fixture/worker execution. Results retain unchanged source callbacks but do not reproduce CI concurrency, browser revision, CDN transport, fixture execution or full runner. No product/test/helper/config fix is justified from these passing local measurements. Proposed next bounded diagnostic, not yet run: actual original Playwright runner/fixture with external network guard and exact three selectors to remove the scratch registration difference. Resources released pending dispatch routing.
|
||||
|
||||
## Approved actual Playwright runner checkpoint
|
||||
|
||||
Dispatch20261022T142037 authorized exact runner/fixture diagnostic with scratch overlay and exactly3 tests. Preflight `--list` exited0 and selected only For You line4, Explore line79, Kids line120 in one copied spec. Copy differs from original solely in its registration import pointing to a scratch auto network guard; that guard extends the actual original instrumentedTest. Original callbacks/expectations and instrumentation/globalSetup source are unchanged.
|
||||
|
||||
Execution command (stdout redirected to owned scratch):
|
||||
|
||||
```sh
|
||||
env -u NODE_TEST_CONTEXT NODE_PATH=/home/user/Documents/GitHub/bitvid-dispatch/node_modules node /home/user/Documents/GitHub/bitvid-dispatch/node_modules/playwright/cli.js test -c /tmp/playback-qa-3-runner/playwright.config.ts --project=e2e-firefox --grep 'exercises (for-you|explore|kids) view' --workers=1 --retries=0
|
||||
```
|
||||
|
||||
Natural exit0. Start14:22:01.436UTC, duration9955.026ms;3 passed,0 unexpected,0 flaky,0 skipped, one attempt each. No readiness wait or passive DOM wrappers were added to this execution. Runner owns/stops its private31857 webServer; post-exit process inventory showed only checking shell/sandbox command lines, no node server process. An independent socket check was sandbox-denied and is not claimed as port verification. RELEASE sent; no other server/preview was touched.
|
||||
|
||||
Explicit environment differences: source checkout rather than CI install/build; existing read-only Playwright1.58.2/Firefox146.0.1 dependency/browser; NODE_PATH resolution; scratch testDir/output and list+JSON reporter; private31857/baseURL; blocked service workers and all nonlocal HTTP/WebSocket; verified reconstructed genuine Buffer fulfillment; workers1 and retries0 instead of CI defaults/retry1. Original http-server dependency is absent locally, so the authorized scratch overlay uses the same prior Node static server (MIME/path serving) rather than installing it. Original global setup absolute path and instrumentedTest/coverage helper are preserved. No coverage/console-capture environment opt-in was added. These differences preclude whole-CI parity claims.
|
||||
|
||||
Retained JSON report, stdout, and exact scratch overlay/guard/server are beside this note. All previous first results remain intact. No product, existing test, helper or configuration file changed. No demonstrated causal defect or fix proposal yet; CI failures remain OPEN/unreproduced, with precise public annotations preserved. Further execution awaits dispatch disposition; no retries/concurrency ramp/broad suite/build planned autonomously.
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"started": "2026-10-22T14:11:11.923Z",
|
||||
"sha": "c5b678f7c9d0b92fbf786b16ae831f1be1d0b899",
|
||||
"cases": [
|
||||
{
|
||||
"name": "exercises for-you view empty-state and hashtag action",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"profileShows": [
|
||||
"hashtags"
|
||||
],
|
||||
"forYouInitialEmpty": true,
|
||||
"forYouLoadingEmpty": false,
|
||||
"forYouVideoEmpty": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "exercises explore view empty-state transitions",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "exercises kids view empty-state transitions",
|
||||
"result": {
|
||||
"ok": true,
|
||||
"emptyInitial": true,
|
||||
"emptyDuringLoading": false,
|
||||
"emptyWithVideo": false
|
||||
},
|
||||
"pass": true
|
||||
}
|
||||
],
|
||||
"blocked": [
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm",
|
||||
"https://cdn.jsdelivr.net/npm/[email protected]/+esm"
|
||||
],
|
||||
"pageErrors": [],
|
||||
"browser": "146.0.1",
|
||||
"ended": "2026-10-22T14:11:17.342Z",
|
||||
"resourcesClosed": true
|
||||
}
|
||||
Reference in new issue
Block a user