@testrelic/playwright-analytics 2.9.0-next.68 → 2.9.0-next.70

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.
@@ -1,10 +1,10 @@
1
- 'use strict';var crypto=require('crypto'),fs$1=require('fs'),path=require('path'),os$1=require('os'),core=require('@testrelic/core'),child_process=require('child_process'),http=require('http'),readline=require('readline'),promises=require('fs/promises'),zlib=require('zlib'),stream=require('stream');var qr=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var zr=".testrelic-report";function xe(t,e,r,a){let s=`${t}|${e.join("|")}|${r}|${a}`;return crypto.createHash("sha256").update(s).digest("hex").substring(0,12)}var G=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=path.join(e,zr),this.testsDir=path.join(this.reportDir,"tests"),fs$1.mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,a){try{let s=path.join(this.testsDir,e);fs$1.mkdirSync(s,{recursive:!0});let n=path.join(s,"meta.json"),o=n+".tmp",i=JSON.stringify(r);return fs$1.writeFileSync(o,i,"utf-8"),fs$1.renameSync(o,n),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),a?.networkRequestsFile&&this.moveFile(a.networkRequestsFile,path.join(s,"network.jsonl")),a?.consoleLogsFile&&this.moveFile(a.consoleLogsFile,path.join(s,"console.jsonl")),a?.apiCallsFile&&this.moveFile(a.apiCallsFile,path.join(s,"api-calls.jsonl")),!0}catch(s){let n=s instanceof Error?s.message:String(s);return this.writeErrors.push({testId:e,error:n,timestamp:new Date().toISOString()}),process.stderr.write(`[testrelic] Failed to write test detail for ${e}: ${n}
1
+ 'use strict';var crypto=require('crypto'),fs$1=require('fs'),path=require('path'),os=require('os'),core=require('@testrelic/core'),child_process=require('child_process'),http=require('http'),readline=require('readline'),promises=require('fs/promises'),zlib=require('zlib'),stream=require('stream');var qr=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var zr=".testrelic-report";function xe(t,e,r,a){let n=`${t}|${e.join("|")}|${r}|${a}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,12)}var G=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=path.join(e,zr),this.testsDir=path.join(this.reportDir,"tests"),fs$1.mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,a){try{let n=path.join(this.testsDir,e);fs$1.mkdirSync(n,{recursive:!0});let s=path.join(n,"meta.json"),o=s+".tmp",i=JSON.stringify(r);return fs$1.writeFileSync(o,i,"utf-8"),fs$1.renameSync(o,s),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),a?.networkRequestsFile&&this.moveFile(a.networkRequestsFile,path.join(n,"network.jsonl")),a?.consoleLogsFile&&this.moveFile(a.consoleLogsFile,path.join(n,"console.jsonl")),a?.apiCallsFile&&this.moveFile(a.apiCallsFile,path.join(n,"api-calls.jsonl")),!0}catch(n){let s=n instanceof Error?n.message:String(n);return this.writeErrors.push({testId:e,error:s,timestamp:new Date().toISOString()}),process.stderr.write(`[testrelic] Failed to write test detail for ${e}: ${s}
2
2
  `),false}}moveFile(e,r){try{fs$1.renameSync(e,r);}catch{try{let{copyFileSync:a}=qr("fs");a(e,r);try{fs$1.unlinkSync(e);}catch{}}catch(a){process.stderr.write(`[testrelic] Failed to move file ${e} \u2192 ${r}: ${a instanceof Error?a.message:String(a)}
3
- `);}}}writeIndex(e){let r=path.join(this.reportDir,"index.json"),a=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(a,s,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),a=r+".tmp",s=e.map(({titlePath:o,project:i,...l})=>l),n=JSON.stringify(s);fs$1.writeFileSync(a,n,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),a=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(a,s,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),a=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(a,s,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var kt=".testrelic",Kr="testrelic-config.json",Jr=".testrelic",Yr=5,Zr=new Set(["__proto__","constructor","prototype"]),xt=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${kt}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),Qr={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Tt(t){let e=path.resolve(t);for(let r=0;r<=Yr;r++){let a=path.join(e,kt,Kr);if(fs$1.existsSync(a))try{if(fs$1.statSync(a).isFile())return a}catch{}let s=path.join(e,Jr);if(fs$1.existsSync(s))try{if(fs$1.statSync(s).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
- `),s}catch{}let n=path.dirname(e);if(n===e)break;e=n;}return null}function St(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!Ct(r)?null:r}catch{return null}}function Ct(t){for(let e of Object.keys(t)){if(Zr.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!Ct(r))return false}return true}function Rt(t){let e=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(t);if(e)return process.env[e[1]]??null;let r=/^\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(t);return r?process.env[r[1]]??null:t}function we(t){let e=Object.create(null);for(let r of Object.keys(t)){let a=t[r];typeof a=="string"&&a.startsWith("$")?e[r]=Rt(a):typeof a=="object"&&a!==null&&!Array.isArray(a)?e[r]=we(a):e[r]=a;}return e}function wt(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),a=e[2],s=Qr[a];return !s||r<=0?null:r*s}function At(t,e){let r=Object.create(null);if(Object.assign(r,xt),t){let l=t.cloud;l&&typeof l=="object"&&(typeof l.endpoint=="string"&&(r.endpoint=l.endpoint),typeof l.upload=="string"&&(r.uploadStrategy=l.upload),typeof l.timeout=="number"&&(r.timeout=l.timeout),typeof l.apiKey=="string"&&l.apiKey.length>0&&(r.apiKey=l.apiKey));let d=t["testrelic-repo"]??t.project;d&&typeof d=="object"&&typeof d.name=="string"&&(r.projectName=d.name),t.project&&!t["testrelic-repo"]&&process.stderr.write(`[testrelic] Deprecation: "project" key in config is deprecated. Rename it to "testrelic-repo".
5
- `);let p=t.queue;if(p&&typeof p=="object"){if(typeof p.maxAge=="string"){let f=wt(p.maxAge);f!==null&&(r.queueMaxAge=f);}typeof p.directory=="string"&&(r.queueDirectory=p.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let l=e.apiKey.startsWith("$")?Rt(e.apiKey):e.apiKey;l&&(r.apiKey=l);}if(typeof e.endpoint=="string"&&(r.endpoint=e.endpoint),typeof e.upload=="string"&&(r.uploadStrategy=e.upload),typeof e.timeout=="number"&&(r.timeout=e.timeout),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let l=wt(e.queueMaxAge);l!==null&&(r.queueMaxAge=l);}typeof e.queueDirectory=="string"&&(r.queueDirectory=e.queueDirectory),typeof e.uploadArtifacts=="boolean"&&(r.uploadArtifacts=e.uploadArtifacts),typeof e.artifactMaxSizeMb=="number"&&(r.artifactMaxSizeMb=e.artifactMaxSizeMb);}let a=process.env.TESTRELIC_API_KEY;a&&a.length>0&&(r.apiKey=a);let s=process.env.TESTRELIC_CLOUD_ENDPOINT;s&&core.isValidEndpointUrl(s)&&(r.endpoint=s);let n=process.env.TESTRELIC_UPLOAD_STRATEGY;n&&["batch","realtime","both"].includes(n)&&(r.uploadStrategy=n);let o=process.env.TESTRELIC_CLOUD_TIMEOUT;if(o){let l=parseInt(o,10);!isNaN(l)&&l>=1e3&&l<=12e4&&(r.timeout=l);}let i=Object.freeze(r);return core.isValidCloudConfig(i)?i:xt}var ra=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],aa=["authorization","cookie","set-cookie","x-api-key"],sa=["password","secret","token","apiKey","api_key"];function _t(t){let e=Object.create(null);return e.trackApiCalls=t?.trackApiCalls??true,e.captureRequestHeaders=t?.captureRequestHeaders??true,e.captureResponseHeaders=t?.captureResponseHeaders??true,e.captureRequestBody=t?.captureRequestBody??true,e.captureResponseBody=t?.captureResponseBody??true,e.captureAssertions=t?.captureAssertions??true,e.redactHeaders=t?.redactHeaders??[...aa],e.redactBodyFields=t?.redactBodyFields??[...sa],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function It(t){if(t!==void 0&&!core.isValidConfig(t))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid reporter configuration");let e=Object.create(null);e.outputPath=t?.outputPath??"./test-results/analytics-timeline.json",e.includeStackTrace=t?.includeStackTrace??false,e.includeCodeSnippets=t?.includeCodeSnippets??true,e.codeContextLines=t?.codeContextLines??3,e.includeNetworkStats=t?.includeNetworkStats??true,e.navigationTypes=t?.navigationTypes??null,e.redactPatterns=[...ra,...t?.redactPatterns??[]],e.testRunId=t?.testRunId??null,e.metadata=t?.metadata??null;let r=e.outputPath;e.openReport=t?.openReport??true,e.htmlReportPath=t?.htmlReportPath??r.replace(/\.json$/,".html"),e.includeArtifacts=t?.includeArtifacts??true,e.trackApiCalls=t?.trackApiCalls??true,e.quiet=t?.quiet??false,e.includeActionSteps=t?.includeActionSteps??true,e.captureConsoleLogs=t?.captureConsoleLogs??true;let a=Tt(process.cwd()),s=a?St(a):null,n=s?we(s):null,o=At(n,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var ke="1.3.0";function Lt(t,e,r){try{let s=fs$1.readFileSync(t,"utf-8").split(`
6
- `);if(e<1||e>s.length)return null;let n=Math.max(1,e-r),o=Math.min(s.length,e+r),i=[];for(let l=n;l<=o;l++){let d=l===e?">":" ",p=String(l).padStart(String(o).length," ");i.push(`${d} ${p} | ${s[l-1]}`);}return i.join(`
7
- `)}catch{return null}}function Mt(t){return e=>{let r=e;for(let a of t)if(typeof a=="string"){let s=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(s,"g"),"[REDACTED]");}else {let s=a.flags.includes("g")?a.flags:a.flags+"g",n=new RegExp(a.source,s);r=r.replace(n,"[REDACTED]");}return r}}function ia(t){return t.GITHUB_ACTIONS!=="true"?null:{provider:"github-actions",buildId:t.GITHUB_RUN_ID??null,commitSha:t.GITHUB_SHA??null,branch:t.GITHUB_REF_NAME??null,runUrl:t.GITHUB_SERVER_URL&&t.GITHUB_REPOSITORY&&t.GITHUB_RUN_ID?`${t.GITHUB_SERVER_URL}/${t.GITHUB_REPOSITORY}/actions/runs/${t.GITHUB_RUN_ID}`:null}}function oa(t){return t.GITLAB_CI!=="true"?null:{provider:"gitlab-ci",buildId:t.CI_PIPELINE_ID??null,commitSha:t.CI_COMMIT_SHA??null,branch:t.CI_COMMIT_BRANCH??t.CI_COMMIT_REF_NAME??null,runUrl:t.CI_PIPELINE_URL??null}}function la(t){if(!t.JENKINS_URL)return null;let e=t.GIT_BRANCH??null;return e?.startsWith("origin/")&&(e=e.slice(7)),{provider:"jenkins",buildId:t.BUILD_ID??null,commitSha:t.GIT_COMMIT??null,branch:e,runUrl:t.BUILD_URL??null}}function da(t){return t.CIRCLECI!=="true"?null:{provider:"circleci",buildId:t.CIRCLE_BUILD_NUM??null,commitSha:t.CIRCLE_SHA1??null,branch:t.CIRCLE_BRANCH??null,runUrl:t.CIRCLE_BUILD_URL??null}}function ca(t){if(!t.BITBUCKET_PIPELINE_UUID)return null;let e=t.BITBUCKET_WORKSPACE&&t.BITBUCKET_REPO_SLUG&&t.BITBUCKET_PIPELINE_UUID?`https://bitbucket.org/${t.BITBUCKET_WORKSPACE}/${t.BITBUCKET_REPO_SLUG}/pipelines/results/${t.BITBUCKET_PIPELINE_UUID}`:null;return {provider:"bitbucket-pipelines",buildId:t.BITBUCKET_BUILD_NUMBER??null,commitSha:t.BITBUCKET_COMMIT??null,branch:t.BITBUCKET_BRANCH??null,runUrl:e}}var ua=[ia,oa,la,da,ca];function P(t){let e=process.env;for(let r of ua){let a=r(e);if(a)return a}return null}var Te=`
3
+ `);}}}writeIndex(e){let r=path.join(this.reportDir,"index.json"),a=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(a,n,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),a=r+".tmp",n=e.map(({titlePath:o,project:i,...l})=>l),s=JSON.stringify(n);fs$1.writeFileSync(a,s,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),a=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(a,n,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),a=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(a,n,"utf-8"),fs$1.renameSync(a,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var kt=".testrelic",Kr="testrelic-config.json",Jr=".testrelic",Yr=5,Zr=new Set(["__proto__","constructor","prototype"]),xt=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${kt}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),Qr={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Tt(t){let e=path.resolve(t);for(let r=0;r<=Yr;r++){let a=path.join(e,kt,Kr);if(fs$1.existsSync(a))try{if(fs$1.statSync(a).isFile())return a}catch{}let n=path.join(e,Jr);if(fs$1.existsSync(n))try{if(fs$1.statSync(n).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
+ `),n}catch{}let s=path.dirname(e);if(s===e)break;e=s;}return null}function St(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!Ct(r)?null:r}catch{return null}}function Ct(t){for(let e of Object.keys(t)){if(Zr.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!Ct(r))return false}return true}function Rt(t){let e=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(t);if(e)return process.env[e[1]]??null;let r=/^\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(t);return r?process.env[r[1]]??null:t}function we(t){let e=Object.create(null);for(let r of Object.keys(t)){let a=t[r];typeof a=="string"&&a.startsWith("$")?e[r]=Rt(a):typeof a=="object"&&a!==null&&!Array.isArray(a)?e[r]=we(a):e[r]=a;}return e}function wt(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),a=e[2],n=Qr[a];return !n||r<=0?null:r*n}function At(t,e){let r=Object.create(null);if(Object.assign(r,xt),t){let l=t.cloud;l&&typeof l=="object"&&(typeof l.endpoint=="string"&&(r.endpoint=l.endpoint),typeof l.upload=="string"&&(r.uploadStrategy=l.upload),typeof l.timeout=="number"&&(r.timeout=l.timeout),typeof l.apiKey=="string"&&l.apiKey.length>0&&(r.apiKey=l.apiKey));let d=t["testrelic-repo"]??t.project;d&&typeof d=="object"&&typeof d.name=="string"&&(r.projectName=d.name),t.project&&!t["testrelic-repo"]&&process.stderr.write(`[testrelic] Deprecation: "project" key in config is deprecated. Rename it to "testrelic-repo".
5
+ `);let p=t.queue;if(p&&typeof p=="object"){if(typeof p.maxAge=="string"){let f=wt(p.maxAge);f!==null&&(r.queueMaxAge=f);}typeof p.directory=="string"&&(r.queueDirectory=p.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let l=e.apiKey.startsWith("$")?Rt(e.apiKey):e.apiKey;l&&(r.apiKey=l);}if(typeof e.endpoint=="string"&&(r.endpoint=e.endpoint),typeof e.upload=="string"&&(r.uploadStrategy=e.upload),typeof e.timeout=="number"&&(r.timeout=e.timeout),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let l=wt(e.queueMaxAge);l!==null&&(r.queueMaxAge=l);}typeof e.queueDirectory=="string"&&(r.queueDirectory=e.queueDirectory),typeof e.uploadArtifacts=="boolean"&&(r.uploadArtifacts=e.uploadArtifacts),typeof e.artifactMaxSizeMb=="number"&&(r.artifactMaxSizeMb=e.artifactMaxSizeMb);}let a=process.env.TESTRELIC_API_KEY;a&&a.length>0&&(r.apiKey=a);let n=process.env.TESTRELIC_CLOUD_ENDPOINT;n&&core.isValidEndpointUrl(n)&&(r.endpoint=n);let s=process.env.TESTRELIC_UPLOAD_STRATEGY;s&&["batch","realtime","both"].includes(s)&&(r.uploadStrategy=s);let o=process.env.TESTRELIC_CLOUD_TIMEOUT;if(o){let l=parseInt(o,10);!isNaN(l)&&l>=1e3&&l<=12e4&&(r.timeout=l);}let i=Object.freeze(r);return core.isValidCloudConfig(i)?i:xt}var ra=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],aa=["authorization","cookie","set-cookie","x-api-key"],na=["password","secret","token","apiKey","api_key"];function _t(t){let e=Object.create(null);return e.trackApiCalls=t?.trackApiCalls??true,e.captureRequestHeaders=t?.captureRequestHeaders??true,e.captureResponseHeaders=t?.captureResponseHeaders??true,e.captureRequestBody=t?.captureRequestBody??true,e.captureResponseBody=t?.captureResponseBody??true,e.captureAssertions=t?.captureAssertions??true,e.redactHeaders=t?.redactHeaders??[...aa],e.redactBodyFields=t?.redactBodyFields??[...na],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function It(t){if(t!==void 0&&!core.isValidConfig(t))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid reporter configuration");let e=Object.create(null);e.outputPath=t?.outputPath??"./test-results/analytics-timeline.json",e.includeStackTrace=t?.includeStackTrace??false,e.includeCodeSnippets=t?.includeCodeSnippets??true,e.codeContextLines=t?.codeContextLines??3,e.includeNetworkStats=t?.includeNetworkStats??true,e.captureNavigation=t?.captureNavigation??true,e.navigationTypes=t?.navigationTypes??null,e.redactPatterns=[...ra,...t?.redactPatterns??[]],e.testRunId=t?.testRunId??null,e.metadata=t?.metadata??null;let r=e.outputPath;e.openReport=t?.openReport??true,e.htmlReportPath=t?.htmlReportPath??r.replace(/\.json$/,".html"),e.includeArtifacts=t?.includeArtifacts??true,e.trackApiCalls=t?.trackApiCalls??true,e.quiet=t?.quiet??false,e.includeActionSteps=t?.includeActionSteps??true,e.captureConsoleLogs=t?.captureConsoleLogs??true;let a=Tt(process.cwd()),n=a?St(a):null,s=n?we(n):null,o=At(s,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var ke="1.3.0";function Lt(t,e,r){try{let n=fs$1.readFileSync(t,"utf-8").split(`
6
+ `);if(e<1||e>n.length)return null;let s=Math.max(1,e-r),o=Math.min(n.length,e+r),i=[];for(let l=s;l<=o;l++){let d=l===e?">":" ",p=String(l).padStart(String(o).length," ");i.push(`${d} ${p} | ${n[l-1]}`);}return i.join(`
7
+ `)}catch{return null}}function Mt(t){return e=>{let r=e;for(let a of t)if(typeof a=="string"){let n=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(n,"g"),"[REDACTED]");}else {let n=a.flags.includes("g")?a.flags:a.flags+"g",s=new RegExp(a.source,n);r=r.replace(s,"[REDACTED]");}return r}}function ia(t){return t.GITHUB_ACTIONS!=="true"?null:{provider:"github-actions",buildId:t.GITHUB_RUN_ID??null,commitSha:t.GITHUB_SHA??null,branch:t.GITHUB_REF_NAME??null,runUrl:t.GITHUB_SERVER_URL&&t.GITHUB_REPOSITORY&&t.GITHUB_RUN_ID?`${t.GITHUB_SERVER_URL}/${t.GITHUB_REPOSITORY}/actions/runs/${t.GITHUB_RUN_ID}`:null}}function oa(t){return t.GITLAB_CI!=="true"?null:{provider:"gitlab-ci",buildId:t.CI_PIPELINE_ID??null,commitSha:t.CI_COMMIT_SHA??null,branch:t.CI_COMMIT_BRANCH??t.CI_COMMIT_REF_NAME??null,runUrl:t.CI_PIPELINE_URL??null}}function la(t){if(!t.JENKINS_URL)return null;let e=t.GIT_BRANCH??null;return e?.startsWith("origin/")&&(e=e.slice(7)),{provider:"jenkins",buildId:t.BUILD_ID??null,commitSha:t.GIT_COMMIT??null,branch:e,runUrl:t.BUILD_URL??null}}function da(t){return t.CIRCLECI!=="true"?null:{provider:"circleci",buildId:t.CIRCLE_BUILD_NUM??null,commitSha:t.CIRCLE_SHA1??null,branch:t.CIRCLE_BRANCH??null,runUrl:t.CIRCLE_BUILD_URL??null}}function ca(t){if(!t.BITBUCKET_PIPELINE_UUID)return null;let e=t.BITBUCKET_WORKSPACE&&t.BITBUCKET_REPO_SLUG&&t.BITBUCKET_PIPELINE_UUID?`https://bitbucket.org/${t.BITBUCKET_WORKSPACE}/${t.BITBUCKET_REPO_SLUG}/pipelines/results/${t.BITBUCKET_PIPELINE_UUID}`:null;return {provider:"bitbucket-pipelines",buildId:t.BITBUCKET_BUILD_NUMBER??null,commitSha:t.BITBUCKET_COMMIT??null,branch:t.BITBUCKET_BRANCH??null,runUrl:e}}var ua=[ia,oa,la,da,ca];function P(t){let e=process.env;for(let r of ua){let a=r(e);if(a)return a}return null}var Te=`
8
8
  /* Theme Variables */
9
9
  :root,[data-theme="dark"]{
10
10
  --bg:#0f1117;--bg-1:#161b22;--bg-2:#1c2128;--bg-3:#21262d;--bg-code:#13111c;
@@ -2331,7 +2331,7 @@ function _updateCard(cls,val){
2331
2331
  renderFilterBar();
2332
2332
  renderTestGrid();
2333
2333
  var _lo=document.getElementById('loading-overlay');if(_lo)_lo.remove();
2334
- })();`;function Et(t,e,r){let a=t.replace(/<\//g,"<\\/"),s=r?r.replace(/<\//g,"<\\/"):null;return `<!-- TestRelic AI Analytics Report \u2014 self-contained, no external dependencies -->
2334
+ })();`;function Et(t,e,r){let a=t.replace(/<\//g,"<\\/"),n=r?r.replace(/<\//g,"<\\/"):null;return `<!-- TestRelic AI Analytics Report \u2014 self-contained, no external dependencies -->
2335
2335
  <!DOCTYPE html>
2336
2336
  <html lang="en" data-theme="">
2337
2337
  <head>
@@ -2384,15 +2384,15 @@ ${""}
2384
2384
  <div class="filter-drawer-body" id="filter-drawer-body"></div>
2385
2385
  </aside>
2386
2386
  <script id="report-data" type="application/json">${a}</script>
2387
- ${s?`<script id="artifact-manifest-data" type="application/json">${s}</script>`:""}
2387
+ ${n?`<script id="artifact-manifest-data" type="application/json">${n}</script>`:""}
2388
2388
  <script>${pa}</script>
2389
2389
  </body>
2390
- </html>`}function Pe(t,e,r,a){let s=t.replace(/<\//g,"<\\/"),n=e.replace(/<\//g,"<\\/"),o=a?a.replace(/<\//g,"<\\/"):null,i={};try{i=JSON.parse(t);}catch{}let l=`{
2390
+ </html>`}function Pe(t,e,r,a){let n=t.replace(/<\//g,"<\\/"),s=e.replace(/<\//g,"<\\/"),o=a?a.replace(/<\//g,"<\\/"):null,i={};try{i=JSON.parse(t);}catch{}let l=`{
2391
2391
  "schemaVersion":"2.0",
2392
2392
  "reportMode":"streaming",
2393
2393
  "serverPort":${r??"null"},
2394
- "summary":${s},
2395
- "index":${n},
2394
+ "summary":${n},
2395
+ "index":${s},
2396
2396
  "timeline":[],
2397
2397
  "testRunId":${JSON.stringify(String(i.testRunId??""))},
2398
2398
  "startedAt":${JSON.stringify(String(i.startedAt??""))},
@@ -2400,7 +2400,7 @@ ${s?`<script id="artifact-manifest-data" type="application/json">${s}</script>`:
2400
2400
  "totalDuration":${Number(i.totalDuration)||0},
2401
2401
  "ci":${i.ci?JSON.stringify(i.ci).replace(/<\//g,"<\\/"):"null"},
2402
2402
  "metadata":${i.metadata?JSON.stringify(i.metadata).replace(/<\//g,"<\\/"):"null"},
2403
- "shardRunIds":null
2403
+ "shardRunIds":${i.shardRunIds?JSON.stringify(i.shardRunIds).replace(/<\//g,"<\\/"):"null"}
2404
2404
  }`,d=`
2405
2405
  (function(){
2406
2406
  var data=JSON.parse(document.getElementById('report-data').textContent);
@@ -2543,27 +2543,27 @@ ${r?`<meta name="artifact-server-port" content="${r}">`:""}
2543
2543
  ${o?`<script id="artifact-manifest-data" type="application/json">${o}</script>`:""}
2544
2544
  <script>${d}</script>
2545
2545
  </body>
2546
- </html>`}function Fe(t){try{let e=process.platform,r;e==="darwin"?r=`open "${t}"`:e==="win32"?r=`start "" "${t}"`:r=`xdg-open "${t}"`,child_process.exec(r,a=>{a&&process.stderr.write(`[testrelic] Failed to open browser: ${a.message}
2547
- `);});}catch{}}path.join(os$1.tmpdir(),"testrelic-data");async function Pt(t,e,r,a){let s=(e-1)*r,n=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let p of i)if(p.length!==0){if(o>=s&&n.length<r)try{n.push(JSON.parse(p));}catch{}if(o++,n.length>=r&&a!==void 0)break}let l=a??o,d=Math.max(1,Math.ceil(l/r));return {items:n,total:l,page:e,pageSize:r,totalPages:d}}var Dt=/^[a-f0-9]{12}$/,Ne=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Bt=500;function w(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Ot(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Allow-Methods","GET, DELETE, OPTIONS"),t.setHeader("Access-Control-Allow-Headers","Content-Type");}function ae(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function se(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let a of r){let s=path.join(t,a.name);a.isFile()?e+=fs$1.statSync(s).size:a.isDirectory()&&(e+=se(s));}}catch{}return e}function qt(t,e,r,a){let s=ae(path.join(r,"index.json"));w(e,200,{status:"ok",reportMode:"streaming",testCount:s?.length??0,uptime:Math.floor((Date.now()-a)/1e3)});}function Ht(t,e,r){let a=ae(path.join(r,"summary.json"));if(!a){w(e,404,{error:"Summary not found"});return}w(e,200,a);}function Ut(t,e,r){let a=ae(path.join(r,"index.json"));if(!a){w(e,404,{error:"Test index not found"});return}let n=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(n.get("page")??"1",10)||1),i=Math.min(Bt,Math.max(1,parseInt(n.get("pageSize")??"100",10)||100)),l=n.get("status")?.split(",").filter(Boolean)??null,d=n.get("file")??null,p=n.get("search")?.toLowerCase()??null,f=n.get("tag")?.split(",").filter(Boolean)??null,h=n.get("sort")??"file",c=n.get("order")==="desc"?-1:1,u=a;l&&l.length>0&&(u=u.filter(y=>l.includes(y.status))),d&&(u=u.filter(y=>y.filePath===d||y.filePath.startsWith(d+"/"))),p&&(u=u.filter(y=>y.title.toLowerCase().includes(p)||y.filePath.toLowerCase().includes(p))),f&&f.length>0&&(u=u.filter(y=>f.some(x=>y.tags.includes(x)))),u=[...u].sort((y,x)=>{let T=0;switch(h){case "duration":T=y.duration-x.duration;break;case "status":T=y.status.localeCompare(x.status);break;case "title":T=y.title.localeCompare(x.title);break;default:T=y.filePath.localeCompare(x.filePath);break}return T*c});let g=u.length,m=Math.max(1,Math.ceil(g/i)),b=(o-1)*i,S=u.slice(b,b+i);w(e,200,{tests:S,pagination:{page:o,pageSize:i,totalItems:g,totalPages:m},filters:{status:l,file:d,search:p,tag:f}});}function zt(t,e,r,a){if(!Dt.test(a)){w(e,400,{error:"Invalid test ID format"});return}let s=path.join(r,"tests",a,"meta.json"),n=path.join(r,"tests",`${a}.json`),o=fs$1.existsSync(s)?s:fs$1.existsSync(n)?n:null;if(!o){w(e,404,{error:`Test not found: ${a}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){w(e,500,{error:i instanceof Error?i.message:String(i)});}}async function $t(t,e,r,a,s){if(!Dt.test(a)){w(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",a,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[s]);if(!fs$1.existsSync(o)){w(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let l=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,d=Math.max(1,parseInt(l.get("page")??"1",10)||1),p=Math.min(Bt,Math.max(1,parseInt(l.get("pageSize")??"50",10)||50)),f,h=path.join(r,"tests",a,"meta.json");if(fs$1.existsSync(h))try{let u=JSON.parse(fs$1.readFileSync(h,"utf-8"));switch(s){case "network":f=u.networkRequestsCount;break;case "console":f=u.consoleLogsCount;break;case "api-calls":f=u.apiCallsCount;break}}catch{}let c=await Pt(o,d,p,f);w(e,200,c);}catch(i){w(e,500,{error:i instanceof Error?i.message:String(i)});}}function jt(t,e,r){let a=ae(path.join(r,"index.json"));if(!a){w(e,404,{error:"Test index not found"});return}let s=new Map;for(let o of a){if(o.isRetry)continue;let i=s.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},s.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let n=Array.from(s.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));w(e,200,{files:n});}function Vt(t,e,r){if(!fs$1.existsSync(r)){w(e,200,{runs:[],totalSizeBytes:0});return}try{let a=[],s=0,n=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of n){if(!o.isDirectory()||!Ne.test(o.name))continue;let i=path.join(r,o.name),l=se(i),d=fs$1.readdirSync(i,{withFileTypes:!0}).filter(p=>p.isDirectory());a.push({folderName:o.name,totalSizeBytes:l,testCount:d.length}),s+=l;}a.sort((o,i)=>i.folderName.localeCompare(o.folderName)),w(e,200,{runs:a,totalSizeBytes:s});}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}function Gt(t,e,r){try{let a=0,s=0;if(fs$1.existsSync(r)){let n=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of n){if(!o.isDirectory()||!Ne.test(o.name))continue;let i=path.join(r,o.name),l=se(i);fs$1.rmSync(i,{recursive:!0,force:!0}),s+=l,a++;}}w(e,200,{deletedCount:a,freedBytes:s});}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}function Wt(t,e,r,a){if(!Ne.test(a)){w(e,400,{error:"Invalid folder name"});return}let s=path.join(r,a);try{if(!fs$1.statSync(s).isDirectory()){w(e,404,{error:"Not found"});return}}catch{w(e,404,{error:"Not found"});return}try{let n=se(s);fs$1.rmSync(s,{recursive:!0,force:!0}),w(e,200,{deleted:a,freedBytes:n});}catch(n){w(e,500,{error:n instanceof Error?n.message:String(n)});}}function Kt(t,e,r){w(e,200,{status:"shutting_down"}),r.close();}function De(t,e,r){if(!fs$1.existsSync(r)){w(e,404,{error:"File not found"});return}try{let a=fs$1.readFileSync(r),s=path.extname(r).toLowerCase(),n=ba[s]??"application/octet-stream";e.writeHead(200,{"Content-Type":n}),e.end(a);}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}var ba={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".json":"application/json",".html":"text/html",".css":"text/css",".js":"text/javascript",".svg":"image/svg+xml"};var Ta=9323,Sa=10,Ca=1800*1e3;function W(t,e){return new Promise((r,a)=>{let s=e?.port??Ta,n=Date.now(),o,i=0,l=fs$1.existsSync(path.join(t,"artifacts"))?path.join(t,"artifacts"):fs$1.existsSync(path.join(t,"..","artifacts"))?path.join(t,"..","artifacts"):path.join(t,"artifacts");function d(){clearTimeout(o),o=setTimeout(()=>{f.close();},Ca);}let p=e?.htmlPath??null;if(!p){let c=path.dirname(t);try{let u=fs$1.readdirSync(c).find(g=>g.endsWith(".html"));u&&(p=path.join(c,u));}catch{}}let f=http.createServer((c,u)=>{if(d(),Ot(u),c.method==="OPTIONS"){u.writeHead(204),u.end();return}let g;try{g=new URL(c.url??"/",`http://${c.headers.host??"localhost"}`).pathname;}catch{w(u,400,{error:"Invalid URL"});return}if(c.method==="GET"&&(g==="/"||g==="/index.html")){if(p&&fs$1.existsSync(p)){De(c,u,p);return}w(u,404,{error:"HTML report not found"});return}if(c.method==="GET"&&g==="/api/health"){qt(c,u,t,n);return}if(c.method==="GET"&&g==="/api/summary"){Ht(c,u,t);return}if(c.method==="GET"&&g==="/api/tests"){Ut(c,u,t);return}if(c.method==="GET"&&g==="/api/files"){jt(c,u,t);return}let m=g.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(c.method==="GET"&&m){$t(c,u,t,m[1],m[2]);return}let b=g.match(/^\/api\/tests\/([a-f0-9]+)$/);if(c.method==="GET"&&b){zt(c,u,t,b[1]);return}if(c.method==="GET"&&g==="/api/artifacts"){Vt(c,u,l);return}if(c.method==="DELETE"&&g==="/api/artifacts"){Gt(c,u,l);return}let S=g.match(/^\/api\/artifacts\/(.+)$/);if(c.method==="DELETE"&&S){Wt(c,u,l,decodeURIComponent(S[1]));return}if(c.method==="GET"&&g.startsWith("/artifacts/")){let y=decodeURIComponent(g.slice(11));if(y.includes("..")||y.includes("\0")){w(u,400,{error:"Invalid path"});return}De(c,u,path.join(l,y));return}if(c.method==="POST"&&g==="/api/shutdown"){Kt(c,u,f);return}w(u,404,{error:"Not found"});});function h(c){let u=g=>{g.code==="EADDRINUSE"&&i<Sa?(i++,h(c+1)):a(g);};f.once("error",u),f.listen(c,"127.0.0.1",()=>{f.removeListener("error",u);let g=f.address();if(!g||typeof g=="string"){a(new Error("Failed to get server address"));return}d(),r({port:g.port,dispose:()=>new Promise(m=>{clearTimeout(o),f.close(()=>m());})});});}h(s);})}async function Jt(t){let e=await W(t);return {port:e.port,dispose:e.dispose}}function _a(t,e,r){let a=JSON.stringify(t),s=r?JSON.stringify(r):null;return Et(a,e,s)}async function Oe(t,e,r){try{let a=null,s=null,n=e.reportMode==="streaming"||e.reportMode==="auto"&&t.timeline.length===0&&t.summary.total>=e.streamingThreshold,o,i=e.htmlReportPath,l=path.dirname(i);fs$1.mkdirSync(l,{recursive:!0});let d="",p="[]",f=null;if(n){d=JSON.stringify(t.summary);let c=path.dirname(e.outputPath),u=path.join(c,".testrelic-report");try{let g=path.join(u,"index-compact.json"),m=path.join(u,"index.json");fs$1.existsSync(g)?p=fs$1.readFileSync(g,"utf-8"):fs$1.existsSync(m)&&(p=fs$1.readFileSync(m,"utf-8"));}catch{}f=r?JSON.stringify(r):null,o=Pe(d,p,null,f);}else o=_a(t,null,r);let h=i+".tmp";if(fs$1.writeFileSync(h,o,"utf-8"),fs$1.renameSync(h,i),n){if(t.ci===null){let c=path.dirname(e.outputPath),u=path.join(c,".testrelic-report"),g=path.resolve(i);try{if(await La(),a=await Ma(u),!a){s=await W(u,{htmlPath:g}),a=s.port;let m=setInterval(()=>{},6e4),b=()=>{clearInterval(m),s?.dispose();};process.on("SIGINT",b),process.on("SIGTERM",b),setTimeout(b,1800*1e3).unref();}if(a){process.stderr.write(`
2546
+ </html>`}function Ne(t){try{let e=process.platform,r;e==="darwin"?r=`open "${t}"`:e==="win32"?r=`start "" "${t}"`:r=`xdg-open "${t}"`,child_process.exec(r,a=>{a&&process.stderr.write(`[testrelic] Failed to open browser: ${a.message}
2547
+ `);});}catch{}}path.join(os.tmpdir(),"testrelic-data");async function Pt(t,e,r,a){let n=(e-1)*r,s=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let p of i)if(p.length!==0){if(o>=n&&s.length<r)try{s.push(JSON.parse(p));}catch{}if(o++,s.length>=r&&a!==void 0)break}let l=a??o,d=Math.max(1,Math.ceil(l/r));return {items:s,total:l,page:e,pageSize:r,totalPages:d}}var Dt=/^[a-f0-9]{12}$/,Fe=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Bt=500;function w(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Ot(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Allow-Methods","GET, DELETE, OPTIONS"),t.setHeader("Access-Control-Allow-Headers","Content-Type");}function ae(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function ne(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let a of r){let n=path.join(t,a.name);a.isFile()?e+=fs$1.statSync(n).size:a.isDirectory()&&(e+=ne(n));}}catch{}return e}function qt(t,e,r,a){let n=ae(path.join(r,"index.json"));w(e,200,{status:"ok",reportMode:"streaming",testCount:n?.length??0,uptime:Math.floor((Date.now()-a)/1e3)});}function Ht(t,e,r){let a=ae(path.join(r,"summary.json"));if(!a){w(e,404,{error:"Summary not found"});return}w(e,200,a);}function Ut(t,e,r){let a=ae(path.join(r,"index.json"));if(!a){w(e,404,{error:"Test index not found"});return}let s=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(s.get("page")??"1",10)||1),i=Math.min(Bt,Math.max(1,parseInt(s.get("pageSize")??"100",10)||100)),l=s.get("status")?.split(",").filter(Boolean)??null,d=s.get("file")??null,p=s.get("search")?.toLowerCase()??null,f=s.get("tag")?.split(",").filter(Boolean)??null,h=s.get("sort")??"file",c=s.get("order")==="desc"?-1:1,u=a;l&&l.length>0&&(u=u.filter(y=>l.includes(y.status))),d&&(u=u.filter(y=>y.filePath===d||y.filePath.startsWith(d+"/"))),p&&(u=u.filter(y=>y.title.toLowerCase().includes(p)||y.filePath.toLowerCase().includes(p))),f&&f.length>0&&(u=u.filter(y=>f.some(x=>y.tags.includes(x)))),u=[...u].sort((y,x)=>{let T=0;switch(h){case "duration":T=y.duration-x.duration;break;case "status":T=y.status.localeCompare(x.status);break;case "title":T=y.title.localeCompare(x.title);break;default:T=y.filePath.localeCompare(x.filePath);break}return T*c});let g=u.length,m=Math.max(1,Math.ceil(g/i)),b=(o-1)*i,S=u.slice(b,b+i);w(e,200,{tests:S,pagination:{page:o,pageSize:i,totalItems:g,totalPages:m},filters:{status:l,file:d,search:p,tag:f}});}function zt(t,e,r,a){if(!Dt.test(a)){w(e,400,{error:"Invalid test ID format"});return}let n=path.join(r,"tests",a,"meta.json"),s=path.join(r,"tests",`${a}.json`),o=fs$1.existsSync(n)?n:fs$1.existsSync(s)?s:null;if(!o){w(e,404,{error:`Test not found: ${a}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){w(e,500,{error:i instanceof Error?i.message:String(i)});}}async function $t(t,e,r,a,n){if(!Dt.test(a)){w(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",a,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[n]);if(!fs$1.existsSync(o)){w(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let l=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,d=Math.max(1,parseInt(l.get("page")??"1",10)||1),p=Math.min(Bt,Math.max(1,parseInt(l.get("pageSize")??"50",10)||50)),f,h=path.join(r,"tests",a,"meta.json");if(fs$1.existsSync(h))try{let u=JSON.parse(fs$1.readFileSync(h,"utf-8"));switch(n){case "network":f=u.networkRequestsCount;break;case "console":f=u.consoleLogsCount;break;case "api-calls":f=u.apiCallsCount;break}}catch{}let c=await Pt(o,d,p,f);w(e,200,c);}catch(i){w(e,500,{error:i instanceof Error?i.message:String(i)});}}function jt(t,e,r){let a=ae(path.join(r,"index.json"));if(!a){w(e,404,{error:"Test index not found"});return}let n=new Map;for(let o of a){if(o.isRetry)continue;let i=n.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},n.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let s=Array.from(n.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));w(e,200,{files:s});}function Vt(t,e,r){if(!fs$1.existsSync(r)){w(e,200,{runs:[],totalSizeBytes:0});return}try{let a=[],n=0,s=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of s){if(!o.isDirectory()||!Fe.test(o.name))continue;let i=path.join(r,o.name),l=ne(i),d=fs$1.readdirSync(i,{withFileTypes:!0}).filter(p=>p.isDirectory());a.push({folderName:o.name,totalSizeBytes:l,testCount:d.length}),n+=l;}a.sort((o,i)=>i.folderName.localeCompare(o.folderName)),w(e,200,{runs:a,totalSizeBytes:n});}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}function Gt(t,e,r){try{let a=0,n=0;if(fs$1.existsSync(r)){let s=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of s){if(!o.isDirectory()||!Fe.test(o.name))continue;let i=path.join(r,o.name),l=ne(i);fs$1.rmSync(i,{recursive:!0,force:!0}),n+=l,a++;}}w(e,200,{deletedCount:a,freedBytes:n});}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}function Wt(t,e,r,a){if(!Fe.test(a)){w(e,400,{error:"Invalid folder name"});return}let n=path.join(r,a);try{if(!fs$1.statSync(n).isDirectory()){w(e,404,{error:"Not found"});return}}catch{w(e,404,{error:"Not found"});return}try{let s=ne(n);fs$1.rmSync(n,{recursive:!0,force:!0}),w(e,200,{deleted:a,freedBytes:s});}catch(s){w(e,500,{error:s instanceof Error?s.message:String(s)});}}function Kt(t,e,r){w(e,200,{status:"shutting_down"}),r.close();}function De(t,e,r){if(!fs$1.existsSync(r)){w(e,404,{error:"File not found"});return}try{let a=fs$1.readFileSync(r),n=path.extname(r).toLowerCase(),s=ba[n]??"application/octet-stream";e.writeHead(200,{"Content-Type":s}),e.end(a);}catch(a){w(e,500,{error:a instanceof Error?a.message:String(a)});}}var ba={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".json":"application/json",".html":"text/html",".css":"text/css",".js":"text/javascript",".svg":"image/svg+xml"};var Ta=9323,Sa=10,Ca=1800*1e3;function W(t,e){return new Promise((r,a)=>{let n=e?.port??Ta,s=Date.now(),o,i=0,l=fs$1.existsSync(path.join(t,"artifacts"))?path.join(t,"artifacts"):fs$1.existsSync(path.join(t,"..","artifacts"))?path.join(t,"..","artifacts"):path.join(t,"artifacts");function d(){clearTimeout(o),o=setTimeout(()=>{f.close();},Ca);}let p=e?.htmlPath??null;if(!p){let c=path.dirname(t);try{let u=fs$1.readdirSync(c).find(g=>g.endsWith(".html"));u&&(p=path.join(c,u));}catch{}}let f=http.createServer((c,u)=>{if(d(),Ot(u),c.method==="OPTIONS"){u.writeHead(204),u.end();return}let g;try{g=new URL(c.url??"/",`http://${c.headers.host??"localhost"}`).pathname;}catch{w(u,400,{error:"Invalid URL"});return}if(c.method==="GET"&&(g==="/"||g==="/index.html")){if(p&&fs$1.existsSync(p)){De(c,u,p);return}w(u,404,{error:"HTML report not found"});return}if(c.method==="GET"&&g==="/api/health"){qt(c,u,t,s);return}if(c.method==="GET"&&g==="/api/summary"){Ht(c,u,t);return}if(c.method==="GET"&&g==="/api/tests"){Ut(c,u,t);return}if(c.method==="GET"&&g==="/api/files"){jt(c,u,t);return}let m=g.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(c.method==="GET"&&m){$t(c,u,t,m[1],m[2]);return}let b=g.match(/^\/api\/tests\/([a-f0-9]+)$/);if(c.method==="GET"&&b){zt(c,u,t,b[1]);return}if(c.method==="GET"&&g==="/api/artifacts"){Vt(c,u,l);return}if(c.method==="DELETE"&&g==="/api/artifacts"){Gt(c,u,l);return}let S=g.match(/^\/api\/artifacts\/(.+)$/);if(c.method==="DELETE"&&S){Wt(c,u,l,decodeURIComponent(S[1]));return}if(c.method==="GET"&&g.startsWith("/artifacts/")){let y=decodeURIComponent(g.slice(11));if(y.includes("..")||y.includes("\0")){w(u,400,{error:"Invalid path"});return}De(c,u,path.join(l,y));return}if(c.method==="POST"&&g==="/api/shutdown"){Kt(c,u,f);return}w(u,404,{error:"Not found"});});function h(c){let u=g=>{g.code==="EADDRINUSE"&&i<Sa?(i++,h(c+1)):a(g);};f.once("error",u),f.listen(c,"127.0.0.1",()=>{f.removeListener("error",u);let g=f.address();if(!g||typeof g=="string"){a(new Error("Failed to get server address"));return}d(),r({port:g.port,dispose:()=>new Promise(m=>{clearTimeout(o),f.close(()=>m());})});});}h(n);})}async function Jt(t){let e=await W(t);return {port:e.port,dispose:e.dispose}}function _a(t,e,r){let a=JSON.stringify(t),n=r?JSON.stringify(r):null;return Et(a,e,n)}async function Oe(t,e,r){try{let a=null,n=null,s=e.reportMode==="streaming"||e.reportMode==="auto"&&t.timeline.length===0&&t.summary.total>=e.streamingThreshold,o,i=e.htmlReportPath,l=path.dirname(i);fs$1.mkdirSync(l,{recursive:!0});let d="",p="[]",f=null;if(s){d=JSON.stringify({...t.summary,testRunId:t.testRunId,startedAt:t.startedAt,completedAt:t.completedAt,totalDuration:t.totalDuration,ci:t.ci,metadata:t.metadata,shardRunIds:t.shardRunIds});let c=path.dirname(e.outputPath),u=path.join(c,".testrelic-report");try{let g=path.join(u,"index-compact.json"),m=path.join(u,"index.json");fs$1.existsSync(g)?p=fs$1.readFileSync(g,"utf-8"):fs$1.existsSync(m)&&(p=fs$1.readFileSync(m,"utf-8"));}catch{}f=r?JSON.stringify(r):null,o=Pe(d,p,null,f);}else o=_a(t,null,r);let h=i+".tmp";if(fs$1.writeFileSync(h,o,"utf-8"),fs$1.renameSync(h,i),s){if(t.ci===null){let c=path.dirname(e.outputPath),u=path.join(c,".testrelic-report"),g=path.resolve(i);try{if(await La(),a=await Ma(u),!a){n=await W(u,{htmlPath:g}),a=n.port;let m=setInterval(()=>{},6e4),b=()=>{clearInterval(m),n?.dispose();};process.on("SIGINT",b),process.on("SIGTERM",b),setTimeout(b,1800*1e3).unref();}if(a){process.stderr.write(`
2548
2548
  Report server: http://127.0.0.1:${a}
2549
- `);try{let m=Pe(d,p,a,f),b=i+".tmp";fs$1.writeFileSync(b,m,"utf-8"),fs$1.renameSync(b,i);}catch{}}}catch{}}}else if(e.openReport&&t.ci===null&&e.includeArtifacts){let c=path.dirname(e.outputPath),u=path.join(c,"artifacts");if(fs$1.existsSync(u))try{let g=await Jt(u);a=g.port,process.on("exit",()=>{g.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(n&&a)Fe(`http://127.0.0.1:${a}`);else {let c=path.resolve(i);Fe(c);}}catch(a){process.stderr.write(`[testrelic] Failed to write HTML report: ${a instanceof Error?a.message:String(a)}
2550
- `);}}var oe=9323,er=10;async function Ia(){for(let t=oe;t<oe+er;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),a=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),a.ok)return t}catch{}return null}async function La(){for(let t=oe;t<oe+er;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),1e3);await fetch(`http://127.0.0.1:${t}/api/shutdown`,{method:"POST",signal:e.signal}),clearTimeout(r);}catch{}await new Promise(t=>setTimeout(t,300));}async function Ma(t){let r=[path.join(__dirname,"cli.cjs"),path.join(__dirname,"cli.js"),path.join(__dirname,"..","dist","cli.cjs"),path.join(__dirname,"..","dist","cli.js")].find(a=>fs$1.existsSync(a));if(!r){let a=await W(t);return process.on("exit",()=>{a?.dispose();}),a.port}return new Promise(a=>{let s=child_process.spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),n="",o=false,i=setTimeout(()=>{o||(o=true,s.stderr?.removeAllListeners(),Ia().then(a));},5e3);s.stderr?.on("data",l=>{n+=l.toString();let d=n.match(/127\.0\.0\.1:(\d+)/);d&&!o&&(o=true,clearTimeout(i),s.stderr?.removeAllListeners(),s.unref(),a(Number(d[1])));}),s.on("error",()=>{o||(o=true,clearTimeout(i),a(null));}),s.on("exit",()=>{o||(o=true,clearTimeout(i),a(null));}),s.unref();})}var Fa=20,qe=0,He=[];async function rr(t,e){qe>=Fa&&await new Promise(r=>He.push(r)),qe++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{qe--,He.length>0&&He.shift()();}}var J=[];async function ar(){J.length!==0&&(await Promise.allSettled(J),J.length=0);}function sr(t){let e=new Date,r=n=>String(n).padStart(2,"0"),a=`${e.getFullYear()}-${r(e.getMonth()+1)}-${r(e.getDate())}T${r(e.getHours())}-${r(e.getMinutes())}-${r(e.getSeconds())}`;if(!fs$1.existsSync(path.join(t,a)))return a;let s=1;for(;fs$1.existsSync(path.join(t,`${a}-${s}`));)s++;return `${a}-${s}`}function Na(t){let e=t.replace(/[^a-zA-Z0-9\-_ ]/g,"-").replace(/\s+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"");return e.length>100&&(e=e.substring(0,100).replace(/-+$/,"")),e||"unnamed-test"}function nr(t,e,r,a,s){let n=t.find(h=>h.name==="screenshot"&&h.path),o=t.find(h=>h.name==="video"&&h.path);if(!n&&!o)return null;let i=Na(e);r>0&&(i+=`--retry-${r}`);let l=s?["artifacts",s,i]:["artifacts",i],d=path.join(a,...l),p=l,f={};try{fs$1.mkdirSync(d,{recursive:!0});}catch{return null}if(n?.path&&fs$1.existsSync(n.path)){let c=`screenshot${path.extname(n.path)||".png"}`,u=path.join(d,c);J.push(rr(n.path,u).then(()=>{})),f.screenshot=`${p.join("/")}/${c}`;}if(o?.path&&fs$1.existsSync(o.path)){let c=`video${path.extname(o.path)||".webm"}`,u=path.join(d,c);J.push(rr(o.path,u).then(()=>{})),f.video=`${p.join("/")}/${c}`;}return !f.screenshot&&!f.video?null:f}var Oa=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,qa="1.0";function Ha(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function ir(t,e,r){let a=[];try{let s=fs$1.readdirSync(t,{withFileTypes:!0});for(let n of s){if(!n.isFile())continue;let o=path.join(t,n.name),i=fs$1.statSync(o);a.push({name:n.name,type:Ha(n.name),relativePath:`artifacts/${e}/${r}/${n.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:a}}function Ua(t,e){let r=path.join(t,e),a=[],s=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let l=ir(path.join(r,i.name),e,i.name);a.push(l);for(let d of l.files)s+=d.sizeBytes;}}catch{}let n=e.replace(/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})/,"$1T$2:$3:$4").replace(/-\d+$/,"");return a.sort((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:n,totalSizeBytes:s,testCount:a.length,tests:a,isCurrentRun:false}}function or(t,e){let r=path.join(t,"artifacts"),a=[],s=[],n=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let l of i)if(l.isDirectory())if(Oa.test(l.name)){let d=Ua(r,l.name);a.push({...d,isCurrentRun:l.name===e});}else {let d=ir(path.join(r,l.name),l.name,l.name);s.push(d);for(let p of d.files)n+=p.sizeBytes;}}catch{}a.sort((i,l)=>l.timestamp.localeCompare(i.timestamp)),s.length>0&&(s.sort((i,l)=>i.testName.localeCompare(l.testName)),a.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:n,testCount:s.length,tests:s,isCurrentRun:false}));let o=a.reduce((i,l)=>i+l.totalSizeBytes,0);return {schemaVersion:qa,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:a,serverPort:null}}function Ga(t){let e=t,{root:r}=path.parse(e);for(;e!==r;){if(fs$1.existsSync(path.join(e,".git")))return e;e=path.join(e,"..");}return null}function dr(t){try{let e=Ga(t);if(!e)return;let r=path.join(e,".gitignore"),a=path.relative(e,t).replace(/\\/g,"/"),s=a.endsWith("/")?a:`${a}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
2551
- `).map(l=>l.trim()).some(l=>l===s||l===a))return;let n=`
2549
+ `);try{let m=Pe(d,p,a,f),b=i+".tmp";fs$1.writeFileSync(b,m,"utf-8"),fs$1.renameSync(b,i);}catch{}}}catch{}}}else if(e.openReport&&t.ci===null&&e.includeArtifacts){let c=path.dirname(e.outputPath),u=path.join(c,"artifacts");if(fs$1.existsSync(u))try{let g=await Jt(u);a=g.port,process.on("exit",()=>{g.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(s&&a)Ne(`http://127.0.0.1:${a}`);else {let c=path.resolve(i);Ne(c);}}catch(a){process.stderr.write(`[testrelic] Failed to write HTML report: ${a instanceof Error?a.message:String(a)}
2550
+ `);}}var oe=9323,er=10;async function Ia(){for(let t=oe;t<oe+er;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),a=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),a.ok)return t}catch{}return null}async function La(){for(let t=oe;t<oe+er;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),1e3);await fetch(`http://127.0.0.1:${t}/api/shutdown`,{method:"POST",signal:e.signal}),clearTimeout(r);}catch{}await new Promise(t=>setTimeout(t,300));}async function Ma(t){let r=[path.join(__dirname,"cli.cjs"),path.join(__dirname,"cli.js"),path.join(__dirname,"..","dist","cli.cjs"),path.join(__dirname,"..","dist","cli.js")].find(a=>fs$1.existsSync(a));if(!r){let a=await W(t);return process.on("exit",()=>{a?.dispose();}),a.port}return new Promise(a=>{let n=child_process.spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),s="",o=false,i=setTimeout(()=>{o||(o=true,n.stderr?.removeAllListeners(),Ia().then(a));},5e3);n.stderr?.on("data",l=>{s+=l.toString();let d=s.match(/127\.0\.0\.1:(\d+)/);d&&!o&&(o=true,clearTimeout(i),n.stderr?.removeAllListeners(),n.unref(),a(Number(d[1])));}),n.on("error",()=>{o||(o=true,clearTimeout(i),a(null));}),n.on("exit",()=>{o||(o=true,clearTimeout(i),a(null));}),n.unref();})}var Na=20,qe=0,He=[];async function rr(t,e){qe>=Na&&await new Promise(r=>He.push(r)),qe++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{qe--,He.length>0&&He.shift()();}}var J=[];async function ar(){J.length!==0&&(await Promise.allSettled(J),J.length=0);}function nr(t){let e=new Date,r=s=>String(s).padStart(2,"0"),a=`${e.getFullYear()}-${r(e.getMonth()+1)}-${r(e.getDate())}T${r(e.getHours())}-${r(e.getMinutes())}-${r(e.getSeconds())}`;if(!fs$1.existsSync(path.join(t,a)))return a;let n=1;for(;fs$1.existsSync(path.join(t,`${a}-${n}`));)n++;return `${a}-${n}`}function Fa(t){let e=t.replace(/[^a-zA-Z0-9\-_ ]/g,"-").replace(/\s+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"");return e.length>100&&(e=e.substring(0,100).replace(/-+$/,"")),e||"unnamed-test"}function sr(t,e,r,a,n){let s=t.find(h=>h.name==="screenshot"&&h.path),o=t.find(h=>h.name==="video"&&h.path);if(!s&&!o)return null;let i=Fa(e);r>0&&(i+=`--retry-${r}`);let l=n?["artifacts",n,i]:["artifacts",i],d=path.join(a,...l),p=l,f={};try{fs$1.mkdirSync(d,{recursive:!0});}catch{return null}if(s?.path&&fs$1.existsSync(s.path)){let c=`screenshot${path.extname(s.path)||".png"}`,u=path.join(d,c);J.push(rr(s.path,u).then(()=>{})),f.screenshot=`${p.join("/")}/${c}`;}if(o?.path&&fs$1.existsSync(o.path)){let c=`video${path.extname(o.path)||".webm"}`,u=path.join(d,c);J.push(rr(o.path,u).then(()=>{})),f.video=`${p.join("/")}/${c}`;}return !f.screenshot&&!f.video?null:f}var Oa=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,qa="1.0";function Ha(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function ir(t,e,r){let a=[];try{let n=fs$1.readdirSync(t,{withFileTypes:!0});for(let s of n){if(!s.isFile())continue;let o=path.join(t,s.name),i=fs$1.statSync(o);a.push({name:s.name,type:Ha(s.name),relativePath:`artifacts/${e}/${r}/${s.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:a}}function Ua(t,e){let r=path.join(t,e),a=[],n=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let l=ir(path.join(r,i.name),e,i.name);a.push(l);for(let d of l.files)n+=d.sizeBytes;}}catch{}let s=e.replace(/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})/,"$1T$2:$3:$4").replace(/-\d+$/,"");return a.sort((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:s,totalSizeBytes:n,testCount:a.length,tests:a,isCurrentRun:false}}function or(t,e){let r=path.join(t,"artifacts"),a=[],n=[],s=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let l of i)if(l.isDirectory())if(Oa.test(l.name)){let d=Ua(r,l.name);a.push({...d,isCurrentRun:l.name===e});}else {let d=ir(path.join(r,l.name),l.name,l.name);n.push(d);for(let p of d.files)s+=p.sizeBytes;}}catch{}a.sort((i,l)=>l.timestamp.localeCompare(i.timestamp)),n.length>0&&(n.sort((i,l)=>i.testName.localeCompare(l.testName)),a.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:s,testCount:n.length,tests:n,isCurrentRun:false}));let o=a.reduce((i,l)=>i+l.totalSizeBytes,0);return {schemaVersion:qa,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:a,serverPort:null}}function Ga(t){let e=t,{root:r}=path.parse(e);for(;e!==r;){if(fs$1.existsSync(path.join(e,".git")))return e;e=path.join(e,"..");}return null}function dr(t){try{let e=Ga(t);if(!e)return;let r=path.join(e,".gitignore"),a=path.relative(e,t).replace(/\\/g,"/"),n=a.endsWith("/")?a:`${a}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
2551
+ `).map(l=>l.trim()).some(l=>l===n||l===a))return;let s=`
2552
2552
  # TestRelic test artifacts
2553
- ${s}
2554
- `;fs$1.appendFileSync(r,n,"utf-8");}catch{}}function pr(t,e){let r=[];for(let a of t){let s=Wa(a),n=Ka(a),o=Ja(a,s,n,e),i=Ya(a,s,n);if(o.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:a.startedAt,durationOnUrl:a.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:a.specFile,test:s,tests:[n],_testTitle:a.title});continue}r.push(...o,...i);}return r.sort(Za),Qa(r,t),r.map((a,s)=>a.type==="navigation"?{...{index:s,type:"navigation",url:a.url,timestamp:a.timestamp,durationOnUrl:a.durationOnUrl??0,navigationType:a.navigationType,domContentLoadedAt:a.domContentLoadedAt??null,networkIdleAt:a.networkIdleAt??null,networkStats:a.networkStats??null,specFile:a.specFile,test:a.test},tests:a.tests}:{...{index:s,type:"api_call",callId:a.callId,method:a.method,url:a.url,timestamp:a.timestamp,responseTime:a.responseTime??null,request:a.request,response:a.response??null,...a.error?{error:a.error}:{},assertions:a.assertions??[],specFile:a.specFile,test:a.test},tests:a.tests})}function Wa(t){return {title:t.title,fullTitle:t.titlePath,status:t.status,duration:t.duration,retries:t.retryCount,retry:t.retry,tags:t.tags,failure:t.failure}}function Ka(t){return {title:t.title,status:t.status,duration:t.duration,startedAt:t.startedAt,completedAt:t.completedAt,retryCount:t.retryCount,tags:t.tags,failure:t.failure,testId:t.testId,filePath:t.filePath,suiteName:t.suiteName,testType:t.testType,isFlaky:t.isFlaky,retryStatus:t.retryStatus,expectedStatus:t.expectedStatus,actualStatus:t.actualStatus,artifacts:t.artifacts,networkRequests:t.networkRequests,apiCalls:t.apiCalls,apiAssertions:t.apiAssertions,actions:t.actions,consoleLogs:t.consoleLogs}}function Ja(t,e,r,a){let s=[];for(let n of t.navigations)a.navigationTypes!==null&&!a.navigationTypes.includes(n.navigationType)||s.push({type:"navigation",url:n.url,timestamp:n.timestamp,durationOnUrl:0,navigationType:n.navigationType,domContentLoadedAt:n.domContentLoadedAt??null,networkIdleAt:n.networkIdleAt??null,networkStats:n.networkStats??null,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title});return s}function Ya(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let a=t.apiAssertions??[];return t.apiCalls.map(s=>{let n=a.filter(i=>i.callId===s.id).map(i=>({type:i.type,expected:i.expected,actual:i.actual,status:i.status,location:i.location,...i.expression!==void 0?{expression:i.expression}:{}})),o=null;return s.responseStatusCode!==null&&s.responseStatusText!==null&&(o={statusCode:s.responseStatusCode,statusText:s.responseStatusText,headers:s.responseHeaders,body:ur(s.responseBody)}),{type:"api_call",callId:s.id,method:s.method,url:s.url,timestamp:s.timestamp,responseTime:s.error?null:s.responseTimeMs,request:{headers:s.requestHeaders,body:ur(s.requestBody)},response:o,...s.error?{error:s.error}:{},assertions:n,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function Za(t,e){let r=new Date(t.timestamp).getTime(),a=new Date(e.timestamp).getTime();if(r!==a)return r-a;let s={navigation:0,api_call:1},n=s[t.type],o=s[e.type];return n!==o?n-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?cr(t.callId)-cr(e.callId):0}function cr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Qa(t,e){for(let r=0;r<t.length;r++){let a=t[r];if(a.type!=="navigation")continue;let s=new Date(a.timestamp).getTime(),n=null;for(let o=r+1;o<t.length;o++)if(t[o]._testTitle===a._testTitle){n=new Date(t[o].timestamp).getTime();break}if(n!==null)a.durationOnUrl=Math.max(0,n-s);else {let o=e.find(i=>i.title===a._testTitle);if(o){let i=new Date(o.completedAt).getTime();a.durationOnUrl=Math.max(0,i-s);}}}}function ur(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function $e(t,e){let r=t.length,a=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,a)]}function Xa(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function es(t){return t==null?"error":t>=200&&t<300?"2xx":t>=300&&t<400?"3xx":t>=400&&t<500?"4xx":t>=500&&t<600?"5xx":"error"}function fr(t,e){let r=0,a=0,s=0,n=0,o=0;for(let v of t)switch(v.status){case "passed":r++;break;case "failed":a++;break;case "flaky":s++;break;case "skipped":n++;break;case "timedout":o++;break}let i=[];for(let v of t)v.apiCalls&&i.push(...v.apiCalls);let l=i.length,d=new Set,p={},f={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},h=[];for(let v of i)d.add(Xa(v.url)),p[v.method]=(p[v.method]??0)+1,f[es(v.responseStatusCode)]+=1,h.push(v.responseTimeMs);let c=null;if(h.length>0){let v=[...h].sort((A,H)=>A-H),k=v.reduce((A,H)=>A+H,0);c={avg:Math.round(k/v.length),min:v[0],max:v[v.length-1],p50:$e(v,50),p95:$e(v,95),p99:$e(v,99)};}let u=0,g=0,m=0;for(let v of t)if(v.apiAssertions)for(let k of v.apiAssertions)u++,k.status==="passed"?g++:m++;let b=0,S=new Set;for(let v of t){b+=v.navigations.length;for(let k of v.navigations)S.add(k.url);}let y=0,x={};function T(v){for(let k of v)y++,x[k.category]=(x[k.category]??0)+1,k.children.length>0&&T(k.children);}for(let v of t)v.actions&&T(v.actions);return {total:t.length,passed:r,failed:a,flaky:s,skipped:n,timedout:o,totalApiCalls:l,uniqueApiUrls:d.size,apiCallsByMethod:p,apiCallsByStatusRange:f,apiResponseTime:c,totalAssertions:u,passedAssertions:g,failedAssertions:m,totalNavigations:b,uniqueNavigationUrls:S.size,totalTimelineSteps:e,totalActionSteps:y,actionStepsByCategory:x}}function ts(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${ts(t)} \u2502
2555
- `}function je(t,e,r,a){if(a||t.total===0)return;let s=`\u250C${"\u2500".repeat(58)}\u2510
2556
- `,n=`\u2514${"\u2500".repeat(58)}\u2518
2557
- `,o=I(""),i=s;i+=I("TestRelic AI - Playwright Test Report"),i+=o;let l=[];if(t.passed>0&&l.push(`${t.passed} \u2713`),t.failed>0&&l.push(`${t.failed} \u2717`),t.flaky>0&&l.push(`${t.flaky} \u26A0`),t.skipped>0&&l.push(`${t.skipped} skipped`),t.timedout>0&&l.push(`${t.timedout} timedout`),i+=I(`Tests: ${t.total} total (${l.join(" ")})`),t.totalNavigations>0&&(i+=I(`Navigations: ${t.totalNavigations} visits across ${t.uniqueNavigationUrls} unique URLs`)),t.totalApiCalls>0){i+=I(`API Calls: ${t.totalApiCalls} calls across ${t.uniqueApiUrls} unique endpoints`);let d=Object.entries(t.apiCallsByMethod).filter(([,f])=>f>0).map(([f,h])=>`${f}: ${h}`);d.length>0&&(i+=I(` ${d.join(" ")}`));let p=Object.entries(t.apiCallsByStatusRange).filter(([,f])=>f>0).map(([f,h])=>`${f}: ${h}`);p.length>0&&(i+=I(` ${p.join(" ")}`)),t.apiResponseTime&&(i+=I(` Avg response: ${t.apiResponseTime.avg}ms P95: ${t.apiResponseTime.p95}ms`));}if(t.totalAssertions>0&&(i+=I(`Assertions: ${t.totalAssertions} total (${t.passedAssertions} \u2713 ${t.failedAssertions} \u2717)`)),t.totalActionSteps>0){let d=[],p=t.actionStepsByCategory;p.ui_action&&d.push(`${p.ui_action} UI`),p.assertion&&d.push(`${p.assertion} assertions`),p.custom_step&&d.push(`${p.custom_step} custom`);let f=d.length>0?` (${d.join(" ")})`:"";i+=I(`Actions: ${t.totalActionSteps} steps${f}`);}i+=I(`Report: ${r}`),i+=I(`Data: ${e}`),i+=n,i+=`For more information visit us at https://docs.testrelic.ai
2558
- `,process.stderr.write(i);}var rs=new Set(["pw:api","expect","test.step"]);function as(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function Ve(t,e,r){if(rs.has(t.category)){let a=[];for(let n of t.steps)Ve(n,e,a);let s=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:as(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:s>=0?s/1e3:null,status:t.error?"failed":"passed",error:t.error?.message??null,children:a});}else for(let a of t.steps)Ve(a,e,r);}function gr(t,e){let r=[];for(let a of t)Ve(a,e,r);return r}var is=new Set(["localhost","127.0.0.1","0.0.0.0"]);function mr(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&is.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var os=3e3;async function Ge(t){let e=new AbortController,r=setTimeout(()=>e.abort(),os);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function vr(t){return new Promise(e=>setTimeout(e,t))}async function hr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let a=r.details;if(Array.isArray(a)&&a.length>0){let s=a.map(n=>`${n.field}: ${n.message}`).join(", ");return `${r.message} (${s})`}return r.message}}catch{}return `HTTP ${t.status}`}async function We(t,e,r){let a=new AbortController,s=setTimeout(()=>a.abort(),r);try{let n=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:a.signal});if(n.ok){let i=await n.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,orgId:i.orgId,orgName:i.orgName,userId:i.userId,userName:i.userName}}if(n.status===429){let i=n.headers.get("Retry-After"),l=i?parseInt(i,10)*1e3:5e3;if(!isNaN(l)&&l>0){await vr(l);let d=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:a.signal});if(d.ok){let p=await d.json();return {accessToken:p.accessToken,refreshToken:p.refreshToken,expiresIn:p.expiresIn,orgId:p.orgId,orgName:p.orgName,userId:p.userId,userName:p.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return n.status===400?{code:"validation_error",message:await hr(n),statusCode:400}:n.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:n.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await hr(n),statusCode:n.status}}catch(n){return n instanceof DOMException&&n.name==="AbortError"?{code:"timeout",message:"Token exchange timed out.",statusCode:null}:{code:"network_error",message:"Failed to reach cloud for token exchange.",statusCode:null}}finally{clearTimeout(s);}}function Ke(t){return "code"in t&&typeof t.code=="string"&&["invalid_key","expired_key","validation_error","rate_limited","server_error","network_error","timeout"].includes(t.code)}async function yr(t,e,r){let a=new AbortController,s=setTimeout(()=>a.abort(),r);try{let n=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:a.signal});if(n.status===429){let i=n.headers.get("Retry-After"),l=i?parseInt(i,10)*1e3:5e3;!isNaN(l)&&l>0&&(await vr(l),n=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:a.signal}));}if(!n.ok)return null;let o=await n.json();return {accessToken:o.accessToken,refreshToken:o.refreshToken,expiresIn:o.expiresIn}}catch{return null}finally{clearTimeout(s);}}async function br(t,e,r,a,s,n){let o=new AbortController,i=setTimeout(()=>o.abort(),s);try{let l={gitId:r,displayName:a};n&&(l.branch=n);let d=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(l),signal:o.signal});if(!d.ok)return null;let p=await d.json();return {repoId:p.repoId,displayName:p.displayName}}catch{return null}finally{clearTimeout(i);}}var ps=5e3;function N(t,e){try{return child_process.execSync(t,{cwd:e,timeout:ps,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function xr(t){let e=N("git rev-parse --abbrev-ref HEAD",t),r=N("git rev-parse --short HEAD",t),a=N("git log -1 --pretty=%s",t),s=N("git log -1 --format=%an",t)??N("git config user.name",t),n=fs(t),o=n?Z(n):null;return {branch:e,commitSha:r,commitMessage:a,commitAuthor:s,remoteUrl:o}}function fs(t){let e=N("git remote get-url origin",t);if(e)return e;let r=N("git remote",t);if(!r)return null;let a=r.split(`
2559
- `)[0]?.trim();return a?N(`git remote get-url ${a}`,t):null}function Z(t){let e=t.trim();return e=e.replace(/^[a-z+]+:\/\//,""),e=e.replace(/^[^@]+@/,""),e=e.replace(/:(?!\d)/,"/"),e=e.replace(/\.git$/,""),e=e.replace(/\/+$/,""),e=e.replace(/^[^@/]+@/,""),e.toLowerCase()}function wr(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Je(t){try{let e=fs$1.readFileSync(path.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return typeof r.name=="string"&&r.name.length>0?r.name:null}catch{return null}}function Q(t){let e=Je(t);return e||`local/${path.basename(t)}`}var xs=1048576,ws="1.0.0",kr=10;function X(t,e,r,a,s,n,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let l=Date.now(),d=`${l}-${e}-${r}.json`,p=path.join(t,d),f={version:ws,queuedAt:new Date(l).toISOString(),reason:a,retryCount:0,targetEndpoint:s,method:n,payload:o,headers:i},h=p+".tmp";fs$1.writeFileSync(h,JSON.stringify(f,null,2),"utf-8"),fs$1.renameSync(h,p);}catch(l){l.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2553
+ ${n}
2554
+ `;fs$1.appendFileSync(r,s,"utf-8");}catch{}}function pr(t,e){let r=[];for(let a of t){let n=Wa(a),s=Ka(a),o=Ja(a,n,s,e),i=Ya(a,n,s);if(o.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:a.startedAt,durationOnUrl:a.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:a.specFile,test:n,tests:[s],_testTitle:a.title});continue}r.push(...o,...i);}return r.sort(Za),Qa(r,t),r.map((a,n)=>a.type==="navigation"?{...{index:n,type:"navigation",url:a.url,timestamp:a.timestamp,durationOnUrl:a.durationOnUrl??0,navigationType:a.navigationType,domContentLoadedAt:a.domContentLoadedAt??null,networkIdleAt:a.networkIdleAt??null,networkStats:a.networkStats??null,specFile:a.specFile,test:a.test},tests:a.tests}:{...{index:n,type:"api_call",callId:a.callId,method:a.method,url:a.url,timestamp:a.timestamp,responseTime:a.responseTime??null,request:a.request,response:a.response??null,...a.error?{error:a.error}:{},assertions:a.assertions??[],specFile:a.specFile,test:a.test},tests:a.tests})}function Wa(t){return {title:t.title,fullTitle:t.titlePath,status:t.status,duration:t.duration,retries:t.retryCount,retry:t.retry,tags:t.tags,failure:t.failure}}function Ka(t){return {title:t.title,status:t.status,duration:t.duration,startedAt:t.startedAt,completedAt:t.completedAt,retryCount:t.retryCount,tags:t.tags,failure:t.failure,testId:t.testId,filePath:t.filePath,suiteName:t.suiteName,testType:t.testType,isFlaky:t.isFlaky,retryStatus:t.retryStatus,expectedStatus:t.expectedStatus,actualStatus:t.actualStatus,artifacts:t.artifacts,networkRequests:t.networkRequests,apiCalls:t.apiCalls,apiAssertions:t.apiAssertions,actions:t.actions,consoleLogs:t.consoleLogs}}function Ja(t,e,r,a){let n=[];for(let s of t.navigations)a.navigationTypes!==null&&!a.navigationTypes.includes(s.navigationType)||n.push({type:"navigation",url:s.url,timestamp:s.timestamp,durationOnUrl:0,navigationType:s.navigationType,domContentLoadedAt:s.domContentLoadedAt??null,networkIdleAt:s.networkIdleAt??null,networkStats:s.networkStats??null,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title});return n}function Ya(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let a=t.apiAssertions??[];return t.apiCalls.map(n=>{let s=a.filter(i=>i.callId===n.id).map(i=>({type:i.type,expected:i.expected,actual:i.actual,status:i.status,location:i.location,...i.expression!==void 0?{expression:i.expression}:{}})),o=null;return n.responseStatusCode!==null&&n.responseStatusText!==null&&(o={statusCode:n.responseStatusCode,statusText:n.responseStatusText,headers:n.responseHeaders,body:ur(n.responseBody)}),{type:"api_call",callId:n.id,method:n.method,url:n.url,timestamp:n.timestamp,responseTime:n.error?null:n.responseTimeMs,request:{headers:n.requestHeaders,body:ur(n.requestBody)},response:o,...n.error?{error:n.error}:{},assertions:s,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function Za(t,e){let r=new Date(t.timestamp).getTime(),a=new Date(e.timestamp).getTime();if(r!==a)return r-a;let n={navigation:0,api_call:1},s=n[t.type],o=n[e.type];return s!==o?s-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?cr(t.callId)-cr(e.callId):0}function cr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Qa(t,e){for(let r=0;r<t.length;r++){let a=t[r];if(a.type!=="navigation")continue;let n=new Date(a.timestamp).getTime(),s=null;for(let o=r+1;o<t.length;o++)if(t[o]._testTitle===a._testTitle){s=new Date(t[o].timestamp).getTime();break}if(s!==null)a.durationOnUrl=Math.max(0,s-n);else {let o=e.find(i=>i.title===a._testTitle);if(o){let i=new Date(o.completedAt).getTime();a.durationOnUrl=Math.max(0,i-n);}}}}function ur(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function $e(t,e){let r=t.length,a=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,a)]}function Xa(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function en(t){return t==null?"error":t>=200&&t<300?"2xx":t>=300&&t<400?"3xx":t>=400&&t<500?"4xx":t>=500&&t<600?"5xx":"error"}function fr(t,e){let r=0,a=0,n=0,s=0,o=0;for(let v of t)switch(v.status){case "passed":r++;break;case "failed":a++;break;case "flaky":n++;break;case "skipped":s++;break;case "timedout":o++;break}let i=[];for(let v of t)v.apiCalls&&i.push(...v.apiCalls);let l=i.length,d=new Set,p={},f={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},h=[];for(let v of i)d.add(Xa(v.url)),p[v.method]=(p[v.method]??0)+1,f[en(v.responseStatusCode)]+=1,h.push(v.responseTimeMs);let c=null;if(h.length>0){let v=[...h].sort((A,H)=>A-H),k=v.reduce((A,H)=>A+H,0);c={avg:Math.round(k/v.length),min:v[0],max:v[v.length-1],p50:$e(v,50),p95:$e(v,95),p99:$e(v,99)};}let u=0,g=0,m=0;for(let v of t)if(v.apiAssertions)for(let k of v.apiAssertions)u++,k.status==="passed"?g++:m++;let b=0,S=new Set;for(let v of t){b+=v.navigations.length;for(let k of v.navigations)S.add(k.url);}let y=0,x={};function T(v){for(let k of v)y++,x[k.category]=(x[k.category]??0)+1,k.children.length>0&&T(k.children);}for(let v of t)v.actions&&T(v.actions);return {total:t.length,passed:r,failed:a,flaky:n,skipped:s,timedout:o,totalApiCalls:l,uniqueApiUrls:d.size,apiCallsByMethod:p,apiCallsByStatusRange:f,apiResponseTime:c,totalAssertions:u,passedAssertions:g,failedAssertions:m,totalNavigations:b,uniqueNavigationUrls:S.size,totalTimelineSteps:e,totalActionSteps:y,actionStepsByCategory:x}}function tn(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${tn(t)} \u2502
2555
+ `}function je(t,e,r,a){if(a||t.total===0)return;let n=`\u250C${"\u2500".repeat(58)}\u2510
2556
+ `,s=`\u2514${"\u2500".repeat(58)}\u2518
2557
+ `,o=I(""),i=n;i+=I("TestRelic AI - Playwright Test Report"),i+=o;let l=[];if(t.passed>0&&l.push(`${t.passed} \u2713`),t.failed>0&&l.push(`${t.failed} \u2717`),t.flaky>0&&l.push(`${t.flaky} \u26A0`),t.skipped>0&&l.push(`${t.skipped} skipped`),t.timedout>0&&l.push(`${t.timedout} timedout`),i+=I(`Tests: ${t.total} total (${l.join(" ")})`),t.totalNavigations>0&&(i+=I(`Navigations: ${t.totalNavigations} visits across ${t.uniqueNavigationUrls} unique URLs`)),t.totalApiCalls>0){i+=I(`API Calls: ${t.totalApiCalls} calls across ${t.uniqueApiUrls} unique endpoints`);let d=Object.entries(t.apiCallsByMethod).filter(([,f])=>f>0).map(([f,h])=>`${f}: ${h}`);d.length>0&&(i+=I(` ${d.join(" ")}`));let p=Object.entries(t.apiCallsByStatusRange).filter(([,f])=>f>0).map(([f,h])=>`${f}: ${h}`);p.length>0&&(i+=I(` ${p.join(" ")}`)),t.apiResponseTime&&(i+=I(` Avg response: ${t.apiResponseTime.avg}ms P95: ${t.apiResponseTime.p95}ms`));}if(t.totalAssertions>0&&(i+=I(`Assertions: ${t.totalAssertions} total (${t.passedAssertions} \u2713 ${t.failedAssertions} \u2717)`)),t.totalActionSteps>0){let d=[],p=t.actionStepsByCategory;p.ui_action&&d.push(`${p.ui_action} UI`),p.assertion&&d.push(`${p.assertion} assertions`),p.custom_step&&d.push(`${p.custom_step} custom`);let f=d.length>0?` (${d.join(" ")})`:"";i+=I(`Actions: ${t.totalActionSteps} steps${f}`);}i+=I(`Report: ${r}`),i+=I(`Data: ${e}`),i+=s,i+=`For more information visit us at https://docs.testrelic.ai
2558
+ `,process.stderr.write(i);}var rn=new Set(["pw:api","expect","test.step"]);function an(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function Ve(t,e,r){if(rn.has(t.category)){let a=[];for(let s of t.steps)Ve(s,e,a);let n=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:an(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:n>=0?n/1e3:null,status:t.error?"failed":"passed",error:t.error?.message??null,children:a});}else for(let a of t.steps)Ve(a,e,r);}function gr(t,e){let r=[];for(let a of t)Ve(a,e,r);return r}var on=new Set(["localhost","127.0.0.1","0.0.0.0"]);function mr(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&on.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var ln=3e3;async function Ge(t){let e=new AbortController,r=setTimeout(()=>e.abort(),ln);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function vr(t){return new Promise(e=>setTimeout(e,t))}async function hr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let a=r.details;if(Array.isArray(a)&&a.length>0){let n=a.map(s=>`${s.field}: ${s.message}`).join(", ");return `${r.message} (${n})`}return r.message}}catch{}return `HTTP ${t.status}`}async function We(t,e,r){let a=new AbortController,n=setTimeout(()=>a.abort(),r);try{let s=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:a.signal});if(s.ok){let i=await s.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,orgId:i.orgId,orgName:i.orgName,userId:i.userId,userName:i.userName}}if(s.status===429){let i=s.headers.get("Retry-After"),l=i?parseInt(i,10)*1e3:5e3;if(!isNaN(l)&&l>0){await vr(l);let d=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:a.signal});if(d.ok){let p=await d.json();return {accessToken:p.accessToken,refreshToken:p.refreshToken,expiresIn:p.expiresIn,orgId:p.orgId,orgName:p.orgName,userId:p.userId,userName:p.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return s.status===400?{code:"validation_error",message:await hr(s),statusCode:400}:s.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:s.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await hr(s),statusCode:s.status}}catch(s){return s instanceof DOMException&&s.name==="AbortError"?{code:"timeout",message:"Token exchange timed out.",statusCode:null}:{code:"network_error",message:"Failed to reach cloud for token exchange.",statusCode:null}}finally{clearTimeout(n);}}function Ke(t){return "code"in t&&typeof t.code=="string"&&["invalid_key","expired_key","validation_error","rate_limited","server_error","network_error","timeout"].includes(t.code)}async function yr(t,e,r){let a=new AbortController,n=setTimeout(()=>a.abort(),r);try{let s=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:a.signal});if(s.status===429){let i=s.headers.get("Retry-After"),l=i?parseInt(i,10)*1e3:5e3;!isNaN(l)&&l>0&&(await vr(l),s=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:a.signal}));}if(!s.ok)return null;let o=await s.json();return {accessToken:o.accessToken,refreshToken:o.refreshToken,expiresIn:o.expiresIn}}catch{return null}finally{clearTimeout(n);}}async function br(t,e,r,a,n,s){let o=new AbortController,i=setTimeout(()=>o.abort(),n);try{let l={gitId:r,displayName:a};s&&(l.branch=s);let d=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(l),signal:o.signal});if(!d.ok)return null;let p=await d.json();return {repoId:p.repoId,displayName:p.displayName}}catch{return null}finally{clearTimeout(i);}}var fn=5e3;function F(t,e){try{return child_process.execSync(t,{cwd:e,timeout:fn,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function xr(t){let e=F("git rev-parse --abbrev-ref HEAD",t),r=F("git rev-parse --short HEAD",t),a=F("git log -1 --pretty=%s",t),n=F("git log -1 --format=%an",t)??F("git config user.name",t),s=gn(t),o=s?Z(s):null;return {branch:e,commitSha:r,commitMessage:a,commitAuthor:n,remoteUrl:o}}function gn(t){let e=F("git remote get-url origin",t);if(e)return e;let r=F("git remote",t);if(!r)return null;let a=r.split(`
2559
+ `)[0]?.trim();return a?F(`git remote get-url ${a}`,t):null}function Z(t){let e=t.trim();return e=e.replace(/^[a-z+]+:\/\//,""),e=e.replace(/^[^@]+@/,""),e=e.replace(/:(?!\d)/,"/"),e=e.replace(/\.git$/,""),e=e.replace(/\/+$/,""),e=e.replace(/^[^@/]+@/,""),e.toLowerCase()}function wr(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Je(t){try{let e=fs$1.readFileSync(path.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return typeof r.name=="string"&&r.name.length>0?r.name:null}catch{return null}}function Q(t){let e=Je(t);return e||`local/${path.basename(t)}`}var wn=1048576,kn="1.0.0",kr=10;function X(t,e,r,a,n,s,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let l=Date.now(),d=`${l}-${e}-${r}.json`,p=path.join(t,d),f={version:kn,queuedAt:new Date(l).toISOString(),reason:a,retryCount:0,targetEndpoint:n,method:s,payload:o,headers:i},h=p+".tmp";fs$1.writeFileSync(h,JSON.stringify(f,null,2),"utf-8"),fs$1.renameSync(h,p);}catch(l){l.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2560
2560
  `):process.stderr.write(`\u26A0 TestRelic: Unable to queue upload data.
2561
- `);}}async function Cr(t,e,r){let a;try{a=fs$1.readdirSync(t).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")).sort();}catch{return}if(a.length===0)return;let s=[];for(let n=0;n<a.length;n+=kr)s.push(a.slice(n,n+kr));for(let n of s)for(let o of n){let i=path.join(t,o);try{if(!fs$1.statSync(i).isFile())continue;let d=fs$1.readFileSync(i,"utf-8"),p=JSON.parse(d);if(!core.isValidQueueEntry(p)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${o}
2562
- `),fs$1.unlinkSync(i);continue}let f=p,h=JSON.stringify(f.payload),c={...f.headers,Authorization:`Bearer ${r}`},u=h;if(Buffer.byteLength(h,"utf-8")>xs&&(u=zlib.gzipSync(Buffer.from(h,"utf-8")),c["Content-Encoding"]="gzip"),(await fetch(f.targetEndpoint,{method:f.method,headers:c,body:u})).ok)fs$1.unlinkSync(i);else return}catch{return}}}function Rr(t,e){try{let r=fs$1.readdirSync(t).filter(s=>s.endsWith(".json")&&!s.endsWith(".tmp")),a=Date.now();for(let s of r){let n=path.join(t,s);try{let o=fs$1.readFileSync(n,"utf-8"),l=JSON.parse(o).queuedAt;if(typeof l=="string"){let d=new Date(l).getTime();a-d>e&&fs$1.unlinkSync(n);}}catch{try{fs$1.unlinkSync(n);}catch{}}}}catch{}}var _s=3e5,Is=864e5,Ls=6e4,Ar=3e4,Qe="https://platform.testrelic.ai/settings/api-keys",ce=class{constructor(e){this.gitMetadata=null;this.repoId=null;this.failureReason=null;this.flushPromise=null;this.healthCheckTimer=null;this.config=e,this.authState={mode:"pending",accessToken:null,refreshToken:null,expiresAt:null,orgId:null,orgName:null,userId:null,userName:null};}async initialize(){if(!this.config||!this.config.apiKey){this.setLocalMode("no_api_key"),process.stderr.write(`\u2139 TestRelic: No API key configured. Running in local mode.
2561
+ `);}}async function Cr(t,e,r){let a;try{a=fs$1.readdirSync(t).filter(s=>s.endsWith(".json")&&!s.endsWith(".tmp")).sort();}catch{return}if(a.length===0)return;let n=[];for(let s=0;s<a.length;s+=kr)n.push(a.slice(s,s+kr));for(let s of n)for(let o of s){let i=path.join(t,o);try{if(!fs$1.statSync(i).isFile())continue;let d=fs$1.readFileSync(i,"utf-8"),p=JSON.parse(d);if(!core.isValidQueueEntry(p)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${o}
2562
+ `),fs$1.unlinkSync(i);continue}let f=p,h=JSON.stringify(f.payload),c={...f.headers,Authorization:`Bearer ${r}`},u=h;if(Buffer.byteLength(h,"utf-8")>wn&&(u=zlib.gzipSync(Buffer.from(h,"utf-8")),c["Content-Encoding"]="gzip"),(await fetch(f.targetEndpoint,{method:f.method,headers:c,body:u})).ok)fs$1.unlinkSync(i);else return}catch{return}}}function Rr(t,e){try{let r=fs$1.readdirSync(t).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")),a=Date.now();for(let n of r){let s=path.join(t,n);try{let o=fs$1.readFileSync(s,"utf-8"),l=JSON.parse(o).queuedAt;if(typeof l=="string"){let d=new Date(l).getTime();a-d>e&&fs$1.unlinkSync(s);}}catch{try{fs$1.unlinkSync(s);}catch{}}}}catch{}}var In=3e5,Ln=864e5,Mn=6e4,Ar=3e4,Qe="https://platform.testrelic.ai/settings/api-keys",ce=class{constructor(e){this.gitMetadata=null;this.repoId=null;this.failureReason=null;this.flushPromise=null;this.healthCheckTimer=null;this.config=e,this.authState={mode:"pending",accessToken:null,refreshToken:null,expiresAt:null,orgId:null,orgName:null,userId:null,userName:null};}async initialize(){if(!this.config||!this.config.apiKey){this.setLocalMode("no_api_key"),process.stderr.write(`\u2139 TestRelic: No API key configured. Running in local mode.
2563
2563
  `);return}try{if(mr(this.config.endpoint),this.gitMetadata=xr(),!await Ge(this.config.endpoint)){this.setLocalMode("cloud_unreachable"),process.stderr.write(`\u26A0 TestRelic: Cloud unreachable. Switching to local mode. Data will be queued for later upload.
2564
2564
  `);return}let r=await We(this.config.endpoint,this.config.apiKey,this.config.timeout);if(Ke(r)){this.handleAuthError(r.code,r.statusCode);return}let a=r;this.authState={mode:"cloud",accessToken:a.accessToken,refreshToken:a.refreshToken,expiresAt:Date.now()+a.expiresIn*1e3,orgId:a.orgId,orgName:a.orgName,userId:a.userId,userName:a.userName},process.stderr.write(`\u2713 TestRelic: Connected to cloud (${a.orgName} / ${a.userName})
2565
2565
  `),await this.resolveRepoId(),this.config.queueDirectory&&(Rr(this.config.queueDirectory,this.config.queueMaxAge),this.startBackgroundFlush()),this.startHealthCheck();}catch(e){this.setLocalMode("unexpected_error"),process.stderr.write(`\u26A0 TestRelic: Unexpected error during cloud initialization. Running in local mode. ${e instanceof Error?e.message:String(e)}
2566
- `);}}getMode(){return this.authState.mode}isCloudMode(){return this.authState.mode==="cloud"}isLocalMode(){return this.authState.mode==="local"}getAccessToken(){return this.authState.accessToken}getRepoId(){return this.repoId}getGitMetadata(){return this.gitMetadata}getConfig(){return this.config}getFailureReason(){return this.failureReason}getEndpoint(){return this.config?.endpoint??"https://platform.testrelic.ai/api/v1"}async ensureValidToken(){if(!this.isCloudMode()||!this.authState.accessToken)return false;let e=this.authState.expiresAt??0;if(Date.now()+_s<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await yr(this.config.endpoint,this.authState.refreshToken,this.config.timeout);return r?(this.authState.accessToken=r.accessToken,this.authState.refreshToken=r.refreshToken,this.authState.expiresAt=Date.now()+r.expiresIn*1e3,!0):(this.switchToLocalMode("token_refresh_failed"),!1)}catch{return this.switchToLocalMode("token_refresh_error"),false}}switchToLocalMode(e){this.authState.mode!=="local"&&(this.authState.mode="local",this.failureReason=e,process.stderr.write(`\u26A0 TestRelic: Switched to local mode (${e}).
2566
+ `);}}getMode(){return this.authState.mode}isCloudMode(){return this.authState.mode==="cloud"}isLocalMode(){return this.authState.mode==="local"}getAccessToken(){return this.authState.accessToken}getRepoId(){return this.repoId}getGitMetadata(){return this.gitMetadata}getConfig(){return this.config}getFailureReason(){return this.failureReason}getEndpoint(){return this.config?.endpoint??"https://platform.testrelic.ai/api/v1"}async ensureValidToken(){if(!this.isCloudMode()||!this.authState.accessToken)return false;let e=this.authState.expiresAt??0;if(Date.now()+In<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await yr(this.config.endpoint,this.authState.refreshToken,this.config.timeout);return r?(this.authState.accessToken=r.accessToken,this.authState.refreshToken=r.refreshToken,this.authState.expiresAt=Date.now()+r.expiresIn*1e3,!0):(this.switchToLocalMode("token_refresh_failed"),!1)}catch{return this.switchToLocalMode("token_refresh_error"),false}}switchToLocalMode(e){this.authState.mode!=="local"&&(this.authState.mode="local",this.failureReason=e,process.stderr.write(`\u26A0 TestRelic: Switched to local mode (${e}).
2567
2567
  `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,new Promise(e=>setTimeout(e,Ar))]);}catch{}this.flushPromise=null;}this.authState={mode:"local",accessToken:null,refreshToken:null,expiresAt:null,orgId:null,orgName:null,userId:null,userName:null},this.repoId=null,this.gitMetadata=null;}setLocalMode(e){this.authState.mode="local",this.failureReason=e;}handleAuthError(e,r){switch(e){case "invalid_key":this.setLocalMode("invalid_api_key"),process.stderr.write(`\u26A0 TestRelic: API key is invalid or revoked. Running in local mode.
2568
2568
  \u2192 Manage keys: ${Qe}
2569
2569
  `);break;case "expired_key":this.setLocalMode("expired_api_key"),process.stderr.write(`\u26A0 TestRelic: API key has expired. Running in local mode.
@@ -2573,29 +2573,31 @@ ${s}
2573
2573
  `);break;case "rate_limited":this.setLocalMode("rate_limited"),process.stderr.write(`\u26A0 TestRelic: Rate limited during authentication. Running in local mode.
2574
2574
  `);break;case "timeout":this.setLocalMode("auth_timeout"),process.stderr.write(`\u26A0 TestRelic: Authentication timed out. Running in local mode.
2575
2575
  `);break;default:this.setLocalMode(`auth_error_${r??"unknown"}`),process.stderr.write(`\u26A0 TestRelic: Cloud authentication failed. Running in local mode.
2576
- `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?Z(this.gitMetadata.remoteUrl):null,r=e?wr(e):this.config.projectName??Q(process.cwd()),a=e??this.config.projectName??Q(process.cwd()),s=this.readRepoCache(a);if(s){this.repoId=s.repoId;return}try{let n=await br(this.config.endpoint,this.authState.accessToken,a,r,this.config.timeout,this.gitMetadata?.branch);n&&(this.repoId=n.repoId,this.writeRepoCache(a,n.repoId,n.displayName));}catch{}!e&&!this.config.projectName&&!Je(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2577
- `);}readRepoCache(e){if(!this.config)return null;let r=path.join(this.config.queueDirectory,"..","cache","repo.json");try{if(!fs$1.existsSync(r))return null;let a=fs$1.readFileSync(r,"utf-8"),s=JSON.parse(a);if(s.gitId!==e||Date.now()-s.resolvedAt>Is)return null;let n=this.hashApiKey();return n&&s.apiKeyHash!==n?null:s}catch{return null}}writeRepoCache(e,r,a){if(!this.config)return;let s=path.join(this.config.queueDirectory,"..","cache"),n=path.join(s,"repo.json");try{fs$1.mkdirSync(s,{recursive:!0});let o={repoId:r,gitId:e,displayName:a,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=n+".tmp";fs$1.writeFileSync(i,JSON.stringify(o,null,2),"utf-8"),fs$1.renameSync(i,n);}catch{}}hashApiKey(){return this.config?.apiKey?crypto.createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let e=this.authState.accessToken,r=this.config.queueDirectory,a=this.config.endpoint;this.flushPromise=Promise.race([Cr(r,a,e),new Promise(s=>setTimeout(s,Ar))]).catch(()=>{});}startHealthCheck(){if(!this.config)return;let e=this.config.endpoint;this.healthCheckTimer=setInterval(async()=>{if(!this.isCloudMode()&&!(!this.failureReason||!["cloud_unreachable","auth_timeout","network_error"].includes(this.failureReason)))try{if(!await Ge(e))return;if(this.config?.apiKey){let a=await We(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Ke(a)){let s=a;this.authState={mode:"cloud",accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:Date.now()+s.expiresIn*1e3,orgId:s.orgId,orgName:s.orgName,userId:s.userId,userName:s.userName},this.failureReason=null,process.stderr.write(`\u2713 TestRelic: Cloud connectivity restored.
2578
- `),this.startBackgroundFlush();}}}catch{}},Ls);}};var Ms=new Set(["smoke","regression","nightly","ci"]);function ue(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&Ms.has(t))return t}var Ps=1048576,pe=[1e3,3e3,9e3],fe=3,Fs=40*1048576,Ns=new Set(["e2e","mobile","unit"]);function et(t){if(t&&t.length>0&&t.every(s=>s.testType==="api")){let s=new Map;for(let i of t){let l=i.apiProtocol??"rest";s.set(l,(s.get(l)??0)+1);}let n="rest",o=0;for(let[i,l]of s)l>o&&(o=l,n=i);return {testType:"api",apiProtocol:n,metadata:{testType:"api",primaryProtocol:n}}}let e=new Map;for(let s of t??[])Ns.has(s.testType)&&e.set(s.testType,(e.get(s.testType)??0)+1);let r=null,a=0;for(let[s,n]of e)n>a&&(a=n,r=s);return {testType:r??"e2e"}}function tt(t,e,r,a,s,n){let o=n?.cloudPlatform?n.cloudPlatform:a?.provider&&a.provider!=="unknown"?a.provider:"local",i=ue(),l=et(s),d=l.testType==="api"?l:null,p=d&&s?s.map(h=>h.apiProtocol?h:{...h,apiProtocol:d.apiProtocol}):s,f={runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:o,...i?{runType:i}:{},...d?{testType:d.testType,apiProtocol:d.apiProtocol,metadata:d.metadata}:{testType:l.testType},...p&&p.length>0?{tests:p}:{},...r?.branch?{branch:r.branch}:{},...r?.commitSha?{commit:r.commitSha}:{},...r?.commitMessage?{commitMessage:r.commitMessage}:{},...r?.commitAuthor?{commitAuthor:r.commitAuthor}:{},...t.completedAt?{finishedAt:t.completedAt}:{},...t.totalDuration?{duration:t.totalDuration}:{},...a?.provider?{ciProvider:a.provider}:{},...a?.runUrl?{ciRunUrl:a.runUrl}:{},...n?.cloudPlatform?{cloudPlatform:n.cloudPlatform}:{},...n?.cloudBuildId?{cloudBuildId:n.cloudBuildId}:{},...n?.cloudSessionId?{cloudSessionId:n.cloudSessionId}:{}};if(f.tests&&f.tests.length>0){let h=JSON.stringify(f);if(Buffer.byteLength(h,"utf-8")>Fs){let c=f.tests.map(({consoleLogs:u,networkRequests:g,apiCalls:m,...b})=>b);return {...f,tests:c}}}return f}function Xe(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function rt(t){return Array.isArray(t)?t.map(e=>{let r=e.statusCode??e.responseStatusCode??null;return {...e.protocol!=null?{protocol:e.protocol}:{},method:e.method??null,url:e.url??null,statusCode:r,statusText:e.statusText??e.responseStatusText??null,ok:typeof r=="number"?r<400:e.ok??null,durationMs:e.durationMs??e.responseTimeMs??null,bytesIn:typeof e.bytesIn=="number"?e.bytesIn:Xe(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Xe(e.requestBody),requestHeaders:e.requestHeaders??null,responseHeaders:e.responseHeaders??null,requestBody:e.requestBody??null,responseBody:e.responseBody??null,requestCookies:e.requestCookies??null,responseCookies:e.responseCookies??null}}):[]}function at(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,a=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:Xe(e.responseBody),duration:e.responseTimeMs??e.durationMs??0,responseTimeMs:e.responseTimeMs??e.durationMs??0,requestHeaders:e.requestHeaders??null,responseHeaders:e.responseHeaders??null,requestBody:e.requestBody??null,responseBody:e.responseBody??null,timestamp:a,startedAt:a}}):[]}function st(t){if(!Array.isArray(t))return [];let e=r=>{if(r==null)return String(r);if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}};return t.map(r=>{let a=r.status==="failed"?"failed":"passed",s=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,n=r.kind??r.type??"assertion",o=a==="failed"?`expected ${e(r.expected)}, received ${e(r.actual)}`:r.expected!==void 0?`expected ${e(r.expected)}`:null;return {kind:n,description:s??r.description??`${n} assertion`,status:a,detail:o}})}async function ge(t){return new Promise(e=>setTimeout(e,t))}function Ds(t){let e={};for(let[r,a]of Object.entries(t))a!=null&&(e[r]=a);return e}async function _r(t,e,r){for(let a=0;a<fe;a++)try{let s=await fetch(t,e);if(s.ok)return s;if(s.status===401&&r&&a===0){let n=await r();if(n){let o={...e,headers:{...e.headers,Authorization:`Bearer ${n}`}},i=await fetch(t,o);if(i.ok)return i}return null}if(s.status===429&&a<fe-1){let n=s.headers.get("Retry-After"),o=n?parseInt(n,10)*1e3:pe[a];!isNaN(o)&&o>0?await ge(o):await ge(pe[a]);continue}if(s.status>=500&&a<fe-1){await ge(pe[a]);continue}return s}catch{if(a<fe-1){await ge(pe[a]);continue}return null}return null}function Bs(t){let e=JSON.stringify(t),r={"Content-Type":"application/json"};if(Buffer.byteLength(e,"utf-8")>Ps){let a=zlib.gzipSync(Buffer.from(e,"utf-8"));return r["Content-Encoding"]="gzip",{body:a,headers:r}}return {body:e,headers:r}}async function Ir(t,e,r,a){let s=`${t}/runs`,{body:n,headers:o}=Bs(r);o.Authorization=`Bearer ${e}`;let i=await _r(s,{method:"POST",headers:o,body:n},a);return i?.ok?{success:true,statusCode:i.status,error:null}:i?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:i?`Upload failed with status ${i.status}`:"Upload failed after retries",statusCode:i?.status??null,payload:r,targetEndpoint:s,method:"POST"}}async function Lr(t,e,r){let a=`${t}/runs/init`;try{let s=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(Ds(r))});return s.ok?{runId:(await s.json()).runId}:null}catch{return null}}function Mr(t,e,r,a){let s=`${t}/runs/${r}/tests`;fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(a)}).catch(()=>{});}async function Er(t,e,r,a){let s=`${t}/runs/${r}/finalize`;return (await _r(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(a)}))?.ok??false}function nt(t,e,r,a){let s=`${t}/runs/${r}/finalize`,n=new Date,o={finishedAt:n.toISOString(),duration:n.getTime()-new Date(a).getTime(),summary:{}};fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)}).catch(()=>{});}function Pr(t,e,r,a){let s=[],n=[],o=null,i=0,l=null,d=0,p=null,f=0,h=t.filter(g=>g.name===core.ATTACHMENT_NAME&&g.body),c=false;if(h.length>0)for(let g of h)try{let m=JSON.parse(g.body.toString());if(core.isTestRelicFilePayload(m)){s=s.concat(m.navigations),n=n.concat(m.apiAssertions),m.networkRequestsFile&&(o=m.networkRequestsFile,i+=m.networkRequestsCount),m.consoleLogsFile&&(l=m.consoleLogsFile,d+=m.consoleLogsCount),m.apiCallsFile&&(p=m.apiCallsFile,f+=m.apiCallsCount),c=!0;continue}if(core.isTestRelicDataPayload(m)){s=s.concat(m.navigations),Array.isArray(m.apiAssertions)&&(n=n.concat(m.apiAssertions)),i+=m.networkRequests?.length??0,f+=m.apiCalls?.length??0;let b=m.consoleLogs;Array.isArray(b)&&(d+=b.length),c=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2579
- `);}return c||(s=e.filter(g=>g.type==="lambdatest-navigation"&&g.description).map(g=>{try{return JSON.parse(g.description)}catch{return null}}).filter(g=>g!==null)),s.length===0&&i===0&&f===0&&!a&&!c&&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.
2580
- `),{navigations:s,apiAssertions:n,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:l,consoleLogsCount:d,apiCallsFile:p,apiCallsCount:f}}function he(t=process.env){let e=Us(t.TESTRELIC_CLOUD_PLATFORM);if(e)return {cloudPlatform:e,cloudBuildId:t.TESTRELIC_CLOUD_BUILD_ID||void 0,cloudSessionId:t.TESTRELIC_CLOUD_SESSION_ID||void 0};if(t.BROWSERSTACK_USERNAME||t.BROWSERSTACK_ACCESS_KEY)return {cloudPlatform:"browserstack",cloudBuildId:t.BROWSERSTACK_BUILD_NAME||t.BROWSERSTACK_BUILD_ID||void 0,cloudSessionId:t.BROWSERSTACK_SESSION_ID||void 0};if(t.LT_USERNAME||t.LAMBDATEST_USERNAME||t.LT_ACCESS_KEY||t.LAMBDATEST_ACCESS_KEY)return {cloudPlatform:"lambdatest",cloudBuildId:t.LT_BUILD||t.LAMBDATEST_BUILD||void 0,cloudSessionId:t.LT_SESSION_ID||t.LAMBDATEST_SESSION_ID||void 0};let r=t.PLAYWRIGHT_WS_ENDPOINT;if(r){if(/cdp\.lambdatest\.com/i.test(r))return {cloudPlatform:"lambdatest"};if(/cdp\.browserstack\.com/i.test(r))return {cloudPlatform:"browserstack"}}return {}}function Us(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Gs=5,me=[1e3,3e3,9e3],z=3,Ws={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},it=0,ot=[];async function Ks(){it>=Gs&&await new Promise(t=>ot.push(t)),it++;}function Js(){it--,ot.length>0&&ot.shift()();}async function ve(t){return new Promise(e=>setTimeout(e,t))}function Ys(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return Ws[e]??"application/octet-stream"}function Zs(t){try{return fs$1.statSync(t).size}catch{return 0}}async function Qs(t,e,r,a,s){let n=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:s,type:r.type,sizeBytes:a});for(let i=0;i<z;i++)try{let l=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o});if(l.ok)return await l.json();if(l.status>=500&&i<z-1){await ve(me[i]);continue}return null}catch{if(i<z-1){await ve(me[i]);continue}return null}return null}async function Xs(t,e,r,a){for(let s=0;s<z;s++)try{let n=fs$1.createReadStream(e),o=stream.Readable.toWeb(n),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(a)},body:o,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&s<z-1){await ve(me[s]);continue}return !1}catch{if(s<z-1){await ve(me[s]);continue}return false}return false}async function en(t,e,r){let a=`${t}/artifacts/confirm`;try{return (await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function tn(t,e,r,a){let s=Zs(r.filePath);if(s===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(s>a*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let n=Ys(r.filePath);await Ks();try{let o=await Qs(t,e,r,s,n);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await Xs(o.uploadUrl,r.filePath,n,s))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let l=await en(t,e,o.artifactId);return {success:l,storageKey:o.storageKey,artifactId:o.artifactId,error:l?null:"confirm_failed"}}finally{Js();}}async function Fr(t,e,r,a){let s=new Map,n=r.map(async o=>{let i=await tn(t,e,o,a);s.set(o.filePath,i);});return await Promise.allSettled(n),s}function lt(t){let r=t.getGitMetadata()?.remoteUrl;return r?Z(r):t.getConfig()?.projectName??Q(process.cwd())}async function Dr(t,e,r,a,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=P(),l=he(),d=ue();return (await Lr(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:lt(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:a,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??l.cloudPlatform??null,cloudPlatform:l.cloudPlatform??null,cloudBuildId:l.cloudBuildId??null,cloudSessionId:l.cloudSessionId??null,...d?{runType:d}:{},testType:"e2e"}))?.runId??null}var rn=true,an=50;async function sn(t,e,r,a){let s=new Map;if(!(e?.uploadArtifacts??rn)||!await t.ensureValidToken())return s;let i=[],l=new Map;for(let c of a){if(c.artifacts.screenshot){let u=path.join(c.outputDir,c.artifacts.screenshot);i.push({filePath:u,runId:r,testId:c.testId,type:"screenshot"}),l.set(u,{testId:c.testId,field:"screenshot"});}if(c.artifacts.video){let u=path.join(c.outputDir,c.artifacts.video);i.push({filePath:u,runId:r,testId:c.testId,type:"video"}),l.set(u,{testId:c.testId,field:"video"});}}if(i.length===0)return s;let d=e?.artifactMaxSizeMb??an,p=await Fr(t.getEndpoint(),t.getAccessToken(),i,d),f=new Map;for(let[c,u]of p){if(!u.success||!u.storageKey)continue;let g=l.get(c);if(!g)continue;let m=f.get(g.testId)??{};g.field==="screenshot"&&(m.screenshotKey=u.storageKey),g.field==="video"&&(m.videoKey=u.storageKey),f.set(g.testId,m);}for(let c of a){let u=f.get(c.testId);s.set(c.testId,{...c.artifacts,...u?.screenshotKey?{screenshotKey:u.screenshotKey}:{},...u?.videoKey?{videoKey:u.videoKey}:{}});}let h=Array.from(p.values()).filter(c=>c.success).length;return h>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${h} artifact(s) to cloud storage.
2581
- `),s}async function dt(t,e,r,a,s,n,o,i,l,d,p){try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){let h=await t.ensureValidToken(),c=t.getGitMetadata(),u=et(p),g={finishedAt:o,duration:i,summary:l,...c?.commitMessage?{commitMessage:c.commitMessage}:{},testType:u.testType,...u.testType==="api"?{apiProtocol:u.apiProtocol,metadata:u.metadata}:{}};if(h){if(!await Er(t.getEndpoint(),t.getAccessToken(),s,g)){let b=e?.queueDirectory??".testrelic/queue";X(b,a,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",g,{"Content-Type":"application/json"});}}else {let m=e?.queueDirectory??".testrelic/queue";X(m,a,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",g,{"Content-Type":"application/json"});}}let f=new Map;if(t.isCloudMode()&&d&&d.length>0&&(f=await sn(t,e,a,d)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let c=t.getGitMetadata(),u=P(),g=lt(t),m=nn(n,f),b=tt(m,g,c,u,p,he()),S=await Ir(t.getEndpoint(),t.getAccessToken(),b,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!S.success){let y=S,x=e?.queueDirectory??".testrelic/queue";X(x,a,"batch",y.reason,y.targetEndpoint,y.method,y.payload,{"Content-Type":"application/json"});}}else {let c=e?.queueDirectory??".testrelic/queue",u=t.getGitMetadata(),g=P(),m=lt(t),b=tt(n,m,u,g,void 0,he());X(c,a,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",b,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function nn(t,e){if(e.size===0)return t;let r=t.timeline.map(a=>{let s=a.testId;if(!s)return a;let n=e.get(s);return n?{...a,...n.screenshotKey?{screenshotKey:n.screenshotKey}:{},...n.videoKey?{videoKey:n.videoKey}:{}}:a});return {...t,timeline:r}}function q(t){try{return fs$1.readFileSync(t,"utf-8").split(`
2582
- `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function ut(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 fn(t,e,r){let a=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(a).digest("hex").substring(0,16)}function gn(t){return t.length<=3?"":t[t.length-2]}function hn(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function mn(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 vn(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function yn(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:a}=e;if(a){let n=a.toLowerCase();return n==="chrome"||n==="chrome-stable"?"Chrome":n.startsWith("chrome-beta")?"Chrome Beta":n.startsWith("chrome-dev")?"Chrome Dev":n.startsWith("chrome-canary")?"Chrome Canary":n==="msedge"||n==="msedge-stable"?"Microsoft Edge":n.startsWith("msedge-beta")?"Edge Beta":n.startsWith("msedge-dev")?"Edge Dev":n.startsWith("msedge-canary")?"Edge Canary":a}if(r){let n=r.toLowerCase();return n==="chromium"?"Chromium":n==="firefox"?"Firefox":n==="webkit"?"WebKit":r}let s=e.defaultBrowserType;if(s){let n=s.toLowerCase();return n==="chromium"?"Chromium":n==="firefox"?"Firefox":n==="webkit"?"WebKit":s}}function bn(t,e,r){let a=r.parent?.project?.(),s="unknown";a!==void 0&&(a.use.isMobile===true?s="mobile":s="e2e");let n=["e2e","api","unit","mobile"];for(let l of n)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 xn="__testrelic_api_config";function wn(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var ye=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=It(e),this.apiConfig=_t(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 n=r.allTests().length;this.activeReportMode=n>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let a=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${a} tests)
2583
- `),this.activeReportMode==="streaming"){let n=path.dirname(this.config.outputPath);this.streamingWriter=new G(n);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&&nt(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",o),process.on("SIGINT",o);}if(this.config.includeArtifacts){let n=path.dirname(this.config.outputPath);this.runTimestamp=sr(path.join(n,"artifacts"));try{dr(path.join(n,"artifacts"));}catch{}}let s=P();this.detectedOs=vn(),this.detectedSource=mn(s);try{this.cloudClient=new ce(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await Dr(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let n=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let o=this.cloudClient.getAccessToken();o&&nt(this.cloudClient.getEndpoint(),o,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",n),process.on("SIGINT",n);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:xn,description:wn(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let a=r,s=e.outcome(),n;s==="flaky"?n="flaky":s==="skipped"?n="skipped":n=ut(a.status);let o=a.startTime.toISOString(),i=new Date(a.startTime.getTime()+a.duration).toISOString(),l=e.tags?[...e.tags]:e.annotations.filter(R=>R.type==="tag").map(R=>R.description??""),d=Pr(a.attachments,e.annotations,e.title,n==="skipped");(d.navigations.length>0||d.networkRequestsCount>0||d.apiCallsCount>0)&&(this.fixtureDataReceived=!0);let p=null;if(n==="failed"||n==="flaky"){let C=(n==="flaky"?e.results.find(B=>B.status!=="passed")?.errors??[]:a.errors)[0];if(C){let B=Mt(this.config.redactPatterns),$=C.location?.line??null,j=null;this.config.includeCodeSnippets&&$!==null&&C.location?.file&&(j=Lt(C.location.file,$,this.config.codeContextLines),j&&(j=B(j))),p={message:B(C.message??"Unknown error"),line:$,code:j,stack:this.config.includeStackTrace&&C.stack?B(C.stack):null};}}let f=e.titlePath().filter(Boolean),h=path.relative(this.rootDir||".",e.location.file),c=gn(f),u=f.join(" > "),g=h,m=fn(g,c,u),b=bn(l,g,e),S=b!=="mobile"&&d.apiCallsCount>0?"api":b,y=s==="flaky",x=hn(e.results),T=ut(e.expectedStatus),v=ut(a.status),k=null;if(this.config.includeArtifacts&&n!=="skipped"&&a.attachments){let R=path.dirname(this.config.outputPath),C=f[f.length-1]??e.title;k=nr(a.attachments,C,a.retry,R,this.runTimestamp||void 0);}let A=this.config.includeActionSteps&&a.steps?gr(a.steps,a.startTime):null,H=yn(e),M={titlePath:f,title:u,status:n,duration:a.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:a.retry,tags:l,failure:p,specFile:h,navigations:d.navigations,testId:m,filePath:g,suiteName:c,testType:S,isFlaky:y,retryStatus:x,expectedStatus:T,actualStatus:v,artifacts:k,apiAssertions:d.apiAssertions,actions:A,networkRequestsFile:d.networkRequestsFile,networkRequestsCount:d.networkRequestsCount,consoleLogsFile:d.consoleLogsFile,consoleLogsCount:d.consoleLogsCount,apiCallsFile:d.apiCallsFile,apiCallsCount:d.apiCallsCount,browser:H,os:this.detectedOs||void 0,source:this.detectedSource||void 0},pt=d.consoleLogsFile&&d.consoleLogsCount>0?q(d.consoleLogsFile):void 0,be=d.networkRequestsFile&&d.networkRequestsCount>0?q(d.networkRequestsFile):void 0,ee=d.apiCallsFile&&d.apiCallsCount>0?q(d.apiCallsFile):void 0,ft=ee?rt(ee):void 0,gt=!be&&ee?at(ee):void 0,ht=d.apiAssertions&&d.apiAssertions.length>0?st(d.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:m,title:u,status:n,duration:a.duration,suiteName:c,filePath:g,testType:S,isFlaky:y,startedAt:o,completedAt:i,tags:l,failure:p,retry:a.retry,retryCount:e.results.length-1,retryStatus:x,browser:H,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...A&&A.length>0?{actions:A}:{},...pt?{consoleLogs:pt}:{},...be?{networkRequests:be}:gt?{networkRequests:gt}:{},...ft?{apiCalls:ft}:{},...ht?{protocolAssertions:ht}:{}});try{let R=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(R==="realtime"||R==="both")){let C=this.cloudClient.getAccessToken();C&&Mr(this.cloudClient.getEndpoint(),C,this.cloudRunId,this.buildCloudTestPayload(M));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let R=xe(g,f,e.id??"",a.retry),C=a.retry===e.results.length-1,B={id:R,navigations:d.navigations,apiAssertions:d.apiAssertions,actions:A??[],artifacts:k,failureDiagnostic:p,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(R,B,{networkRequestsFile:d.networkRequestsFile,consoleLogsFile:d.consoleLogsFile,apiCallsFile:d.apiCallsFile});let $={id:R,title:f[f.length-1]??e.title,titlePath:f,filePath:g,status:n,duration:a.duration,project:f[1]??"",retryIndex:a.retry,tags:l,hasNetworkData:d.networkRequestsCount>0,hasConsoleData:d.consoleLogsCount>0,hasArtifacts:k!==null,hasActionSteps:(A?.length??0)>0,errorMessage:p?.message?.split(`
2584
- `)[0]??null,networkCount:d.networkRequestsCount,consoleCount:d.consoleLogsCount,actionCount:A?.length??0,isRetry:!C};if(this.testIndex.push($),C)switch(this.summaryCounters.total++,n){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+=A?.length??0,k&&this.pendingArtifactEntries.push({testId:m,artifacts:k,outputDir:path.dirname(this.config.outputPath)}),M.actions=null,M.apiAssertions=null,M.navigations=[],M.artifacts=null,M.failure=null,M.networkRequestsFile=null,M.consoleLogsFile=null,M.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(M),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),a=new Date(this.startedAt).getTime(),n=new Date(r).getTime()-a,o=this.activeReportMode==="streaming"?this.testIndex.some(l=>l.status!=="skipped"):this.collectedTests.some(l=>l.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
2576
+ `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?Z(this.gitMetadata.remoteUrl):null,r=e?wr(e):this.config.projectName??Q(process.cwd()),a=e??this.config.projectName??Q(process.cwd()),n=this.readRepoCache(a);if(n){this.repoId=n.repoId;return}try{let s=await br(this.config.endpoint,this.authState.accessToken,a,r,this.config.timeout,this.gitMetadata?.branch);s&&(this.repoId=s.repoId,this.writeRepoCache(a,s.repoId,s.displayName));}catch{}!e&&!this.config.projectName&&!Je(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2577
+ `);}readRepoCache(e){if(!this.config)return null;let r=path.join(this.config.queueDirectory,"..","cache","repo.json");try{if(!fs$1.existsSync(r))return null;let a=fs$1.readFileSync(r,"utf-8"),n=JSON.parse(a);if(n.gitId!==e||Date.now()-n.resolvedAt>Ln)return null;let s=this.hashApiKey();return s&&n.apiKeyHash!==s?null:n}catch{return null}}writeRepoCache(e,r,a){if(!this.config)return;let n=path.join(this.config.queueDirectory,"..","cache"),s=path.join(n,"repo.json");try{fs$1.mkdirSync(n,{recursive:!0});let o={repoId:r,gitId:e,displayName:a,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=s+".tmp";fs$1.writeFileSync(i,JSON.stringify(o,null,2),"utf-8"),fs$1.renameSync(i,s);}catch{}}hashApiKey(){return this.config?.apiKey?crypto.createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let e=this.authState.accessToken,r=this.config.queueDirectory,a=this.config.endpoint;this.flushPromise=Promise.race([Cr(r,a,e),new Promise(n=>setTimeout(n,Ar))]).catch(()=>{});}startHealthCheck(){if(!this.config)return;let e=this.config.endpoint;this.healthCheckTimer=setInterval(async()=>{if(!this.isCloudMode()&&!(!this.failureReason||!["cloud_unreachable","auth_timeout","network_error"].includes(this.failureReason)))try{if(!await Ge(e))return;if(this.config?.apiKey){let a=await We(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Ke(a)){let n=a;this.authState={mode:"cloud",accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:Date.now()+n.expiresIn*1e3,orgId:n.orgId,orgName:n.orgName,userId:n.userId,userName:n.userName},this.failureReason=null,process.stderr.write(`\u2713 TestRelic: Cloud connectivity restored.
2578
+ `),this.startBackgroundFlush();}}}catch{}},Mn);}};var En=new Set(["smoke","regression","nightly","ci"]);function ue(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&En.has(t))return t}var Nn=1048576,pe=[1e3,3e3,9e3],fe=3,Fn=40*1048576,Dn=new Set(["e2e","mobile","unit"]);function et(t){if(t&&t.length>0&&t.every(n=>n.testType==="api")){let n=new Map;for(let i of t){let l=i.apiProtocol??"rest";n.set(l,(n.get(l)??0)+1);}let s="rest",o=0;for(let[i,l]of n)l>o&&(o=l,s=i);return {testType:"api",apiProtocol:s,metadata:{testType:"api",primaryProtocol:s}}}let e=new Map;for(let n of t??[])Dn.has(n.testType)&&e.set(n.testType,(e.get(n.testType)??0)+1);let r=null,a=0;for(let[n,s]of e)s>a&&(a=s,r=n);return {testType:r??"e2e"}}function tt(t,e,r,a,n,s){let o=s?.cloudPlatform?s.cloudPlatform:a?.provider&&a.provider!=="unknown"?a.provider:"local",i=ue(),l=et(n),d=l.testType==="api"?l:null,p=d&&n?n.map(h=>h.apiProtocol?h:{...h,apiProtocol:d.apiProtocol}):n,f={runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:o,...i?{runType:i}:{},...d?{testType:d.testType,apiProtocol:d.apiProtocol,metadata:d.metadata}:{testType:l.testType},...p&&p.length>0?{tests:p}:{},...r?.branch?{branch:r.branch}:{},...r?.commitSha?{commit:r.commitSha}:{},...r?.commitMessage?{commitMessage:r.commitMessage}:{},...r?.commitAuthor?{commitAuthor:r.commitAuthor}:{},...t.completedAt?{finishedAt:t.completedAt}:{},...t.totalDuration?{duration:t.totalDuration}:{},...a?.provider?{ciProvider:a.provider}:{},...a?.runUrl?{ciRunUrl:a.runUrl}:{},...s?.cloudPlatform?{cloudPlatform:s.cloudPlatform}:{},...s?.cloudBuildId?{cloudBuildId:s.cloudBuildId}:{},...s?.cloudSessionId?{cloudSessionId:s.cloudSessionId}:{}};if(f.tests&&f.tests.length>0){let h=JSON.stringify(f);if(Buffer.byteLength(h,"utf-8")>Fn){let c=f.tests.map(({consoleLogs:u,networkRequests:g,apiCalls:m,...b})=>b);return {...f,tests:c}}}return f}function Xe(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function rt(t){return Array.isArray(t)?t.map(e=>{let r=e.statusCode??e.responseStatusCode??null;return {...e.protocol!=null?{protocol:e.protocol}:{},method:e.method??null,url:e.url??null,statusCode:r,statusText:e.statusText??e.responseStatusText??null,ok:typeof r=="number"?r<400:e.ok??null,durationMs:e.durationMs??e.responseTimeMs??null,bytesIn:typeof e.bytesIn=="number"?e.bytesIn:Xe(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Xe(e.requestBody),requestHeaders:e.requestHeaders??null,responseHeaders:e.responseHeaders??null,requestBody:e.requestBody??null,responseBody:e.responseBody??null,requestCookies:e.requestCookies??null,responseCookies:e.responseCookies??null}}):[]}function at(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,a=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:Xe(e.responseBody),duration:e.responseTimeMs??e.durationMs??0,responseTimeMs:e.responseTimeMs??e.durationMs??0,requestHeaders:e.requestHeaders??null,responseHeaders:e.responseHeaders??null,requestBody:e.requestBody??null,responseBody:e.responseBody??null,timestamp:a,startedAt:a}}):[]}function nt(t){if(!Array.isArray(t))return [];let e=r=>{if(r==null)return String(r);if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}};return t.map(r=>{let a=r.status==="failed"?"failed":"passed",n=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,s=r.kind??r.type??"assertion",o=a==="failed"?`expected ${e(r.expected)}, received ${e(r.actual)}`:r.expected!==void 0?`expected ${e(r.expected)}`:null;return {kind:s,description:n??r.description??`${s} assertion`,status:a,detail:o}})}async function ge(t){return new Promise(e=>setTimeout(e,t))}function Bn(t){let e={};for(let[r,a]of Object.entries(t))a!=null&&(e[r]=a);return e}async function _r(t,e,r){for(let a=0;a<fe;a++)try{let n=await fetch(t,e);if(n.ok)return n;if(n.status===401&&r&&a===0){let s=await r();if(s){let o={...e,headers:{...e.headers,Authorization:`Bearer ${s}`}},i=await fetch(t,o);if(i.ok)return i}return null}if(n.status===429&&a<fe-1){let s=n.headers.get("Retry-After"),o=s?parseInt(s,10)*1e3:pe[a];!isNaN(o)&&o>0?await ge(o):await ge(pe[a]);continue}if(n.status>=500&&a<fe-1){await ge(pe[a]);continue}return n}catch{if(a<fe-1){await ge(pe[a]);continue}return null}return null}function On(t){let e=JSON.stringify(t),r={"Content-Type":"application/json"};if(Buffer.byteLength(e,"utf-8")>Nn){let a=zlib.gzipSync(Buffer.from(e,"utf-8"));return r["Content-Encoding"]="gzip",{body:a,headers:r}}return {body:e,headers:r}}async function Ir(t,e,r,a){let n=`${t}/runs`,{body:s,headers:o}=On(r);o.Authorization=`Bearer ${e}`;let i=await _r(n,{method:"POST",headers:o,body:s},a);return i?.ok?{success:true,statusCode:i.status,error:null}:i?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:i?`Upload failed with status ${i.status}`:"Upload failed after retries",statusCode:i?.status??null,payload:r,targetEndpoint:n,method:"POST"}}async function Lr(t,e,r){let a=`${t}/runs/init`;try{let n=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(Bn(r))});return n.ok?{runId:(await n.json()).runId}:null}catch{return null}}function Mr(t,e,r,a){let n=`${t}/runs/${r}/tests`;fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(a)}).catch(()=>{});}async function Er(t,e,r,a){let n=`${t}/runs/${r}/finalize`;return (await _r(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(a)}))?.ok??false}function st(t,e,r,a){let n=`${t}/runs/${r}/finalize`,s=new Date,o={finishedAt:s.toISOString(),duration:s.getTime()-new Date(a).getTime(),summary:{}};fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)}).catch(()=>{});}function Pr(t,e,r,a){let n=[],s=[],o=null,i=0,l=null,d=0,p=null,f=0,h=t.filter(g=>g.name===core.ATTACHMENT_NAME&&g.body),c=false;if(h.length>0)for(let g of h)try{let m=JSON.parse(g.body.toString());if(core.isTestRelicFilePayload(m)){n=n.concat(m.navigations),s=s.concat(m.apiAssertions),m.networkRequestsFile&&(o=m.networkRequestsFile,i+=m.networkRequestsCount),m.consoleLogsFile&&(l=m.consoleLogsFile,d+=m.consoleLogsCount),m.apiCallsFile&&(p=m.apiCallsFile,f+=m.apiCallsCount),c=!0;continue}if(core.isTestRelicDataPayload(m)){n=n.concat(m.navigations),Array.isArray(m.apiAssertions)&&(s=s.concat(m.apiAssertions)),i+=m.networkRequests?.length??0,f+=m.apiCalls?.length??0;let b=m.consoleLogs;Array.isArray(b)&&(d+=b.length),c=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2579
+ `);}return c||(n=e.filter(g=>g.type==="lambdatest-navigation"&&g.description).map(g=>{try{return JSON.parse(g.description)}catch{return null}}).filter(g=>g!==null)),n.length===0&&i===0&&f===0&&!a&&!c&&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 Test Navigation data cannot be captured.
2580
+ `),{navigations:n,apiAssertions:s,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:l,consoleLogsCount:d,apiCallsFile:p,apiCallsCount:f}}function he(t=process.env){let e=zn(t.TESTRELIC_CLOUD_PLATFORM);if(e)return {cloudPlatform:e,cloudBuildId:t.TESTRELIC_CLOUD_BUILD_ID||void 0,cloudSessionId:t.TESTRELIC_CLOUD_SESSION_ID||void 0};if(t.BROWSERSTACK_USERNAME||t.BROWSERSTACK_ACCESS_KEY)return {cloudPlatform:"browserstack",cloudBuildId:t.BROWSERSTACK_BUILD_NAME||t.BROWSERSTACK_BUILD_ID||void 0,cloudSessionId:t.BROWSERSTACK_SESSION_ID||void 0};if(t.LT_USERNAME||t.LAMBDATEST_USERNAME||t.LT_ACCESS_KEY||t.LAMBDATEST_ACCESS_KEY)return {cloudPlatform:"lambdatest",cloudBuildId:t.LT_BUILD||t.LAMBDATEST_BUILD||void 0,cloudSessionId:t.LT_SESSION_ID||t.LAMBDATEST_SESSION_ID||void 0};let r=t.PLAYWRIGHT_WS_ENDPOINT;if(r){if(/cdp\.lambdatest\.com/i.test(r))return {cloudPlatform:"lambdatest"};if(/cdp\.browserstack\.com/i.test(r))return {cloudPlatform:"browserstack"}}return {}}function zn(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Wn=5,me=[1e3,3e3,9e3],z=3,Kn={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},it=0,ot=[];async function Jn(){it>=Wn&&await new Promise(t=>ot.push(t)),it++;}function Yn(){it--,ot.length>0&&ot.shift()();}async function ve(t){return new Promise(e=>setTimeout(e,t))}function Zn(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return Kn[e]??"application/octet-stream"}function Qn(t){try{return fs$1.statSync(t).size}catch{return 0}}async function Xn(t,e,r,a,n){let s=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:n,type:r.type,sizeBytes:a});for(let i=0;i<z;i++)try{let l=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o});if(l.ok)return await l.json();if(l.status>=500&&i<z-1){await ve(me[i]);continue}return null}catch{if(i<z-1){await ve(me[i]);continue}return null}return null}async function es(t,e,r,a){for(let n=0;n<z;n++)try{let s=fs$1.createReadStream(e),o=stream.Readable.toWeb(s),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(a)},body:o,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&n<z-1){await ve(me[n]);continue}return !1}catch{if(n<z-1){await ve(me[n]);continue}return false}return false}async function ts(t,e,r){let a=`${t}/artifacts/confirm`;try{return (await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function rs(t,e,r,a){let n=Qn(r.filePath);if(n===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(n>a*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let s=Zn(r.filePath);await Jn();try{let o=await Xn(t,e,r,n,s);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await es(o.uploadUrl,r.filePath,s,n))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let l=await ts(t,e,o.artifactId);return {success:l,storageKey:o.storageKey,artifactId:o.artifactId,error:l?null:"confirm_failed"}}finally{Yn();}}async function Nr(t,e,r,a){let n=new Map,s=r.map(async o=>{let i=await rs(t,e,o,a);n.set(o.filePath,i);});return await Promise.allSettled(s),n}function lt(t){let r=t.getGitMetadata()?.remoteUrl;return r?Z(r):t.getConfig()?.projectName??Q(process.cwd())}async function Dr(t,e,r,a,n){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=P(),l=he(),d=ue();return (await Lr(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:lt(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:a,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:n??l.cloudPlatform??null,cloudPlatform:l.cloudPlatform??null,cloudBuildId:l.cloudBuildId??null,cloudSessionId:l.cloudSessionId??null,...d?{runType:d}:{},testType:"e2e"}))?.runId??null}var as=true,ns=50;async function ss(t,e,r,a){let n=new Map;if(!(e?.uploadArtifacts??as)||!await t.ensureValidToken())return n;let i=[],l=new Map;for(let c of a){if(c.artifacts.screenshot){let u=path.join(c.outputDir,c.artifacts.screenshot);i.push({filePath:u,runId:r,testId:c.testId,type:"screenshot"}),l.set(u,{testId:c.testId,field:"screenshot"});}if(c.artifacts.video){let u=path.join(c.outputDir,c.artifacts.video);i.push({filePath:u,runId:r,testId:c.testId,type:"video"}),l.set(u,{testId:c.testId,field:"video"});}}if(i.length===0)return n;let d=e?.artifactMaxSizeMb??ns,p=await Nr(t.getEndpoint(),t.getAccessToken(),i,d),f=new Map;for(let[c,u]of p){if(!u.success||!u.storageKey)continue;let g=l.get(c);if(!g)continue;let m=f.get(g.testId)??{};g.field==="screenshot"&&(m.screenshotKey=u.storageKey),g.field==="video"&&(m.videoKey=u.storageKey),f.set(g.testId,m);}for(let c of a){let u=f.get(c.testId);n.set(c.testId,{...c.artifacts,...u?.screenshotKey?{screenshotKey:u.screenshotKey}:{},...u?.videoKey?{videoKey:u.videoKey}:{}});}let h=Array.from(p.values()).filter(c=>c.success).length;return h>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${h} artifact(s) to cloud storage.
2581
+ `),n}async function dt(t,e,r,a,n,s,o,i,l,d,p){try{if(t.isCloudMode()&&n&&(r==="realtime"||r==="both")){let h=await t.ensureValidToken(),c=t.getGitMetadata(),u=et(p),g={finishedAt:o,duration:i,summary:l,...c?.commitMessage?{commitMessage:c.commitMessage}:{},testType:u.testType,...u.testType==="api"?{apiProtocol:u.apiProtocol,metadata:u.metadata}:{}};if(h){if(!await Er(t.getEndpoint(),t.getAccessToken(),n,g)){let b=e?.queueDirectory??".testrelic/queue";X(b,a,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",g,{"Content-Type":"application/json"});}}else {let m=e?.queueDirectory??".testrelic/queue";X(m,a,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",g,{"Content-Type":"application/json"});}}let f=new Map;if(t.isCloudMode()&&d&&d.length>0&&(f=await ss(t,e,a,d)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let c=t.getGitMetadata(),u=P(),g=lt(t),m=is(s,f),b=tt(m,g,c,u,p,he()),S=await Ir(t.getEndpoint(),t.getAccessToken(),b,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!S.success){let y=S,x=e?.queueDirectory??".testrelic/queue";X(x,a,"batch",y.reason,y.targetEndpoint,y.method,y.payload,{"Content-Type":"application/json"});}}else {let c=e?.queueDirectory??".testrelic/queue",u=t.getGitMetadata(),g=P(),m=lt(t),b=tt(s,m,u,g,void 0,he());X(c,a,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",b,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function is(t,e){if(e.size===0)return t;let r=t.timeline.map(a=>{let n=a.testId;if(!n)return a;let s=e.get(n);return s?{...a,...s.screenshotKey?{screenshotKey:s.screenshotKey}:{},...s.videoKey?{videoKey:s.videoKey}:{}}:a});return {...t,timeline:r}}function q(t){try{return fs$1.readFileSync(t,"utf-8").split(`
2582
+ `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function ut(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 fs(t,e,r){let a=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(a).digest("hex").substring(0,16)}function gs(t){return t.length<=3?"":t[t.length-2]}function hs(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function ms(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 vs(){let t=os.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function ys(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:a}=e;if(a){let s=a.toLowerCase();return s==="chrome"||s==="chrome-stable"?"Chrome":s.startsWith("chrome-beta")?"Chrome Beta":s.startsWith("chrome-dev")?"Chrome Dev":s.startsWith("chrome-canary")?"Chrome Canary":s==="msedge"||s==="msedge-stable"?"Microsoft Edge":s.startsWith("msedge-beta")?"Edge Beta":s.startsWith("msedge-dev")?"Edge Dev":s.startsWith("msedge-canary")?"Edge Canary":a}if(r){let s=r.toLowerCase();return s==="chromium"?"Chromium":s==="firefox"?"Firefox":s==="webkit"?"WebKit":r}let n=e.defaultBrowserType;if(n){let s=n.toLowerCase();return s==="chromium"?"Chromium":s==="firefox"?"Firefox":s==="webkit"?"WebKit":n}}function bs(t,e,r){let a=r.parent?.project?.(),n="unknown";a!==void 0&&(a.use.isMobile===true?n="mobile":n="e2e");let s=["e2e","api","unit","mobile"];for(let l of s)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 n}var xs="__testrelic_api_config";function ws(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var ye=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.navigationsCaptured=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=It(e),this.apiConfig=_t(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 s=r.allTests().length;this.activeReportMode=s>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let a=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${a} tests)
2583
+ `),this.activeReportMode==="streaming"){let s=path.dirname(this.config.outputPath);this.streamingWriter=new G(s);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&&st(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",o),process.on("SIGINT",o);}if(this.config.includeArtifacts){let s=path.dirname(this.config.outputPath);this.runTimestamp=nr(path.join(s,"artifacts"));try{dr(path.join(s,"artifacts"));}catch{}}let n=P();this.detectedOs=vs(),this.detectedSource=ms(n);try{this.cloudClient=new ce(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await Dr(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let s=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let o=this.cloudClient.getAccessToken();o&&st(this.cloudClient.getEndpoint(),o,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",s),process.on("SIGINT",s);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:xs,description:ws(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let a=r,n=e.outcome(),s;n==="flaky"?s="flaky":n==="skipped"?s="skipped":s=ut(a.status);let o=a.startTime.toISOString(),i=new Date(a.startTime.getTime()+a.duration).toISOString(),l=e.tags?[...e.tags]:e.annotations.filter(R=>R.type==="tag").map(R=>R.description??""),d=Pr(a.attachments,e.annotations,e.title,s==="skipped");(d.navigations.length>0||d.networkRequestsCount>0||d.apiCallsCount>0)&&(this.fixtureDataReceived=!0),d.navigations.length>0&&(this.navigationsCaptured=!0),!this.config.captureNavigation&&d.navigations.length>0&&(d={...d,navigations:[]});let p=null;if(s==="failed"||s==="flaky"){let C=(s==="flaky"?e.results.find(B=>B.status!=="passed")?.errors??[]:a.errors)[0];if(C){let B=Mt(this.config.redactPatterns),$=C.location?.line??null,j=null;this.config.includeCodeSnippets&&$!==null&&C.location?.file&&(j=Lt(C.location.file,$,this.config.codeContextLines),j&&(j=B(j))),p={message:B(C.message??"Unknown error"),line:$,code:j,stack:this.config.includeStackTrace&&C.stack?B(C.stack):null};}}let f=e.titlePath().filter(Boolean),h=path.relative(this.rootDir||".",e.location.file),c=gs(f),u=f.join(" > "),g=h,m=fs(g,c,u),b=bs(l,g,e),S=b!=="mobile"&&d.apiCallsCount>0?"api":b,y=n==="flaky",x=hs(e.results),T=ut(e.expectedStatus),v=ut(a.status),k=null;if(this.config.includeArtifacts&&s!=="skipped"&&a.attachments){let R=path.dirname(this.config.outputPath),C=f[f.length-1]??e.title;k=sr(a.attachments,C,a.retry,R,this.runTimestamp||void 0);}let A=this.config.includeActionSteps&&a.steps?gr(a.steps,a.startTime):null,H=ys(e),M={titlePath:f,title:u,status:s,duration:a.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:a.retry,tags:l,failure:p,specFile:h,navigations:d.navigations,testId:m,filePath:g,suiteName:c,testType:S,isFlaky:y,retryStatus:x,expectedStatus:T,actualStatus:v,artifacts:k,apiAssertions:d.apiAssertions,actions:A,networkRequestsFile:d.networkRequestsFile,networkRequestsCount:d.networkRequestsCount,consoleLogsFile:d.consoleLogsFile,consoleLogsCount:d.consoleLogsCount,apiCallsFile:d.apiCallsFile,apiCallsCount:d.apiCallsCount,browser:H,os:this.detectedOs||void 0,source:this.detectedSource||void 0},pt=d.consoleLogsFile&&d.consoleLogsCount>0?q(d.consoleLogsFile):void 0,be=d.networkRequestsFile&&d.networkRequestsCount>0?q(d.networkRequestsFile):void 0,ee=d.apiCallsFile&&d.apiCallsCount>0?q(d.apiCallsFile):void 0,ft=ee?rt(ee):void 0,gt=!be&&ee?at(ee):void 0,ht=d.apiAssertions&&d.apiAssertions.length>0?nt(d.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:m,title:u,status:s,duration:a.duration,suiteName:c,filePath:g,testType:S,isFlaky:y,startedAt:o,completedAt:i,tags:l,failure:p,retry:a.retry,retryCount:e.results.length-1,retryStatus:x,browser:H,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...A&&A.length>0?{actions:A}:{},...d.navigations&&d.navigations.length>0?{navigations:d.navigations}:{},...pt?{consoleLogs:pt}:{},...be?{networkRequests:be}:gt?{networkRequests:gt}:{},...ft?{apiCalls:ft}:{},...ht?{protocolAssertions:ht}:{}});try{let R=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(R==="realtime"||R==="both")){let C=this.cloudClient.getAccessToken();C&&Mr(this.cloudClient.getEndpoint(),C,this.cloudRunId,this.buildCloudTestPayload(M));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let R=xe(g,f,e.id??"",a.retry),C=a.retry===e.results.length-1,B={id:R,navigations:d.navigations,apiAssertions:d.apiAssertions,actions:A??[],artifacts:k,failureDiagnostic:p,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(R,B,{networkRequestsFile:d.networkRequestsFile,consoleLogsFile:d.consoleLogsFile,apiCallsFile:d.apiCallsFile});let $={id:R,title:f[f.length-1]??e.title,titlePath:f,filePath:g,status:s,duration:a.duration,project:f[1]??"",retryIndex:a.retry,tags:l,hasNetworkData:d.networkRequestsCount>0,hasConsoleData:d.consoleLogsCount>0,hasArtifacts:k!==null,hasActionSteps:(A?.length??0)>0,errorMessage:p?.message?.split(`
2584
+ `)[0]??null,networkCount:d.networkRequestsCount,consoleCount:d.consoleLogsCount,actionCount:A?.length??0,isRetry:!C};if(this.testIndex.push($),C)switch(this.summaryCounters.total++,s){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+=A?.length??0,k&&this.pendingArtifactEntries.push({testId:m,artifacts:k,outputDir:path.dirname(this.config.outputPath)}),M.actions=null,M.apiAssertions=null,M.navigations=[],M.artifacts=null,M.failure=null,M.networkRequestsFile=null,M.consoleLogsFile=null,M.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(M),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),a=new Date(this.startedAt).getTime(),s=new Date(r).getTime()-a,o=this.activeReportMode==="streaming"?this.testIndex.some(l=>l.status!=="skipped"):this.collectedTests.some(l=>l.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
2585
2585
  \u26A0 TestRelic: No fixture data received from any test.
2586
- To enable network logs, video sync, and timeline tracking, import the TestRelic fixture:
2586
+ To enable network logs, video sync, and Test Navigation tracking, import the TestRelic fixture:
2587
2587
  import { test, expect } from '@testrelic/playwright-analytics/fixture';
2588
2588
  instead of:
2589
2589
  import { test, expect } from '@playwright/test';
2590
2590
 
2591
- `),await ar();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let l=path.dirname(this.config.outputPath);i=or(l,this.runTimestamp);let d=path.join(l,"artifact-manifest.json"),p=JSON.stringify(i),f=d+".tmp";fs$1.writeFileSync(f,p,"utf-8"),fs$1.renameSync(f,d);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,n,e,i);else {let l=this.buildTimeline(),d=new Map;for(let c of this.collectedTests){let u=d.get(c.testId);(!u||c.retry>u.retry)&&d.set(c.testId,c);}let p=Array.from(d.values()),f=fr(p,l.length),h={schemaVersion:ke,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:n,summary:f,ci:P(),metadata:this.config.metadata,timeline:l,shardRunIds:null};if(this.writeReport(h),await Oe(h,this.config,i),je(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let c=this.collectArtifactEntries(),u=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await dt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,h,r,n,f,c,u);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let a of this.collectedTests)a.artifacts&&r.push({testId:a.testId,artifacts:a.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,a,s){if(!this.streamingWriter)return;let{totalApiCalls:n,totalAssertions:o,totalNavigations:i,totalNetworkRequests:l,totalConsoleLogs:d,totalActionSteps:p}=this.summaryCounters;this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:n,totalAssertions:o,totalNavigations:i,totalNetworkRequests:l,totalConsoleLogs:d,totalActionSteps:p};let f=new Map,h=new Map;for(let x of this.testIndex){let T=`${x.filePath}::${x.titlePath.join(" > ")}`,v=f.get(T);(v===void 0||x.retryIndex>v)&&f.set(T,x.retryIndex);}let c=0;for(let x of this.testIndex){let T=`${x.filePath}::${x.titlePath.join(" > ")}`,v=f.get(T);if(x.isRetry=x.retryIndex<v,x.isRetry)continue;switch(c++,this.summaryCounters.total++,x.status){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}let k=h.get(x.filePath);switch(k||(k={filePath:x.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},h.set(x.filePath,k)),k.total++,x.status){case "passed":k.passed++;break;case "failed":k.failed++;break;case "flaky":k.flaky++;break;case "skipped":k.skipped++;break;case "timedout":k.timedOut++;break}}let u=Array.from(h.values());this.streamingWriter.writeIndex(this.testIndex),this.streamingWriter.writeCompactIndex(this.testIndex);let g={reporterTotal:this.summaryCounters.total,indexTotal:c,playwrightStatus:a.status,isValid:this.summaryCounters.total===c};g.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${g.reporterTotal}, index: ${g.indexTotal}
2592
- `);let m={total:this.summaryCounters.total,passed:this.summaryCounters.passed,failed:this.summaryCounters.failed,flaky:this.summaryCounters.flaky,skipped:this.summaryCounters.skipped,timedout:this.summaryCounters.timedOut,totalApiCalls:this.summaryCounters.totalApiCalls,uniqueApiUrls:0,apiCallsByMethod:{},apiCallsByStatusRange:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},apiResponseTime:null,totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:0,failedAssertions:0,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:0,totalTimelineSteps:this.testIndex.length,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{}},b={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:u,enrichedSummary:m,validation:g,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(b);let S={schemaVersion:"2.0",generatedAt:new Date().toISOString(),reportMode:"streaming",summaryFile:"summary.json",indexFile:"index.json",testsDir:"tests",artifactsDir:"artifacts",testCount:this.testIndex.length,totalSizeBytes:this.streamingWriter.computeTotalSize()};this.streamingWriter.writeManifest(S),await Oe(this.buildStreamingReport(b,m,e,r),this.config,s),je(m,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let y=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${y}
2591
+ `),this.config.captureNavigation?this.fixtureDataReceived&&!this.navigationsCaptured&&o&&process.stderr.write(`[testrelic] Test Navigation: 0 navigation events captured this run. Navigation is recorded automatically on page.goto()/clicks; if you expected a navigation graph, ensure your tests drive page navigations (and use the '@testrelic/playwright-analytics/fixture' import).
2592
+ `):process.stderr.write(`[testrelic] Test Navigation capture is disabled (captureNavigation: false). Remove the option or set it to true to capture the navigation graph.
2593
+ `),await ar();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let l=path.dirname(this.config.outputPath);i=or(l,this.runTimestamp);let d=path.join(l,"artifact-manifest.json"),p=JSON.stringify(i),f=d+".tmp";fs$1.writeFileSync(f,p,"utf-8"),fs$1.renameSync(f,d);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,s,e,i);else {let l=this.buildTimeline(),d=new Map;for(let c of this.collectedTests){let u=d.get(c.testId);(!u||c.retry>u.retry)&&d.set(c.testId,c);}let p=Array.from(d.values()),f=fr(p,l.length),h={schemaVersion:ke,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:s,summary:f,ci:P(),metadata:this.config.metadata,timeline:l,shardRunIds:null};if(this.writeReport(h),await Oe(h,this.config,i),je(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let c=this.collectArtifactEntries(),u=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await dt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,h,r,s,f,c,u);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let a of this.collectedTests)a.artifacts&&r.push({testId:a.testId,artifacts:a.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,a,n){if(!this.streamingWriter)return;let{totalApiCalls:s,totalAssertions:o,totalNavigations:i,totalNetworkRequests:l,totalConsoleLogs:d,totalActionSteps:p}=this.summaryCounters;this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:s,totalAssertions:o,totalNavigations:i,totalNetworkRequests:l,totalConsoleLogs:d,totalActionSteps:p};let f=new Map,h=new Map;for(let x of this.testIndex){let T=`${x.filePath}::${x.titlePath.join(" > ")}`,v=f.get(T);(v===void 0||x.retryIndex>v)&&f.set(T,x.retryIndex);}let c=0;for(let x of this.testIndex){let T=`${x.filePath}::${x.titlePath.join(" > ")}`,v=f.get(T);if(x.isRetry=x.retryIndex<v,x.isRetry)continue;switch(c++,this.summaryCounters.total++,x.status){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}let k=h.get(x.filePath);switch(k||(k={filePath:x.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},h.set(x.filePath,k)),k.total++,x.status){case "passed":k.passed++;break;case "failed":k.failed++;break;case "flaky":k.flaky++;break;case "skipped":k.skipped++;break;case "timedout":k.timedOut++;break}}let u=Array.from(h.values());this.streamingWriter.writeIndex(this.testIndex),this.streamingWriter.writeCompactIndex(this.testIndex);let g={reporterTotal:this.summaryCounters.total,indexTotal:c,playwrightStatus:a.status,isValid:this.summaryCounters.total===c};g.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${g.reporterTotal}, index: ${g.indexTotal}
2594
+ `);let m={total:this.summaryCounters.total,passed:this.summaryCounters.passed,failed:this.summaryCounters.failed,flaky:this.summaryCounters.flaky,skipped:this.summaryCounters.skipped,timedout:this.summaryCounters.timedOut,totalApiCalls:this.summaryCounters.totalApiCalls,uniqueApiUrls:0,apiCallsByMethod:{},apiCallsByStatusRange:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},apiResponseTime:null,totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:0,failedAssertions:0,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:0,totalTimelineSteps:this.testIndex.length,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{}},b={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:u,enrichedSummary:m,validation:g,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(b);let S={schemaVersion:"2.0",generatedAt:new Date().toISOString(),reportMode:"streaming",summaryFile:"summary.json",indexFile:"index.json",testsDir:"tests",artifactsDir:"artifacts",testCount:this.testIndex.length,totalSizeBytes:this.streamingWriter.computeTotalSize()};this.streamingWriter.writeManifest(S),await Oe(this.buildStreamingReport(b,m,e,r),this.config,n),je(m,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let y=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${y}
2593
2595
  [testrelic] ${this.testIndex.length} test detail files on disk
2594
2596
  [testrelic] View report: npx testrelic serve ${y}
2595
2597
  `),this.streamingWriter.getWriteErrors().length>0&&process.stderr.write(`[testrelic] WARNING: ${this.streamingWriter.getWriteErrors().length} write error(s) during streaming
2596
- `),this.streamingWriter.dispose(),this.cloudClient){let x=this.buildStreamingReport(b,m,e,r),T=this.collectArtifactEntries(),v=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await dt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,x,e,r,m,T,v);}this.testIndex.length=0,this.collectedTests.length=0,this.pendingArtifactEntries.length=0,this.cloudTestsBuffer.length=0,this.streamingWriter=null,this.cloudClient=null;}buildStreamingReport(e,r,a,s){return {schemaVersion:ke,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:a,totalDuration:s,summary:r,ci:P(),metadata:this.config.metadata,timeline:[],shardRunIds:null}}printsToStdio(){return false}checkMemoryPressure(){try{let e=process.memoryUsage(),r=e.heapUsed/1024/1024;if(r<200)return;let a=e.heapUsed/e.heapTotal;a>.9&&this.activeReportMode==="embedded"?(process.stderr.write(`[testrelic] WARNING: High memory (${Math.round(r)} MB). Auto-switching to streaming mode.
2598
+ `),this.streamingWriter.dispose(),this.cloudClient){let x=this.buildStreamingReport(b,m,e,r),T=this.collectArtifactEntries(),v=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await dt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,x,e,r,m,T,v);}this.testIndex.length=0,this.collectedTests.length=0,this.pendingArtifactEntries.length=0,this.cloudTestsBuffer.length=0,this.streamingWriter=null,this.cloudClient=null;}buildStreamingReport(e,r,a,n){return {schemaVersion:ke,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:a,totalDuration:n,summary:r,ci:P(),metadata:this.config.metadata,timeline:[],shardRunIds:null}}printsToStdio(){return false}checkMemoryPressure(){try{let e=process.memoryUsage(),r=e.heapUsed/1024/1024;if(r<200)return;let a=e.heapUsed/e.heapTotal;a>.9&&this.activeReportMode==="embedded"?(process.stderr.write(`[testrelic] WARNING: High memory (${Math.round(r)} MB). Auto-switching to streaming mode.
2597
2599
  `),this.switchToStreamingMode()):a>.8&&process.stderr.write(`[testrelic] WARNING: Memory pressure detected (${Math.round(r)} MB used).
2598
- `);}catch{}}switchToStreamingMode(){try{if(this.activeReportMode==="streaming")return;this.activeReportMode="streaming";let e=path.dirname(this.config.outputPath);this.streamingWriter=new G(e);for(let r of this.collectedTests){let a=xe(r.filePath,r.titlePath,r.testId,r.retry),s={id:a,navigations:r.navigations??[],apiAssertions:r.apiAssertions??[],actions:r.actions??[],artifacts:r.artifacts,failureDiagnostic:r.failure,hasNetworkFile:r.networkRequestsFile!==null,networkRequestsCount:r.networkRequestsCount,hasConsoleFile:r.consoleLogsFile!==null,consoleLogsCount:r.consoleLogsCount,hasApiCallsFile:r.apiCallsFile!==null,apiCallsCount:r.apiCallsCount,startedAt:r.startedAt};this.streamingWriter.writeTestDetail(a,s,{networkRequestsFile:r.networkRequestsFile,consoleLogsFile:r.consoleLogsFile,apiCallsFile:r.apiCallsFile});let n={id:a,title:r.titlePath[r.titlePath.length-1]??r.title,titlePath:r.titlePath,filePath:r.filePath,status:r.status,duration:r.duration,project:r.titlePath[1]??"",retryIndex:r.retry,tags:r.tags,hasNetworkData:r.networkRequestsCount>0,hasConsoleData:r.consoleLogsCount>0,hasArtifacts:r.artifacts!==null,hasActionSteps:(r.actions?.length??0)>0,errorMessage:r.failure?.message?.split(`
2599
- `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};switch(this.testIndex.push(n),this.summaryCounters.total++,r.status){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+=r.apiCallsCount,this.summaryCounters.totalAssertions+=r.apiAssertions?.length??0,this.summaryCounters.totalNavigations+=r.navigations?.length??0,this.summaryCounters.totalNetworkRequests+=r.networkRequestsCount,this.summaryCounters.totalConsoleLogs+=r.consoleLogsCount,this.summaryCounters.totalActionSteps+=r.actions?.length??0;}this.collectedTests.length=0;}catch{}}buildTimeline(){let e=this.collectedTests.map(r=>({titlePath:r.titlePath,title:r.title,status:r.status,duration:r.duration,startedAt:r.startedAt,completedAt:r.completedAt,retryCount:r.retryCount,retry:r.retry,tags:r.tags,failure:r.failure,specFile:r.specFile,navigations:r.navigations,apiCalls:null,apiAssertions:r.apiAssertions,testId:r.testId,filePath:r.filePath,suiteName:r.suiteName,testType:r.testType,isFlaky:r.isFlaky,retryStatus:r.retryStatus,expectedStatus:r.expectedStatus,actualStatus:r.actualStatus,artifacts:r.artifacts,networkRequests:null,actions:r.actions,consoleLogs:null}));return pr(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=q(e);return r.length>0?r:null}toTestResult(e,r){let a=null,s=null,n=null;return r?.loadFiles&&(a=this.readJsonlFile(e.networkRequestsFile),s=this.readJsonlFile(e.consoleLogsFile),n=this.readJsonlFile(e.apiCallsFile)),{title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:e.retryCount,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,retryStatus:e.retryStatus,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,networkRequests:a,apiCalls:n,apiAssertions:e.apiAssertions,actions:e.actions??null,consoleLogs:s}}buildCloudTestPayload(e){let r={title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retry:e.retry,retryCount:e.retryCount,retryStatus:e.retryStatus,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,actions:e.actions??[],navigations:e.navigations??[],steps:e.actions??[],browser:e.browser,os:e.os,source:e.source};if(e.apiAssertions&&e.apiAssertions.length>0&&(r.protocolAssertions=st(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=q(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=q(e.networkRequestsFile)),e.apiCallsFile){let a=q(e.apiCallsFile);r.apiCalls=rt(a),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=at(a));}return r}writeReport(e){try{let r=JSON.stringify(e),a=this.config.outputPath,s=path.dirname(a);fs$1.mkdirSync(s,{recursive:!0});let n=a+".tmp";fs$1.writeFileSync(n,r,"utf-8"),fs$1.renameSync(n,a);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2600
+ `);}catch{}}switchToStreamingMode(){try{if(this.activeReportMode==="streaming")return;this.activeReportMode="streaming";let e=path.dirname(this.config.outputPath);this.streamingWriter=new G(e);for(let r of this.collectedTests){let a=xe(r.filePath,r.titlePath,r.testId,r.retry),n={id:a,navigations:r.navigations??[],apiAssertions:r.apiAssertions??[],actions:r.actions??[],artifacts:r.artifacts,failureDiagnostic:r.failure,hasNetworkFile:r.networkRequestsFile!==null,networkRequestsCount:r.networkRequestsCount,hasConsoleFile:r.consoleLogsFile!==null,consoleLogsCount:r.consoleLogsCount,hasApiCallsFile:r.apiCallsFile!==null,apiCallsCount:r.apiCallsCount,startedAt:r.startedAt};this.streamingWriter.writeTestDetail(a,n,{networkRequestsFile:r.networkRequestsFile,consoleLogsFile:r.consoleLogsFile,apiCallsFile:r.apiCallsFile});let s={id:a,title:r.titlePath[r.titlePath.length-1]??r.title,titlePath:r.titlePath,filePath:r.filePath,status:r.status,duration:r.duration,project:r.titlePath[1]??"",retryIndex:r.retry,tags:r.tags,hasNetworkData:r.networkRequestsCount>0,hasConsoleData:r.consoleLogsCount>0,hasArtifacts:r.artifacts!==null,hasActionSteps:(r.actions?.length??0)>0,errorMessage:r.failure?.message?.split(`
2601
+ `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};switch(this.testIndex.push(s),this.summaryCounters.total++,r.status){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+=r.apiCallsCount,this.summaryCounters.totalAssertions+=r.apiAssertions?.length??0,this.summaryCounters.totalNavigations+=r.navigations?.length??0,this.summaryCounters.totalNetworkRequests+=r.networkRequestsCount,this.summaryCounters.totalConsoleLogs+=r.consoleLogsCount,this.summaryCounters.totalActionSteps+=r.actions?.length??0;}this.collectedTests.length=0;}catch{}}buildTimeline(){let e=this.collectedTests.map(r=>({titlePath:r.titlePath,title:r.title,status:r.status,duration:r.duration,startedAt:r.startedAt,completedAt:r.completedAt,retryCount:r.retryCount,retry:r.retry,tags:r.tags,failure:r.failure,specFile:r.specFile,navigations:r.navigations,apiCalls:null,apiAssertions:r.apiAssertions,testId:r.testId,filePath:r.filePath,suiteName:r.suiteName,testType:r.testType,isFlaky:r.isFlaky,retryStatus:r.retryStatus,expectedStatus:r.expectedStatus,actualStatus:r.actualStatus,artifacts:r.artifacts,networkRequests:null,actions:r.actions,consoleLogs:null}));return pr(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=q(e);return r.length>0?r:null}toTestResult(e,r){let a=null,n=null,s=null;return r?.loadFiles&&(a=this.readJsonlFile(e.networkRequestsFile),n=this.readJsonlFile(e.consoleLogsFile),s=this.readJsonlFile(e.apiCallsFile)),{title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:e.retryCount,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,retryStatus:e.retryStatus,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,networkRequests:a,apiCalls:s,apiAssertions:e.apiAssertions,actions:e.actions??null,consoleLogs:n}}buildCloudTestPayload(e){let r={title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retry:e.retry,retryCount:e.retryCount,retryStatus:e.retryStatus,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,actions:e.actions??[],navigations:e.navigations??[],steps:e.actions??[],browser:e.browser,os:e.os,source:e.source};if(e.apiAssertions&&e.apiAssertions.length>0&&(r.protocolAssertions=nt(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=q(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=q(e.networkRequestsFile)),e.apiCallsFile){let a=q(e.apiCallsFile);r.apiCalls=rt(a),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=at(a));}return r}writeReport(e){try{let r=JSON.stringify(e),a=this.config.outputPath,n=path.dirname(a);fs$1.mkdirSync(n,{recursive:!0});let s=a+".tmp";fs$1.writeFileSync(s,r,"utf-8"),fs$1.renameSync(s,a);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2600
2602
  `);}}};module.exports=ye;//# sourceMappingURL=reporter-entry.cjs.map
2601
2603
  //# sourceMappingURL=reporter-entry.cjs.map