@testrelic/playwright-analytics 2.11.1-next.75 → 2.11.1-next.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import {randomUUID,createHash}from'crypto';import {mkdirSync,openSync,writeSync,closeSync,unlinkSync,readFileSync,writeFileSync,renameSync,existsSync,appendFileSync,readdirSync,statSync,rmSync,createReadStream}from'fs';import {join,dirname,relative,extname,resolve,parse,basename}from'path';import {tmpdir,platform}from'os';import {PAYLOAD_VERSION,ATTACHMENT_NAME,ATTACHMENT_CONTENT_TYPE,isValidConfig,createError,ErrorCode,isTestRelicFilePayload,isTestRelicDataPayload,isValidEndpointUrl,isValidCloudConfig,isValidQueueEntry}from'@testrelic/core';export{ATTACHMENT_CONTENT_TYPE,ATTACHMENT_NAME,PAYLOAD_VERSION,isTestRelicDataPayload}from'@testrelic/core';import {spawn,exec,execSync}from'child_process';import {createServer}from'http';import {createInterface}from'readline';import {copyFile}from'fs/promises';import {gzip}from'zlib';import {promisify}from'util';import {Readable}from'stream';import {test,expect,defineConfig}from'@playwright/test';import {performance}from'perf_hooks';import {fileURLToPath}from'url';var An=(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 Ln=".testrelic-report";function Me(t,e,r,n){let s=`${t}|${e.join("|")}|${r}|${n}`;return createHash("sha256").update(s).digest("hex").substring(0,12)}var ee=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=join(e,Ln),this.testsDir=join(this.reportDir,"tests"),mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,n){try{let s=join(this.testsDir,e);mkdirSync(s,{recursive:!0});let a=join(s,"meta.json"),l=a+".tmp",i=JSON.stringify(r);return writeFileSync(l,i,"utf-8"),renameSync(l,a),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),n?.networkRequestsFile&&this.moveFile(n.networkRequestsFile,join(s,"network.jsonl")),n?.consoleLogsFile&&this.moveFile(n.consoleLogsFile,join(s,"console.jsonl")),n?.apiCallsFile&&this.moveFile(n.apiCallsFile,join(s,"api-calls.jsonl")),!0}catch(s){let a=s instanceof Error?s.message:String(s);return this.writeErrors.push({testId:e,error:a,timestamp:new Date().toISOString()}),process.stderr.write(`[testrelic] Failed to write test detail for ${e}: ${a}
2
- `),false}}moveFile(e,r){try{renameSync(e,r);}catch{try{let{copyFileSync:n}=An("fs");n(e,r);try{unlinkSync(e);}catch{}}catch(n){process.stderr.write(`[testrelic] Failed to move file ${e} \u2192 ${r}: ${n instanceof Error?n.message:String(n)}
3
- `);}}}writeIndex(e){let r=join(this.reportDir,"index.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeCompactIndex(e){let r=join(this.reportDir,"index-compact.json"),n=r+".tmp",s=e.map(({titlePath:l,project:i,...d})=>d),a=JSON.stringify(s);writeFileSync(n,a,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=join(this.reportDir,"summary.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeManifest(e){let r=join(this.reportDir,"manifest.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var Ht=".testrelic",Dn="testrelic-config.json",Bn=".testrelic",On=5,qn=new Set(["__proto__","constructor","prototype"]),Ot=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${Ht}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),Hn={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Ut(t){let e=resolve(t);for(let r=0;r<=On;r++){let n=join(e,Ht,Dn);if(existsSync(n))try{if(statSync(n).isFile())return n}catch{}let s=join(e,Bn);if(existsSync(s))try{if(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 a=dirname(e);if(a===e)break;e=a;}return null}function $t(t){try{let e=readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!zt(r)?null:r}catch{return null}}function zt(t){for(let e of Object.keys(t)){if(qn.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!zt(r))return false}return true}function jt(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 Ee(t){let e=Object.create(null);for(let r of Object.keys(t)){let n=t[r];typeof n=="string"&&n.startsWith("$")?e[r]=jt(n):typeof n=="object"&&n!==null&&!Array.isArray(n)?e[r]=Ee(n):e[r]=n;}return e}function qt(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),n=e[2],s=Hn[n];return !s||r<=0?null:r*s}function Wt(t,e){let r=Object.create(null);if(Object.assign(r,Ot),t){let d=t.cloud;d&&typeof d=="object"&&(typeof d.endpoint=="string"&&(r.endpoint=d.endpoint),typeof d.upload=="string"&&(r.uploadStrategy=d.upload),typeof d.timeout=="number"&&(r.timeout=d.timeout),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let o=t["testrelic-repo"]??t.project;o&&typeof o=="object"&&typeof o.name=="string"&&(r.projectName=o.name),t.project&&!t["testrelic-repo"]&&process.stderr.write(`[testrelic] Deprecation: "project" key in config is deprecated. Rename it to "testrelic-repo".
5
- `);let c=t.queue;if(c&&typeof c=="object"){if(typeof c.maxAge=="string"){let f=qt(c.maxAge);f!==null&&(r.queueMaxAge=f);}typeof c.directory=="string"&&(r.queueDirectory=c.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?jt(e.apiKey):e.apiKey;d&&(r.apiKey=d);}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 d=qt(e.queueMaxAge);d!==null&&(r.queueMaxAge=d);}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 n=process.env.TESTRELIC_API_KEY;n&&n.length>0&&(r.apiKey=n);let s=process.env.TESTRELIC_CLOUD_ENDPOINT;s&&isValidEndpointUrl(s)&&(r.endpoint=s);let a=process.env.TESTRELIC_UPLOAD_STRATEGY;a&&["batch","realtime","both"].includes(a)&&(r.uploadStrategy=a);let l=process.env.TESTRELIC_CLOUD_TIMEOUT;if(l){let d=parseInt(l,10);!isNaN(d)&&d>=1e3&&d<=12e4&&(r.timeout=d);}let i=Object.freeze(r);return isValidCloudConfig(i)?i:Ot}var jn=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],Wn=["authorization","cookie","set-cookie","x-api-key"],Vn=["password","secret","token","apiKey","api_key"];function Vt(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??[...Wn],e.redactBodyFields=t?.redactBodyFields??[...Vn],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Gt(t){if(t!==void 0&&!isValidConfig(t))throw createError(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=[...jn,...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 n=Ut(process.cwd()),s=n?$t(n):null,a=s?Ee(s):null,l=Wt(a,t?.cloud);return e.cloud=l.apiKey?l:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var le="1.3.0";function Jt(t,e,r){try{let s=readFileSync(t,"utf-8").split(`
1
+ import {randomUUID,createHash}from'crypto';import {mkdirSync,openSync,writeSync,closeSync,unlinkSync,readFileSync,writeFileSync,renameSync,existsSync,appendFileSync,readdirSync,statSync,rmSync,createReadStream}from'fs';import {join,dirname,relative,extname,resolve,parse,basename}from'path';import {tmpdir,platform}from'os';import {PAYLOAD_VERSION,ATTACHMENT_NAME,ATTACHMENT_CONTENT_TYPE,isValidConfig,createError,ErrorCode,isTestRelicFilePayload,isTestRelicDataPayload,isValidEndpointUrl,isValidCloudConfig,isValidQueueEntry}from'@testrelic/core';export{ATTACHMENT_CONTENT_TYPE,ATTACHMENT_NAME,PAYLOAD_VERSION,isTestRelicDataPayload}from'@testrelic/core';import {spawn,execFile,execSync}from'child_process';import {createServer}from'http';import {createInterface}from'readline';import {copyFile}from'fs/promises';import {gzip}from'zlib';import {promisify}from'util';import {Readable}from'stream';import {test,expect,defineConfig}from'@playwright/test';import {performance}from'perf_hooks';import {fileURLToPath}from'url';var _n=(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 Pn=".testrelic-report";function Me(t,e,r,n){let s=`${t}|${e.join("|")}|${r}|${n}`;return createHash("sha256").update(s).digest("hex").substring(0,12)}var ee=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=join(e,Pn),this.testsDir=join(this.reportDir,"tests"),mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,n){try{let s=join(this.testsDir,e);mkdirSync(s,{recursive:!0});let a=join(s,"meta.json"),l=a+".tmp",i=JSON.stringify(r);return writeFileSync(l,i,"utf-8"),renameSync(l,a),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),n?.networkRequestsFile&&this.moveFile(n.networkRequestsFile,join(s,"network.jsonl")),n?.consoleLogsFile&&this.moveFile(n.consoleLogsFile,join(s,"console.jsonl")),n?.apiCallsFile&&this.moveFile(n.apiCallsFile,join(s,"api-calls.jsonl")),!0}catch(s){let a=s instanceof Error?s.message:String(s);return this.writeErrors.push({testId:e,error:a,timestamp:new Date().toISOString()}),process.stderr.write(`[testrelic] Failed to write test detail for ${e}: ${a}
2
+ `),false}}moveFile(e,r){try{renameSync(e,r);}catch{try{let{copyFileSync:n}=_n("fs");n(e,r);try{unlinkSync(e);}catch{}}catch(n){process.stderr.write(`[testrelic] Failed to move file ${e} \u2192 ${r}: ${n instanceof Error?n.message:String(n)}
3
+ `);}}}writeIndex(e){let r=join(this.reportDir,"index.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeCompactIndex(e){let r=join(this.reportDir,"index-compact.json"),n=r+".tmp",s=e.map(({titlePath:l,project:i,...d})=>d),a=JSON.stringify(s);writeFileSync(n,a,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=join(this.reportDir,"summary.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeManifest(e){let r=join(this.reportDir,"manifest.json"),n=r+".tmp",s=JSON.stringify(e);writeFileSync(n,s,"utf-8"),renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var Ut=".testrelic",Bn="testrelic-config.json",On=".testrelic",qn=5,Hn=new Set(["__proto__","constructor","prototype"]),qt=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${Ut}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),Un={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function zt(t){let e=resolve(t);for(let r=0;r<=qn;r++){let n=join(e,Ut,Bn);if(existsSync(n))try{if(statSync(n).isFile())return n}catch{}let s=join(e,On);if(existsSync(s))try{if(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 a=dirname(e);if(a===e)break;e=a;}return null}function $t(t){try{let e=readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!jt(r)?null:r}catch{return null}}function jt(t){for(let e of Object.keys(t)){if(Hn.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!jt(r))return false}return true}function Wt(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 Ee(t){let e=Object.create(null);for(let r of Object.keys(t)){let n=t[r];typeof n=="string"&&n.startsWith("$")?e[r]=Wt(n):typeof n=="object"&&n!==null&&!Array.isArray(n)?e[r]=Ee(n):e[r]=n;}return e}function Ht(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),n=e[2],s=Un[n];return !s||r<=0?null:r*s}function Vt(t,e){let r=Object.create(null);if(Object.assign(r,qt),t){let d=t.cloud;d&&typeof d=="object"&&(typeof d.endpoint=="string"&&(r.endpoint=d.endpoint),typeof d.upload=="string"&&(r.uploadStrategy=d.upload),typeof d.timeout=="number"&&(r.timeout=d.timeout),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let o=t["testrelic-repo"]??t.project;o&&typeof o=="object"&&typeof o.name=="string"&&(r.projectName=o.name),t.project&&!t["testrelic-repo"]&&process.stderr.write(`[testrelic] Deprecation: "project" key in config is deprecated. Rename it to "testrelic-repo".
5
+ `);let c=t.queue;if(c&&typeof c=="object"){if(typeof c.maxAge=="string"){let f=Ht(c.maxAge);f!==null&&(r.queueMaxAge=f);}typeof c.directory=="string"&&(r.queueDirectory=c.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?Wt(e.apiKey):e.apiKey;d&&(r.apiKey=d);}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 d=Ht(e.queueMaxAge);d!==null&&(r.queueMaxAge=d);}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 n=process.env.TESTRELIC_API_KEY;n&&n.length>0&&(r.apiKey=n);let s=process.env.TESTRELIC_CLOUD_ENDPOINT;s&&isValidEndpointUrl(s)&&(r.endpoint=s);let a=process.env.TESTRELIC_UPLOAD_STRATEGY;a&&["batch","realtime","both"].includes(a)&&(r.uploadStrategy=a);let l=process.env.TESTRELIC_CLOUD_TIMEOUT;if(l){let d=parseInt(l,10);!isNaN(d)&&d>=1e3&&d<=12e4&&(r.timeout=d);}let i=Object.freeze(r);return isValidCloudConfig(i)?i:qt}var Wn=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],Vn=["authorization","cookie","set-cookie","x-api-key"],Gn=["password","secret","token","apiKey","api_key"];function Gt(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??[...Vn],e.redactBodyFields=t?.redactBodyFields??[...Gn],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Jt(t){if(t!==void 0&&!isValidConfig(t))throw createError(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=[...Wn,...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 n=zt(process.cwd()),s=n?$t(n):null,a=s?Ee(s):null,l=Vt(a,t?.cloud);return e.cloud=l.apiKey?l:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var le="1.3.0";function Kt(t,e,r){try{let s=readFileSync(t,"utf-8").split(`
6
6
  `);if(e<1||e>s.length)return null;let a=Math.max(1,e-r),l=Math.min(s.length,e+r),i=[];for(let d=a;d<=l;d++){let o=d===e?">":" ",c=String(d).padStart(String(l).length," ");i.push(`${o} ${c} | ${s[d-1]}`);}return i.join(`
7
- `)}catch{return null}}function Kt(t){return e=>{let r=e;for(let n of t)if(typeof n=="string"){let s=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(s,"g"),"[REDACTED]");}else {let s=n.flags.includes("g")?n.flags:n.flags+"g",a=new RegExp(n.source,s);r=r.replace(a,"[REDACTED]");}return r}}function Jn(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 Kn(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 Yn(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 Qn(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 Zn(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 Xn=[Jn,Kn,Yn,Qn,Zn];function F(t){let e=process.env;for(let r of Xn){let n=r(e);if(n)return n}return null}var Ne=`
7
+ `)}catch{return null}}function Yt(t){return e=>{let r=e;for(let n of t)if(typeof n=="string"){let s=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(s,"g"),"[REDACTED]");}else {let s=n.flags.includes("g")?n.flags:n.flags+"g",a=new RegExp(n.source,s);r=r.replace(a,"[REDACTED]");}return r}}function Kn(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 Yn(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 Qn(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 Zn(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 Xn(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 es=[Kn,Yn,Qn,Zn,Xn];function F(t){let e=process.env;for(let r of es){let n=r(e);if(n)return n}return null}var Ne=`
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;
@@ -2118,7 +2118,7 @@ function _updateCard(cls,val){
2118
2118
  h+='</div>';
2119
2119
  return h;
2120
2120
  }
2121
- `;var $e=`
2121
+ `;var ze=`
2122
2122
  /* \u2500\u2500 Console Log Level Colors & Labels \u2500\u2500 */
2123
2123
  var LOG_COLORS={log:'#9ca3af',warn:'#fbbf24',error:'#f87171',info:'#60a5fa',debug:'#a78bfa',stdout:'#9ca3af',stderr:'#f87171'};
2124
2124
  var LOG_LABELS={log:'LOG',warn:'WARN',error:'ERR',info:'INFO',debug:'DBG',stdout:'OUT',stderr:'ERR'};
@@ -2305,7 +2305,7 @@ function _updateCard(cls,val){
2305
2305
  }
2306
2306
  return h;
2307
2307
  }
2308
- `;var ze=`
2308
+ `;var $e=`
2309
2309
  /* \u2500\u2500 Artifact Utilities \u2500\u2500 */
2310
2310
  function formatBytes(bytes){
2311
2311
  if(bytes===0)return '0 B';
@@ -2314,15 +2314,15 @@ function _updateCard(cls,val){
2314
2314
  if(i>=sizes.length)i=sizes.length-1;
2315
2315
  return parseFloat((bytes/Math.pow(k,i)).toFixed(1))+' '+sizes[i];
2316
2316
  }
2317
- `;var es=`
2317
+ `;var ts=`
2318
2318
  (function(){
2319
2319
  var data=JSON.parse(document.getElementById('report-data').textContent);
2320
2320
  ${Be}
2321
2321
  ${Ue}
2322
- ${$e}
2322
+ ${ze}
2323
2323
  ${Oe}
2324
2324
  ${qe}
2325
- ${ze}
2325
+ ${$e}
2326
2326
  ${He}
2327
2327
  applyTheme();
2328
2328
  renderRunMeta();
@@ -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 Yt(t,e,r){let n=t.replace(/<\//g,"<\\/"),s=r?r.replace(/<\//g,"<\\/"):null;return `<!-- TestRelic AI Analytics Report \u2014 self-contained, no external dependencies -->
2334
+ })();`;function Qt(t,e,r){let n=t.replace(/<\//g,"<\\/"),s=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>
@@ -2385,7 +2385,7 @@ ${""}
2385
2385
  </aside>
2386
2386
  <script id="report-data" type="application/json">${n}</script>
2387
2387
  ${s?`<script id="artifact-manifest-data" type="application/json">${s}</script>`:""}
2388
- <script>${es}</script>
2388
+ <script>${ts}</script>
2389
2389
  </body>
2390
2390
  </html>`}function je(t,e,r,n){let s=t.replace(/<\//g,"<\\/"),a=e.replace(/<\//g,"<\\/"),l=n?n.replace(/<\//g,"<\\/"):null,i={};try{i=JSON.parse(t);}catch{}let d=`{
2391
2391
  "schemaVersion":"2.0",
@@ -2473,10 +2473,10 @@ ${s?`<script id="artifact-manifest-data" type="application/json">${s}</script>`:
2473
2473
 
2474
2474
  ${Be}
2475
2475
  ${Ue}
2476
- ${$e}
2476
+ ${ze}
2477
2477
  ${Oe}
2478
2478
  ${qe}
2479
- ${ze}
2479
+ ${$e}
2480
2480
  ${He}
2481
2481
  applyTheme();
2482
2482
  renderRunMeta();
@@ -2543,37 +2543,37 @@ ${r?`<meta name="artifact-server-port" content="${r}">`:""}
2543
2543
  ${l?`<script id="artifact-manifest-data" type="application/json">${l}</script>`:""}
2544
2544
  <script>${o}</script>
2545
2545
  </body>
2546
- </html>`}function We(t){try{let e=process.platform,r;e==="darwin"?r=`open "${t}"`:e==="win32"?r=`start "" "${t}"`:r=`xdg-open "${t}"`,exec(r,n=>{n&&process.stderr.write(`[testrelic] Failed to open browser: ${n.message}
2547
- `);});}catch{}}var Qt=join(tmpdir(),"testrelic-data"),E=class{constructor(e){this.count=0;this.closed=false;mkdirSync(Qt,{recursive:true}),this.filePath=join(Qt,`${e}-${randomUUID().substring(0,8)}.jsonl`),this.fd=openSync(this.filePath,"w");}append(e){if(this.closed)return;let r=JSON.stringify(e)+`
2548
- `;writeSync(this.fd,r),this.count++;}getPath(){return this.filePath}getCount(){return this.count}close(){if(!this.closed){this.closed=true;try{closeSync(this.fd);}catch{}}}cleanup(){try{unlinkSync(this.filePath);}catch{}}};async function Xt(t,e,r,n){let s=(e-1)*r,a=[],l=0,i=createInterface({input:createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let c of i)if(c.length!==0){if(l>=s&&a.length<r)try{a.push(JSON.parse(c));}catch{}if(l++,a.length>=r&&n!==void 0)break}let d=n??l,o=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:o}}var rr=/^[a-f0-9]{12}$/,Ve=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,nr=500;function x(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function sr(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 ue(t){try{return existsSync(t)?JSON.parse(readFileSync(t,"utf-8")):null}catch{return null}}function pe(t){let e=0;try{let r=readdirSync(t,{withFileTypes:!0});for(let n of r){let s=join(t,n.name);n.isFile()?e+=statSync(s).size:n.isDirectory()&&(e+=pe(s));}}catch{}return e}function ar(t,e,r,n){let s=ue(join(r,"index.json"));x(e,200,{status:"ok",reportMode:"streaming",testCount:s?.length??0,uptime:Math.floor((Date.now()-n)/1e3)});}function ir(t,e,r){let n=ue(join(r,"summary.json"));if(!n){x(e,404,{error:"Summary not found"});return}x(e,200,n);}function or(t,e,r){let n=ue(join(r,"index.json"));if(!n){x(e,404,{error:"Test index not found"});return}let a=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,l=Math.max(1,parseInt(a.get("page")??"1",10)||1),i=Math.min(nr,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,o=a.get("file")??null,c=a.get("search")?.toLowerCase()??null,f=a.get("tag")?.split(",").filter(Boolean)??null,g=a.get("sort")??"file",u=a.get("order")==="desc"?-1:1,h=n;d&&d.length>0&&(h=h.filter(v=>d.includes(v.status))),o&&(h=h.filter(v=>v.filePath===o||v.filePath.startsWith(o+"/"))),c&&(h=h.filter(v=>v.title.toLowerCase().includes(c)||v.filePath.toLowerCase().includes(c))),f&&f.length>0&&(h=h.filter(v=>f.some(k=>v.tags.includes(k)))),h=[...h].sort((v,k)=>{let C=0;switch(g){case "duration":C=v.duration-k.duration;break;case "status":C=v.status.localeCompare(k.status);break;case "title":C=v.title.localeCompare(k.title);break;default:C=v.filePath.localeCompare(k.filePath);break}return C*u});let p=h.length,m=Math.max(1,Math.ceil(p/i)),y=(l-1)*i,w=h.slice(y,y+i);x(e,200,{tests:w,pagination:{page:l,pageSize:i,totalItems:p,totalPages:m},filters:{status:d,file:o,search:c,tag:f}});}function lr(t,e,r,n){if(!rr.test(n)){x(e,400,{error:"Invalid test ID format"});return}let s=join(r,"tests",n,"meta.json"),a=join(r,"tests",`${n}.json`),l=existsSync(s)?s:existsSync(a)?a:null;if(!l){x(e,404,{error:`Test not found: ${n}`});return}try{let i=readFileSync(l,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){x(e,500,{error:i instanceof Error?i.message:String(i)});}}async function dr(t,e,r,n,s){if(!rr.test(n)){x(e,400,{error:"Invalid test ID format"});return}let l=join(r,"tests",n,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[s]);if(!existsSync(l)){x(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let d=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(d.get("page")??"1",10)||1),c=Math.min(nr,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),f,g=join(r,"tests",n,"meta.json");if(existsSync(g))try{let h=JSON.parse(readFileSync(g,"utf-8"));switch(s){case "network":f=h.networkRequestsCount;break;case "console":f=h.consoleLogsCount;break;case "api-calls":f=h.apiCallsCount;break}}catch{}let u=await Xt(l,o,c,f);x(e,200,u);}catch(i){x(e,500,{error:i instanceof Error?i.message:String(i)});}}function cr(t,e,r){let n=ue(join(r,"index.json"));if(!n){x(e,404,{error:"Test index not found"});return}let s=new Map;for(let l of n){if(l.isRetry)continue;let i=s.get(l.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},s.set(l.filePath,i)),i.total++,l.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 a=Array.from(s.entries()).map(([l,i])=>({filePath:l,...i})).sort((l,i)=>l.filePath.localeCompare(i.filePath));x(e,200,{files:a});}function ur(t,e,r){if(!existsSync(r)){x(e,200,{runs:[],totalSizeBytes:0});return}try{let n=[],s=0,a=readdirSync(r,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||!Ve.test(l.name))continue;let i=join(r,l.name),d=pe(i),o=readdirSync(i,{withFileTypes:!0}).filter(c=>c.isDirectory());n.push({folderName:l.name,totalSizeBytes:d,testCount:o.length}),s+=d;}n.sort((l,i)=>i.folderName.localeCompare(l.folderName)),x(e,200,{runs:n,totalSizeBytes:s});}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}function pr(t,e,r){try{let n=0,s=0;if(existsSync(r)){let a=readdirSync(r,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||!Ve.test(l.name))continue;let i=join(r,l.name),d=pe(i);rmSync(i,{recursive:!0,force:!0}),s+=d,n++;}}x(e,200,{deletedCount:n,freedBytes:s});}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}function fr(t,e,r,n){if(!Ve.test(n)){x(e,400,{error:"Invalid folder name"});return}let s=join(r,n);try{if(!statSync(s).isDirectory()){x(e,404,{error:"Not found"});return}}catch{x(e,404,{error:"Not found"});return}try{let a=pe(s);rmSync(s,{recursive:!0,force:!0}),x(e,200,{deleted:n,freedBytes:a});}catch(a){x(e,500,{error:a instanceof Error?a.message:String(a)});}}function gr(t,e,r){x(e,200,{status:"shutting_down"}),r.close();}function Ge(t,e,r){if(!existsSync(r)){x(e,404,{error:"File not found"});return}try{let n=readFileSync(r),s=extname(r).toLowerCase(),a=ps[s]??"application/octet-stream";e.writeHead(200,{"Content-Type":a}),e.end(n);}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}var ps={".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 ms=9323,ys=10,vs=1800*1e3;function te(t,e){return new Promise((r,n)=>{let s=e?.port??ms,a=Date.now(),l,i=0,d=existsSync(join(t,"artifacts"))?join(t,"artifacts"):existsSync(join(t,"..","artifacts"))?join(t,"..","artifacts"):join(t,"artifacts");function o(){clearTimeout(l),l=setTimeout(()=>{f.close();},vs);}let c=e?.htmlPath??null;if(!c){let u=dirname(t);try{let h=readdirSync(u).find(p=>p.endsWith(".html"));h&&(c=join(u,h));}catch{}}let f=createServer((u,h)=>{if(o(),sr(h),u.method==="OPTIONS"){h.writeHead(204),h.end();return}let p;try{p=new URL(u.url??"/",`http://${u.headers.host??"localhost"}`).pathname;}catch{x(h,400,{error:"Invalid URL"});return}if(u.method==="GET"&&(p==="/"||p==="/index.html")){if(c&&existsSync(c)){Ge(u,h,c);return}x(h,404,{error:"HTML report not found"});return}if(u.method==="GET"&&p==="/api/health"){ar(u,h,t,a);return}if(u.method==="GET"&&p==="/api/summary"){ir(u,h,t);return}if(u.method==="GET"&&p==="/api/tests"){or(u,h,t);return}if(u.method==="GET"&&p==="/api/files"){cr(u,h,t);return}let m=p.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(u.method==="GET"&&m){dr(u,h,t,m[1],m[2]);return}let y=p.match(/^\/api\/tests\/([a-f0-9]+)$/);if(u.method==="GET"&&y){lr(u,h,t,y[1]);return}if(u.method==="GET"&&p==="/api/artifacts"){ur(u,h,d);return}if(u.method==="DELETE"&&p==="/api/artifacts"){pr(u,h,d);return}let w=p.match(/^\/api\/artifacts\/(.+)$/);if(u.method==="DELETE"&&w){fr(u,h,d,decodeURIComponent(w[1]));return}if(u.method==="GET"&&p.startsWith("/artifacts/")){let v=decodeURIComponent(p.slice(11));if(v.includes("..")||v.includes("\0")){x(h,400,{error:"Invalid path"});return}Ge(u,h,join(d,v));return}if(u.method==="POST"&&p==="/api/shutdown"){gr(u,h,f);return}x(h,404,{error:"Not found"});});function g(u){let h=p=>{p.code==="EADDRINUSE"&&i<ys?(i++,g(u+1)):n(p);};f.once("error",h),f.listen(u,"127.0.0.1",()=>{f.removeListener("error",h);let p=f.address();if(!p||typeof p=="string"){n(new Error("Failed to get server address"));return}o(),r({port:p.port,dispose:()=>new Promise(m=>{clearTimeout(l),f.close(()=>m());})});});}g(s);})}async function hr(t){let e=await te(t);return {port:e.port,dispose:e.dispose}}function xs(t,e,r){let n=JSON.stringify(t),s=r?JSON.stringify(r):null;return Yt(n,e,s)}async function Ke(t,e,r){try{let n=null,s=null,a=e.reportMode==="streaming"||e.reportMode==="auto"&&t.timeline.length===0&&t.summary.total>=e.streamingThreshold,l,i=e.htmlReportPath,d=dirname(i);mkdirSync(d,{recursive:!0});let o="",c="[]",f=null;if(a){o=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 u=dirname(e.outputPath),h=join(u,".testrelic-report");try{let p=join(h,"index-compact.json"),m=join(h,"index.json");existsSync(p)?c=readFileSync(p,"utf-8"):existsSync(m)&&(c=readFileSync(m,"utf-8"));}catch{}f=r?JSON.stringify(r):null,l=je(o,c,null,f);}else l=xs(t,null,r);let g=i+".tmp";if(writeFileSync(g,l,"utf-8"),renameSync(g,i),a){if(t.ci===null){let u=dirname(e.outputPath),h=join(u,".testrelic-report"),p=resolve(i);try{if(await Ts(),n=await Cs(h),!n){s=await te(h,{htmlPath:p}),n=s.port;let m=setInterval(()=>{},6e4),y=()=>{clearInterval(m),s?.dispose();};process.on("SIGINT",y),process.on("SIGTERM",y),setTimeout(y,1800*1e3).unref();}if(n){process.stderr.write(`
2546
+ </html>`}function We(t){try{let e=process.platform,r,n;e==="darwin"?(r="open",n=[t]):e==="win32"?(r="cmd",n=["/c","start","",t]):(r="xdg-open",n=[t]),execFile(r,n,s=>{s&&process.stderr.write(`[testrelic] Failed to open browser: ${s.message}
2547
+ `);});}catch{}}var Zt=join(tmpdir(),"testrelic-data"),E=class{constructor(e){this.count=0;this.closed=false;mkdirSync(Zt,{recursive:true}),this.filePath=join(Zt,`${e}-${randomUUID().substring(0,8)}.jsonl`),this.fd=openSync(this.filePath,"w");}append(e){if(this.closed)return;let r=JSON.stringify(e)+`
2548
+ `;writeSync(this.fd,r),this.count++;}getPath(){return this.filePath}getCount(){return this.count}close(){if(!this.closed){this.closed=true;try{closeSync(this.fd);}catch{}}}cleanup(){try{unlinkSync(this.filePath);}catch{}}};async function er(t,e,r,n){let s=(e-1)*r,a=[],l=0,i=createInterface({input:createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let c of i)if(c.length!==0){if(l>=s&&a.length<r)try{a.push(JSON.parse(c));}catch{}if(l++,a.length>=r&&n!==void 0)break}let d=n??l,o=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:o}}var nr=/^[a-f0-9]{12}$/,Ve=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,sr=500;function x(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function ar(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 ue(t){try{return existsSync(t)?JSON.parse(readFileSync(t,"utf-8")):null}catch{return null}}function pe(t){let e=0;try{let r=readdirSync(t,{withFileTypes:!0});for(let n of r){let s=join(t,n.name);n.isFile()?e+=statSync(s).size:n.isDirectory()&&(e+=pe(s));}}catch{}return e}function ir(t,e,r,n){let s=ue(join(r,"index.json"));x(e,200,{status:"ok",reportMode:"streaming",testCount:s?.length??0,uptime:Math.floor((Date.now()-n)/1e3)});}function or(t,e,r){let n=ue(join(r,"summary.json"));if(!n){x(e,404,{error:"Summary not found"});return}x(e,200,n);}function lr(t,e,r){let n=ue(join(r,"index.json"));if(!n){x(e,404,{error:"Test index not found"});return}let a=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,l=Math.max(1,parseInt(a.get("page")??"1",10)||1),i=Math.min(sr,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,o=a.get("file")??null,c=a.get("search")?.toLowerCase()??null,f=a.get("tag")?.split(",").filter(Boolean)??null,g=a.get("sort")??"file",u=a.get("order")==="desc"?-1:1,h=n;d&&d.length>0&&(h=h.filter(v=>d.includes(v.status))),o&&(h=h.filter(v=>v.filePath===o||v.filePath.startsWith(o+"/"))),c&&(h=h.filter(v=>v.title.toLowerCase().includes(c)||v.filePath.toLowerCase().includes(c))),f&&f.length>0&&(h=h.filter(v=>f.some(k=>v.tags.includes(k)))),h=[...h].sort((v,k)=>{let C=0;switch(g){case "duration":C=v.duration-k.duration;break;case "status":C=v.status.localeCompare(k.status);break;case "title":C=v.title.localeCompare(k.title);break;default:C=v.filePath.localeCompare(k.filePath);break}return C*u});let p=h.length,m=Math.max(1,Math.ceil(p/i)),y=(l-1)*i,w=h.slice(y,y+i);x(e,200,{tests:w,pagination:{page:l,pageSize:i,totalItems:p,totalPages:m},filters:{status:d,file:o,search:c,tag:f}});}function dr(t,e,r,n){if(!nr.test(n)){x(e,400,{error:"Invalid test ID format"});return}let s=join(r,"tests",n,"meta.json"),a=join(r,"tests",`${n}.json`),l=existsSync(s)?s:existsSync(a)?a:null;if(!l){x(e,404,{error:`Test not found: ${n}`});return}try{let i=readFileSync(l,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){x(e,500,{error:i instanceof Error?i.message:String(i)});}}async function cr(t,e,r,n,s){if(!nr.test(n)){x(e,400,{error:"Invalid test ID format"});return}let l=join(r,"tests",n,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[s]);if(!existsSync(l)){x(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let d=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(d.get("page")??"1",10)||1),c=Math.min(sr,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),f,g=join(r,"tests",n,"meta.json");if(existsSync(g))try{let h=JSON.parse(readFileSync(g,"utf-8"));switch(s){case "network":f=h.networkRequestsCount;break;case "console":f=h.consoleLogsCount;break;case "api-calls":f=h.apiCallsCount;break}}catch{}let u=await er(l,o,c,f);x(e,200,u);}catch(i){x(e,500,{error:i instanceof Error?i.message:String(i)});}}function ur(t,e,r){let n=ue(join(r,"index.json"));if(!n){x(e,404,{error:"Test index not found"});return}let s=new Map;for(let l of n){if(l.isRetry)continue;let i=s.get(l.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},s.set(l.filePath,i)),i.total++,l.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 a=Array.from(s.entries()).map(([l,i])=>({filePath:l,...i})).sort((l,i)=>l.filePath.localeCompare(i.filePath));x(e,200,{files:a});}function pr(t,e,r){if(!existsSync(r)){x(e,200,{runs:[],totalSizeBytes:0});return}try{let n=[],s=0,a=readdirSync(r,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||!Ve.test(l.name))continue;let i=join(r,l.name),d=pe(i),o=readdirSync(i,{withFileTypes:!0}).filter(c=>c.isDirectory());n.push({folderName:l.name,totalSizeBytes:d,testCount:o.length}),s+=d;}n.sort((l,i)=>i.folderName.localeCompare(l.folderName)),x(e,200,{runs:n,totalSizeBytes:s});}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}function fr(t,e,r){try{let n=0,s=0;if(existsSync(r)){let a=readdirSync(r,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||!Ve.test(l.name))continue;let i=join(r,l.name),d=pe(i);rmSync(i,{recursive:!0,force:!0}),s+=d,n++;}}x(e,200,{deletedCount:n,freedBytes:s});}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}function gr(t,e,r,n){if(!Ve.test(n)){x(e,400,{error:"Invalid folder name"});return}let s=join(r,n);try{if(!statSync(s).isDirectory()){x(e,404,{error:"Not found"});return}}catch{x(e,404,{error:"Not found"});return}try{let a=pe(s);rmSync(s,{recursive:!0,force:!0}),x(e,200,{deleted:n,freedBytes:a});}catch(a){x(e,500,{error:a instanceof Error?a.message:String(a)});}}function hr(t,e,r){x(e,200,{status:"shutting_down"}),r.close();}function Ge(t,e,r){if(!existsSync(r)){x(e,404,{error:"File not found"});return}try{let n=readFileSync(r),s=extname(r).toLowerCase(),a=fs[s]??"application/octet-stream";e.writeHead(200,{"Content-Type":a}),e.end(n);}catch(n){x(e,500,{error:n instanceof Error?n.message:String(n)});}}var fs={".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 ys=9323,vs=10,bs=1800*1e3;function te(t,e){return new Promise((r,n)=>{let s=e?.port??ys,a=Date.now(),l,i=0,d=existsSync(join(t,"artifacts"))?join(t,"artifacts"):existsSync(join(t,"..","artifacts"))?join(t,"..","artifacts"):join(t,"artifacts");function o(){clearTimeout(l),l=setTimeout(()=>{f.close();},bs);}let c=e?.htmlPath??null;if(!c){let u=dirname(t);try{let h=readdirSync(u).find(p=>p.endsWith(".html"));h&&(c=join(u,h));}catch{}}let f=createServer((u,h)=>{if(o(),ar(h),u.method==="OPTIONS"){h.writeHead(204),h.end();return}let p;try{p=new URL(u.url??"/",`http://${u.headers.host??"localhost"}`).pathname;}catch{x(h,400,{error:"Invalid URL"});return}if(u.method==="GET"&&(p==="/"||p==="/index.html")){if(c&&existsSync(c)){Ge(u,h,c);return}x(h,404,{error:"HTML report not found"});return}if(u.method==="GET"&&p==="/api/health"){ir(u,h,t,a);return}if(u.method==="GET"&&p==="/api/summary"){or(u,h,t);return}if(u.method==="GET"&&p==="/api/tests"){lr(u,h,t);return}if(u.method==="GET"&&p==="/api/files"){ur(u,h,t);return}let m=p.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(u.method==="GET"&&m){cr(u,h,t,m[1],m[2]);return}let y=p.match(/^\/api\/tests\/([a-f0-9]+)$/);if(u.method==="GET"&&y){dr(u,h,t,y[1]);return}if(u.method==="GET"&&p==="/api/artifacts"){pr(u,h,d);return}if(u.method==="DELETE"&&p==="/api/artifacts"){fr(u,h,d);return}let w=p.match(/^\/api\/artifacts\/(.+)$/);if(u.method==="DELETE"&&w){gr(u,h,d,decodeURIComponent(w[1]));return}if(u.method==="GET"&&p.startsWith("/artifacts/")){let v=decodeURIComponent(p.slice(11));if(v.includes("..")||v.includes("\0")){x(h,400,{error:"Invalid path"});return}Ge(u,h,join(d,v));return}if(u.method==="POST"&&p==="/api/shutdown"){hr(u,h,f);return}x(h,404,{error:"Not found"});});function g(u){let h=p=>{p.code==="EADDRINUSE"&&i<vs?(i++,g(u+1)):n(p);};f.once("error",h),f.listen(u,"127.0.0.1",()=>{f.removeListener("error",h);let p=f.address();if(!p||typeof p=="string"){n(new Error("Failed to get server address"));return}o(),r({port:p.port,dispose:()=>new Promise(m=>{clearTimeout(l),f.close(()=>m());})});});}g(s);})}async function mr(t){let e=await te(t);return {port:e.port,dispose:e.dispose}}function ks(t,e,r){let n=JSON.stringify(t),s=r?JSON.stringify(r):null;return Qt(n,e,s)}async function Ke(t,e,r){try{let n=null,s=null,a=e.reportMode==="streaming"||e.reportMode==="auto"&&t.timeline.length===0&&t.summary.total>=e.streamingThreshold,l,i=e.htmlReportPath,d=dirname(i);mkdirSync(d,{recursive:!0});let o="",c="[]",f=null;if(a){o=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 u=dirname(e.outputPath),h=join(u,".testrelic-report");try{let p=join(h,"index-compact.json"),m=join(h,"index.json");existsSync(p)?c=readFileSync(p,"utf-8"):existsSync(m)&&(c=readFileSync(m,"utf-8"));}catch{}f=r?JSON.stringify(r):null,l=je(o,c,null,f);}else l=ks(t,null,r);let g=i+".tmp";if(writeFileSync(g,l,"utf-8"),renameSync(g,i),a){if(t.ci===null){let u=dirname(e.outputPath),h=join(u,".testrelic-report"),p=resolve(i);try{if(await Cs(),n=await Ss(h),!n){s=await te(h,{htmlPath:p}),n=s.port;let m=setInterval(()=>{},6e4),y=()=>{clearInterval(m),s?.dispose();};process.on("SIGINT",y),process.on("SIGTERM",y),setTimeout(y,1800*1e3).unref();}if(n){process.stderr.write(`
2549
2549
  Report server: http://127.0.0.1:${n}
2550
- `);try{let m=je(o,c,n,f),y=i+".tmp";writeFileSync(y,m,"utf-8"),renameSync(y,i);}catch{}}}catch{}}}else if(e.openReport&&t.ci===null&&e.includeArtifacts){let u=dirname(e.outputPath),h=join(u,"artifacts");if(existsSync(h))try{let p=await hr(h);n=p.port,process.on("exit",()=>{p.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(a&&n)We(`http://127.0.0.1:${n}`);else {let u=resolve(i);We(u);}}catch(n){process.stderr.write(`[testrelic] Failed to write HTML report: ${n instanceof Error?n.message:String(n)}
2551
- `);}}var he=9323,wr=10;async function ks(){for(let t=he;t<he+wr;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),n=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),n.ok)return t}catch{}return null}async function Ts(){for(let t=he;t<he+wr;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 Cs(t){let r=[join(__dirname,"cli.cjs"),join(__dirname,"cli.js"),join(__dirname,"..","dist","cli.cjs"),join(__dirname,"..","dist","cli.js")].find(n=>existsSync(n));if(!r){let n=await te(t);return process.on("exit",()=>{n?.dispose();}),n.port}return new Promise(n=>{let s=spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),a="",l=false,i=setTimeout(()=>{l||(l=true,s.stderr?.removeAllListeners(),ks().then(n));},5e3);s.stderr?.on("data",d=>{a+=d.toString();let o=a.match(/127\.0\.0\.1:(\d+)/);o&&!l&&(l=true,clearTimeout(i),s.stderr?.removeAllListeners(),s.unref(),n(Number(o[1])));}),s.on("error",()=>{l||(l=true,clearTimeout(i),n(null));}),s.on("exit",()=>{l||(l=true,clearTimeout(i),n(null));}),s.unref();})}var As=20,Ye=0,Qe=[];async function kr(t,e){Ye>=As&&await new Promise(r=>Qe.push(r)),Ye++;try{return await copyFile(t,e),!0}catch{return false}finally{Ye--,Qe.length>0&&Qe.shift()();}}var ne=[];async function Tr(){ne.length!==0&&(await Promise.allSettled(ne),ne.length=0);}function Cr(t){let e=new Date,r=a=>String(a).padStart(2,"0"),n=`${e.getFullYear()}-${r(e.getMonth()+1)}-${r(e.getDate())}T${r(e.getHours())}-${r(e.getMinutes())}-${r(e.getSeconds())}`;if(!existsSync(join(t,n)))return n;let s=1;for(;existsSync(join(t,`${n}-${s}`));)s++;return `${n}-${s}`}function _s(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,n,s){let a=t.find(g=>g.name==="screenshot"&&g.path),l=t.find(g=>g.name==="video"&&g.path);if(!a&&!l)return null;let i=_s(e);r>0&&(i+=`--retry-${r}`);let d=s?["artifacts",s,i]:["artifacts",i],o=join(n,...d),c=d,f={};try{mkdirSync(o,{recursive:!0});}catch{return null}if(a?.path&&existsSync(a.path)){let u=`screenshot${extname(a.path)||".png"}`,h=join(o,u);ne.push(kr(a.path,h).then(()=>{})),f.screenshot=`${c.join("/")}/${u}`;}if(l?.path&&existsSync(l.path)){let u=`video${extname(l.path)||".webm"}`,h=join(o,u);ne.push(kr(l.path,h).then(()=>{})),f.video=`${c.join("/")}/${u}`;}return !f.screenshot&&!f.video?null:f}var Ps=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Ms="1.0";function Es(t){let e=extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function Rr(t,e,r){let n=[];try{let s=readdirSync(t,{withFileTypes:!0});for(let a of s){if(!a.isFile())continue;let l=join(t,a.name),i=statSync(l);n.push({name:a.name,type:Es(a.name),relativePath:`artifacts/${e}/${r}/${a.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:n}}function Ns(t,e){let r=join(t,e),n=[],s=0;try{let l=readdirSync(r,{withFileTypes:!0});for(let i of l){if(!i.isDirectory())continue;let d=Rr(join(r,i.name),e,i.name);n.push(d);for(let o of d.files)s+=o.sizeBytes;}}catch{}let a=e.replace(/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})/,"$1T$2:$3:$4").replace(/-\d+$/,"");return n.sort((l,i)=>l.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:s,testCount:n.length,tests:n,isCurrentRun:false}}function Ar(t,e){let r=join(t,"artifacts"),n=[],s=[],a=0;try{let i=readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(Ps.test(d.name)){let o=Ns(r,d.name);n.push({...o,isCurrentRun:d.name===e});}else {let o=Rr(join(r,d.name),d.name,d.name);s.push(o);for(let c of o.files)a+=c.sizeBytes;}}catch{}n.sort((i,d)=>d.timestamp.localeCompare(i.timestamp)),s.length>0&&(s.sort((i,d)=>i.testName.localeCompare(d.testName)),n.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:a,testCount:s.length,tests:s,isCurrentRun:false}));let l=n.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:Ms,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:l,runs:n,serverPort:null}}function qs(t){let e=t,{root:r}=parse(e);for(;e!==r;){if(existsSync(join(e,".git")))return e;e=join(e,"..");}return null}function Ir(t){try{let e=qs(t);if(!e)return;let r=join(e,".gitignore"),n=relative(e,t).replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(existsSync(r)&&readFileSync(r,"utf-8").split(`
2550
+ `);try{let m=je(o,c,n,f),y=i+".tmp";writeFileSync(y,m,"utf-8"),renameSync(y,i);}catch{}}}catch{}}}else if(e.openReport&&t.ci===null&&e.includeArtifacts){let u=dirname(e.outputPath),h=join(u,"artifacts");if(existsSync(h))try{let p=await mr(h);n=p.port,process.on("exit",()=>{p.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(a&&n)We(`http://127.0.0.1:${n}`);else {let u=resolve(i);We(u);}}catch(n){process.stderr.write(`[testrelic] Failed to write HTML report: ${n instanceof Error?n.message:String(n)}
2551
+ `);}}var he=9323,xr=10;async function Ts(){for(let t=he;t<he+xr;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),n=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),n.ok)return t}catch{}return null}async function Cs(){for(let t=he;t<he+xr;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 Ss(t){let r=[join(__dirname,"cli.cjs"),join(__dirname,"cli.js"),join(__dirname,"..","dist","cli.cjs"),join(__dirname,"..","dist","cli.js")].find(n=>existsSync(n));if(!r){let n=await te(t);return process.on("exit",()=>{n?.dispose();}),n.port}return new Promise(n=>{let s=spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),a="",l=false,i=setTimeout(()=>{l||(l=true,s.stderr?.removeAllListeners(),Ts().then(n));},5e3);s.stderr?.on("data",d=>{a+=d.toString();let o=a.match(/127\.0\.0\.1:(\d+)/);o&&!l&&(l=true,clearTimeout(i),s.stderr?.removeAllListeners(),s.unref(),n(Number(o[1])));}),s.on("error",()=>{l||(l=true,clearTimeout(i),n(null));}),s.on("exit",()=>{l||(l=true,clearTimeout(i),n(null));}),s.unref();})}var _s=20,Ye=0,Qe=[];async function Tr(t,e){Ye>=_s&&await new Promise(r=>Qe.push(r)),Ye++;try{return await copyFile(t,e),!0}catch{return false}finally{Ye--,Qe.length>0&&Qe.shift()();}}var ne=[];async function Cr(){ne.length!==0&&(await Promise.allSettled(ne),ne.length=0);}function Sr(t){let e=new Date,r=a=>String(a).padStart(2,"0"),n=`${e.getFullYear()}-${r(e.getMonth()+1)}-${r(e.getDate())}T${r(e.getHours())}-${r(e.getMinutes())}-${r(e.getSeconds())}`;if(!existsSync(join(t,n)))return n;let s=1;for(;existsSync(join(t,`${n}-${s}`));)s++;return `${n}-${s}`}function Is(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 Rr(t,e,r,n,s){let a=t.find(g=>g.name==="screenshot"&&g.path),l=t.find(g=>g.name==="video"&&g.path);if(!a&&!l)return null;let i=Is(e);r>0&&(i+=`--retry-${r}`);let d=s?["artifacts",s,i]:["artifacts",i],o=join(n,...d),c=d,f={};try{mkdirSync(o,{recursive:!0});}catch{return null}if(a?.path&&existsSync(a.path)){let u=`screenshot${extname(a.path)||".png"}`,h=join(o,u);ne.push(Tr(a.path,h).then(()=>{})),f.screenshot=`${c.join("/")}/${u}`;}if(l?.path&&existsSync(l.path)){let u=`video${extname(l.path)||".webm"}`,h=join(o,u);ne.push(Tr(l.path,h).then(()=>{})),f.video=`${c.join("/")}/${u}`;}return !f.screenshot&&!f.video?null:f}var Ms=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Es="1.0";function Ns(t){let e=extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function Ar(t,e,r){let n=[];try{let s=readdirSync(t,{withFileTypes:!0});for(let a of s){if(!a.isFile())continue;let l=join(t,a.name),i=statSync(l);n.push({name:a.name,type:Ns(a.name),relativePath:`artifacts/${e}/${r}/${a.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:n}}function Fs(t,e){let r=join(t,e),n=[],s=0;try{let l=readdirSync(r,{withFileTypes:!0});for(let i of l){if(!i.isDirectory())continue;let d=Ar(join(r,i.name),e,i.name);n.push(d);for(let o of d.files)s+=o.sizeBytes;}}catch{}let a=e.replace(/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})/,"$1T$2:$3:$4").replace(/-\d+$/,"");return n.sort((l,i)=>l.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:s,testCount:n.length,tests:n,isCurrentRun:false}}function _r(t,e){let r=join(t,"artifacts"),n=[],s=[],a=0;try{let i=readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(Ms.test(d.name)){let o=Fs(r,d.name);n.push({...o,isCurrentRun:d.name===e});}else {let o=Ar(join(r,d.name),d.name,d.name);s.push(o);for(let c of o.files)a+=c.sizeBytes;}}catch{}n.sort((i,d)=>d.timestamp.localeCompare(i.timestamp)),s.length>0&&(s.sort((i,d)=>i.testName.localeCompare(d.testName)),n.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:a,testCount:s.length,tests:s,isCurrentRun:false}));let l=n.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:Es,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:l,runs:n,serverPort:null}}function Hs(t){let e=t,{root:r}=parse(e);for(;e!==r;){if(existsSync(join(e,".git")))return e;e=join(e,"..");}return null}function Lr(t){try{let e=Hs(t);if(!e)return;let r=join(e,".gitignore"),n=relative(e,t).replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(existsSync(r)&&readFileSync(r,"utf-8").split(`
2552
2552
  `).map(d=>d.trim()).some(d=>d===s||d===n))return;let a=`
2553
2553
  # TestRelic test artifacts
2554
2554
  ${s}
2555
- `;appendFileSync(r,a,"utf-8");}catch{}}function Mr(t,e){let r=[];for(let n of t){let s=Hs(n),a=Us(n),l=$s(n,s,a,e),i=zs(n,s,a);if(l.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:n.startedAt,durationOnUrl:n.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:n.specFile,test:s,tests:[a],_testTitle:n.title});continue}r.push(...l,...i);}return r.sort(js),Ws(r,t),r.map((n,s)=>n.type==="navigation"?{...{index:s,type:"navigation",url:n.url,timestamp:n.timestamp,durationOnUrl:n.durationOnUrl??0,navigationType:n.navigationType,domContentLoadedAt:n.domContentLoadedAt??null,networkIdleAt:n.networkIdleAt??null,networkStats:n.networkStats??null,specFile:n.specFile,test:n.test},tests:n.tests}:{...{index:s,type:"api_call",callId:n.callId,method:n.method,url:n.url,timestamp:n.timestamp,responseTime:n.responseTime??null,request:n.request,response:n.response??null,...n.error?{error:n.error}:{},assertions:n.assertions??[],specFile:n.specFile,test:n.test},tests:n.tests})}function Hs(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 Us(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 $s(t,e,r,n){let s=[];for(let a of t.navigations)n.navigationTypes!==null&&!n.navigationTypes.includes(a.navigationType)||s.push({type:"navigation",url:a.url,timestamp:a.timestamp,durationOnUrl:0,navigationType:a.navigationType,domContentLoadedAt:a.domContentLoadedAt??null,networkIdleAt:a.networkIdleAt??null,networkStats:a.networkStats??null,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title});return s}function zs(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let n=t.apiAssertions??[];return t.apiCalls.map(s=>{let a=n.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}:{}})),l=null;return s.responseStatusCode!==null&&s.responseStatusText!==null&&(l={statusCode:s.responseStatusCode,statusText:s.responseStatusText,headers:s.responseHeaders,body:Pr(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:Pr(s.requestBody)},response:l,...s.error?{error:s.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function js(t,e){let r=new Date(t.timestamp).getTime(),n=new Date(e.timestamp).getTime();if(r!==n)return r-n;let s={navigation:0,api_call:1},a=s[t.type],l=s[e.type];return a!==l?a-l:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?Lr(t.callId)-Lr(e.callId):0}function Lr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Ws(t,e){for(let r=0;r<t.length;r++){let n=t[r];if(n.type!=="navigation")continue;let s=new Date(n.timestamp).getTime(),a=null;for(let l=r+1;l<t.length;l++)if(t[l]._testTitle===n._testTitle){a=new Date(t[l].timestamp).getTime();break}if(a!==null)n.durationOnUrl=Math.max(0,a-s);else {let l=e.find(i=>i.title===n._testTitle);if(l){let i=new Date(l.completedAt).getTime();n.durationOnUrl=Math.max(0,i-s);}}}}function Pr(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function $(t,e){let r=t.length,n=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,n)]}function et(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function Vs(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 Er(t,e){let r=0,n=0,s=0,a=0,l=0;for(let b of t)switch(b.status){case "passed":r++;break;case "failed":n++;break;case "flaky":s++;break;case "skipped":a++;break;case "timedout":l++;break}let i=[];for(let b of t)b.apiCalls&&i.push(...b.apiCalls);let d=i.length,o=new Set,c={},f={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},g=[];for(let b of i)o.add(et(b.url)),c[b.method]=(c[b.method]??0)+1,f[Vs(b.responseStatusCode)]+=1,g.push(b.responseTimeMs);let u=null;if(g.length>0){let b=[...g].sort((S,P)=>S-P),T=b.reduce((S,P)=>S+P,0);u={avg:Math.round(T/b.length),min:b[0],max:b[b.length-1],p50:$(b,50),p95:$(b,95),p99:$(b,99)};}let h=0,p=0,m=0;for(let b of t)if(b.apiAssertions)for(let T of b.apiAssertions)h++,T.status==="passed"?p++:m++;let y=0,w=new Set;for(let b of t){y+=b.navigations.length;for(let T of b.navigations)w.add(T.url);}let v=0,k={};function C(b){for(let T of b)v++,k[T.category]=(k[T.category]??0)+1,T.children.length>0&&C(T.children);}for(let b of t)b.actions&&C(b.actions);return {total:t.length,passed:r,failed:n,flaky:s,skipped:a,timedout:l,totalApiCalls:d,uniqueApiUrls:o.size,apiCallsByMethod:c,apiCallsByStatusRange:f,apiResponseTime:u,totalAssertions:h,passedAssertions:p,failedAssertions:m,totalNavigations:y,uniqueNavigationUrls:w.size,totalTimelineSteps:e,totalActionSteps:v,actionStepsByCategory:k}}function Gs(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${Gs(t)} \u2502
2555
+ `;appendFileSync(r,a,"utf-8");}catch{}}function Er(t,e){let r=[];for(let n of t){let s=Us(n),a=zs(n),l=$s(n,s,a,e),i=js(n,s,a);if(l.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:n.startedAt,durationOnUrl:n.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:n.specFile,test:s,tests:[a],_testTitle:n.title});continue}r.push(...l,...i);}return r.sort(Ws),Vs(r,t),r.map((n,s)=>n.type==="navigation"?{...{index:s,type:"navigation",url:n.url,timestamp:n.timestamp,durationOnUrl:n.durationOnUrl??0,navigationType:n.navigationType,domContentLoadedAt:n.domContentLoadedAt??null,networkIdleAt:n.networkIdleAt??null,networkStats:n.networkStats??null,specFile:n.specFile,test:n.test},tests:n.tests}:{...{index:s,type:"api_call",callId:n.callId,method:n.method,url:n.url,timestamp:n.timestamp,responseTime:n.responseTime??null,request:n.request,response:n.response??null,...n.error?{error:n.error}:{},assertions:n.assertions??[],specFile:n.specFile,test:n.test},tests:n.tests})}function Us(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 zs(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 $s(t,e,r,n){let s=[];for(let a of t.navigations)n.navigationTypes!==null&&!n.navigationTypes.includes(a.navigationType)||s.push({type:"navigation",url:a.url,timestamp:a.timestamp,durationOnUrl:0,navigationType:a.navigationType,domContentLoadedAt:a.domContentLoadedAt??null,networkIdleAt:a.networkIdleAt??null,networkStats:a.networkStats??null,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title});return s}function js(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let n=t.apiAssertions??[];return t.apiCalls.map(s=>{let a=n.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}:{}})),l=null;return s.responseStatusCode!==null&&s.responseStatusText!==null&&(l={statusCode:s.responseStatusCode,statusText:s.responseStatusText,headers:s.responseHeaders,body:Mr(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:Mr(s.requestBody)},response:l,...s.error?{error:s.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function Ws(t,e){let r=new Date(t.timestamp).getTime(),n=new Date(e.timestamp).getTime();if(r!==n)return r-n;let s={navigation:0,api_call:1},a=s[t.type],l=s[e.type];return a!==l?a-l:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?Pr(t.callId)-Pr(e.callId):0}function Pr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Vs(t,e){for(let r=0;r<t.length;r++){let n=t[r];if(n.type!=="navigation")continue;let s=new Date(n.timestamp).getTime(),a=null;for(let l=r+1;l<t.length;l++)if(t[l]._testTitle===n._testTitle){a=new Date(t[l].timestamp).getTime();break}if(a!==null)n.durationOnUrl=Math.max(0,a-s);else {let l=e.find(i=>i.title===n._testTitle);if(l){let i=new Date(l.completedAt).getTime();n.durationOnUrl=Math.max(0,i-s);}}}}function Mr(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function z(t,e){let r=t.length,n=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,n)]}function et(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function Gs(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 Nr(t,e){let r=0,n=0,s=0,a=0,l=0;for(let b of t)switch(b.status){case "passed":r++;break;case "failed":n++;break;case "flaky":s++;break;case "skipped":a++;break;case "timedout":l++;break}let i=[];for(let b of t)b.apiCalls&&i.push(...b.apiCalls);let d=i.length,o=new Set,c={},f={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},g=[];for(let b of i)o.add(et(b.url)),c[b.method]=(c[b.method]??0)+1,f[Gs(b.responseStatusCode)]+=1,g.push(b.responseTimeMs);let u=null;if(g.length>0){let b=[...g].sort((S,P)=>S-P),T=b.reduce((S,P)=>S+P,0);u={avg:Math.round(T/b.length),min:b[0],max:b[b.length-1],p50:z(b,50),p95:z(b,95),p99:z(b,99)};}let h=0,p=0,m=0;for(let b of t)if(b.apiAssertions)for(let T of b.apiAssertions)h++,T.status==="passed"?p++:m++;let y=0,w=new Set;for(let b of t){y+=b.navigations.length;for(let T of b.navigations)w.add(T.url);}let v=0,k={};function C(b){for(let T of b)v++,k[T.category]=(k[T.category]??0)+1,T.children.length>0&&C(T.children);}for(let b of t)b.actions&&C(b.actions);return {total:t.length,passed:r,failed:n,flaky:s,skipped:a,timedout:l,totalApiCalls:d,uniqueApiUrls:o.size,apiCallsByMethod:c,apiCallsByStatusRange:f,apiResponseTime:u,totalAssertions:h,passedAssertions:p,failedAssertions:m,totalNavigations:y,uniqueNavigationUrls:w.size,totalTimelineSteps:e,totalActionSteps:v,actionStepsByCategory:k}}function Js(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${Js(t)} \u2502
2556
2556
  `}function tt(t,e,r,n){if(n||t.total===0)return;let s=`\u250C${"\u2500".repeat(58)}\u2510
2557
2557
  `,a=`\u2514${"\u2500".repeat(58)}\u2518
2558
2558
  `,l=I(""),i=s;i+=I("TestRelic AI - Playwright Test Report"),i+=l;let d=[];if(t.passed>0&&d.push(`${t.passed} \u2713`),t.failed>0&&d.push(`${t.failed} \u2717`),t.flaky>0&&d.push(`${t.flaky} \u26A0`),t.skipped>0&&d.push(`${t.skipped} skipped`),t.timedout>0&&d.push(`${t.timedout} timedout`),i+=I(`Tests: ${t.total} total (${d.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 o=Object.entries(t.apiCallsByMethod).filter(([,f])=>f>0).map(([f,g])=>`${f}: ${g}`);o.length>0&&(i+=I(` ${o.join(" ")}`));let c=Object.entries(t.apiCallsByStatusRange).filter(([,f])=>f>0).map(([f,g])=>`${f}: ${g}`);c.length>0&&(i+=I(` ${c.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 o=[],c=t.actionStepsByCategory;c.ui_action&&o.push(`${c.ui_action} UI`),c.assertion&&o.push(`${c.assertion} assertions`),c.custom_step&&o.push(`${c.custom_step} custom`);let f=o.length>0?` (${o.join(" ")})`:"";i+=I(`Actions: ${t.totalActionSteps} steps${f}`);}i+=I(`Report: ${r}`),i+=I(`Data: ${e}`),i+=a,i+=`For more information visit us at https://docs.testrelic.ai
2559
- `,process.stderr.write(i);}var Js=new Set(["pw:api","expect","test.step"]);function Ks(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function rt(t,e,r){if(Js.has(t.category)){let n=[];for(let a of t.steps)rt(a,e,n);let s=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:Ks(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:n});}else for(let n of t.steps)rt(n,e,r);}function Nr(t,e){let r=[];for(let n of t)rt(n,e,r);return r}var Zs=new Set(["localhost","127.0.0.1","0.0.0.0"]);function Dr(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&Zs.has(e.hostname)))throw createError(ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var Xs=3e3;async function nt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),Xs);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function Br(t){return new Promise(e=>setTimeout(e,t))}async function Fr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let n=r.details;if(Array.isArray(n)&&n.length>0){let s=n.map(a=>`${a.field}: ${a.message}`).join(", ");return `${r.message} (${s})`}return r.message}}catch{}return `HTTP ${t.status}`}async function st(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),r);try{let a=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(a.ok){let i=await a.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,orgId:i.orgId,orgName:i.orgName,userId:i.userId,userName:i.userName}}if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;if(!isNaN(d)&&d>0){await Br(d);let o=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(o.ok){let c=await o.json();return {accessToken:c.accessToken,refreshToken:c.refreshToken,expiresIn:c.expiresIn,orgId:c.orgId,orgName:c.orgName,userId:c.userId,userName:c.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return a.status===400?{code:"validation_error",message:await Fr(a),statusCode:400}:a.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:a.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await Fr(a),statusCode:a.status}}catch(a){return a instanceof DOMException&&a.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 at(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 Or(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),r);try{let a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:n.signal});if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;!isNaN(d)&&d>0&&(await Br(d),a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:n.signal}));}if(!a.ok)return null;let l=await a.json();return {accessToken:l.accessToken,refreshToken:l.refreshToken,expiresIn:l.expiresIn}}catch{return null}finally{clearTimeout(s);}}async function qr(t,e,r,n,s,a){let l=new AbortController,i=setTimeout(()=>l.abort(),s);try{let d={gitId:r,displayName:n};a&&(d.branch=a);let o=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(d),signal:l.signal});if(!o.ok)return null;let c=await o.json();return {repoId:c.repoId,displayName:c.displayName}}catch{return null}finally{clearTimeout(i);}}var sa=5e3;function B(t,e){try{return execSync(t,{cwd:e,timeout:sa,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Hr(t){let e=B("git rev-parse --abbrev-ref HEAD",t),r=B("git rev-parse --short HEAD",t),n=B("git log -1 --pretty=%s",t),s=B("git log -1 --format=%an",t)??B("git config user.name",t),a=aa(t),l=a?ae(a):null;return {branch:e,commitSha:r,commitMessage:n,commitAuthor:s,remoteUrl:l}}function aa(t){let e=B("git remote get-url origin",t);if(e)return e;let r=B("git remote",t);if(!r)return null;let n=r.split(`
2560
- `)[0]?.trim();return n?B(`git remote get-url ${n}`,t):null}function ae(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 Ur(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function it(t){try{let e=readFileSync(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 ie(t){let e=it(t);return e||`local/${basename(t)}`}var ia=new Set(["smoke","regression","nightly","ci"]);function ye(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&ia.has(t))return t}var da=1048576,ve=[1e3,3e3,9e3],be=3,ca=90*1048576,ua=new Set(["e2e","mobile","unit"]);function lt(t){if(t&&t.length>0&&t.every(s=>s.testType==="api")){let s=new Map;for(let i of t){let d=i.apiProtocol??"rest";s.set(d,(s.get(d)??0)+1);}let a="rest",l=0;for(let[i,d]of s)d>l&&(l=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let s of t??[])ua.has(s.testType)&&e.set(s.testType,(e.get(s.testType)??0)+1);let r=null,n=0;for(let[s,a]of e)a>n&&(n=a,r=s);return {testType:r??"e2e"}}function dt(t,e,r,n,s,a){let l=a?.cloudPlatform?a.cloudPlatform:n?.provider&&n.provider!=="unknown"?n.provider:"local",i=ye(),d=lt(s),o=d.testType==="api"?d:null,c=o&&s?s.map(g=>g.apiProtocol?g:{...g,apiProtocol:o.apiProtocol}):s;return {runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:l,...i?{runType:i}:{},...o?{testType:o.testType,apiProtocol:o.apiProtocol,metadata:o.metadata}:{testType:d.testType},...c&&c.length>0?{tests:c}:{},...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}:{},...n?.provider?{ciProvider:n.provider}:{},...n?.runUrl?{ciRunUrl:n.runUrl}:{},...a?.cloudPlatform?{cloudPlatform:a.cloudPlatform}:{},...a?.cloudBuildId?{cloudBuildId:a.cloudBuildId}:{},...a?.cloudSessionId?{cloudSessionId:a.cloudSessionId}:{}}}function ot(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function ct(t){return Array.isArray(t)?t.map(e=>{let r=e.statusCode??e.responseStatusCode??null;return {...e.id!=null?{id:e.id}:{},...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:ot(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:ot(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 ut(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,n=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:ot(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:n,startedAt:n}}):[]}function pt(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 n=r.status==="failed"?"failed":"passed",s=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,a=r.kind??r.type??"assertion",l=n==="failed"?`expected ${e(r.expected)}, received ${e(r.actual)}`:r.expected!==void 0?`expected ${e(r.expected)}`:null;return {...r.callId!=null?{callId:r.callId}:{},kind:a,description:s??r.description??`${a} assertion`,status:n,detail:l}})}async function we(t){return new Promise(e=>setTimeout(e,t))}function pa(t){let e={};for(let[r,n]of Object.entries(t))n!=null&&(e[r]=n);return e}async function zr(t,e,r){for(let n=0;n<be;n++)try{let s=await fetch(t,e);if(s.ok)return s;if(s.status===401&&r&&n===0){let a=await r();if(a){let l={...e,headers:{...e.headers,Authorization:`Bearer ${a}`}},i=await fetch(t,l);if(i.ok)return i}return null}if(s.status===429&&n<be-1){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:ve[n];!isNaN(l)&&l>0?await we(l):await we(ve[n]);continue}if(s.status>=500&&n<be-1){await we(ve[n]);continue}return s}catch{if(n<be-1){await we(ve[n]);continue}return null}return null}var fa=promisify(gzip);function $r(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(n=>{let{consoleLogs:s,networkRequests:a,apiCalls:l,...i}=n;return e?i:{...i,...l!==void 0?{apiCalls:l}:{}}});return {...t,tests:r}}var ga=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions"];function ha(t){if(!Array.isArray(t.tests))return t;let e=new Set(ga),r=t.tests.map(n=>{let s={};for(let a in n)if(!e.has(a))if(a==="failure"&&n[a]&&typeof n[a]=="object"){let l=n[a];s.failure={message:l.message??null,line:l.line??null};}else s[a]=n[a];return s});return {...t,tests:r}}function ma(t){let e=new Set(["tests","timeline","unifiedTimeline","navigations"]),r={};for(let n in t)e.has(n)||(r[n]=t[n]);return r.tests=[],r}async function ft(t,e=ca){let r={"Content-Type":"application/json"},n=JSON.stringify(t),s=t,a=Array.isArray(s?.tests)?s.tests.length:0,l=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&l(n)){let i=Math.max(1,Math.round(e/1048576));process.stderr.write(`[testrelic] WARNING: batch payload exceeds ${i}MB \u2014 dropping consoleLogs/networkRequests from ${a} test(s) to avoid HTTP 413. Console/network detail will be missing in the cloud.
2559
+ `,process.stderr.write(i);}var Ks=new Set(["pw:api","expect","test.step"]);function Ys(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function rt(t,e,r){if(Ks.has(t.category)){let n=[];for(let a of t.steps)rt(a,e,n);let s=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:Ys(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:n});}else for(let n of t.steps)rt(n,e,r);}function Fr(t,e){let r=[];for(let n of t)rt(n,e,r);return r}var Xs=new Set(["localhost","127.0.0.1","0.0.0.0"]);function Br(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&Xs.has(e.hostname)))throw createError(ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var ea=3e3;async function nt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),ea);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function Or(t){return new Promise(e=>setTimeout(e,t))}async function Dr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let n=r.details;if(Array.isArray(n)&&n.length>0){let s=n.map(a=>`${a.field}: ${a.message}`).join(", ");return `${r.message} (${s})`}return r.message}}catch{}return `HTTP ${t.status}`}async function st(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),r);try{let a=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(a.ok){let i=await a.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,orgId:i.orgId,orgName:i.orgName,userId:i.userId,userName:i.userName}}if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;if(!isNaN(d)&&d>0){await Or(d);let o=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(o.ok){let c=await o.json();return {accessToken:c.accessToken,refreshToken:c.refreshToken,expiresIn:c.expiresIn,orgId:c.orgId,orgName:c.orgName,userId:c.userId,userName:c.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return a.status===400?{code:"validation_error",message:await Dr(a),statusCode:400}:a.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:a.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await Dr(a),statusCode:a.status}}catch(a){return a instanceof DOMException&&a.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 at(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 qr(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),r);try{let a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:n.signal});if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;!isNaN(d)&&d>0&&(await Or(d),a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:n.signal}));}if(!a.ok)return null;let l=await a.json();return {accessToken:l.accessToken,refreshToken:l.refreshToken,expiresIn:l.expiresIn}}catch{return null}finally{clearTimeout(s);}}async function Hr(t,e,r,n,s,a){let l=new AbortController,i=setTimeout(()=>l.abort(),s);try{let d={gitId:r,displayName:n};a&&(d.branch=a);let o=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(d),signal:l.signal});if(!o.ok)return null;let c=await o.json();return {repoId:c.repoId,displayName:c.displayName}}catch{return null}finally{clearTimeout(i);}}var aa=5e3;function B(t,e){try{return execSync(t,{cwd:e,timeout:aa,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Ur(t){let e=B("git rev-parse --abbrev-ref HEAD",t),r=B("git rev-parse --short HEAD",t),n=B("git log -1 --pretty=%s",t),s=B("git log -1 --format=%an",t)??B("git config user.name",t),a=ia(t),l=a?ae(a):null;return {branch:e,commitSha:r,commitMessage:n,commitAuthor:s,remoteUrl:l}}function ia(t){let e=B("git remote get-url origin",t);if(e)return e;let r=B("git remote",t);if(!r)return null;let n=r.split(`
2560
+ `)[0]?.trim();return n?B(`git remote get-url ${n}`,t):null}function ae(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 zr(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function it(t){try{let e=readFileSync(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 ie(t){let e=it(t);return e||`local/${basename(t)}`}var oa=new Set(["smoke","regression","nightly","ci"]);function ye(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&oa.has(t))return t}var ca=1048576,ve=[1e3,3e3,9e3],be=3,ua=90*1048576,pa=new Set(["e2e","mobile","unit"]);function lt(t){if(t&&t.length>0&&t.every(s=>s.testType==="api")){let s=new Map;for(let i of t){let d=i.apiProtocol??"rest";s.set(d,(s.get(d)??0)+1);}let a="rest",l=0;for(let[i,d]of s)d>l&&(l=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let s of t??[])pa.has(s.testType)&&e.set(s.testType,(e.get(s.testType)??0)+1);let r=null,n=0;for(let[s,a]of e)a>n&&(n=a,r=s);return {testType:r??"e2e"}}function dt(t,e,r,n,s,a){let l=a?.cloudPlatform?a.cloudPlatform:n?.provider&&n.provider!=="unknown"?n.provider:"local",i=ye(),d=lt(s),o=d.testType==="api"?d:null,c=o&&s?s.map(g=>g.apiProtocol?g:{...g,apiProtocol:o.apiProtocol}):s;return {runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:l,...i?{runType:i}:{},...o?{testType:o.testType,apiProtocol:o.apiProtocol,metadata:o.metadata}:{testType:d.testType},...c&&c.length>0?{tests:c}:{},...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}:{},...n?.provider?{ciProvider:n.provider}:{},...n?.runUrl?{ciRunUrl:n.runUrl}:{},...a?.cloudPlatform?{cloudPlatform:a.cloudPlatform}:{},...a?.cloudBuildId?{cloudBuildId:a.cloudBuildId}:{},...a?.cloudSessionId?{cloudSessionId:a.cloudSessionId}:{}}}function ot(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function ct(t){return Array.isArray(t)?t.map(e=>{let r=e.statusCode??e.responseStatusCode??null;return {...e.id!=null?{id:e.id}:{},...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:ot(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:ot(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 ut(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,n=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:ot(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:n,startedAt:n}}):[]}function pt(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 n=r.status==="failed"?"failed":"passed",s=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,a=r.kind??r.type??"assertion",l=n==="failed"?`expected ${e(r.expected)}, received ${e(r.actual)}`:r.expected!==void 0?`expected ${e(r.expected)}`:null;return {...r.callId!=null?{callId:r.callId}:{},kind:a,description:s??r.description??`${a} assertion`,status:n,detail:l}})}async function we(t){return new Promise(e=>setTimeout(e,t))}function fa(t){let e={};for(let[r,n]of Object.entries(t))n!=null&&(e[r]=n);return e}async function jr(t,e,r){for(let n=0;n<be;n++)try{let s=await fetch(t,e);if(s.ok)return s;if(s.status===401&&r&&n===0){let a=await r();if(a){let l={...e,headers:{...e.headers,Authorization:`Bearer ${a}`}},i=await fetch(t,l);if(i.ok)return i}return null}if(s.status===429&&n<be-1){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:ve[n];!isNaN(l)&&l>0?await we(l):await we(ve[n]);continue}if(s.status>=500&&n<be-1){await we(ve[n]);continue}return s}catch{if(n<be-1){await we(ve[n]);continue}return null}return null}var ga=promisify(gzip);function $r(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(n=>{let{consoleLogs:s,networkRequests:a,apiCalls:l,...i}=n;return e?i:{...i,...l!==void 0?{apiCalls:l}:{}}});return {...t,tests:r}}var ha=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions"];function ma(t){if(!Array.isArray(t.tests))return t;let e=new Set(ha),r=t.tests.map(n=>{let s={};for(let a in n)if(!e.has(a))if(a==="failure"&&n[a]&&typeof n[a]=="object"){let l=n[a];s.failure={message:l.message??null,line:l.line??null};}else s[a]=n[a];return s});return {...t,tests:r}}function ya(t){let e=new Set(["tests","timeline","unifiedTimeline","navigations"]),r={};for(let n in t)e.has(n)||(r[n]=t[n]);return r.tests=[],r}async function ft(t,e=ua){let r={"Content-Type":"application/json"},n=JSON.stringify(t),s=t,a=Array.isArray(s?.tests)?s.tests.length:0,l=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&l(n)){let i=Math.max(1,Math.round(e/1048576));process.stderr.write(`[testrelic] WARNING: batch payload exceeds ${i}MB \u2014 dropping consoleLogs/networkRequests from ${a} test(s) to avoid HTTP 413. Console/network detail will be missing in the cloud.
2561
2561
  `),n=JSON.stringify($r(s,false)),l(n)&&(process.stderr.write(`[testrelic] WARNING: batch still exceeds ${i}MB after dropping logs \u2014 also dropping apiCalls from ${a} test(s). API request/response detail will be missing in the cloud.
2562
2562
  `),n=JSON.stringify($r(s,true))),l(n)&&(process.stderr.write(`[testrelic] WARNING: batch still exceeds ${i}MB \u2014 shedding remaining per-test detail (actions/navigations/assertions) from ${a} test(s). Only test results + summary will reach the cloud.
2563
- `),n=JSON.stringify(ha(s))),l(n)&&(process.stderr.write(`[testrelic] ERROR: batch still exceeds ${i}MB after shedding all per-test detail \u2014 uploading run summary only (${a} per-test result(s) omitted) to avoid losing the run to HTTP 413.
2564
- `),n=JSON.stringify(ma(s)));}return Buffer.byteLength(n,"utf-8")>da?(r["Content-Encoding"]="gzip",{body:await fa(Buffer.from(n,"utf-8")),headers:r}):{body:n,headers:r}}async function jr(t,e,r,n){let s=`${t}/runs`,{body:a,headers:l}=await ft(r);l.Authorization=`Bearer ${e}`;let i=await zr(s,{method:"POST",headers:l,body:a},n);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 Wr(t,e,r){let n=`${t}/runs/init`;try{let s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(pa(r))});return s.ok?{runId:(await s.json()).runId}:null}catch{return null}}function Vr(t,e,r,n){let s=`${t}/runs/${r}/tests`;fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}).catch(()=>{});}async function Gr(t,e,r,n){let s=`${t}/runs/${r}/finalize`;return (await zr(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}))?.ok??false}function gt(t,e,r,n){let s=`${t}/runs/${r}/finalize`,a=new Date,l={finishedAt:a.toISOString(),duration:a.getTime()-new Date(n).getTime(),summary:{}};fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(l)}).catch(()=>{});}var xa="1.0.0",Jr=10;function Kr(t){return t instanceof Error?t.message:String(t)}function ka(t){return t>=400&&t<500&&t!==408&&t!==429}function oe(t,e,r,n,s,a,l,i){try{mkdirSync(t,{recursive:!0});let d=Date.now(),o=`${d}-${e}-${r}.json`,c=join(t,o),f={version:xa,queuedAt:new Date(d).toISOString(),reason:n,retryCount:0,targetEndpoint:s,method:a,payload:l,headers:i},g=c+".tmp";writeFileSync(g,JSON.stringify(f,null,2),"utf-8"),renameSync(g,c);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2563
+ `),n=JSON.stringify(ma(s))),l(n)&&(process.stderr.write(`[testrelic] ERROR: batch still exceeds ${i}MB after shedding all per-test detail \u2014 uploading run summary only (${a} per-test result(s) omitted) to avoid losing the run to HTTP 413.
2564
+ `),n=JSON.stringify(ya(s)));}return Buffer.byteLength(n,"utf-8")>ca?(r["Content-Encoding"]="gzip",{body:await ga(Buffer.from(n,"utf-8")),headers:r}):{body:n,headers:r}}async function Wr(t,e,r,n){let s=`${t}/runs`,{body:a,headers:l}=await ft(r);l.Authorization=`Bearer ${e}`;let i=await jr(s,{method:"POST",headers:l,body:a},n);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 Vr(t,e,r){let n=`${t}/runs/init`;try{let s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(fa(r))});return s.ok?{runId:(await s.json()).runId}:null}catch{return null}}function Gr(t,e,r,n){let s=`${t}/runs/${r}/tests`;fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}).catch(()=>{});}async function Jr(t,e,r,n){let s=`${t}/runs/${r}/finalize`;return (await jr(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}))?.ok??false}function gt(t,e,r,n){let s=`${t}/runs/${r}/finalize`,a=new Date,l={finishedAt:a.toISOString(),duration:a.getTime()-new Date(n).getTime(),summary:{}};fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(l)}).catch(()=>{});}var ka="1.0.0",Kr=10;function Yr(t){return t instanceof Error?t.message:String(t)}function Ta(t){return t>=400&&t<500&&t!==408&&t!==429}function oe(t,e,r,n,s,a,l,i){try{mkdirSync(t,{recursive:!0});let d=Date.now(),o=`${d}-${e}-${r}.json`,c=join(t,o),f={version:ka,queuedAt:new Date(d).toISOString(),reason:n,retryCount:0,targetEndpoint:s,method:a,payload:l,headers:i},g=c+".tmp";writeFileSync(g,JSON.stringify(f,null,2),"utf-8"),renameSync(g,c);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2565
2565
  `):process.stderr.write(`\u26A0 TestRelic: Unable to queue upload data.
2566
- `);}}async function Xr(t,e,r){let n;try{n=readdirSync(t).filter(a=>a.endsWith(".json")&&!a.endsWith(".tmp")).sort();}catch{return}if(n.length===0)return;let s=[];for(let a=0;a<n.length;a+=Jr)s.push(n.slice(a,a+Jr));for(let a of s)for(let l of a){let i=join(t,l),d;try{if(!statSync(i).isFile())continue;let c=JSON.parse(readFileSync(i,"utf-8"));if(!isValidQueueEntry(c)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${l}
2567
- `),unlinkSync(i);continue}d=c;}catch(o){process.stderr.write(`\u26A0 TestRelic: Skipping unreadable queue file ${l}: ${Kr(o)}
2568
- `);try{unlinkSync(i);}catch{}continue}try{let{body:o,headers:c}=await ft(d.payload),f={...d.headers,...c,Authorization:`Bearer ${r}`},g=await fetch(d.targetEndpoint,{method:d.method,headers:f,body:o});if(g.ok)unlinkSync(i);else if(ka(g.status)){process.stderr.write(`\u26A0 TestRelic: Queue entry ${l} rejected (HTTP ${g.status}) \u2014 moving aside; it will not be retried.
2566
+ `);}}async function en(t,e,r){let n;try{n=readdirSync(t).filter(a=>a.endsWith(".json")&&!a.endsWith(".tmp")).sort();}catch{return}if(n.length===0)return;let s=[];for(let a=0;a<n.length;a+=Kr)s.push(n.slice(a,a+Kr));for(let a of s)for(let l of a){let i=join(t,l),d;try{if(!statSync(i).isFile())continue;let c=JSON.parse(readFileSync(i,"utf-8"));if(!isValidQueueEntry(c)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${l}
2567
+ `),unlinkSync(i);continue}d=c;}catch(o){process.stderr.write(`\u26A0 TestRelic: Skipping unreadable queue file ${l}: ${Yr(o)}
2568
+ `);try{unlinkSync(i);}catch{}continue}try{let{body:o,headers:c}=await ft(d.payload),f={...d.headers,...c,Authorization:`Bearer ${r}`},g=await fetch(d.targetEndpoint,{method:d.method,headers:f,body:o});if(g.ok)unlinkSync(i);else if(Ta(g.status)){process.stderr.write(`\u26A0 TestRelic: Queue entry ${l} rejected (HTTP ${g.status}) \u2014 moving aside; it will not be retried.
2569
2569
  `);try{renameSync(i,`${i}.failed`);}catch{try{unlinkSync(i);}catch{}}}else {process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 server returned HTTP ${g.status} for ${l}; will retry later.
2570
- `);return}}catch(o){process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 ${Kr(o)}; will retry later.
2571
- `);return}}}function en(t,e){try{let r=readdirSync(t).filter(s=>(s.endsWith(".json")||s.endsWith(".failed"))&&!s.endsWith(".tmp")),n=Date.now();for(let s of r){let a=join(t,s);try{let l=readFileSync(a,"utf-8"),d=JSON.parse(l).queuedAt;if(typeof d=="string"){let o=new Date(d).getTime();n-o>e&&unlinkSync(a);}}catch{try{unlinkSync(a);}catch{}}}}catch{}}var Ia=3e5,La=864e5,Pa=6e4,tn=3e4,yt="https://platform.testrelic.ai/settings/api-keys",xe=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.
2572
- `);return}try{if(Dr(this.config.endpoint),this.gitMetadata=Hr(),!await nt(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.
2570
+ `);return}}catch(o){process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 ${Yr(o)}; will retry later.
2571
+ `);return}}}function tn(t,e){try{let r=readdirSync(t).filter(s=>(s.endsWith(".json")||s.endsWith(".failed"))&&!s.endsWith(".tmp")),n=Date.now();for(let s of r){let a=join(t,s);try{let l=readFileSync(a,"utf-8"),d=JSON.parse(l).queuedAt;if(typeof d=="string"){let o=new Date(d).getTime();n-o>e&&unlinkSync(a);}}catch{try{unlinkSync(a);}catch{}}}}catch{}}var La=3e5,Pa=864e5,Ma=6e4,rn=3e4,yt="https://platform.testrelic.ai/settings/api-keys",xe=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.
2572
+ `);return}try{if(Br(this.config.endpoint),this.gitMetadata=Ur(),!await nt(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.
2573
2573
  `);return}let r=await st(this.config.endpoint,this.config.apiKey,this.config.timeout);if(at(r)){this.handleAuthError(r.code,r.statusCode);return}let n=r;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},process.stderr.write(`\u2713 TestRelic: Connected to cloud (${n.orgName} / ${n.userName})
2574
- `),await this.resolveRepoId(),this.config.queueDirectory&&(en(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)}
2575
- `);}}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()+Ia<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await Or(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}).
2576
- `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,new Promise(e=>setTimeout(e,tn))]);}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.
2574
+ `),await this.resolveRepoId(),this.config.queueDirectory&&(tn(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)}
2575
+ `);}}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()+La<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await qr(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}).
2576
+ `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,new Promise(e=>setTimeout(e,rn))]);}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.
2577
2577
  \u2192 Manage keys: ${yt}
2578
2578
  `);break;case "expired_key":this.setLocalMode("expired_api_key"),process.stderr.write(`\u26A0 TestRelic: API key has expired. Running in local mode.
2579
2579
  \u2192 Generate a new key: ${yt}
@@ -2582,15 +2582,15 @@ ${s}
2582
2582
  `);break;case "rate_limited":this.setLocalMode("rate_limited"),process.stderr.write(`\u26A0 TestRelic: Rate limited during authentication. Running in local mode.
2583
2583
  `);break;case "timeout":this.setLocalMode("auth_timeout"),process.stderr.write(`\u26A0 TestRelic: Authentication timed out. Running in local mode.
2584
2584
  `);break;default:this.setLocalMode(`auth_error_${r??"unknown"}`),process.stderr.write(`\u26A0 TestRelic: Cloud authentication failed. Running in local mode.
2585
- `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?ae(this.gitMetadata.remoteUrl):null,r=e?Ur(e):this.config.projectName??ie(process.cwd()),n=e??this.config.projectName??ie(process.cwd()),s=this.readRepoCache(n);if(s){this.repoId=s.repoId;return}try{let a=await qr(this.config.endpoint,this.authState.accessToken,n,r,this.config.timeout,this.gitMetadata?.branch);a&&(this.repoId=a.repoId,this.writeRepoCache(n,a.repoId,a.displayName));}catch{}!e&&!this.config.projectName&&!it(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2586
- `);}readRepoCache(e){if(!this.config)return null;let r=join(this.config.queueDirectory,"..","cache","repo.json");try{if(!existsSync(r))return null;let n=readFileSync(r,"utf-8"),s=JSON.parse(n);if(s.gitId!==e||Date.now()-s.resolvedAt>La)return null;let a=this.hashApiKey();return a&&s.apiKeyHash!==a?null:s}catch{return null}}writeRepoCache(e,r,n){if(!this.config)return;let s=join(this.config.queueDirectory,"..","cache"),a=join(s,"repo.json");try{mkdirSync(s,{recursive:!0});let l={repoId:r,gitId:e,displayName:n,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=a+".tmp";writeFileSync(i,JSON.stringify(l,null,2),"utf-8"),renameSync(i,a);}catch{}}hashApiKey(){return this.config?.apiKey?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,n=this.config.endpoint;this.flushPromise=Promise.race([Xr(r,n,e),new Promise(s=>setTimeout(s,tn))]).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 nt(e))return;if(this.config?.apiKey){let n=await st(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!at(n)){let s=n;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.
2587
- `),this.startBackgroundFlush();}}}catch{}},Pa);}};function rn(t,e,r,n){let s=[],a=[],l=null,i=0,d=null,o=0,c=null,f=0,g=t.filter(p=>p.name===ATTACHMENT_NAME&&p.body),u=false;if(g.length>0)for(let p of g)try{let m=JSON.parse(p.body.toString());if(isTestRelicFilePayload(m)){s=s.concat(m.navigations),a=a.concat(m.apiAssertions),m.networkRequestsFile&&(l=m.networkRequestsFile,i+=m.networkRequestsCount),m.consoleLogsFile&&(d=m.consoleLogsFile,o+=m.consoleLogsCount),m.apiCallsFile&&(c=m.apiCallsFile,f+=m.apiCallsCount),u=!0;continue}if(isTestRelicDataPayload(m)){s=s.concat(m.navigations),Array.isArray(m.apiAssertions)&&(a=a.concat(m.apiAssertions)),i+=m.networkRequests?.length??0,f+=m.apiCalls?.length??0;let y=m.consoleLogs;Array.isArray(y)&&(o+=y.length),u=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2585
+ `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?ae(this.gitMetadata.remoteUrl):null,r=e?zr(e):this.config.projectName??ie(process.cwd()),n=e??this.config.projectName??ie(process.cwd()),s=this.readRepoCache(n);if(s){this.repoId=s.repoId;return}try{let a=await Hr(this.config.endpoint,this.authState.accessToken,n,r,this.config.timeout,this.gitMetadata?.branch);a&&(this.repoId=a.repoId,this.writeRepoCache(n,a.repoId,a.displayName));}catch{}!e&&!this.config.projectName&&!it(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2586
+ `);}readRepoCache(e){if(!this.config)return null;let r=join(this.config.queueDirectory,"..","cache","repo.json");try{if(!existsSync(r))return null;let n=readFileSync(r,"utf-8"),s=JSON.parse(n);if(s.gitId!==e||Date.now()-s.resolvedAt>Pa)return null;let a=this.hashApiKey();return a&&s.apiKeyHash!==a?null:s}catch{return null}}writeRepoCache(e,r,n){if(!this.config)return;let s=join(this.config.queueDirectory,"..","cache"),a=join(s,"repo.json");try{mkdirSync(s,{recursive:!0});let l={repoId:r,gitId:e,displayName:n,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=a+".tmp";writeFileSync(i,JSON.stringify(l,null,2),"utf-8"),renameSync(i,a);}catch{}}hashApiKey(){return this.config?.apiKey?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,n=this.config.endpoint;this.flushPromise=Promise.race([en(r,n,e),new Promise(s=>setTimeout(s,rn))]).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 nt(e))return;if(this.config?.apiKey){let n=await st(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!at(n)){let s=n;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.
2587
+ `),this.startBackgroundFlush();}}}catch{}},Ma);}};function nn(t,e,r,n){let s=[],a=[],l=null,i=0,d=null,o=0,c=null,f=0,g=t.filter(p=>p.name===ATTACHMENT_NAME&&p.body),u=false;if(g.length>0)for(let p of g)try{let m=JSON.parse(p.body.toString());if(isTestRelicFilePayload(m)){s=s.concat(m.navigations),a=a.concat(m.apiAssertions),m.networkRequestsFile&&(l=m.networkRequestsFile,i+=m.networkRequestsCount),m.consoleLogsFile&&(d=m.consoleLogsFile,o+=m.consoleLogsCount),m.apiCallsFile&&(c=m.apiCallsFile,f+=m.apiCallsCount),u=!0;continue}if(isTestRelicDataPayload(m)){s=s.concat(m.navigations),Array.isArray(m.apiAssertions)&&(a=a.concat(m.apiAssertions)),i+=m.networkRequests?.length??0,f+=m.apiCalls?.length??0;let y=m.consoleLogs;Array.isArray(y)&&(o+=y.length),u=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2588
2588
  `);}return u||(s=e.filter(p=>p.type==="lambdatest-navigation"&&p.description).map(p=>{try{return JSON.parse(p.description)}catch{return null}}).filter(p=>p!==null)),s.length===0&&i===0&&f===0&&!n&&!u&&process.stderr.write(`[testrelic] Warning: No data found for test "${r}". Make sure your tests import { test, expect } from '@testrelic/playwright-analytics/fixture' instead of '@playwright/test'. Without the TestRelic fixture, network logs, video sync, and Test Navigation data cannot be captured.
2589
- `),{navigations:s,apiAssertions:a,networkRequestsFile:l,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:o,apiCallsFile:c,apiCallsCount:f}}function ke(t=process.env){let e=Fa(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 Fa(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Ha=5,Te=[1e3,3e3,9e3],V=3,Ua={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},vt=0,bt=[];async function $a(){vt>=Ha&&await new Promise(t=>bt.push(t)),vt++;}function za(){vt--,bt.length>0&&bt.shift()();}async function Ce(t){return new Promise(e=>setTimeout(e,t))}function ja(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return Ua[e]??"application/octet-stream"}function Wa(t){try{return statSync(t).size}catch{return 0}}async function Va(t,e,r,n,s){let a=`${t}/artifacts/upload-url`,l=JSON.stringify({runId:r.runId,testId:r.testId,fileName:basename(r.filePath),contentType:s,type:r.type,sizeBytes:n});for(let i=0;i<V;i++)try{let d=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:l});if(d.ok)return await d.json();if(d.status>=500&&i<V-1){await Ce(Te[i]);continue}return null}catch{if(i<V-1){await Ce(Te[i]);continue}return null}return null}async function Ga(t,e,r,n){for(let s=0;s<V;s++)try{let a=createReadStream(e),l=Readable.toWeb(a),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(n)},body:l,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&s<V-1){await Ce(Te[s]);continue}return !1}catch{if(s<V-1){await Ce(Te[s]);continue}return false}return false}async function Ja(t,e,r){let n=`${t}/artifacts/confirm`;try{return (await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function Ka(t,e,r,n){let s=Wa(r.filePath);if(s===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(s>n*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let a=ja(r.filePath);await $a();try{let l=await Va(t,e,r,s,a);if(!l)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await Ga(l.uploadUrl,r.filePath,a,s))return {success:!1,storageKey:l.storageKey,artifactId:l.artifactId,error:"presigned_put_failed"};let d=await Ja(t,e,l.artifactId);return {success:d,storageKey:l.storageKey,artifactId:l.artifactId,error:d?null:"confirm_failed"}}finally{za();}}async function nn(t,e,r,n){let s=new Map,a=r.map(async l=>{let i=await Ka(t,e,l,n);s.set(l.filePath,i);});return await Promise.allSettled(a),s}function wt(t){let r=t.getGitMetadata()?.remoteUrl;return r?ae(r):t.getConfig()?.projectName??ie(process.cwd())}async function an(t,e,r,n,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let l=t.getGitMetadata(),i=F(),d=ke(),o=ye();return (await Wr(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:wt(t),branch:l?.branch??null,commit:l?.commitSha??null,commitMessage:l?.commitMessage??null,commitAuthor:l?.commitAuthor??null,startedAt:n,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...o?{runType:o}:{},testType:"e2e"}))?.runId??null}var Ya=true,Qa=50;async function Za(t,e,r,n){let s=new Map;if(!(e?.uploadArtifacts??Ya)||!await t.ensureValidToken())return s;let i=[],d=new Map;for(let u of n){if(u.artifacts.screenshot){let h=join(u.outputDir,u.artifacts.screenshot);i.push({filePath:h,runId:r,testId:u.testId,type:"screenshot"}),d.set(h,{testId:u.testId,field:"screenshot"});}if(u.artifacts.video){let h=join(u.outputDir,u.artifacts.video);i.push({filePath:h,runId:r,testId:u.testId,type:"video"}),d.set(h,{testId:u.testId,field:"video"});}}if(i.length===0)return s;let o=e?.artifactMaxSizeMb??Qa,c=await nn(t.getEndpoint(),t.getAccessToken(),i,o),f=new Map;for(let[u,h]of c){if(!h.success||!h.storageKey)continue;let p=d.get(u);if(!p)continue;let m=f.get(p.testId)??{};p.field==="screenshot"&&(m.screenshotKey=h.storageKey),p.field==="video"&&(m.videoKey=h.storageKey),f.set(p.testId,m);}for(let u of n){let h=f.get(u.testId);s.set(u.testId,{...u.artifacts,...h?.screenshotKey?{screenshotKey:h.screenshotKey}:{},...h?.videoKey?{videoKey:h.videoKey}:{}});}let g=Array.from(c.values()).filter(u=>u.success).length;return g>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${g} artifact(s) to cloud storage.
2590
- `),s}async function xt(t,e,r,n,s,a,l,i,d,o,c){try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){let g=await t.ensureValidToken(),u=t.getGitMetadata(),h=lt(c),p={finishedAt:l,duration:i,summary:d,...u?.commitMessage?{commitMessage:u.commitMessage}:{},testType:h.testType,...h.testType==="api"?{apiProtocol:h.apiProtocol,metadata:h.metadata}:{}};if(g){if(!await Gr(t.getEndpoint(),t.getAccessToken(),s,p)){let y=e?.queueDirectory??".testrelic/queue";oe(y,n,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",p,{"Content-Type":"application/json"});}}else {let m=e?.queueDirectory??".testrelic/queue";oe(m,n,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",p,{"Content-Type":"application/json"});}}let f=new Map;if(t.isCloudMode()&&o&&o.length>0&&(f=await Za(t,e,n,o)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let u=t.getGitMetadata(),h=F(),p=wt(t),m=Xa(a,f),y=dt(m,p,u,h,c,ke()),w=await jr(t.getEndpoint(),t.getAccessToken(),y,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!w.success){let v=w,k=e?.queueDirectory??".testrelic/queue";oe(k,n,"batch",v.reason,v.targetEndpoint,v.method,v.payload,{"Content-Type":"application/json"});}}else {let u=e?.queueDirectory??".testrelic/queue",h=t.getGitMetadata(),p=F(),m=wt(t),y=dt(a,m,h,p,void 0,ke());oe(u,n,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",y,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function Xa(t,e){if(e.size===0)return t;let r=t.timeline.map(n=>{let s=n.testId;if(!s)return n;let a=e.get(s);return a?{...n,...a.screenshotKey?{screenshotKey:a.screenshotKey}:{},...a.videoKey?{videoKey:a.videoKey}:{}}:n});return {...t,timeline:r}}function q(t){try{return readFileSync(t,"utf-8").split(`
2591
- `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function Tt(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 ii(t,e,r){let n=`${t}::${e}::${r}`;return createHash("sha256").update(n).digest("hex").substring(0,16)}function oi(t){return t.length<=3?"":t[t.length-2]}function li(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function di(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 cn(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&cn(r.children,e);}function ci(t){if(t.length===0)return null;let e=[...t].sort((n,s)=>n-s),r=e.reduce((n,s)=>n+s,0);return {avg:Math.round(r/e.length),min:e[0],max:e[e.length-1],p50:$(e,50),p95:$(e,95),p99:$(e,99)}}var un=2e5,Se=1e5;function dn(t,e,r,n,s,a,l){let i={retryIndex:t,apiCalls:e?.length??0,apiUrls:[],methodCounts:{},statusRanges:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},responseTimes:[],passedAssertions:0,failedAssertions:0,assertions:r.length,navigations:n.length,navUrls:[],networkRequests:s,consoleLogs:a,actionSteps:l?.length??0,actionCategories:{}};if(e){let o=new Set;for(let c of e){let f=typeof c.method=="string"?c.method:"OTHER";i.methodCounts[f]=(i.methodCounts[f]??0)+1;let g=typeof c.url=="string"?c.url:null;g&&o.size<Se&&o.add(et(g));let u=typeof c.responseStatusCode=="number"?c.responseStatusCode:typeof c.statusCode=="number"?c.statusCode:null,h=u!==null&&Number.isFinite(u)?u:null;i.statusRanges[di(h)]++;let p=typeof c.responseTimeMs=="number"?c.responseTimeMs:typeof c.durationMs=="number"?c.durationMs:null;p!==null&&Number.isFinite(p)&&i.responseTimes.length<un&&i.responseTimes.push(p);}i.apiUrls=Array.from(o);}for(let o of r)o.status==="passed"?i.passedAssertions++:i.failedAssertions++;let d=new Set;for(let o of n)o.url&&d.size<Se&&d.add(o.url);return i.navUrls=Array.from(d),l&&cn(l,i.actionCategories),i}function ui(){return {apiUrlSet:new Set,methodCounts:{},statusRanges:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},responseTimes:[],passedAssertions:0,failedAssertions:0,navUrlSet:new Set,actionCategoryCounts:{},volApiCalls:0,volAssertions:0,volNavigations:0,volNetworkRequests:0,volConsoleLogs:0,volActionSteps:0}}function pi(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 fi(){let t=platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function gi(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:n}=e;if(n){let a=n.toLowerCase();return a==="chrome"||a==="chrome-stable"?"Chrome":a.startsWith("chrome-beta")?"Chrome Beta":a.startsWith("chrome-dev")?"Chrome Dev":a.startsWith("chrome-canary")?"Chrome Canary":a==="msedge"||a==="msedge-stable"?"Microsoft Edge":a.startsWith("msedge-beta")?"Edge Beta":a.startsWith("msedge-dev")?"Edge Dev":a.startsWith("msedge-canary")?"Edge Canary":n}if(r){let a=r.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":r}let s=e.defaultBrowserType;if(s){let a=s.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":s}}function hi(t,e,r){let n=r.parent?.project?.(),s="unknown";n!==void 0&&(n.use.isMobile===true?s="mobile":s="e2e");let a=["e2e","api","unit","mobile"];for(let d of a)if(t.some(o=>o===`@${d}`||o===d))return d;let l=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let d of i)if(l.includes(`/${d}/`))return d;return s}var mi="__testrelic_api_config";function yi(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var Re=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.streamingTestAgg=new Map;this.config=Gt(e),this.apiConfig=Vt(e);}upsertAggContribution(e,r){let n=this.streamingTestAgg.get(e);(!n||r.retryIndex>n.retryIndex)&&this.streamingTestAgg.set(e,r);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let n=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${n} tests)
2592
- `),this.activeReportMode==="streaming"){let a=dirname(this.config.outputPath);this.streamingWriter=new ee(a);let l=()=>{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&&gt(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",l),process.on("SIGINT",l);}if(this.config.includeArtifacts){let a=dirname(this.config.outputPath);this.runTimestamp=Cr(join(a,"artifacts"));try{Ir(join(a,"artifacts"));}catch{}}let s=F();this.detectedOs=fi(),this.detectedSource=pi(s);try{this.cloudClient=new xe(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await an(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let a=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let l=this.cloudClient.getAccessToken();l&&gt(this.cloudClient.getEndpoint(),l,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",a),process.on("SIGINT",a);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:mi,description:yi(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let n=r,s=e.outcome(),a;s==="flaky"?a="flaky":s==="skipped"?a="skipped":a=Tt(n.status);let l=n.startTime.toISOString(),i=new Date(n.startTime.getTime()+n.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(A=>A.type==="tag").map(A=>A.description??""),o=rn(n.attachments,e.annotations,e.title,a==="skipped");(o.navigations.length>0||o.networkRequestsCount>0||o.apiCallsCount>0)&&(this.fixtureDataReceived=!0),o.navigations.length>0&&(this.navigationsCaptured=!0),!this.config.captureNavigation&&o.navigations.length>0&&(o={...o,navigations:[]});let c=null;if(a==="failed"||a==="flaky"){let R=(a==="flaky"?e.results.find(H=>H.status!=="passed")?.errors??[]:n.errors)[0];if(R){let H=Kt(this.config.redactPatterns),Q=R.location?.line??null,Z=null;this.config.includeCodeSnippets&&Q!==null&&R.location?.file&&(Z=Jt(R.location.file,Q,this.config.codeContextLines),Z&&(Z=H(Z))),c={message:H(R.message??"Unknown error"),line:Q,code:Z,stack:this.config.includeStackTrace&&R.stack?H(R.stack):null};}}let f=e.titlePath().filter(Boolean),g=relative(this.rootDir||".",e.location.file),u=oi(f),h=f.join(" > "),p=g,m=ii(p,u,h),y=hi(d,p,e),w=y!=="mobile"&&o.apiCallsCount>0?"api":y,v=s==="flaky",k=li(e.results),C=Tt(e.expectedStatus),b=Tt(n.status),T=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments){let A=dirname(this.config.outputPath),R=f[f.length-1]??e.title;T=Sr(n.attachments,R,n.retry,A,this.runTimestamp||void 0);}let S=this.config.includeActionSteps&&n.steps?Nr(n.steps,n.startTime):null,P=gi(e),M={titlePath:f,title:h,status:a,duration:n.duration,startedAt:l,completedAt:i,retryCount:e.results.length-1,retry:n.retry,tags:d,failure:c,specFile:g,navigations:o.navigations,testId:m,filePath:p,suiteName:u,testType:w,isFlaky:v,retryStatus:k,expectedStatus:C,actualStatus:b,artifacts:T,apiAssertions:o.apiAssertions,actions:S,networkRequestsFile:o.networkRequestsFile,networkRequestsCount:o.networkRequestsCount,consoleLogsFile:o.consoleLogsFile,consoleLogsCount:o.consoleLogsCount,apiCallsFile:o.apiCallsFile,apiCallsCount:o.apiCallsCount,browser:P,os:this.detectedOs||void 0,source:this.detectedSource||void 0},Lt=o.consoleLogsFile&&o.consoleLogsCount>0?q(o.consoleLogsFile):void 0,Pe=o.networkRequestsFile&&o.networkRequestsCount>0?q(o.networkRequestsFile):void 0,Y=o.apiCallsFile&&o.apiCallsCount>0?q(o.apiCallsFile):void 0,Pt=Y?ct(Y):void 0,Mt=!Pe&&Y?ut(Y):void 0,Et=o.apiAssertions&&o.apiAssertions.length>0?pt(o.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:m,title:h,status:a,duration:n.duration,suiteName:u,filePath:p,testType:w,isFlaky:v,startedAt:l,completedAt:i,tags:d,failure:c,retry:n.retry,retryCount:e.results.length-1,retryStatus:k,browser:P,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...S&&S.length>0?{actions:S}:{},...o.navigations&&o.navigations.length>0?{navigations:o.navigations}:{},...Lt?{consoleLogs:Lt}:{},...Pe?{networkRequests:Pe}:Mt?{networkRequests:Mt}:{},...Pt?{apiCalls:Pt}:{},...Et?{protocolAssertions:Et}:{}});try{let A=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(A==="realtime"||A==="both")){let R=this.cloudClient.getAccessToken();R&&Vr(this.cloudClient.getEndpoint(),R,this.cloudRunId,this.buildCloudTestPayload(M));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let A=Me(p,f,e.id??"",n.retry),R=n.retry===e.results.length-1,H={id:A,navigations:o.navigations,apiAssertions:o.apiAssertions,actions:S??[],artifacts:T,failureDiagnostic:c,hasNetworkFile:o.networkRequestsFile!==null,networkRequestsCount:o.networkRequestsCount,hasConsoleFile:o.consoleLogsFile!==null,consoleLogsCount:o.consoleLogsCount,hasApiCallsFile:o.apiCallsFile!==null,apiCallsCount:o.apiCallsCount,startedAt:l};this.streamingWriter.writeTestDetail(A,H,{networkRequestsFile:o.networkRequestsFile,consoleLogsFile:o.consoleLogsFile,apiCallsFile:o.apiCallsFile});let Q={id:A,title:f[f.length-1]??e.title,titlePath:f,filePath:p,status:a,duration:n.duration,project:f[1]??"",retryIndex:n.retry,tags:d,hasNetworkData:o.networkRequestsCount>0,hasConsoleData:o.consoleLogsCount>0,hasArtifacts:T!==null,hasActionSteps:(S?.length??0)>0,errorMessage:c?.message?.split(`
2593
- `)[0]??null,networkCount:o.networkRequestsCount,consoleCount:o.consoleLogsCount,actionCount:S?.length??0,isRetry:!R};if(this.testIndex.push(Q),R)switch(this.summaryCounters.total++,a){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.upsertAggContribution(`${p}::${f.join(" > ")}`,dn(n.retry,Y,o.apiAssertions,o.navigations,o.networkRequestsCount,o.consoleLogsCount,S)),T&&this.pendingArtifactEntries.push({testId:m,artifacts:T,outputDir: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(),n=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-n,l=this.activeReportMode==="streaming"?this.testIndex.some(d=>d.status!=="skipped"):this.collectedTests.some(d=>d.status!=="skipped");!this.fixtureDataReceived&&l&&process.stderr.write(`
2589
+ `),{navigations:s,apiAssertions:a,networkRequestsFile:l,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:o,apiCallsFile:c,apiCallsCount:f}}function ke(t=process.env){let e=Da(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 Da(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Ua=5,Te=[1e3,3e3,9e3],V=3,za={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},vt=0,bt=[];async function $a(){vt>=Ua&&await new Promise(t=>bt.push(t)),vt++;}function ja(){vt--,bt.length>0&&bt.shift()();}async function Ce(t){return new Promise(e=>setTimeout(e,t))}function Wa(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return za[e]??"application/octet-stream"}function Va(t){try{return statSync(t).size}catch{return 0}}async function Ga(t,e,r,n,s){let a=`${t}/artifacts/upload-url`,l=JSON.stringify({runId:r.runId,testId:r.testId,fileName:basename(r.filePath),contentType:s,type:r.type,sizeBytes:n});for(let i=0;i<V;i++)try{let d=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:l});if(d.ok)return await d.json();if(d.status>=500&&i<V-1){await Ce(Te[i]);continue}return null}catch{if(i<V-1){await Ce(Te[i]);continue}return null}return null}async function Ja(t,e,r,n){for(let s=0;s<V;s++)try{let a=createReadStream(e),l=Readable.toWeb(a),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(n)},body:l,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&s<V-1){await Ce(Te[s]);continue}return !1}catch{if(s<V-1){await Ce(Te[s]);continue}return false}return false}async function Ka(t,e,r){let n=`${t}/artifacts/confirm`;try{return (await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function Ya(t,e,r,n){let s=Va(r.filePath);if(s===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(s>n*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let a=Wa(r.filePath);await $a();try{let l=await Ga(t,e,r,s,a);if(!l)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await Ja(l.uploadUrl,r.filePath,a,s))return {success:!1,storageKey:l.storageKey,artifactId:l.artifactId,error:"presigned_put_failed"};let d=await Ka(t,e,l.artifactId);return {success:d,storageKey:l.storageKey,artifactId:l.artifactId,error:d?null:"confirm_failed"}}finally{ja();}}async function sn(t,e,r,n){let s=new Map,a=r.map(async l=>{let i=await Ya(t,e,l,n);s.set(l.filePath,i);});return await Promise.allSettled(a),s}function wt(t){let r=t.getGitMetadata()?.remoteUrl;return r?ae(r):t.getConfig()?.projectName??ie(process.cwd())}async function on(t,e,r,n,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let l=t.getGitMetadata(),i=F(),d=ke(),o=ye();return (await Vr(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:wt(t),branch:l?.branch??null,commit:l?.commitSha??null,commitMessage:l?.commitMessage??null,commitAuthor:l?.commitAuthor??null,startedAt:n,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...o?{runType:o}:{},testType:"e2e"}))?.runId??null}var Qa=true,Za=50;async function Xa(t,e,r,n){let s=new Map;if(!(e?.uploadArtifacts??Qa)||!await t.ensureValidToken())return s;let i=[],d=new Map;for(let u of n){if(u.artifacts.screenshot){let h=join(u.outputDir,u.artifacts.screenshot);i.push({filePath:h,runId:r,testId:u.testId,type:"screenshot"}),d.set(h,{testId:u.testId,field:"screenshot"});}if(u.artifacts.video){let h=join(u.outputDir,u.artifacts.video);i.push({filePath:h,runId:r,testId:u.testId,type:"video"}),d.set(h,{testId:u.testId,field:"video"});}}if(i.length===0)return s;let o=e?.artifactMaxSizeMb??Za,c=await sn(t.getEndpoint(),t.getAccessToken(),i,o),f=new Map;for(let[u,h]of c){if(!h.success||!h.storageKey)continue;let p=d.get(u);if(!p)continue;let m=f.get(p.testId)??{};p.field==="screenshot"&&(m.screenshotKey=h.storageKey),p.field==="video"&&(m.videoKey=h.storageKey),f.set(p.testId,m);}for(let u of n){let h=f.get(u.testId);s.set(u.testId,{...u.artifacts,...h?.screenshotKey?{screenshotKey:h.screenshotKey}:{},...h?.videoKey?{videoKey:h.videoKey}:{}});}let g=Array.from(c.values()).filter(u=>u.success).length;return g>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${g} artifact(s) to cloud storage.
2590
+ `),s}async function xt(t,e,r,n,s,a,l,i,d,o,c){try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){let g=await t.ensureValidToken(),u=t.getGitMetadata(),h=lt(c),p={finishedAt:l,duration:i,summary:d,...u?.commitMessage?{commitMessage:u.commitMessage}:{},testType:h.testType,...h.testType==="api"?{apiProtocol:h.apiProtocol,metadata:h.metadata}:{}};if(g){if(!await Jr(t.getEndpoint(),t.getAccessToken(),s,p)){let y=e?.queueDirectory??".testrelic/queue";oe(y,n,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",p,{"Content-Type":"application/json"});}}else {let m=e?.queueDirectory??".testrelic/queue";oe(m,n,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",p,{"Content-Type":"application/json"});}}let f=new Map;if(t.isCloudMode()&&o&&o.length>0&&(f=await Xa(t,e,n,o)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let u=t.getGitMetadata(),h=F(),p=wt(t),m=ei(a,f),y=dt(m,p,u,h,c,ke()),w=await Wr(t.getEndpoint(),t.getAccessToken(),y,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!w.success){let v=w,k=e?.queueDirectory??".testrelic/queue";oe(k,n,"batch",v.reason,v.targetEndpoint,v.method,v.payload,{"Content-Type":"application/json"});}}else {let u=e?.queueDirectory??".testrelic/queue",h=t.getGitMetadata(),p=F(),m=wt(t),y=dt(a,m,h,p,void 0,ke());oe(u,n,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",y,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function ei(t,e){if(e.size===0)return t;let r=t.timeline.map(n=>{let s=n.testId;if(!s)return n;let a=e.get(s);return a?{...n,...a.screenshotKey?{screenshotKey:a.screenshotKey}:{},...a.videoKey?{videoKey:a.videoKey}:{}}:n});return {...t,timeline:r}}function q(t){try{return readFileSync(t,"utf-8").split(`
2591
+ `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function Tt(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 oi(t,e,r){let n=`${t}::${e}::${r}`;return createHash("sha256").update(n).digest("hex").substring(0,16)}function li(t){return t.length<=3?"":t[t.length-2]}function di(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function ci(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 un(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&un(r.children,e);}function ui(t){if(t.length===0)return null;let e=[...t].sort((n,s)=>n-s),r=e.reduce((n,s)=>n+s,0);return {avg:Math.round(r/e.length),min:e[0],max:e[e.length-1],p50:z(e,50),p95:z(e,95),p99:z(e,99)}}var pn=2e5,Se=1e5;function cn(t,e,r,n,s,a,l){let i={retryIndex:t,apiCalls:e?.length??0,apiUrls:[],methodCounts:{},statusRanges:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},responseTimes:[],passedAssertions:0,failedAssertions:0,assertions:r.length,navigations:n.length,navUrls:[],networkRequests:s,consoleLogs:a,actionSteps:l?.length??0,actionCategories:{}};if(e){let o=new Set;for(let c of e){let f=typeof c.method=="string"?c.method:"OTHER";i.methodCounts[f]=(i.methodCounts[f]??0)+1;let g=typeof c.url=="string"?c.url:null;g&&o.size<Se&&o.add(et(g));let u=typeof c.responseStatusCode=="number"?c.responseStatusCode:typeof c.statusCode=="number"?c.statusCode:null,h=u!==null&&Number.isFinite(u)?u:null;i.statusRanges[ci(h)]++;let p=typeof c.responseTimeMs=="number"?c.responseTimeMs:typeof c.durationMs=="number"?c.durationMs:null;p!==null&&Number.isFinite(p)&&i.responseTimes.length<pn&&i.responseTimes.push(p);}i.apiUrls=Array.from(o);}for(let o of r)o.status==="passed"?i.passedAssertions++:i.failedAssertions++;let d=new Set;for(let o of n)o.url&&d.size<Se&&d.add(o.url);return i.navUrls=Array.from(d),l&&un(l,i.actionCategories),i}function pi(){return {apiUrlSet:new Set,methodCounts:{},statusRanges:{"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},responseTimes:[],passedAssertions:0,failedAssertions:0,navUrlSet:new Set,actionCategoryCounts:{},volApiCalls:0,volAssertions:0,volNavigations:0,volNetworkRequests:0,volConsoleLogs:0,volActionSteps:0}}function fi(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 gi(){let t=platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function hi(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:n}=e;if(n){let a=n.toLowerCase();return a==="chrome"||a==="chrome-stable"?"Chrome":a.startsWith("chrome-beta")?"Chrome Beta":a.startsWith("chrome-dev")?"Chrome Dev":a.startsWith("chrome-canary")?"Chrome Canary":a==="msedge"||a==="msedge-stable"?"Microsoft Edge":a.startsWith("msedge-beta")?"Edge Beta":a.startsWith("msedge-dev")?"Edge Dev":a.startsWith("msedge-canary")?"Edge Canary":n}if(r){let a=r.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":r}let s=e.defaultBrowserType;if(s){let a=s.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":s}}function mi(t,e,r){let n=r.parent?.project?.(),s="unknown";n!==void 0&&(n.use.isMobile===true?s="mobile":s="e2e");let a=["e2e","api","unit","mobile"];for(let d of a)if(t.some(o=>o===`@${d}`||o===d))return d;let l=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let d of i)if(l.includes(`/${d}/`))return d;return s}var yi="__testrelic_api_config";function vi(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var Re=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.streamingTestAgg=new Map;this.config=Jt(e),this.apiConfig=Gt(e);}upsertAggContribution(e,r){let n=this.streamingTestAgg.get(e);(!n||r.retryIndex>n.retryIndex)&&this.streamingTestAgg.set(e,r);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let n=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${n} tests)
2592
+ `),this.activeReportMode==="streaming"){let a=dirname(this.config.outputPath);this.streamingWriter=new ee(a);let l=()=>{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&&gt(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",l),process.on("SIGINT",l);}if(this.config.includeArtifacts){let a=dirname(this.config.outputPath);this.runTimestamp=Sr(join(a,"artifacts"));try{Lr(join(a,"artifacts"));}catch{}}let s=F();this.detectedOs=gi(),this.detectedSource=fi(s);try{this.cloudClient=new xe(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await on(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let a=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let l=this.cloudClient.getAccessToken();l&&gt(this.cloudClient.getEndpoint(),l,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",a),process.on("SIGINT",a);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:yi,description:vi(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let n=r,s=e.outcome(),a;s==="flaky"?a="flaky":s==="skipped"?a="skipped":a=Tt(n.status);let l=n.startTime.toISOString(),i=new Date(n.startTime.getTime()+n.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(A=>A.type==="tag").map(A=>A.description??""),o=nn(n.attachments,e.annotations,e.title,a==="skipped");(o.navigations.length>0||o.networkRequestsCount>0||o.apiCallsCount>0)&&(this.fixtureDataReceived=!0),o.navigations.length>0&&(this.navigationsCaptured=!0),!this.config.captureNavigation&&o.navigations.length>0&&(o={...o,navigations:[]});let c=null;if(a==="failed"||a==="flaky"){let R=(a==="flaky"?e.results.find(H=>H.status!=="passed")?.errors??[]:n.errors)[0];if(R){let H=Yt(this.config.redactPatterns),Q=R.location?.line??null,Z=null;this.config.includeCodeSnippets&&Q!==null&&R.location?.file&&(Z=Kt(R.location.file,Q,this.config.codeContextLines),Z&&(Z=H(Z))),c={message:H(R.message??"Unknown error"),line:Q,code:Z,stack:this.config.includeStackTrace&&R.stack?H(R.stack):null};}}let f=e.titlePath().filter(Boolean),g=relative(this.rootDir||".",e.location.file),u=li(f),h=f.join(" > "),p=g,m=oi(p,u,h),y=mi(d,p,e),w=y!=="mobile"&&o.apiCallsCount>0?"api":y,v=s==="flaky",k=di(e.results),C=Tt(e.expectedStatus),b=Tt(n.status),T=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments){let A=dirname(this.config.outputPath),R=f[f.length-1]??e.title;T=Rr(n.attachments,R,n.retry,A,this.runTimestamp||void 0);}let S=this.config.includeActionSteps&&n.steps?Fr(n.steps,n.startTime):null,P=hi(e),M={titlePath:f,title:h,status:a,duration:n.duration,startedAt:l,completedAt:i,retryCount:e.results.length-1,retry:n.retry,tags:d,failure:c,specFile:g,navigations:o.navigations,testId:m,filePath:p,suiteName:u,testType:w,isFlaky:v,retryStatus:k,expectedStatus:C,actualStatus:b,artifacts:T,apiAssertions:o.apiAssertions,actions:S,networkRequestsFile:o.networkRequestsFile,networkRequestsCount:o.networkRequestsCount,consoleLogsFile:o.consoleLogsFile,consoleLogsCount:o.consoleLogsCount,apiCallsFile:o.apiCallsFile,apiCallsCount:o.apiCallsCount,browser:P,os:this.detectedOs||void 0,source:this.detectedSource||void 0},Pt=o.consoleLogsFile&&o.consoleLogsCount>0?q(o.consoleLogsFile):void 0,Pe=o.networkRequestsFile&&o.networkRequestsCount>0?q(o.networkRequestsFile):void 0,Y=o.apiCallsFile&&o.apiCallsCount>0?q(o.apiCallsFile):void 0,Mt=Y?ct(Y):void 0,Et=!Pe&&Y?ut(Y):void 0,Nt=o.apiAssertions&&o.apiAssertions.length>0?pt(o.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:m,title:h,status:a,duration:n.duration,suiteName:u,filePath:p,testType:w,isFlaky:v,startedAt:l,completedAt:i,tags:d,failure:c,retry:n.retry,retryCount:e.results.length-1,retryStatus:k,browser:P,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...S&&S.length>0?{actions:S}:{},...o.navigations&&o.navigations.length>0?{navigations:o.navigations}:{},...Pt?{consoleLogs:Pt}:{},...Pe?{networkRequests:Pe}:Et?{networkRequests:Et}:{},...Mt?{apiCalls:Mt}:{},...Nt?{protocolAssertions:Nt}:{}});try{let A=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(A==="realtime"||A==="both")){let R=this.cloudClient.getAccessToken();R&&Gr(this.cloudClient.getEndpoint(),R,this.cloudRunId,this.buildCloudTestPayload(M));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let A=Me(p,f,e.id??"",n.retry),R=n.retry===e.results.length-1,H={id:A,navigations:o.navigations,apiAssertions:o.apiAssertions,actions:S??[],artifacts:T,failureDiagnostic:c,hasNetworkFile:o.networkRequestsFile!==null,networkRequestsCount:o.networkRequestsCount,hasConsoleFile:o.consoleLogsFile!==null,consoleLogsCount:o.consoleLogsCount,hasApiCallsFile:o.apiCallsFile!==null,apiCallsCount:o.apiCallsCount,startedAt:l};this.streamingWriter.writeTestDetail(A,H,{networkRequestsFile:o.networkRequestsFile,consoleLogsFile:o.consoleLogsFile,apiCallsFile:o.apiCallsFile});let Q={id:A,title:f[f.length-1]??e.title,titlePath:f,filePath:p,status:a,duration:n.duration,project:f[1]??"",retryIndex:n.retry,tags:d,hasNetworkData:o.networkRequestsCount>0,hasConsoleData:o.consoleLogsCount>0,hasArtifacts:T!==null,hasActionSteps:(S?.length??0)>0,errorMessage:c?.message?.split(`
2593
+ `)[0]??null,networkCount:o.networkRequestsCount,consoleCount:o.consoleLogsCount,actionCount:S?.length??0,isRetry:!R};if(this.testIndex.push(Q),R)switch(this.summaryCounters.total++,a){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.upsertAggContribution(`${p}::${f.join(" > ")}`,cn(n.retry,Y,o.apiAssertions,o.navigations,o.networkRequestsCount,o.consoleLogsCount,S)),T&&this.pendingArtifactEntries.push({testId:m,artifacts:T,outputDir: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(),n=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-n,l=this.activeReportMode==="streaming"?this.testIndex.some(d=>d.status!=="skipped"):this.collectedTests.some(d=>d.status!=="skipped");!this.fixtureDataReceived&&l&&process.stderr.write(`
2594
2594
  \u26A0 TestRelic: No fixture data received from any test.
2595
2595
  To enable network logs, video sync, and Test Navigation tracking, import the TestRelic fixture:
2596
2596
  import { test, expect } from '@testrelic/playwright-analytics/fixture';
@@ -2599,17 +2599,17 @@ ${s}
2599
2599
 
2600
2600
  `),this.config.captureNavigation?this.fixtureDataReceived&&!this.navigationsCaptured&&l&&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).
2601
2601
  `):process.stderr.write(`[testrelic] Test Navigation capture is disabled (captureNavigation: false). Remove the option or set it to true to capture the navigation graph.
2602
- `),await Tr();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=dirname(this.config.outputPath);i=Ar(d,this.runTimestamp);let o=join(d,"artifact-manifest.json"),c=JSON.stringify(i),f=o+".tmp";writeFileSync(f,c,"utf-8"),renameSync(f,o);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,a,e,i);else {let d=this.buildTimeline(),o=new Map;for(let u of this.collectedTests){let h=o.get(u.testId);(!h||u.retry>h.retry)&&o.set(u.testId,u);}let c=Array.from(o.values()),f=Er(c,d.length),g={schemaVersion:le,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:f,ci:F(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(g),await Ke(g,this.config,i),tt(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let u=this.collectArtifactEntries(),h=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await xt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,g,r,a,f,u,h);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=dirname(this.config.outputPath),r=[];for(let n of this.collectedTests)n.artifacts&&r.push({testId:n.testId,artifacts:n.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,n,s){if(!this.streamingWriter)return;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};let a=new Map,l=new Map;for(let p of this.testIndex){let m=`${p.filePath}::${p.titlePath.join(" > ")}`,y=a.get(m);(y===void 0||p.retryIndex>y)&&a.set(m,p.retryIndex);}let i=0;for(let p of this.testIndex){let m=`${p.filePath}::${p.titlePath.join(" > ")}`,y=a.get(m);if(p.isRetry=p.retryIndex<y,p.isRetry)continue;switch(i++,this.summaryCounters.total++,p.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 w=l.get(p.filePath);switch(w||(w={filePath:p.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},l.set(p.filePath,w)),w.total++,p.status){case "passed":w.passed++;break;case "failed":w.failed++;break;case "flaky":w.flaky++;break;case "skipped":w.skipped++;break;case "timedout":w.timedOut++;break}}let d=Array.from(l.values()),o=ui();for(let p of this.streamingTestAgg.values()){o.volApiCalls+=p.apiCalls,o.volAssertions+=p.assertions,o.volNavigations+=p.navigations,o.volNetworkRequests+=p.networkRequests,o.volConsoleLogs+=p.consoleLogs,o.volActionSteps+=p.actionSteps;for(let m in p.methodCounts)o.methodCounts[m]=(o.methodCounts[m]??0)+p.methodCounts[m];o.statusRanges["2xx"]+=p.statusRanges["2xx"],o.statusRanges["3xx"]+=p.statusRanges["3xx"],o.statusRanges["4xx"]+=p.statusRanges["4xx"],o.statusRanges["5xx"]+=p.statusRanges["5xx"],o.statusRanges.error+=p.statusRanges.error,o.passedAssertions+=p.passedAssertions,o.failedAssertions+=p.failedAssertions;for(let m in p.actionCategories)o.actionCategoryCounts[m]=(o.actionCategoryCounts[m]??0)+p.actionCategories[m];for(let m of p.apiUrls){if(o.apiUrlSet.size>=Se)break;o.apiUrlSet.add(m);}for(let m of p.navUrls){if(o.navUrlSet.size>=Se)break;o.navUrlSet.add(m);}for(let m of p.responseTimes){if(o.responseTimes.length>=un)break;o.responseTimes.push(m);}}this.summaryCounters.totalApiCalls=o.volApiCalls,this.summaryCounters.totalAssertions=o.volAssertions,this.summaryCounters.totalNavigations=o.volNavigations,this.summaryCounters.totalNetworkRequests=o.volNetworkRequests,this.summaryCounters.totalConsoleLogs=o.volConsoleLogs,this.summaryCounters.totalActionSteps=o.volActionSteps,this.streamingWriter.writeIndex(this.testIndex),this.streamingWriter.writeCompactIndex(this.testIndex);let c={reporterTotal:this.summaryCounters.total,indexTotal:i,playwrightStatus:n.status,isValid:this.summaryCounters.total===i};c.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${c.reporterTotal}, index: ${c.indexTotal}
2603
- `);let f={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:o.apiUrlSet.size,apiCallsByMethod:{...o.methodCounts},apiCallsByStatusRange:{"2xx":o.statusRanges["2xx"],"3xx":o.statusRanges["3xx"],"4xx":o.statusRanges["4xx"],"5xx":o.statusRanges["5xx"],error:o.statusRanges.error},apiResponseTime:ci(o.responseTimes),totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:o.passedAssertions,failedAssertions:o.failedAssertions,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:o.navUrlSet.size,totalTimelineSteps:i,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{...o.actionCategoryCounts}},g={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:f,validation:c,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(g);let u={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(u),await Ke(this.buildStreamingReport(g,f,e,r),this.config,s),tt(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let h=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${h}
2602
+ `),await Cr();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=dirname(this.config.outputPath);i=_r(d,this.runTimestamp);let o=join(d,"artifact-manifest.json"),c=JSON.stringify(i),f=o+".tmp";writeFileSync(f,c,"utf-8"),renameSync(f,o);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,a,e,i);else {let d=this.buildTimeline(),o=new Map;for(let u of this.collectedTests){let h=o.get(u.testId);(!h||u.retry>h.retry)&&o.set(u.testId,u);}let c=Array.from(o.values()),f=Nr(c,d.length),g={schemaVersion:le,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:f,ci:F(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(g),await Ke(g,this.config,i),tt(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let u=this.collectArtifactEntries(),h=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await xt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,g,r,a,f,u,h);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=dirname(this.config.outputPath),r=[];for(let n of this.collectedTests)n.artifacts&&r.push({testId:n.testId,artifacts:n.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,n,s){if(!this.streamingWriter)return;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};let a=new Map,l=new Map;for(let p of this.testIndex){let m=`${p.filePath}::${p.titlePath.join(" > ")}`,y=a.get(m);(y===void 0||p.retryIndex>y)&&a.set(m,p.retryIndex);}let i=0;for(let p of this.testIndex){let m=`${p.filePath}::${p.titlePath.join(" > ")}`,y=a.get(m);if(p.isRetry=p.retryIndex<y,p.isRetry)continue;switch(i++,this.summaryCounters.total++,p.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 w=l.get(p.filePath);switch(w||(w={filePath:p.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},l.set(p.filePath,w)),w.total++,p.status){case "passed":w.passed++;break;case "failed":w.failed++;break;case "flaky":w.flaky++;break;case "skipped":w.skipped++;break;case "timedout":w.timedOut++;break}}let d=Array.from(l.values()),o=pi();for(let p of this.streamingTestAgg.values()){o.volApiCalls+=p.apiCalls,o.volAssertions+=p.assertions,o.volNavigations+=p.navigations,o.volNetworkRequests+=p.networkRequests,o.volConsoleLogs+=p.consoleLogs,o.volActionSteps+=p.actionSteps;for(let m in p.methodCounts)o.methodCounts[m]=(o.methodCounts[m]??0)+p.methodCounts[m];o.statusRanges["2xx"]+=p.statusRanges["2xx"],o.statusRanges["3xx"]+=p.statusRanges["3xx"],o.statusRanges["4xx"]+=p.statusRanges["4xx"],o.statusRanges["5xx"]+=p.statusRanges["5xx"],o.statusRanges.error+=p.statusRanges.error,o.passedAssertions+=p.passedAssertions,o.failedAssertions+=p.failedAssertions;for(let m in p.actionCategories)o.actionCategoryCounts[m]=(o.actionCategoryCounts[m]??0)+p.actionCategories[m];for(let m of p.apiUrls){if(o.apiUrlSet.size>=Se)break;o.apiUrlSet.add(m);}for(let m of p.navUrls){if(o.navUrlSet.size>=Se)break;o.navUrlSet.add(m);}for(let m of p.responseTimes){if(o.responseTimes.length>=pn)break;o.responseTimes.push(m);}}this.summaryCounters.totalApiCalls=o.volApiCalls,this.summaryCounters.totalAssertions=o.volAssertions,this.summaryCounters.totalNavigations=o.volNavigations,this.summaryCounters.totalNetworkRequests=o.volNetworkRequests,this.summaryCounters.totalConsoleLogs=o.volConsoleLogs,this.summaryCounters.totalActionSteps=o.volActionSteps,this.streamingWriter.writeIndex(this.testIndex),this.streamingWriter.writeCompactIndex(this.testIndex);let c={reporterTotal:this.summaryCounters.total,indexTotal:i,playwrightStatus:n.status,isValid:this.summaryCounters.total===i};c.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${c.reporterTotal}, index: ${c.indexTotal}
2603
+ `);let f={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:o.apiUrlSet.size,apiCallsByMethod:{...o.methodCounts},apiCallsByStatusRange:{"2xx":o.statusRanges["2xx"],"3xx":o.statusRanges["3xx"],"4xx":o.statusRanges["4xx"],"5xx":o.statusRanges["5xx"],error:o.statusRanges.error},apiResponseTime:ui(o.responseTimes),totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:o.passedAssertions,failedAssertions:o.failedAssertions,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:o.navUrlSet.size,totalTimelineSteps:i,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{...o.actionCategoryCounts}},g={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:f,validation:c,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(g);let u={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(u),await Ke(this.buildStreamingReport(g,f,e,r),this.config,s),tt(f,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let h=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${h}
2604
2604
  [testrelic] ${this.testIndex.length} test detail files on disk
2605
2605
  [testrelic] View report: npx testrelic serve ${h}
2606
2606
  `),this.streamingWriter.getWriteErrors().length>0&&process.stderr.write(`[testrelic] WARNING: ${this.streamingWriter.getWriteErrors().length} write error(s) during streaming
2607
2607
  `),this.streamingWriter.dispose(),this.cloudClient){let p=this.buildStreamingReport(g,f,e,r),m=this.collectArtifactEntries(),y=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await xt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,p,e,r,f,m,y);}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,n,s){return {schemaVersion:le,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:n,totalDuration:s,summary:r,ci:F(),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 n=e.heapUsed/e.heapTotal;n>.9&&this.activeReportMode==="embedded"?(process.stderr.write(`[testrelic] WARNING: High memory (${Math.round(r)} MB). Auto-switching to streaming mode.
2608
2608
  `),this.switchToStreamingMode()):n>.8&&process.stderr.write(`[testrelic] WARNING: Memory pressure detected (${Math.round(r)} MB used).
2609
2609
  `);}catch{}}switchToStreamingMode(){try{if(this.activeReportMode==="streaming")return;this.activeReportMode="streaming";let e=dirname(this.config.outputPath);this.streamingWriter=new ee(e);for(let r of this.collectedTests){let n=Me(r.filePath,r.titlePath,r.testId,r.retry),s=r.apiCallsFile&&r.apiCallsCount>0?q(r.apiCallsFile):void 0,a={id:n,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(n,a,{networkRequestsFile:r.networkRequestsFile,consoleLogsFile:r.consoleLogsFile,apiCallsFile:r.apiCallsFile});let l={id:n,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(`
2610
- `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};switch(this.testIndex.push(l),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.upsertAggContribution(`${r.filePath}::${r.titlePath.join(" > ")}`,dn(r.retry,s,r.apiAssertions??[],r.navigations??[],r.networkRequestsCount,r.consoleLogsCount,r.actions??null));}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 Mr(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 n=null,s=null,a=null;return r?.loadFiles&&(n=this.readJsonlFile(e.networkRequestsFile),s=this.readJsonlFile(e.consoleLogsFile),a=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:n,apiCalls:a,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=pt(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=q(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=q(e.networkRequestsFile)),e.apiCallsFile){let n=q(e.apiCallsFile);r.apiCalls=ct(n),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=ut(n));}return r}writeReport(e){try{let r=JSON.stringify(e),n=this.config.outputPath,s=dirname(n);mkdirSync(s,{recursive:!0});let a=n+".tmp";writeFileSync(a,r,"utf-8"),renameSync(a,n);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2611
- `);}}};var ki=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function Ti(t){let e=t.toLowerCase();return ki.some(r=>e.includes(r))}var Ae=class t{constructor(e,r){this.page=e;this.records=[];this.listeners=[];this.navCounters=[];this.pendingRequests=new Map;this.networkWriter=null;this.consoleWriter=null;this.pendingBodyReads=[];this.requestIdCounter=0;this.networkRequestCount=0;this.consoleLogCount=0;this.includeNetworkStats=r?.includeNetworkStats??true,this.origGoto=e.goto.bind(e),this.origGoBack=e.goBack.bind(e),this.origGoForward=e.goForward.bind(e),this.origReload=e.reload.bind(e);try{this.includeNetworkStats&&(this.networkWriter=new E("network")),this.consoleWriter=new E("console");}catch{}this.interceptMethods(),this.attachListeners();}async init(){await this.injectSPADetection();}async finalizeCapturedRequests(){await Promise.allSettled(this.pendingBodyReads),this.pendingBodyReads=[];for(let[,e]of this.pendingRequests)this.networkWriter&&(this.networkWriter.append({url:e.url,method:e.method,resourceType:e.resourceType,statusCode:0,responseTimeMs:Date.now()-e.startTimeMs,startedAt:e.startedAt,requestHeaders:e.headers,requestBody:e.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:e.postDataTruncated,responseBodyTruncated:false,isBinary:false,error:"incomplete"}),this.networkRequestCount++);this.pendingRequests.clear(),this.networkWriter?.close(),this.consoleWriter?.close();}static mapConsoleType(e){switch(e){case "log":return "log";case "warning":return "warn";case "error":return "error";case "info":return "info";case "debug":return "debug";default:return "log"}}async getFileData(){this.assembleNetworkStats();let e=this.records.map(r=>({url:r.url,navigationType:r.navigationType,timestamp:r.timestamp,domContentLoadedAt:r.domContentLoadedAt,networkIdleAt:r.networkIdleAt,networkStats:r.networkStats}));return this.includeNetworkStats?await this.finalizeCapturedRequests():this.consoleWriter?.close(),{navigations:e,networkRequestsFile:this.networkWriter?.getCount()?this.networkWriter.getPath():null,networkRequestsCount:this.networkWriter?.getCount()??0,consoleLogsFile:this.consoleWriter?.getCount()?this.consoleWriter.getPath():null,consoleLogsCount:this.consoleWriter?.getCount()??0}}async flushLegacyAnnotations(e){}dispose(){this.page.goto=this.origGoto,this.page.goBack=this.origGoBack,this.page.goForward=this.origGoForward,this.page.reload=this.origReload;for(let{event:e,handler:r}of this.listeners)this.page.off(e,r);this.listeners=[],this.records=[],this.pendingRequests.clear(),this.pendingBodyReads=[],this.networkWriter?.close(),this.consoleWriter?.close();}getRecords(){return this.assembleNetworkStats(),this.records}interceptMethods(){let e=this,r=this.page;r.goto=async function(n,s){return e.recordNavigation(n,"goto"),e.origGoto(n,s)},r.goBack=async function(n){let s=await e.origGoBack(n);return e.recordNavigation(r.url(),"back"),s},r.goForward=async function(n){let s=await e.origGoForward(n);return e.recordNavigation(r.url(),"forward"),s},r.reload=async function(n){return e.recordNavigation(r.url(),"refresh"),e.origReload(n)};}attachListeners(){let e=()=>{this.lastDomContentLoaded=new Date().toISOString(),this.records.length>0&&(this.records[this.records.length-1].domContentLoadedAt=this.lastDomContentLoaded);};this.page.on("domcontentloaded",e),this.listeners.push({event:"domcontentloaded",handler:e});let r=s=>{try{let a=s;if(typeof a.parentFrame=="function"&&a.parentFrame()!==null)return;let l=a.url(),i=this.records[this.records.length-1];if(i&&Date.now()-new Date(i.timestamp).getTime()<50&&i.url===l)return;this.recordNavigation(l,"navigation");}catch{}};this.page.on("framenavigated",r),this.listeners.push({event:"framenavigated",handler:r});let n=s=>{try{let a=s,l=a.type(),i=a.text();if(l==="debug"&&i.startsWith("__testrelic_nav:")){try{let d=JSON.parse(i.slice(16));d.type&&d.url&&this.recordNavigation(d.url,d.type);}catch{}return}{let d=null;try{let c=a.location();c&&c.url&&(d=`${c.url}:${c.lineNumber}:${c.columnNumber}`);}catch{}let o=t.mapConsoleType(l);this.consoleWriter&&(this.consoleWriter.append({level:o,text:i,timestamp:new Date().toISOString(),location:d}),this.consoleLogCount++);}}catch{}};if(this.page.on("console",n),this.listeners.push({event:"console",handler:n}),this.includeNetworkStats){let s=i=>{let d=this.records.length-1,o=this.counterForNav(d);o&&o.totalRequests++;try{let c=i,f=String(this.requestIdCounter++),g=c.postData()??null,u={url:c.url(),method:c.method(),resourceType:this.mapResourceType(c.resourceType()),headers:c.headers(),postData:g,postDataTruncated:!1,startedAt:new Date().toISOString(),startTimeMs:Date.now(),navIndex:d};this.pendingRequests.set(f,u),i.__testrelic_id=f;}catch{}};this.page.on("request",s),this.listeners.push({event:"request",handler:s});let a=i=>{try{let d=i,o=d.request().__testrelic_id,c=o?this.pendingRequests.get(o):void 0,f=this.counterForNav(c?c.navIndex:this.records.length-1);if(f){let w=d.status();w>=400&&(f.failedRequests++,f.failedRequestUrls.push(w+" "+d.url()));let v=d.headers()["content-length"];v&&(f.totalBytes+=parseInt(v,10)||0);let k=d.request().resourceType(),C=this.mapResourceType(k);f.byType[C]++;}if(!o||!c)return;this.pendingRequests.delete(o);let g=Date.now()-c.startTimeMs,u=d.headers(),h=u["content-type"]??null,p=parseInt(u["content-length"]??"0",10)||0,m=h?!Ti(h):!1,y=(async()=>{let w=null;if(!m)try{w=(await d.body()).toString("utf-8");}catch{}let v={url:c.url,method:c.method,resourceType:c.resourceType,statusCode:d.status(),responseTimeMs:g,startedAt:c.startedAt,requestHeaders:c.headers,requestBody:c.postData,responseBody:w,responseHeaders:u,contentType:h,responseSize:p,requestBodyTruncated:c.postDataTruncated,responseBodyTruncated:!1,isBinary:m,error:null};this.networkWriter&&(this.networkWriter.append(v),this.networkRequestCount++);})();this.pendingBodyReads.push(y);}catch{}};this.page.on("response",a),this.listeners.push({event:"response",handler:a});let l=i=>{let d=i.__testrelic_id,o=d?this.pendingRequests.get(d):void 0,c=this.counterForNav(o?o.navIndex:this.records.length-1);if(c){c.failedRequests++;try{let f=i;c.failedRequestUrls.push("ERR "+f.url());}catch{}}try{let f=i;if(!d||!o)return;this.pendingRequests.delete(d);let g={url:o.url,method:o.method,resourceType:o.resourceType,statusCode:0,responseTimeMs:Date.now()-o.startTimeMs,startedAt:o.startedAt,requestHeaders:o.headers,requestBody:o.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:o.postDataTruncated,responseBodyTruncated:!1,isBinary:!1,error:f.failure()?.errorText??"Unknown error"};this.networkWriter&&(this.networkWriter.append(g),this.networkRequestCount++);}catch{}};this.page.on("requestfailed",l),this.listeners.push({event:"requestfailed",handler:l});}}async injectSPADetection(){try{await this.page.addInitScript(()=>{let e=history.pushState.bind(history),r=history.replaceState.bind(history);history.pushState=function(...n){e(...n),console.debug("__testrelic_nav:"+JSON.stringify({type:"spa_route",url:location.href}));},history.replaceState=function(...n){r(...n),console.debug("__testrelic_nav:"+JSON.stringify({type:"spa_replace",url:location.href}));},window.addEventListener("popstate",()=>{console.debug("__testrelic_nav:"+JSON.stringify({type:"popstate",url:location.href}));}),window.addEventListener("hashchange",()=>{console.debug("__testrelic_nav:"+JSON.stringify({type:"hash_change",url:location.href}));});});}catch{}}recordNavigation(e,r){this.records.push({url:e,navigationType:r,timestamp:new Date().toISOString()}),this.includeNetworkStats&&this.navCounters.push(this.createNetworkCounter());}createNetworkCounter(){return {totalRequests:0,failedRequests:0,failedRequestUrls:[],totalBytes:0,byType:{xhr:0,document:0,script:0,stylesheet:0,image:0,font:0,other:0}}}counterForNav(e){return e>=0?this.navCounters[e]:void 0}assembleNetworkStats(){if(this.includeNetworkStats)for(let e=0;e<this.records.length;e++){let r=this.navCounters[e];r&&(this.records[e].networkStats={totalRequests:r.totalRequests,failedRequests:r.failedRequests,failedRequestUrls:[...r.failedRequestUrls],totalBytes:r.totalBytes,byType:{...r.byType}});}}mapResourceType(e){switch(e){case "xhr":case "fetch":return "xhr";case "document":return "document";case "script":return "script";case "stylesheet":return "stylesheet";case "image":return "image";case "font":return "font";default:return "other"}}};var St=Symbol.for("__testrelic_call_id"),Ri="__testrelic_api_assertions",z=new WeakMap,G=class{constructor(){this.assertions=[];this.currentCallId=null;}recordAssertion(e){this.assertions.push(e);}getAssertions(){return this.assertions}setCurrentCallId(e){this.currentCallId=e;}getCurrentCallId(){return this.currentCallId}getData(){return [...this.assertions]}flushLegacyAnnotations(e){this.assertions.length!==0&&e.annotations.push({type:Ri,description:JSON.stringify(this.assertions)});}dispose(){this.assertions=[],this.currentCallId=null;}},pn=new Map;function Ai(t){let e=pn.get(t);if(e)return e;try{let r=t.startsWith("file://")?fileURLToPath(t):t,s=readFileSync(r,"utf-8").split(`
2612
- `);return pn.set(t,s),s}catch{return null}}function _i(){let e=new Error().stack;if(!e)return null;let r=e.split(`
2613
- `);for(let n of r){if(n.includes("/assertion-tracker.")||n.includes("/api-request-tracker.")||n.includes("node:internal")||n.includes(" at new Error")||n.includes(" at captureAssertionLocation")||n.includes(" at expectWrapper")||n.includes(" at wrappedMatcher"))continue;let s=n.match(/at\s+(?:.*?\s+\()?(.+?):(\d+):(\d+)\)?$/);if(s)return {file:s[1],line:parseInt(s[2],10),column:parseInt(s[3],10)}}return null}function Ii(t,e){if(!t)return "custom";let r=t.toLowerCase();return r.includes(".status()")&&!r.includes(".statustext()")?r.includes(".ok()")?"statusOk":"status":r.includes(".ok()")?"statusOk":r.includes(".headers()")||r.includes(".headersarray()")?"header":r.includes("tomatchobject")||r.includes("toequal")?"bodyMatch":r.includes("tocontain")||r.includes("tostringcontaining")?"bodyContains":r.includes(".json()")||r.includes(".text()")?"bodyField":"custom"}function Li(t,e,r){let n=function(a,...l){let i=t(),d=e();if(!i||!d)return r(a,...l);let o=null;if(a!=null&&typeof a=="object"){let u=a[St];typeof u=="string"&&(o=u);}if(!o&&a!==null&&a!==void 0&&typeof a=="object"&&(o=z.get(a)??null),o||(o=d.getCallIdForValue(a)),o||(o=i.getCurrentCallId()),!o)return r(a,...l);let c=_i(),f;if(c){let u=Ai(c.file);u&&c.line>0&&c.line<=u.length&&(f=u[c.line-1].trim());}let g=r(a,...l);return o?mn(g,{tracker:i,callId:o,received:a,location:c??{file:"unknown",line:0},expression:f}):g};for(let s of Object.keys(r))n[s]=r[s];return n}var gn=null,hn=null;function J(t,e){gn=t,hn=e;}function _e(t){return Li(()=>gn,()=>hn,t)}function mn(t,e){return new Proxy(t,{get(r,n,s){let a=Reflect.get(r,n,s);return typeof a!="function"||typeof n=="symbol"?a:n==="not"?mn(a,e):function(...i){let d=i[0],o="passed",c=e.received,f=null;try{let g=a.apply(this??r,i);return g&&typeof g=="object"&&typeof g.then=="function"?g.then(()=>{Ct(e,n,d,c,"passed");},u=>{throw Ct(e,n,d,c,"failed"),u}):g}catch(g){if(o="failed",f=g,g instanceof Error&&g.message){let u=g.message.match(/Received:\s*(.+)/);u&&(c=u[1]);}throw g}finally{(f!==null||o==="passed")&&Ct(e,n,d,c,o);}}}})}function Ct(t,e,r,n,s){let a=Ii(t.expression,t.received),l={callId:t.callId,type:a,expected:fn(r),actual:fn(n),status:s,location:t.location,expression:t.expression};t.tracker.recordAssertion(l);}function fn(t){if(t==null||typeof t=="string"||typeof t=="number"||typeof t=="boolean")return t;try{return JSON.stringify(t),t}catch{return String(t)}}var yn="[REDACTED]";function At(t,e){if(t===null||e.length===0)return t;let r=new Set(e.map(s=>s.toLowerCase())),n={};for(let s of Object.keys(t))Object.hasOwn(t,s)&&(n[s]=r.has(s.toLowerCase())?yn:t[s]);return n}function Ie(t,e){if(t===null||e.length===0)return t;let r;try{r=JSON.parse(t);}catch{return t}if(typeof r!="object"||r===null)return t;let n=new Set(e),s=Rt(r,n);return JSON.stringify(s)}function Rt(t,e){if(Array.isArray(t))return t.map(r=>Rt(r,e));if(typeof t=="object"&&t!==null){let r={};for(let n of Object.keys(t)){if(!Object.hasOwn(t,n))continue;let s=t[n];e.has(n)?r[n]=yn:r[n]=Rt(s,e);}return r}return t}function bn(t,e,r){if(r.length>0){for(let n of r)if(vn(t,n))return false}if(e.length>0){for(let n of e)if(vn(t,n))return true;return false}return true}function vn(t,e){try{return e instanceof RegExp?e.test(t):Pi(e).test(t)}catch{return console.warn(`[testrelic] Invalid URL filter pattern: ${String(e)}`),false}}function Pi(t){let e="",r=0;for(;r<t.length;){let n=t[r];n==="*"&&t[r+1]==="*"?(e+=".*",r+=2,t[r]==="/"&&r++):n==="*"?(e+="[^/]*",r++):n==="?"?(e+="[^/]",r++):".+^${}()|[]\\".includes(n)?(e+="\\"+n,r++):(e+=n,r++);}return new RegExp(e)}var Mi=["get","post","put","patch","delete","head","fetch"],Ei=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function Ni(t){let e=t.toLowerCase();return Ei.some(r=>e.includes(r))}function Fi(t){if(!t)return null;if(t.data!==void 0&&t.data!==null){let e=t.data;return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("base64"):JSON.stringify(e)}if(t.form!==void 0&&t.form!==null)return JSON.stringify(t.form);if(t.multipart!==void 0&&t.multipart!==null){let e=t.multipart,r={};for(let[n,s]of Object.entries(e))typeof s=="string"||typeof s=="number"||typeof s=="boolean"?r[n]=String(s):s&&typeof s=="object"&&"name"in s?r[n]=`[file: ${s.name}]`:r[n]="[binary]";return JSON.stringify(r)}return null}function wn(t){return t?"\u2022\u2022\u2022\u2022":""}function Di(t){if(!t)return [];let e;for(let[n,s]of Object.entries(t))if(n.toLowerCase()==="cookie"){e=s;break}if(!e)return [];let r=[];for(let n of e.split(";")){let s=n.trim();if(!s)continue;let a=s.indexOf("="),l=a===-1?s:s.slice(0,a).trim(),i=a===-1?"":s.slice(a+1).trim();l&&r.push({name:l,value:wn(i)});}return r}function Bi(t){let e=[];for(let r of t)for(let n of r.split(/,(?=\s*[A-Za-z0-9_.\-]+=)/)){let s=n.trim();if(!s)continue;let a=s.split(";"),l=a[0].indexOf("=");if(l===-1)continue;let i=a[0].slice(0,l).trim(),d=a[0].slice(l+1).trim(),o=a.slice(1).map(c=>c.trim()).filter(Boolean).join(" \xB7 ")||void 0;i&&e.push({name:i,value:wn(d),attributes:o});}return e}var Le=class Le{constructor(e,r,n){this.originals=new Map;this.apiCallWriter=null;this.callCounter=0;this.apiCallCount=0;this.disposed=false;this._lastCallId=null;this.primitiveCallIds=new Map;this.context=e,this.assertionTracker=r??null,this.apiConfig=n??Le.DEFAULT_API_CONFIG;try{this.apiCallWriter=new E("api-calls");}catch{}}get lastCallId(){return this._lastCallId}getCallIdForValue(e){return e!=null&&typeof e=="object"?z.get(e)??null:this.primitiveCallIds.get(e)??null}intercept(){for(let r of Mi){let n=this.context[r].bind(this.context);this.originals.set(r,n),this.context[r]=this.createWrapper(r,n);}let e=this.context.dispose.bind(this.context);this.originals.set("dispose",e),this.context.dispose=async r=>(this.disposed=true,e(r));}getFileData(){return this.apiCallWriter?.close(),{apiCallsFile:this.apiCallWriter?.getCount()?this.apiCallWriter.getPath():null,apiCallsCount:this.apiCallWriter?.getCount()??0}}flushLegacyAnnotations(e){}dispose(){for(let[e,r]of this.originals)this.context[e]=r;this.originals.clear(),this.apiCallWriter?.close(),this.callCounter=0,this.apiCallCount=0,this._lastCallId=null,this.primitiveCallIds.clear();}get isDisposed(){return this.disposed}getCapturedCallCount(){return this.apiCallCount}tagResponseMethods(e,r){let n=this,s=e.headers.bind(e);e.headers=function(){let u=s();return z.set(u,r),u};let a=e.headersArray.bind(e);e.headersArray=function(){let u=a();return z.set(u,r),u};let l=e.json.bind(e);e.json=async function(){let u=await l();return u!=null&&typeof u=="object"&&z.set(u,r),u};let i=e.status.bind(e);e.status=function(){let u=i();return n.primitiveCallIds.set(u,r),u};let d=e.statusText.bind(e);e.statusText=function(){let u=d();return n.primitiveCallIds.set(u,r),u};let o=e.ok.bind(e);e.ok=function(){let u=o();return n.primitiveCallIds.set(u,r),u};let c=e.text.bind(e);e.text=async function(){let u=await c();return n.primitiveCallIds.set(u,r),u};let f=e.body.bind(e);e.body=async function(){let u=await f();return z.set(u,r),u};}createWrapper(e,r){let n=this;return async function(a,l){if(!bn(a,n.apiConfig.apiIncludeUrls,n.apiConfig.apiExcludeUrls))return r(a,l);let i=`api-call-${n.callCounter++}`,d=new Date().toISOString(),o=e==="fetch"?(l?.method??"GET").toUpperCase():e.toUpperCase(),c=Fi(l),f=performance.now();n._lastCallId=i,n.assertionTracker&&n.assertionTracker.setCurrentCallId(i);let g;try{g=await r(a,l);}catch(u){let h=performance.now();try{let p=n.apiConfig.captureRequestBody?Ie(c,n.apiConfig.redactBodyFields):null,m={id:i,timestamp:d,method:o,url:a,requestHeaders:null,requestBody:p,responseStatusCode:null,responseStatusText:null,responseHeaders:null,responseBody:null,responseTimeMs:Math.round((h-f)*100)/100,isBinary:!1,error:u instanceof Error?u.message:String(u)};n.apiCallWriter&&(n.apiCallWriter.append(m),n.apiCallCount++);}catch{}throw u}try{let u=performance.now(),h=g.headers(),p=h["content-type"]??null,m=p?!Ni(p):!1,y=null;n.apiConfig.captureRequestHeaders&&l?.headers&&(y=l.headers);let w=null;n.apiConfig.captureResponseHeaders&&(w=h);let v=n.apiConfig.captureRequestBody?c:null,k=null;if(n.apiConfig.captureResponseBody)try{m?k=(await g.body()).toString("base64"):k=await g.text();}catch{}let C=[],b=[];try{if(n.apiConfig.captureRequestHeaders&&(C=Di(l?.headers)),n.apiConfig.captureResponseHeaders){let S=g.headersArray().filter(P=>P.name.toLowerCase()==="set-cookie").map(P=>P.value);b=Bi(S);}}catch{}y=At(y,n.apiConfig.redactHeaders),w=At(w,n.apiConfig.redactHeaders),v=Ie(v,n.apiConfig.redactBodyFields),k=Ie(k,n.apiConfig.redactBodyFields);let T={id:i,timestamp:d,method:o,url:g.url(),requestHeaders:y,requestBody:v,responseStatusCode:g.status(),responseStatusText:g.statusText(),responseHeaders:w,responseBody:k,requestCookies:C.length?C:null,responseCookies:b.length?b:null,responseTimeMs:Math.round((u-f)*100)/100,isBinary:m,error:null};n.apiCallWriter&&(n.apiCallWriter.append(T),n.apiCallCount++);}catch{}try{g[St]=i,n.tagResponseMethods(g,i);}catch{}return g}}};Le.DEFAULT_API_CONFIG=Object.freeze({trackApiCalls:true,captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]});var K=Le;_e(expect);var Hi="__testrelic_api_config",Ui="__testrelic_config_trackApiCalls";function It(t){let e=t.annotations.find(n=>n.type===Hi&&n.description!==void 0);if(e)try{return JSON.parse(e.description,$i)}catch{}let r=t.annotations.find(n=>n.type===Ui&&n.description!==void 0);return r?{trackApiCalls:r.description!=="false",captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]}:{trackApiCalls:true,captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]}}function $i(t,e){if(typeof e=="object"&&e!==null&&e.__regexp===true&&typeof e.source=="string"){let{source:r,flags:n}=e;return new RegExp(r,n)}return e}var Cn={page:async({page:t},e,r)=>{let n=new Ae(t);try{await n.init();}catch{}await e(t);try{let{navigations:s,networkRequestsFile:a,networkRequestsCount:l,consoleLogsFile:i,consoleLogsCount:d}=await n.getFileData(),o={testRelicData:!0,version:PAYLOAD_VERSION,navigations:s,apiAssertions:[],networkRequestsFile:a,networkRequestsCount:l,consoleLogsFile:i,consoleLogsCount:d,apiCallsFile:null,apiCallsCount:0};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(o)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}n.dispose();},request:async({request:t},e,r)=>{let n=It(r);if(!n.trackApiCalls){await e(t);return}let s=new G,a=new K(t,s,n);a.intercept(),J(s,a);try{await e(t);}finally{J(null,null);}try{let{apiCallsFile:l,apiCallsCount:i}=a.getFileData(),d=n.captureAssertions?s.getData():[],o={testRelicData:!0,version:PAYLOAD_VERSION,navigations:[],apiAssertions:d,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:null,consoleLogsCount:0,apiCallsFile:l,apiCallsCount:i};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(o)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};test.extend(Cn);_e(expect);var Gi={request:async({request:t},e,r)=>{let n=It(r);if(!n.trackApiCalls){await e(t);return}let s=new G,a=new K(t,s,n);a.intercept(),J(s,a);let l=null;try{l=new E("api-console");}catch{}let i=0,d=process.stdout.write,o=process.stderr.write;process.stdout.write=function(c,...f){try{let g=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!g.startsWith("[testrelic]")&&!g.startsWith("\u2139 TestRelic")&&!g.startsWith("\u2713 TestRelic")&&!g.startsWith("\u26A0 TestRelic")&&l&&(l.append({level:"stdout",text:g.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return d.apply(process.stdout,[c,...f])},process.stderr.write=function(c,...f){try{let g=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!g.startsWith("[testrelic]")&&!g.startsWith("\u26A0 TestRelic")&&l&&(l.append({level:"stderr",text:g.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return o.apply(process.stderr,[c,...f])};try{await e(t);}finally{process.stdout.write=d,process.stderr.write=o,J(null,null);}try{l?.close();let{apiCallsFile:c,apiCallsCount:f}=a.getFileData(),g=n.captureAssertions?s.getData():[],u={testRelicData:!0,version:PAYLOAD_VERSION,navigations:[],apiAssertions:g,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:i>0?l?.getPath()??null:null,consoleLogsCount:i,apiCallsFile:c,apiCallsCount:f};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(u)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};var Sn="@testrelic/playwright-analytics";function Ki(t){return Array.isArray(t)?t.some(e=>Array.isArray(e)&&typeof e[0]=="string"&&e[0]===Sn):false}function Yi(t,e){let n={video:"on",screenshot:"on",trace:"on",...t.use??{}},s;Array.isArray(t.reporter)?s=t.reporter:typeof t.reporter=="string"?s=[[t.reporter]]:s=[["list"]];let a=Ki(s)?s:[...s,[Sn,e??{}]];return defineConfig({...t,use:n,reporter:a})}var Rn=false;function uc(t,e,r="manual_record"){if(!t||!t.annotations){Rn||(Rn=true,process.stderr.write(`[testrelic] recordNavigation: reporter not active, navigation not recorded
2614
- `));return}let n={url:e,navigationType:r,timestamp:new Date().toISOString()};t.annotations.push({type:"lambdatest-navigation",description:JSON.stringify(n)});}export{le as SCHEMA_VERSION,Re as default,Yi as defineConfig,uc as recordNavigation,Gi as testRelicApiFixture,Cn as testRelicFixture};//# sourceMappingURL=index.js.map
2610
+ `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};switch(this.testIndex.push(l),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.upsertAggContribution(`${r.filePath}::${r.titlePath.join(" > ")}`,cn(r.retry,s,r.apiAssertions??[],r.navigations??[],r.networkRequestsCount,r.consoleLogsCount,r.actions??null));}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 Er(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 n=null,s=null,a=null;return r?.loadFiles&&(n=this.readJsonlFile(e.networkRequestsFile),s=this.readJsonlFile(e.consoleLogsFile),a=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:n,apiCalls:a,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=pt(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=q(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=q(e.networkRequestsFile)),e.apiCallsFile){let n=q(e.apiCallsFile);r.apiCalls=ct(n),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=ut(n));}return r}writeReport(e){try{let r=JSON.stringify(e),n=this.config.outputPath,s=dirname(n);mkdirSync(s,{recursive:!0});let a=n+".tmp";writeFileSync(a,r,"utf-8"),renameSync(a,n);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2611
+ `);}}};var Ti=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function Ci(t){let e=t.toLowerCase();return Ti.some(r=>e.includes(r))}var Ae=class t{constructor(e,r){this.page=e;this.records=[];this.listeners=[];this.navCounters=[];this.pendingRequests=new Map;this.networkWriter=null;this.consoleWriter=null;this.pendingBodyReads=[];this.requestIdCounter=0;this.networkRequestCount=0;this.consoleLogCount=0;this.includeNetworkStats=r?.includeNetworkStats??true,this.origGoto=e.goto.bind(e),this.origGoBack=e.goBack.bind(e),this.origGoForward=e.goForward.bind(e),this.origReload=e.reload.bind(e);try{this.includeNetworkStats&&(this.networkWriter=new E("network")),this.consoleWriter=new E("console");}catch{}this.interceptMethods(),this.attachListeners();}async init(){await this.injectSPADetection();}async finalizeCapturedRequests(){await Promise.allSettled(this.pendingBodyReads),this.pendingBodyReads=[];for(let[,e]of this.pendingRequests)this.networkWriter&&(this.networkWriter.append({url:e.url,method:e.method,resourceType:e.resourceType,statusCode:0,responseTimeMs:Date.now()-e.startTimeMs,startedAt:e.startedAt,requestHeaders:e.headers,requestBody:e.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:e.postDataTruncated,responseBodyTruncated:false,isBinary:false,error:"incomplete"}),this.networkRequestCount++);this.pendingRequests.clear(),this.networkWriter?.close(),this.consoleWriter?.close();}static mapConsoleType(e){switch(e){case "log":return "log";case "warning":return "warn";case "error":return "error";case "info":return "info";case "debug":return "debug";default:return "log"}}async getFileData(){this.assembleNetworkStats();let e=this.records.map(r=>({url:r.url,navigationType:r.navigationType,timestamp:r.timestamp,domContentLoadedAt:r.domContentLoadedAt,networkIdleAt:r.networkIdleAt,networkStats:r.networkStats}));return this.includeNetworkStats?await this.finalizeCapturedRequests():this.consoleWriter?.close(),{navigations:e,networkRequestsFile:this.networkWriter?.getCount()?this.networkWriter.getPath():null,networkRequestsCount:this.networkWriter?.getCount()??0,consoleLogsFile:this.consoleWriter?.getCount()?this.consoleWriter.getPath():null,consoleLogsCount:this.consoleWriter?.getCount()??0}}async flushLegacyAnnotations(e){}dispose(){this.page.goto=this.origGoto,this.page.goBack=this.origGoBack,this.page.goForward=this.origGoForward,this.page.reload=this.origReload;for(let{event:e,handler:r}of this.listeners)this.page.off(e,r);this.listeners=[],this.records=[],this.pendingRequests.clear(),this.pendingBodyReads=[],this.networkWriter?.close(),this.consoleWriter?.close();}getRecords(){return this.assembleNetworkStats(),this.records}interceptMethods(){let e=this,r=this.page;r.goto=async function(n,s){return e.recordNavigation(n,"goto"),e.origGoto(n,s)},r.goBack=async function(n){let s=await e.origGoBack(n);return e.recordNavigation(r.url(),"back"),s},r.goForward=async function(n){let s=await e.origGoForward(n);return e.recordNavigation(r.url(),"forward"),s},r.reload=async function(n){return e.recordNavigation(r.url(),"refresh"),e.origReload(n)};}attachListeners(){let e=()=>{this.lastDomContentLoaded=new Date().toISOString(),this.records.length>0&&(this.records[this.records.length-1].domContentLoadedAt=this.lastDomContentLoaded);};this.page.on("domcontentloaded",e),this.listeners.push({event:"domcontentloaded",handler:e});let r=s=>{try{let a=s;if(typeof a.parentFrame=="function"&&a.parentFrame()!==null)return;let l=a.url(),i=this.records[this.records.length-1];if(i&&Date.now()-new Date(i.timestamp).getTime()<50&&i.url===l)return;this.recordNavigation(l,"navigation");}catch{}};this.page.on("framenavigated",r),this.listeners.push({event:"framenavigated",handler:r});let n=s=>{try{let a=s,l=a.type(),i=a.text();if(l==="debug"&&i.startsWith("__testrelic_nav:")){try{let d=JSON.parse(i.slice(16));d.type&&d.url&&this.recordNavigation(d.url,d.type);}catch{}return}{let d=null;try{let c=a.location();c&&c.url&&(d=`${c.url}:${c.lineNumber}:${c.columnNumber}`);}catch{}let o=t.mapConsoleType(l);this.consoleWriter&&(this.consoleWriter.append({level:o,text:i,timestamp:new Date().toISOString(),location:d}),this.consoleLogCount++);}}catch{}};if(this.page.on("console",n),this.listeners.push({event:"console",handler:n}),this.includeNetworkStats){let s=i=>{let d=this.records.length-1,o=this.counterForNav(d);o&&o.totalRequests++;try{let c=i,f=String(this.requestIdCounter++),g=c.postData()??null,u={url:c.url(),method:c.method(),resourceType:this.mapResourceType(c.resourceType()),headers:c.headers(),postData:g,postDataTruncated:!1,startedAt:new Date().toISOString(),startTimeMs:Date.now(),navIndex:d};this.pendingRequests.set(f,u),i.__testrelic_id=f;}catch{}};this.page.on("request",s),this.listeners.push({event:"request",handler:s});let a=i=>{try{let d=i,o=d.request().__testrelic_id,c=o?this.pendingRequests.get(o):void 0,f=this.counterForNav(c?c.navIndex:this.records.length-1);if(f){let w=d.status();w>=400&&(f.failedRequests++,f.failedRequestUrls.push(w+" "+d.url()));let v=d.headers()["content-length"];v&&(f.totalBytes+=parseInt(v,10)||0);let k=d.request().resourceType(),C=this.mapResourceType(k);f.byType[C]++;}if(!o||!c)return;this.pendingRequests.delete(o);let g=Date.now()-c.startTimeMs,u=d.headers(),h=u["content-type"]??null,p=parseInt(u["content-length"]??"0",10)||0,m=h?!Ci(h):!1,y=(async()=>{let w=null;if(!m)try{w=(await d.body()).toString("utf-8");}catch{}let v={url:c.url,method:c.method,resourceType:c.resourceType,statusCode:d.status(),responseTimeMs:g,startedAt:c.startedAt,requestHeaders:c.headers,requestBody:c.postData,responseBody:w,responseHeaders:u,contentType:h,responseSize:p,requestBodyTruncated:c.postDataTruncated,responseBodyTruncated:!1,isBinary:m,error:null};this.networkWriter&&(this.networkWriter.append(v),this.networkRequestCount++);})();this.pendingBodyReads.push(y);}catch{}};this.page.on("response",a),this.listeners.push({event:"response",handler:a});let l=i=>{let d=i.__testrelic_id,o=d?this.pendingRequests.get(d):void 0,c=this.counterForNav(o?o.navIndex:this.records.length-1);if(c){c.failedRequests++;try{let f=i;c.failedRequestUrls.push("ERR "+f.url());}catch{}}try{let f=i;if(!d||!o)return;this.pendingRequests.delete(d);let g={url:o.url,method:o.method,resourceType:o.resourceType,statusCode:0,responseTimeMs:Date.now()-o.startTimeMs,startedAt:o.startedAt,requestHeaders:o.headers,requestBody:o.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:o.postDataTruncated,responseBodyTruncated:!1,isBinary:!1,error:f.failure()?.errorText??"Unknown error"};this.networkWriter&&(this.networkWriter.append(g),this.networkRequestCount++);}catch{}};this.page.on("requestfailed",l),this.listeners.push({event:"requestfailed",handler:l});}}async injectSPADetection(){try{await this.page.addInitScript(()=>{let e=history.pushState.bind(history),r=history.replaceState.bind(history);history.pushState=function(...n){e(...n),console.debug("__testrelic_nav:"+JSON.stringify({type:"spa_route",url:location.href}));},history.replaceState=function(...n){r(...n),console.debug("__testrelic_nav:"+JSON.stringify({type:"spa_replace",url:location.href}));},window.addEventListener("popstate",()=>{console.debug("__testrelic_nav:"+JSON.stringify({type:"popstate",url:location.href}));}),window.addEventListener("hashchange",()=>{console.debug("__testrelic_nav:"+JSON.stringify({type:"hash_change",url:location.href}));});});}catch{}}recordNavigation(e,r){this.records.push({url:e,navigationType:r,timestamp:new Date().toISOString()}),this.includeNetworkStats&&this.navCounters.push(this.createNetworkCounter());}createNetworkCounter(){return {totalRequests:0,failedRequests:0,failedRequestUrls:[],totalBytes:0,byType:{xhr:0,document:0,script:0,stylesheet:0,image:0,font:0,other:0}}}counterForNav(e){return e>=0?this.navCounters[e]:void 0}assembleNetworkStats(){if(this.includeNetworkStats)for(let e=0;e<this.records.length;e++){let r=this.navCounters[e];r&&(this.records[e].networkStats={totalRequests:r.totalRequests,failedRequests:r.failedRequests,failedRequestUrls:[...r.failedRequestUrls],totalBytes:r.totalBytes,byType:{...r.byType}});}}mapResourceType(e){switch(e){case "xhr":case "fetch":return "xhr";case "document":return "document";case "script":return "script";case "stylesheet":return "stylesheet";case "image":return "image";case "font":return "font";default:return "other"}}};var St=Symbol.for("__testrelic_call_id"),Ai="__testrelic_api_assertions",$=new WeakMap,G=class{constructor(){this.assertions=[];this.currentCallId=null;}recordAssertion(e){this.assertions.push(e);}getAssertions(){return this.assertions}setCurrentCallId(e){this.currentCallId=e;}getCurrentCallId(){return this.currentCallId}getData(){return [...this.assertions]}flushLegacyAnnotations(e){this.assertions.length!==0&&e.annotations.push({type:Ai,description:JSON.stringify(this.assertions)});}dispose(){this.assertions=[],this.currentCallId=null;}},fn=new Map;function _i(t){let e=fn.get(t);if(e)return e;try{let r=t.startsWith("file://")?fileURLToPath(t):t,s=readFileSync(r,"utf-8").split(`
2612
+ `);return fn.set(t,s),s}catch{return null}}function Ii(){let e=new Error().stack;if(!e)return null;let r=e.split(`
2613
+ `);for(let n of r){if(n.includes("/assertion-tracker.")||n.includes("/api-request-tracker.")||n.includes("node:internal")||n.includes(" at new Error")||n.includes(" at captureAssertionLocation")||n.includes(" at expectWrapper")||n.includes(" at wrappedMatcher"))continue;let s=n.match(/at\s+(?:.*?\s+\()?(.+?):(\d+):(\d+)\)?$/);if(s)return {file:s[1],line:parseInt(s[2],10),column:parseInt(s[3],10)}}return null}function Li(t,e){if(!t)return "custom";let r=t.toLowerCase();return r.includes(".status()")&&!r.includes(".statustext()")?r.includes(".ok()")?"statusOk":"status":r.includes(".ok()")?"statusOk":r.includes(".headers()")||r.includes(".headersarray()")?"header":r.includes("tomatchobject")||r.includes("toequal")?"bodyMatch":r.includes("tocontain")||r.includes("tostringcontaining")?"bodyContains":r.includes(".json()")||r.includes(".text()")?"bodyField":"custom"}function Pi(t,e,r){let n=function(a,...l){let i=t(),d=e();if(!i||!d)return r(a,...l);let o=null;if(a!=null&&typeof a=="object"){let u=a[St];typeof u=="string"&&(o=u);}if(!o&&a!==null&&a!==void 0&&typeof a=="object"&&(o=$.get(a)??null),o||(o=d.getCallIdForValue(a)),o||(o=i.getCurrentCallId()),!o)return r(a,...l);let c=Ii(),f;if(c){let u=_i(c.file);u&&c.line>0&&c.line<=u.length&&(f=u[c.line-1].trim());}let g=r(a,...l);return o?yn(g,{tracker:i,callId:o,received:a,location:c??{file:"unknown",line:0},expression:f}):g};for(let s of Object.keys(r))n[s]=r[s];return n}var hn=null,mn=null;function J(t,e){hn=t,mn=e;}function _e(t){return Pi(()=>hn,()=>mn,t)}function yn(t,e){return new Proxy(t,{get(r,n,s){let a=Reflect.get(r,n,s);return typeof a!="function"||typeof n=="symbol"?a:n==="not"?yn(a,e):function(...i){let d=i[0],o="passed",c=e.received,f=null;try{let g=a.apply(this??r,i);return g&&typeof g=="object"&&typeof g.then=="function"?g.then(()=>{Ct(e,n,d,c,"passed");},u=>{throw Ct(e,n,d,c,"failed"),u}):g}catch(g){if(o="failed",f=g,g instanceof Error&&g.message){let u=g.message.match(/Received:\s*(.+)/);u&&(c=u[1]);}throw g}finally{(f!==null||o==="passed")&&Ct(e,n,d,c,o);}}}})}function Ct(t,e,r,n,s){let a=Li(t.expression,t.received),l={callId:t.callId,type:a,expected:gn(r),actual:gn(n),status:s,location:t.location,expression:t.expression};t.tracker.recordAssertion(l);}function gn(t){if(t==null||typeof t=="string"||typeof t=="number"||typeof t=="boolean")return t;try{return JSON.stringify(t),t}catch{return String(t)}}var vn="[REDACTED]";function At(t,e){if(t===null||e.length===0)return t;let r=new Set(e.map(s=>s.toLowerCase())),n={};for(let s of Object.keys(t))Object.hasOwn(t,s)&&(n[s]=r.has(s.toLowerCase())?vn:t[s]);return n}function Ie(t,e){if(t===null||e.length===0)return t;let r;try{r=JSON.parse(t);}catch{return t}if(typeof r!="object"||r===null)return t;let n=new Set(e.map(a=>a.toLowerCase())),s=Rt(r,n);return JSON.stringify(s)}function Rt(t,e){if(Array.isArray(t))return t.map(r=>Rt(r,e));if(typeof t=="object"&&t!==null){let r={};for(let n of Object.keys(t)){if(!Object.hasOwn(t,n))continue;let s=t[n];e.has(n.toLowerCase())?r[n]=vn:r[n]=Rt(s,e);}return r}return t}var Mi=new Set(["access_token","api_key","token","sig"]);function _t(t){if(!t)return t;let e;try{e=new URL(t);}catch{return t}let r=false;for(let n of [...e.searchParams.keys()])Mi.has(n.toLowerCase())&&(e.searchParams.delete(n),r=true);return r?e.toString():t}function wn(t,e,r){if(r.length>0){for(let n of r)if(bn(t,n))return false}if(e.length>0){for(let n of e)if(bn(t,n))return true;return false}return true}function bn(t,e){try{return e instanceof RegExp?e.test(t):Ei(e).test(t)}catch{return console.warn(`[testrelic] Invalid URL filter pattern: ${String(e)}`),false}}function Ei(t){let e="",r=0;for(;r<t.length;){let n=t[r];n==="*"&&t[r+1]==="*"?(e+=".*",r+=2,t[r]==="/"&&r++):n==="*"?(e+="[^/]*",r++):n==="?"?(e+="[^/]",r++):".+^${}()|[]\\".includes(n)?(e+="\\"+n,r++):(e+=n,r++);}return new RegExp(e)}var Ni=["get","post","put","patch","delete","head","fetch"],Fi=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function Di(t){let e=t.toLowerCase();return Fi.some(r=>e.includes(r))}function Bi(t){if(!t)return null;if(t.data!==void 0&&t.data!==null){let e=t.data;return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("base64"):JSON.stringify(e)}if(t.form!==void 0&&t.form!==null)return JSON.stringify(t.form);if(t.multipart!==void 0&&t.multipart!==null){let e=t.multipart,r={};for(let[n,s]of Object.entries(e))typeof s=="string"||typeof s=="number"||typeof s=="boolean"?r[n]=String(s):s&&typeof s=="object"&&"name"in s?r[n]=`[file: ${s.name}]`:r[n]="[binary]";return JSON.stringify(r)}return null}function xn(t){return t?"\u2022\u2022\u2022\u2022":""}function Oi(t){if(!t)return [];let e;for(let[n,s]of Object.entries(t))if(n.toLowerCase()==="cookie"){e=s;break}if(!e)return [];let r=[];for(let n of e.split(";")){let s=n.trim();if(!s)continue;let a=s.indexOf("="),l=a===-1?s:s.slice(0,a).trim(),i=a===-1?"":s.slice(a+1).trim();l&&r.push({name:l,value:xn(i)});}return r}function qi(t){let e=[];for(let r of t)for(let n of r.split(/,(?=\s*[A-Za-z0-9_.\-]+=)/)){let s=n.trim();if(!s)continue;let a=s.split(";"),l=a[0].indexOf("=");if(l===-1)continue;let i=a[0].slice(0,l).trim(),d=a[0].slice(l+1).trim(),o=a.slice(1).map(c=>c.trim()).filter(Boolean).join(" \xB7 ")||void 0;i&&e.push({name:i,value:xn(d),attributes:o});}return e}var Le=class Le{constructor(e,r,n){this.originals=new Map;this.apiCallWriter=null;this.callCounter=0;this.apiCallCount=0;this.disposed=false;this._lastCallId=null;this.primitiveCallIds=new Map;this.context=e,this.assertionTracker=r??null,this.apiConfig=n??Le.DEFAULT_API_CONFIG;try{this.apiCallWriter=new E("api-calls");}catch{}}get lastCallId(){return this._lastCallId}getCallIdForValue(e){return e!=null&&typeof e=="object"?$.get(e)??null:this.primitiveCallIds.get(e)??null}intercept(){for(let r of Ni){let n=this.context[r].bind(this.context);this.originals.set(r,n),this.context[r]=this.createWrapper(r,n);}let e=this.context.dispose.bind(this.context);this.originals.set("dispose",e),this.context.dispose=async r=>(this.disposed=true,e(r));}getFileData(){return this.apiCallWriter?.close(),{apiCallsFile:this.apiCallWriter?.getCount()?this.apiCallWriter.getPath():null,apiCallsCount:this.apiCallWriter?.getCount()??0}}flushLegacyAnnotations(e){}dispose(){for(let[e,r]of this.originals)this.context[e]=r;this.originals.clear(),this.apiCallWriter?.close(),this.callCounter=0,this.apiCallCount=0,this._lastCallId=null,this.primitiveCallIds.clear();}get isDisposed(){return this.disposed}getCapturedCallCount(){return this.apiCallCount}tagResponseMethods(e,r){let n=this,s=e.headers.bind(e);e.headers=function(){let u=s();return $.set(u,r),u};let a=e.headersArray.bind(e);e.headersArray=function(){let u=a();return $.set(u,r),u};let l=e.json.bind(e);e.json=async function(){let u=await l();return u!=null&&typeof u=="object"&&$.set(u,r),u};let i=e.status.bind(e);e.status=function(){let u=i();return n.primitiveCallIds.set(u,r),u};let d=e.statusText.bind(e);e.statusText=function(){let u=d();return n.primitiveCallIds.set(u,r),u};let o=e.ok.bind(e);e.ok=function(){let u=o();return n.primitiveCallIds.set(u,r),u};let c=e.text.bind(e);e.text=async function(){let u=await c();return n.primitiveCallIds.set(u,r),u};let f=e.body.bind(e);e.body=async function(){let u=await f();return $.set(u,r),u};}createWrapper(e,r){let n=this;return async function(a,l){if(!wn(a,n.apiConfig.apiIncludeUrls,n.apiConfig.apiExcludeUrls))return r(a,l);let i=`api-call-${n.callCounter++}`,d=new Date().toISOString(),o=e==="fetch"?(l?.method??"GET").toUpperCase():e.toUpperCase(),c=Bi(l),f=performance.now();n._lastCallId=i,n.assertionTracker&&n.assertionTracker.setCurrentCallId(i);let g;try{g=await r(a,l);}catch(u){let h=performance.now();try{let p=n.apiConfig.captureRequestBody?Ie(c,n.apiConfig.redactBodyFields):null,m={id:i,timestamp:d,method:o,url:_t(a),requestHeaders:null,requestBody:p,responseStatusCode:null,responseStatusText:null,responseHeaders:null,responseBody:null,responseTimeMs:Math.round((h-f)*100)/100,isBinary:!1,error:u instanceof Error?u.message:String(u)};n.apiCallWriter&&(n.apiCallWriter.append(m),n.apiCallCount++);}catch{}throw u}try{let u=performance.now(),h=g.headers(),p=h["content-type"]??null,m=p?!Di(p):!1,y=null;n.apiConfig.captureRequestHeaders&&l?.headers&&(y=l.headers);let w=null;n.apiConfig.captureResponseHeaders&&(w=h);let v=n.apiConfig.captureRequestBody?c:null,k=null;if(n.apiConfig.captureResponseBody)try{m?k=(await g.body()).toString("base64"):k=await g.text();}catch{}let C=[],b=[];try{if(n.apiConfig.captureRequestHeaders&&(C=Oi(l?.headers)),n.apiConfig.captureResponseHeaders){let S=g.headersArray().filter(P=>P.name.toLowerCase()==="set-cookie").map(P=>P.value);b=qi(S);}}catch{}y=At(y,n.apiConfig.redactHeaders),w=At(w,n.apiConfig.redactHeaders),v=Ie(v,n.apiConfig.redactBodyFields),k=Ie(k,n.apiConfig.redactBodyFields);let T={id:i,timestamp:d,method:o,url:_t(g.url()),requestHeaders:y,requestBody:v,responseStatusCode:g.status(),responseStatusText:g.statusText(),responseHeaders:w,responseBody:k,requestCookies:C.length?C:null,responseCookies:b.length?b:null,responseTimeMs:Math.round((u-f)*100)/100,isBinary:m,error:null};n.apiCallWriter&&(n.apiCallWriter.append(T),n.apiCallCount++);}catch{}try{g[St]=i,n.tagResponseMethods(g,i);}catch{}return g}}};Le.DEFAULT_API_CONFIG=Object.freeze({trackApiCalls:true,captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]});var K=Le;_e(expect);var zi="__testrelic_api_config",$i="__testrelic_config_trackApiCalls";function Lt(t){let e=t.annotations.find(n=>n.type===zi&&n.description!==void 0);if(e)try{return JSON.parse(e.description,ji)}catch{}let r=t.annotations.find(n=>n.type===$i&&n.description!==void 0);return r?{trackApiCalls:r.description!=="false",captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]}:{trackApiCalls:true,captureRequestHeaders:true,captureResponseHeaders:true,captureRequestBody:true,captureResponseBody:true,captureAssertions:true,redactHeaders:["authorization","cookie","set-cookie","x-api-key"],redactBodyFields:["password","secret","token","apiKey","api_key"],apiIncludeUrls:[],apiExcludeUrls:[]}}function ji(t,e){if(typeof e=="object"&&e!==null&&e.__regexp===true&&typeof e.source=="string"){let{source:r,flags:n}=e;return new RegExp(r,n)}return e}var Sn={page:async({page:t},e,r)=>{let n=new Ae(t);try{await n.init();}catch{}await e(t);try{let{navigations:s,networkRequestsFile:a,networkRequestsCount:l,consoleLogsFile:i,consoleLogsCount:d}=await n.getFileData(),o={testRelicData:!0,version:PAYLOAD_VERSION,navigations:s,apiAssertions:[],networkRequestsFile:a,networkRequestsCount:l,consoleLogsFile:i,consoleLogsCount:d,apiCallsFile:null,apiCallsCount:0};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(o)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}n.dispose();},request:async({request:t},e,r)=>{let n=Lt(r);if(!n.trackApiCalls){await e(t);return}let s=new G,a=new K(t,s,n);a.intercept(),J(s,a);try{await e(t);}finally{J(null,null);}try{let{apiCallsFile:l,apiCallsCount:i}=a.getFileData(),d=n.captureAssertions?s.getData():[],o={testRelicData:!0,version:PAYLOAD_VERSION,navigations:[],apiAssertions:d,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:null,consoleLogsCount:0,apiCallsFile:l,apiCallsCount:i};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(o)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};test.extend(Sn);_e(expect);var Ki={request:async({request:t},e,r)=>{let n=Lt(r);if(!n.trackApiCalls){await e(t);return}let s=new G,a=new K(t,s,n);a.intercept(),J(s,a);let l=null;try{l=new E("api-console");}catch{}let i=0,d=process.stdout.write,o=process.stderr.write;process.stdout.write=function(c,...f){try{let g=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!g.startsWith("[testrelic]")&&!g.startsWith("\u2139 TestRelic")&&!g.startsWith("\u2713 TestRelic")&&!g.startsWith("\u26A0 TestRelic")&&l&&(l.append({level:"stdout",text:g.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return d.apply(process.stdout,[c,...f])},process.stderr.write=function(c,...f){try{let g=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!g.startsWith("[testrelic]")&&!g.startsWith("\u26A0 TestRelic")&&l&&(l.append({level:"stderr",text:g.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return o.apply(process.stderr,[c,...f])};try{await e(t);}finally{process.stdout.write=d,process.stderr.write=o,J(null,null);}try{l?.close();let{apiCallsFile:c,apiCallsCount:f}=a.getFileData(),g=n.captureAssertions?s.getData():[],u={testRelicData:!0,version:PAYLOAD_VERSION,navigations:[],apiAssertions:g,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:i>0?l?.getPath()??null:null,consoleLogsCount:i,apiCallsFile:c,apiCallsCount:f};await r.attach(ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(u)),contentType:ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};var Rn="@testrelic/playwright-analytics";function Qi(t){return Array.isArray(t)?t.some(e=>Array.isArray(e)&&typeof e[0]=="string"&&e[0]===Rn):false}function Zi(t,e){let n={video:"on",screenshot:"on",trace:"on",...t.use??{}},s;Array.isArray(t.reporter)?s=t.reporter:typeof t.reporter=="string"?s=[[t.reporter]]:s=[["list"]];let a=Qi(s)?s:[...s,[Rn,e??{}]];return defineConfig({...t,use:n,reporter:a})}var An=false;function fc(t,e,r="manual_record"){if(!t||!t.annotations){An||(An=true,process.stderr.write(`[testrelic] recordNavigation: reporter not active, navigation not recorded
2614
+ `));return}let n={url:e,navigationType:r,timestamp:new Date().toISOString()};t.annotations.push({type:"lambdatest-navigation",description:JSON.stringify(n)});}export{le as SCHEMA_VERSION,Re as default,Zi as defineConfig,fc as recordNavigation,Ki as testRelicApiFixture,Sn as testRelicFixture};//# sourceMappingURL=index.js.map
2615
2615
  //# sourceMappingURL=index.js.map