@testrelic/playwright-analytics 2.4.4 → 2.4.5

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/dist/index.cjs CHANGED
@@ -2580,7 +2580,7 @@ ${s}
2580
2580
  `);}return u||(s=e.filter(h=>h.type==="lambdatest-navigation"&&h.description).map(h=>{try{return JSON.parse(h.description)}catch{return null}}).filter(h=>h!==null)),s.length===0&&i===0&&p===0&&!n&&!u&&process.stderr.write(`[testrelic] Warning: No data found for test "${r}". Make sure your tests import { test, expect } from '@testrelic/playwright-analytics/fixture' instead of '@playwright/test'. Without the TestRelic fixture, network logs, video sync, and timeline data cannot be captured.
2581
2581
  `),{navigations:s,apiAssertions:a,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:l,consoleLogsCount:d,apiCallsFile:c,apiCallsCount:p}}var ta=5,me=[1e3,3e3,9e3],U=3,ra={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},nt=0,st=[];async function na(){nt>=ta&&await new Promise(t=>st.push(t)),nt++;}function sa(){nt--,st.length>0&&st.shift()();}async function ve(t){return new Promise(e=>setTimeout(e,t))}function aa(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return ra[e]??"application/octet-stream"}function ia(t){try{return fs$1.statSync(t).size}catch{return 0}}async function oa(t,e,r,n,s){let a=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:s,type:r.type,sizeBytes:n});for(let i=0;i<U;i++)try{let l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o});if(l.ok)return await l.json();if(l.status>=500&&i<U-1){await ve(me[i]);continue}return null}catch{if(i<U-1){await ve(me[i]);continue}return null}return null}async function la(t,e,r,n){for(let s=0;s<U;s++)try{let a=fs$1.createReadStream(e),o=stream.Readable.toWeb(a),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(n)},body:o,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&s<U-1){await ve(me[s]);continue}return !1}catch{if(s<U-1){await ve(me[s]);continue}return false}return false}async function da(t,e,r){let n=`${t}/artifacts/confirm`;try{return (await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function ca(t,e,r,n){let s=ia(r.filePath);if(s===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(s>n*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let a=aa(r.filePath);await na();try{let o=await oa(t,e,r,s,a);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await la(o.uploadUrl,r.filePath,a,s))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let l=await da(t,e,o.artifactId);return {success:l,storageKey:o.storageKey,artifactId:o.artifactId,error:l?null:"confirm_failed"}}finally{sa();}}async function Pr(t,e,r,n){let s=new Map,a=r.map(async o=>{let i=await ca(t,e,o,n);s.set(o.filePath,i);});return await Promise.allSettled(a),s}function at(t){let r=t.getGitMetadata()?.remoteUrl;return r?X(r):t.getConfig()?.projectName??ee(process.cwd())}async function Fr(t,e,r,n,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=P();return (await Ir(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:at(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:n,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??null}))?.runId??null}async function ua(t,e,r,n){let s=new Map;if(!e.uploadArtifacts||!await t.ensureValidToken())return s;let o=[],i=new Map;for(let p of n){if(p.artifacts.screenshot){let f=path.join(p.outputDir,p.artifacts.screenshot);o.push({filePath:f,runId:r,testId:p.testId,type:"screenshot"}),i.set(f,{testId:p.testId,field:"screenshot"});}if(p.artifacts.video){let f=path.join(p.outputDir,p.artifacts.video);o.push({filePath:f,runId:r,testId:p.testId,type:"video"}),i.set(f,{testId:p.testId,field:"video"});}}if(o.length===0)return s;let l=await Pr(t.getEndpoint(),t.getAccessToken(),o,e.artifactMaxSizeMb),d=new Map;for(let[p,f]of l){if(!f.success||!f.storageKey)continue;let u=i.get(p);if(!u)continue;let g=d.get(u.testId)??{};u.field==="screenshot"&&(g.screenshotKey=f.storageKey),u.field==="video"&&(g.videoKey=f.storageKey),d.set(u.testId,g);}for(let p of n){let f=d.get(p.testId);s.set(p.testId,{...p.artifacts,...f?.screenshotKey?{screenshotKey:f.screenshotKey}:{},...f?.videoKey?{videoKey:f.videoKey}:{}});}let c=Array.from(l.values()).filter(p=>p.success).length;return c>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${c} artifact(s) to cloud storage.
2582
2582
  `),s}async function it(t,e,r,n,s,a,o,i,l,d,c){try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){let f=await t.ensureValidToken(),u=t.getGitMetadata(),g={finishedAt:o,duration:i,summary:l,...u?.commitMessage?{commitMessage:u.commitMessage}:{}};if(f){if(!await Mr(t.getEndpoint(),t.getAccessToken(),s,g)){let m=e?.queueDirectory??".testrelic/queue";te(m,n,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",g,{"Content-Type":"application/json"});}}else {let h=e?.queueDirectory??".testrelic/queue";te(h,n,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",g,{"Content-Type":"application/json"});}}let p=new Map;if(t.isCloudMode()&&e&&d&&d.length>0&&(p=await ua(t,e,n,d)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let u=t.getGitMetadata(),g=P(),h=at(t),m=pa(a,p),y=tt(m,h,u,g,c),T=await _r(t.getEndpoint(),t.getAccessToken(),y,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!T.success){let b=T,w=e?.queueDirectory??".testrelic/queue";te(w,n,"batch",b.reason,b.targetEndpoint,b.method,b.payload,{"Content-Type":"application/json"});}}else {let u=e?.queueDirectory??".testrelic/queue",g=t.getGitMetadata(),h=P(),m=at(t),y=tt(a,m,g,h);te(u,n,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",y,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function pa(t,e){if(e.size===0)return t;let r=t.timeline.map(n=>{let s=n.testId;if(!s)return n;let a=e.get(s);return a?{...n,...a.screenshotKey?{screenshotKey:a.screenshotKey}:{},...a.videoKey?{videoKey:a.videoKey}:{}}:n});return {...t,timeline:r}}function ye(t){try{return fs$1.readFileSync(t,"utf-8").split(`
2583
- `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function lt(t){switch(t){case "passed":return "passed";case "failed":return "failed";case "timedOut":return "timedout";case "skipped":return "skipped";case "interrupted":return "failed";default:return "failed"}}function ba(t,e,r){let n=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,16)}function wa(t){return t.length<=3?"":t[t.length-2]}function xa(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function ka(t){return process.env.BROWSERSTACK_USERNAME?"BrowserStack":t?{"github-actions":"GitHub Actions","gitlab-ci":"GitLab CI",jenkins:"Jenkins",circleci:"CircleCI","bitbucket-pipelines":"Bitbucket Pipelines"}[t.provider]??"CI":"Local"}function Ta(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function Ca(t){let e=t.toLowerCase();return e.includes("chrom")?"Chrome":e.includes("firefox")?"Firefox":e.includes("webkit")||e.includes("safari")?"WebKit":t||void 0}function Sa(t,e,r){let n=r.parent?.project?.(),s="unknown";if(n!==void 0){let l=n.use;l.isMobile===true?s="mobile":l.browserName?s="e2e":s="api";}let a=["e2e","api","unit","mobile"];for(let l of a)if(t.some(d=>d===`@${l}`||d===l))return l;let o=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let l of i)if(o.includes(`/${l}/`))return l;return s}var Ra="__testrelic_api_config";function Aa(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var be=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.pendingArtifactEntries=[];this.detectedOs="";this.detectedSource="";this.cloudTestsBuffer=[];this.activeReportMode="embedded";this.streamingWriter=null;this.testIndex=[];this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};this.config=Rt(e),this.apiConfig=St(e);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let n=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${n} tests)
2583
+ `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function lt(t){switch(t){case "passed":return "passed";case "failed":return "failed";case "timedOut":return "timedout";case "skipped":return "skipped";case "interrupted":return "failed";default:return "failed"}}function ba(t,e,r){let n=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,16)}function wa(t){return t.length<=3?"":t[t.length-2]}function xa(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function ka(t){return process.env.BROWSERSTACK_USERNAME?"BrowserStack":t?{"github-actions":"GitHub Actions","gitlab-ci":"GitLab CI",jenkins:"Jenkins",circleci:"CircleCI","bitbucket-pipelines":"Bitbucket Pipelines"}[t.provider]??"CI":"Local"}function Ta(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function Ca(t){let e=t.toLowerCase();return e.includes("chrom")?"Chrome":e.includes("firefox")?"Firefox":e.includes("webkit")||e.includes("safari")?"WebKit":t||void 0}function Sa(t,e,r){let n=r.parent?.project?.(),s="unknown";n!==void 0&&(n.use.isMobile===true?s="mobile":s="e2e");let a=["e2e","api","unit","mobile"];for(let l of a)if(t.some(d=>d===`@${l}`||d===l))return l;let o=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let l of i)if(o.includes(`/${l}/`))return l;return s}var Ra="__testrelic_api_config";function Aa(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var be=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.pendingArtifactEntries=[];this.detectedOs="";this.detectedSource="";this.cloudTestsBuffer=[];this.activeReportMode="embedded";this.streamingWriter=null;this.testIndex=[];this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};this.config=Rt(e),this.apiConfig=St(e);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let n=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${n} tests)
2584
2584
  `),this.activeReportMode==="streaming"){let a=path.dirname(this.config.outputPath);this.streamingWriter=new J(a);let o=()=>{if(this.streamingWriter){try{this.streamingWriter.writeIndex(this.testIndex);let i={testRunId:this.testRunId??"",startedAt:this.startedAt,completedAt:new Date().toISOString(),totalDuration:Date.now()-new Date(this.startedAt).getTime(),...this.summaryCounters,metadata:null,reportMode:"streaming",files:[],enrichedSummary:null,validation:null,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(i);}catch{}this.streamingWriter.dispose();}try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let i=this.cloudClient.getAccessToken();i&&rt(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",o),process.on("SIGINT",o);}if(this.config.includeArtifacts){let a=path.dirname(this.config.outputPath);this.runTimestamp=nr(path.join(a,"artifacts"));try{lr(path.join(a,"artifacts"));}catch{}}let s=P();this.detectedOs=Ta(),this.detectedSource=ka(s);try{this.cloudClient=new pe(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await Fr(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let a=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let o=this.cloudClient.getAccessToken();o&&rt(this.cloudClient.getEndpoint(),o,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",a),process.on("SIGINT",a);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:Ra,description:Aa(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let n=r,s=e.outcome(),a;s==="flaky"?a="flaky":s==="skipped"?a="skipped":a=lt(n.status);let o=n.startTime.toISOString(),i=new Date(n.startTime.getTime()+n.duration).toISOString(),l=e.tags?[...e.tags]:e.annotations.filter(A=>A.type==="tag").map(A=>A.description??""),d=Nr(n.attachments,e.annotations,e.title,a==="skipped");(d.navigations.length>0||d.networkRequestsCount>0||d.apiCallsCount>0)&&(this.fixtureDataReceived=!0);let c=null;if(a==="failed"||a==="flaky"){let S=(a==="flaky"?e.results.find(B=>B.status!=="passed")?.errors??[]:n.errors)[0];if(S){let B=_t(this.config.redactPatterns),V=S.location?.line??null,G=null;this.config.includeCodeSnippets&&V!==null&&S.location?.file&&(G=At(S.location.file,V,this.config.codeContextLines),G&&(G=B(G))),c={message:B(S.message??"Unknown error"),line:V,code:G,stack:this.config.includeStackTrace&&S.stack?B(S.stack):null};}}let p=e.titlePath().filter(Boolean),f=path.relative(this.rootDir||".",e.location.file),u=wa(p),g=p.join(" > "),h=f,m=ba(h,u,g),y=Sa(l,h,e),T=s==="flaky",b=xa(e.results),w=lt(e.expectedStatus),C=lt(n.status),v=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments){let A=path.dirname(this.config.outputPath),S=p[p.length-1]??e.title;v=sr(n.attachments,S,n.retry,A,this.runTimestamp||void 0);}let k=this.config.includeActionSteps&&n.steps?fr(n.steps,n.startTime):null,q=Ca(p[0]??""),R={titlePath:p,title:g,status:a,duration:n.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:n.retry,tags:l,failure:c,specFile:f,navigations:d.navigations,testId:m,filePath:h,suiteName:u,testType:y,isFlaky:T,retryStatus:b,expectedStatus:w,actualStatus:C,artifacts:v,apiAssertions:d.apiAssertions,actions:k,networkRequestsFile:d.networkRequestsFile,networkRequestsCount:d.networkRequestsCount,consoleLogsFile:d.consoleLogsFile,consoleLogsCount:d.consoleLogsCount,apiCallsFile:d.apiCallsFile,apiCallsCount:d.apiCallsCount,browser:q,os:this.detectedOs||void 0,source:this.detectedSource||void 0};this.cloudTestsBuffer.push({testId:m,title:g,status:a,duration:n.duration,suiteName:u,filePath:h,testType:y,isFlaky:T,startedAt:o,completedAt:i,tags:l,failure:c,browser:q,os:this.detectedOs||void 0,source:this.detectedSource||void 0});try{let A=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(A==="realtime"||A==="both")){let S=this.cloudClient.getAccessToken();S&&Lr(this.cloudClient.getEndpoint(),S,this.cloudRunId,this.buildCloudTestPayload(R));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let A=Te(h,p,e.id??"",n.retry),S=n.retry===e.results.length-1,B={id:A,navigations:d.navigations,apiAssertions:d.apiAssertions,actions:k??[],artifacts:v,failureDiagnostic:c,hasNetworkFile:d.networkRequestsFile!==null,networkRequestsCount:d.networkRequestsCount,hasConsoleFile:d.consoleLogsFile!==null,consoleLogsCount:d.consoleLogsCount,hasApiCallsFile:d.apiCallsFile!==null,apiCallsCount:d.apiCallsCount,startedAt:o};this.streamingWriter.writeTestDetail(A,B,{networkRequestsFile:d.networkRequestsFile,consoleLogsFile:d.consoleLogsFile,apiCallsFile:d.apiCallsFile});let V={id:A,title:p[p.length-1]??e.title,titlePath:p,filePath:h,status:a,duration:n.duration,project:p[1]??"",retryIndex:n.retry,tags:l,hasNetworkData:d.networkRequestsCount>0,hasConsoleData:d.consoleLogsCount>0,hasArtifacts:v!==null,hasActionSteps:(k?.length??0)>0,errorMessage:c?.message?.split(`
2585
2585
  `)[0]??null,networkCount:d.networkRequestsCount,consoleCount:d.consoleLogsCount,actionCount:k?.length??0,isRetry:!S};if(this.testIndex.push(V),S)switch(this.summaryCounters.total++,a){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.summaryCounters.totalApiCalls+=d.apiCallsCount,this.summaryCounters.totalAssertions+=d.apiAssertions.length,this.summaryCounters.totalNavigations+=d.navigations.length,this.summaryCounters.totalNetworkRequests+=d.networkRequestsCount,this.summaryCounters.totalConsoleLogs+=d.consoleLogsCount,this.summaryCounters.totalActionSteps+=k?.length??0,v&&this.pendingArtifactEntries.push({testId:m,artifacts:v,outputDir:path.dirname(this.config.outputPath)}),R.actions=null,R.apiAssertions=null,R.navigations=[],R.artifacts=null,R.failure=null,R.networkRequestsFile=null,R.consoleLogsFile=null,R.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(R),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),n=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-n,o=this.activeReportMode==="streaming"?this.testIndex.some(l=>l.status!=="skipped"):this.collectedTests.some(l=>l.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
2586
2586
  \u26A0 TestRelic: No fixture data received from any test.