@checksum-ai/runtime 4.13.0 → 4.13.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/checksum-progress-reporter.js +3 -3
- package/checksum-root/tsconfig.json +0 -1
- package/checksumlib.js +7 -7
- package/cli.js +169 -744
- package/helpers.ts +1 -1
- package/index.d.ts +6 -2
- package/index.js +124 -743
- package/package.json +13 -10
- package/pw-report-template.html +1 -1
- package/test-run-monitor.js +12 -486
- package/index.d.helpers.ts +0 -14
package/package.json
CHANGED
|
@@ -4,16 +4,19 @@
|
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@playwright/test": "1.60.0",
|
|
7
|
-
"dotenv": "
|
|
8
|
-
"jsdom": "
|
|
9
|
-
"playwright-extra": "
|
|
10
|
-
"puppeteer-extra-plugin": "
|
|
11
|
-
"puppeteer-extra-plugin-stealth": "
|
|
7
|
+
"dotenv": "17.4.2",
|
|
8
|
+
"jsdom": "30.0.1",
|
|
9
|
+
"playwright-extra": "4.3.6",
|
|
10
|
+
"puppeteer-extra-plugin": "3.2.3",
|
|
11
|
+
"puppeteer-extra-plugin-stealth": "2.11.2",
|
|
12
12
|
"rrweb": "2.0.0-alpha.18",
|
|
13
|
-
"sucrase": "
|
|
14
|
-
"sharp": "
|
|
15
|
-
"
|
|
16
|
-
"
|
|
13
|
+
"sucrase": "3.35.1",
|
|
14
|
+
"sharp": "0.35.3",
|
|
15
|
+
"htmlparser2": "12.0.0",
|
|
16
|
+
"typescript": "^5.0.0"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20.18"
|
|
17
20
|
},
|
|
18
21
|
"repository": {
|
|
19
22
|
"type": "git",
|
|
@@ -42,5 +45,5 @@
|
|
|
42
45
|
"url": "https://github.com/checksum-ai/checksum-ai-monorepo/issues"
|
|
43
46
|
},
|
|
44
47
|
"homepage": "https://github.com/checksum-ai/checksum-ai-monorepo/tree/main/packages/runtime#readme",
|
|
45
|
-
"version": "4.13.
|
|
48
|
+
"version": "4.13.1-beta.1"
|
|
46
49
|
}
|
package/pw-report-template.html
CHANGED
|
@@ -65,7 +65,7 @@ Error generating stack: `+p.message+`
|
|
|
65
65
|
- Following Playwright test failed.
|
|
66
66
|
- Explain why, be concise, respect Playwright best practices.
|
|
67
67
|
- Provide a snippet of code with the fix, if possible.
|
|
68
|
-
`.trimStart(),rc=({code:t,children:i,testId:r})=>{const o=oe.useMemo(()=>Ou(t),[t]);return x.jsxs("div",{className:"test-error-container test-error-text","data-testid":r,children:[i,x.jsx("div",{className:"test-error-view",dangerouslySetInnerHTML:{__html:o||""}})]})},Zx=({context:t})=>{const[i,r]=oe.useState(!1);return x.jsx("button",{className:"button",style:{minWidth:100},onClick:async()=>{try{let o=t==null?void 0:t.path;const a=window.checksum_api_base_url;o&&a&&o.includes("https://api.checksum.ai")&&(o=o.replace("https://api.checksum.ai",a));const u=window.checksum_alt_token;if(o&&u&&!o.includes("altToken=")){const h=o.includes("?")?"&":"?";o=`${o}${h}altToken=${u}`}let c="";if(o){const h=await fetch(o);if(!h.ok)throw new Error(`Failed to fetch context: ${h.status} ${h.statusText}`);c=await h.text()}else t!=null&&t.body&&(c=t.body);const d=Kx+(c||"");await navigator.clipboard.writeText(d),r(!0),setTimeout(()=>{r(!1)},3e3)}catch(o){console.error("[PromptButton] Error:",o),alert(`Failed to copy prompt: ${o.message}`)}},children:i?"Copied":"Copy prompt"})},qx=({errorPrefix:t,diff:i,errorSuffix:r})=>{const o=oe.useMemo(()=>Ou(t),[t]),a=oe.useMemo(()=>Ou(r),[r]);return x.jsxs("div",{"data-testid":"test-screenshot-error-view",className:"test-error-view",children:[x.jsx("div",{dangerouslySetInnerHTML:{__html:o||""},className:"test-error-text",style:{marginBottom:20}}),x.jsx(l1,{diff:i,hideDetails:!0},"image-diff"),x.jsx("div",{"data-testid":"error-suffix",dangerouslySetInnerHTML:{__html:a||""},className:"test-error-text"})]})};function Ou(t){return Yx(t||"",{bg:"var(--color-canvas-subtle)",fg:"var(--color-fg-default)"})}const Lo=U0;async function Jx(t){var E;const i={};window.checksum_alt_token&&(i.Authorization=`Bearer ${window.checksum_alt_token}`);const r=await fetch(t,{headers:i});if(!r.ok)throw new Error(`Failed to fetch trace: ${r.statusText}`);const o=await r.arrayBuffer();if(new TextDecoder().decode(o.slice(0,30)).startsWith("checksum-playwright-trace:"))throw new Error("Trace file is a placeholder, video not available");const u=new Blob([o]),c=new Lo.ZipReader(new Lo.BlobReader(u),{useWebWorkers:!1}),d=await c.getEntries(),h=new Map;for(const O of d)h.set(O.filename,O);const m=["test.trace"];for(const[O]of h)O.endsWith(".trace")&&O!=="test.trace"&&m.push(O);const y=new Map;for(const O of m){const k=h.get(O);if(!k)continue;const v=new Lo.TextWriter;await k.getData(v);const P=(await v.getData()).split(`
|
|
68
|
+
`.trimStart(),rc=({code:t,children:i,testId:r})=>{const o=oe.useMemo(()=>Ou(t),[t]);return x.jsxs("div",{className:"test-error-container test-error-text","data-testid":r,children:[i,x.jsx("div",{className:"test-error-view",dangerouslySetInnerHTML:{__html:o||""}})]})},Zx=({context:t})=>{const[i,r]=oe.useState(!1);return x.jsx("button",{className:"button",style:{minWidth:100},onClick:async()=>{try{let o=t==null?void 0:t.path;const a=window.checksum_api_base_url;o&&a&&o.includes("https://api.checksum.ai")&&(o=o.replace("https://api.checksum.ai",a));const u=window.checksum_alt_token;if(o&&u&&!o.includes("altToken=")){const h=o.includes("?")?"&":"?";o=`${o}${h}altToken=${u}`}let c="";if(o){const h=await fetch(o);if(!h.ok)throw new Error(`Failed to fetch context: ${h.status} ${h.statusText}`);c=await h.text()}else t!=null&&t.body&&(c=t.body);const d=Kx+(c||"");await navigator.clipboard.writeText(d),r(!0),setTimeout(()=>{r(!1)},3e3)}catch(o){console.error("[PromptButton] Error:",o),alert(`Failed to copy prompt: ${o instanceof Error?o.message:String(o)}`)}},children:i?"Copied":"Copy prompt"})},qx=({errorPrefix:t,diff:i,errorSuffix:r})=>{const o=oe.useMemo(()=>Ou(t),[t]),a=oe.useMemo(()=>Ou(r),[r]);return x.jsxs("div",{"data-testid":"test-screenshot-error-view",className:"test-error-view",children:[x.jsx("div",{dangerouslySetInnerHTML:{__html:o||""},className:"test-error-text",style:{marginBottom:20}}),x.jsx(l1,{diff:i,hideDetails:!0},"image-diff"),x.jsx("div",{"data-testid":"error-suffix",dangerouslySetInnerHTML:{__html:a||""},className:"test-error-text"})]})};function Ou(t){return Yx(t||"",{bg:"var(--color-canvas-subtle)",fg:"var(--color-fg-default)"})}const Lo=U0;async function Jx(t){var E;const i={};window.checksum_alt_token&&(i.Authorization=`Bearer ${window.checksum_alt_token}`);const r=await fetch(t,{headers:i});if(!r.ok)throw new Error(`Failed to fetch trace: ${r.statusText}`);const o=await r.arrayBuffer();if(new TextDecoder().decode(o.slice(0,30)).startsWith("checksum-playwright-trace:"))throw new Error("Trace file is a placeholder, video not available");const u=new Blob([o]),c=new Lo.ZipReader(new Lo.BlobReader(u),{useWebWorkers:!1}),d=await c.getEntries(),h=new Map;for(const O of d)h.set(O.filename,O);const m=["test.trace"];for(const[O]of h)O.endsWith(".trace")&&O!=="test.trace"&&m.push(O);const y=new Map;for(const O of m){const k=h.get(O);if(!k)continue;const v=new Lo.TextWriter;await k.getData(v);const P=(await v.getData()).split(`
|
|
69
69
|
`).filter(b=>b.trim());for(const b of P)try{const M=JSON.parse(b);if(M.attachments&&Array.isArray(M.attachments))for(const B of M.attachments)B.name==="video"&&((E=B.contentType)!=null&&E.startsWith("video/"))&&B.sha1&&!y.has(B.sha1)&&y.set(B.sha1,B)}catch{}}if(y.size===0)return await c.close(),[];const g=[];let A=0;for(const O of y.values()){const k=`resources/${O.sha1}`,v=h.get(k);if(!v)continue;const S=new Lo.BlobWriter(O.contentType);await v.getData(S);const P=await S.getData(),b=O.contentType==="video/webm"?"webm":"mp4";g.push({blobUrl:URL.createObjectURL(P),contentType:O.contentType,filename:`video-${A+1}.${b}`}),A++}return await c.close(),g}const _x=({traceUrls:t})=>{const[i,r]=oe.useState([]),[o,a]=oe.useState(!0),[u,c]=oe.useState(null);return oe.useEffect(()=>{const d=[];return(async()=>{try{a(!0),c(null);const g=(await Promise.all(t.map(A=>Jx(A).catch(()=>[])))).flat().map((A,E)=>({...A,filename:`video-${E+1}.${A.contentType==="video/webm"?"webm":"mp4"}`}));g.forEach(A=>d.push(A.blobUrl)),r(g),a(!1)}catch(m){c(m instanceof Error?m.message:"Failed to extract videos"),a(!1)}})(),()=>{d.forEach(m=>URL.revokeObjectURL(m))}},[t]),o?x.jsx("div",{style:{padding:"20px",color:"#666"},children:"Loading videos from traces..."}):u?x.jsxs("div",{style:{padding:"20px",color:"#c41a16"},children:["Error loading videos: ",u]}):i.length===0?null:x.jsx("div",{children:i.map((d,h)=>x.jsxs("div",{style:{marginBottom:h<i.length-1?"20px":0},children:[x.jsxs("video",{controls:!0,style:{maxWidth:"100%"},children:[x.jsx("source",{src:d.blobUrl,type:d.contentType}),"Your browser does not support the video tag."]}),x.jsx("div",{style:{marginTop:"8px"},children:x.jsxs("a",{href:d.blobUrl,download:d.filename,style:{color:"var(--color-underline-link)",textDecoration:"none",display:"inline-flex",alignItems:"center",gap:"4px"},children:["📥 Download ",d.filename]})})]},h))})};function $x(t,i){var o;const r=new Map;for(const a of t){const u=a.name.match(/^(.*)-(expected|actual|diff|previous)(\.[^.]+)?$/);if(!u)continue;const[,c,d,h=""]=u,m=c+h;let y=r.get(m);y||(y={name:m,anchors:[`attachment-${c}`]},r.set(m,y)),y.anchors.push(`attachment-${i.attachments.indexOf(a)}`),d==="actual"&&(y.actual={attachment:a}),d==="expected"&&(y.expected={attachment:a,title:"Expected"}),d==="previous"&&(y.expected={attachment:a,title:"Previous"}),d==="diff"&&(y.diff={attachment:a})}for(const[a,u]of r)!u.actual||!u.expected?r.delete(a):(t.delete(u.actual.attachment),t.delete(u.expected.attachment),t.delete((o=u.diff)==null?void 0:o.attachment));return[...r.values()]}const ev=({test:t,result:i})=>{const{screenshots:r,videos:o,traces:a,otherAttachments:u,diffs:c,errors:d,otherAttachmentAnchors:h,screenshotAnchors:m,errorContext:y}=oe.useMemo(()=>{const g=i.attachments.filter(B=>!B.name.startsWith("_")),A=new Set(g.filter(B=>B.contentType.startsWith("image/"))),E=[...A].map(B=>`attachment-${g.indexOf(B)}`),O=g.filter(B=>B.contentType.startsWith("video/")),k=g.filter(B=>B.name==="trace");let v=g.find(B=>B.name==="error-context");!v&&i.errors.length>0&&(v={name:"error-context",contentType:"text/markdown",body:["## Test Errors","",...i.errors.flatMap((I,F)=>{const Q=[`### Error ${F+1}`,"```"];return typeof I=="string"?Q.push(I):(Q.push(I.message||String(I)),I.codeframe&&Q.push("",I.codeframe)),Q.push("```",""),Q})].join(`
|
|
70
70
|
`)});const S=new Set(g);[...A,...O,...k].forEach(B=>S.delete(B));const P=[...S].map(B=>`attachment-${g.indexOf(B)}`),b=$x(A,i),M=nv(i.errors,b);return{screenshots:[...A],videos:O,traces:k,otherAttachments:S,diffs:b,errors:M,otherAttachmentAnchors:P,screenshotAnchors:E,errorContext:v}},[i]);return x.jsxs("div",{className:"test-result",children:[!!d.length&&x.jsxs(gn,{header:"Errors",children:[y&&x.jsx("div",{style:{position:"absolute",right:"16px",padding:"10px",zIndex:1},children:x.jsx(Zx,{context:y})}),d.map((g,A)=>g.type==="screenshot"?x.jsx(qx,{errorPrefix:g.errorPrefix,diff:g.diff,errorSuffix:g.errorSuffix},"test-result-error-message-"+A):x.jsx(rc,{code:g.error},"test-result-error-message-"+A))]}),!!i.steps.length&&x.jsx(gn,{header:"Test Steps",children:i.steps.map((g,A)=>x.jsx(o1,{step:g,result:i,test:t,depth:0},`step-${A}`))}),c.map((g,A)=>x.jsx(ol,{id:g.anchors,children:x.jsx(gn,{dataTestId:"test-results-image-diff",header:`Image mismatch: ${g.name}`,revealOnAnchorId:g.anchors,children:x.jsx(l1,{diff:g})})},`diff-${A}`)),!!r.length&&x.jsx(gn,{header:"Screenshots",revealOnAnchorId:m,children:r.map((g,A)=>x.jsxs(ol,{id:`attachment-${i.attachments.indexOf(g)}`,children:[x.jsx("a",{href:g.path,children:x.jsx("img",{className:"screenshot",src:g.path})}),x.jsx(nu,{attachment:g,result:i})]},`screenshot-${A}`))}),!!a.length&&x.jsx(ol,{id:"attachment-trace",children:x.jsx(gn,{header:"Traces",revealOnAnchorId:"attachment-trace",children:x.jsxs("div",{children:[x.jsx("a",{href:t1(a),children:x.jsx("img",{className:"screenshot",src:Qx,style:{width:192,height:117,marginLeft:20}})}),a.map((g,A)=>x.jsx(nu,{attachment:g,result:i,linkName:a.length===1?"trace":`trace-${A+1}`},`trace-${A}`))]})})}),!!a.length&&x.jsx(ol,{id:"attachment-video",children:x.jsx(gn,{header:"Videos",revealOnAnchorId:"attachment-video",children:x.jsx(_x,{traceUrls:a.filter(g=>g.path).map(g=>g.path)})})}),!!u.size&&x.jsx(gn,{header:"Attachments",revealOnAnchorId:h,dataTestId:"attachments",children:[...u].map((g,A)=>x.jsx(ol,{id:`attachment-${i.attachments.indexOf(g)}`,children:x.jsx(nu,{attachment:g,result:i,openInNewTab:g.contentType.startsWith("text/html")})},`attachment-link-${A}`))})]})};function tv(t){return typeof t=="string"?t:t.codeframe?`${t.message}
|
|
71
71
|
${t.codeframe}`:t.message}function nv(t,i){return t.map(r=>{const o=tv(r),a=o.split(`
|