@testrelic/playwright-analytics 2.16.0-next.121 → 2.16.0-next.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var crypto=require('crypto'),fs$1=require('fs'),path=require('path'),os$1=require('os'),core=require('@testrelic/core'),child_process=require('child_process'),http=require('http'),readline=require('readline'),promises=require('fs/promises'),zlib=require('zlib'),util=require('util'),stream=require('stream'),test=require('@playwright/test'),perf_hooks=require('perf_hooks'),url=require('url');var oa=(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 da=".testrelic-report";function et(t,e,r,n){let s=`${t}|${e.join("|")}|${r}|${n}`;return crypto.createHash("sha256").update(s).digest("hex").substring(0,12)}function tt(t,e,r){let n=`${t}|${e.join("|")}|${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,12)}var he=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=path.join(e,da),this.testsDir=path.join(this.reportDir,"tests"),fs$1.mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,n){try{let s=path.join(this.testsDir,e);fs$1.mkdirSync(s,{recursive:!0});let a=path.join(s,"meta.json"),o=a+".tmp",i=JSON.stringify(r);return fs$1.writeFileSync(o,i,"utf-8"),fs$1.renameSync(o,a),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),n?.networkRequestsFile&&this.moveFile(n.networkRequestsFile,path.join(s,"network.jsonl")),n?.consoleLogsFile&&this.moveFile(n.consoleLogsFile,path.join(s,"console.jsonl")),n?.apiCallsFile&&this.moveFile(n.apiCallsFile,path.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{fs$1.renameSync(e,r);}catch{try{let{copyFileSync:n}=oa("fs");n(e,r);try{fs$1.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=path.join(this.reportDir,"index.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),n=r+".tmp",s=e.map(({titlePath:o,project:i,...d})=>d),a=JSON.stringify(s);fs$1.writeFileSync(n,a,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var Lr=".testrelic",ha="testrelic-config.json",ma=".testrelic",va=5,ya=new Set(["__proto__","constructor","prototype"]),Er=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,uploadBudgetMs:12e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${Lr}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),ba={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Nr(t){let e=path.resolve(t);for(let r=0;r<=va;r++){let n=path.join(e,Lr,ha);if(fs$1.existsSync(n))try{if(fs$1.statSync(n).isFile())return n}catch{}let s=path.join(e,ma);if(fs$1.existsSync(s))try{if(fs$1.statSync(s).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
- `),s}catch{}let a=path.dirname(e);if(a===e)break;e=a;}return null}function Dr(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!Fr(r)?null:r}catch{return null}}function Fr(t){for(let e of Object.keys(t)){if(ya.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!Fr(r))return false}return true}function Br(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 rt(t){let e=Object.create(null);for(let r of Object.keys(t)){let n=t[r];typeof n=="string"&&n.startsWith("$")?e[r]=Br(n):typeof n=="object"&&n!==null&&!Array.isArray(n)?e[r]=rt(n):e[r]=n;}return e}function Pr(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),n=e[2],s=ba[n];return !s||r<=0?null:r*s}function Or(t,e){let r=Object.create(null);if(Object.assign(r,Er),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.uploadBudgetMs=="number"&&(r.uploadBudgetMs=d.uploadBudgetMs),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let l=t["testrelic-repo"]??t.project;l&&typeof l=="object"&&typeof l.name=="string"&&(r.projectName=l.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 u=Pr(c.maxAge);u!==null&&(r.queueMaxAge=u);}typeof c.directory=="string"&&(r.queueDirectory=c.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?Br(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.uploadBudgetMs=="number"&&(r.uploadBudgetMs=e.uploadBudgetMs),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let d=Pr(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&&core.isValidEndpointUrl(s)&&(r.endpoint=s);let a=process.env.TESTRELIC_UPLOAD_STRATEGY;a&&["batch","realtime","both"].includes(a)&&(r.uploadStrategy=a);let o=process.env.TESTRELIC_CLOUD_TIMEOUT;if(o){let d=parseInt(o,10);!isNaN(d)&&d>=1e3&&d<=12e4&&(r.timeout=d);}let i=Object.freeze(r);return core.isValidCloudConfig(i)?i:Er}var Ca=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],Ta=["authorization","cookie","set-cookie","x-api-key"],Sa=["password","secret","token","apiKey","api_key"];function qr(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??[...Ta],e.redactBodyFields=t?.redactBodyFields??[...Sa],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Hr(t){if(t!==void 0&&!core.isValidConfig(t))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid reporter configuration");let e=Object.create(null);e.outputPath=t?.outputPath??"./test-results/analytics-timeline.json",e.includeStackTrace=t?.includeStackTrace??false,e.includeCodeSnippets=t?.includeCodeSnippets??true,e.codeContextLines=t?.codeContextLines??3,e.includeNetworkStats=t?.includeNetworkStats??true,e.captureNavigation=t?.captureNavigation??true,e.navigationTypes=t?.navigationTypes??null,e.redactPatterns=[...Ca,...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=Nr(process.cwd()),s=n?Dr(n):null,a=s?rt(s):null,o=Or(a,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var Ce="1.6.0";function Ur(t,e,r){try{let s=fs$1.readFileSync(t,"utf-8").split(`
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var crypto=require('crypto'),fs$1=require('fs'),path=require('path'),os$1=require('os'),core=require('@testrelic/core'),child_process=require('child_process'),http=require('http'),readline=require('readline'),promises=require('fs/promises'),zlib=require('zlib'),util=require('util'),stream=require('stream'),test=require('@playwright/test'),perf_hooks=require('perf_hooks'),url=require('url');var ia=(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 la=".testrelic-report";function et(t,e,r,n){let s=`${t}|${e.join("|")}|${r}|${n}`;return crypto.createHash("sha256").update(s).digest("hex").substring(0,12)}function tt(t,e,r){let n=`${t}|${e.join("|")}|${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,12)}var he=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=path.join(e,la),this.testsDir=path.join(this.reportDir,"tests"),fs$1.mkdirSync(this.testsDir,{recursive:true});}getReportDir(){return this.reportDir}getWriteErrors(){return this.writeErrors}writeTestDetail(e,r,n){try{let s=path.join(this.testsDir,e);fs$1.mkdirSync(s,{recursive:!0});let a=path.join(s,"meta.json"),o=a+".tmp",i=JSON.stringify(r);return fs$1.writeFileSync(o,i,"utf-8"),fs$1.renameSync(o,a),this.totalBytesWritten+=Buffer.byteLength(i,"utf-8"),n?.networkRequestsFile&&this.moveFile(n.networkRequestsFile,path.join(s,"network.jsonl")),n?.consoleLogsFile&&this.moveFile(n.consoleLogsFile,path.join(s,"console.jsonl")),n?.apiCallsFile&&this.moveFile(n.apiCallsFile,path.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{fs$1.renameSync(e,r);}catch{try{let{copyFileSync:n}=ia("fs");n(e,r);try{fs$1.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=path.join(this.reportDir,"index.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),n=r+".tmp",s=e.map(({titlePath:o,project:i,...d})=>d),a=JSON.stringify(s);fs$1.writeFileSync(n,a,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),n=r+".tmp",s=JSON.stringify(e);fs$1.writeFileSync(n,s,"utf-8"),fs$1.renameSync(n,r),this.totalBytesWritten+=Buffer.byteLength(s,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var Lr=".testrelic",ga="testrelic-config.json",ha=".testrelic",ma=5,va=new Set(["__proto__","constructor","prototype"]),Er=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,uploadBudgetMs:12e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${Lr}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),ya={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Nr(t){let e=path.resolve(t);for(let r=0;r<=ma;r++){let n=path.join(e,Lr,ga);if(fs$1.existsSync(n))try{if(fs$1.statSync(n).isFile())return n}catch{}let s=path.join(e,ha);if(fs$1.existsSync(s))try{if(fs$1.statSync(s).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
+ `),s}catch{}let a=path.dirname(e);if(a===e)break;e=a;}return null}function Dr(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!Fr(r)?null:r}catch{return null}}function Fr(t){for(let e of Object.keys(t)){if(va.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!Fr(r))return false}return true}function Br(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 rt(t){let e=Object.create(null);for(let r of Object.keys(t)){let n=t[r];typeof n=="string"&&n.startsWith("$")?e[r]=Br(n):typeof n=="object"&&n!==null&&!Array.isArray(n)?e[r]=rt(n):e[r]=n;}return e}function Pr(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),n=e[2],s=ya[n];return !s||r<=0?null:r*s}function Or(t,e){let r=Object.create(null);if(Object.assign(r,Er),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.uploadBudgetMs=="number"&&(r.uploadBudgetMs=d.uploadBudgetMs),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let l=t["testrelic-repo"]??t.project;l&&typeof l=="object"&&typeof l.name=="string"&&(r.projectName=l.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 u=Pr(c.maxAge);u!==null&&(r.queueMaxAge=u);}typeof c.directory=="string"&&(r.queueDirectory=c.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?Br(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.uploadBudgetMs=="number"&&(r.uploadBudgetMs=e.uploadBudgetMs),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let d=Pr(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&&core.isValidEndpointUrl(s)&&(r.endpoint=s);let a=process.env.TESTRELIC_UPLOAD_STRATEGY;a&&["batch","realtime","both"].includes(a)&&(r.uploadStrategy=a);let o=process.env.TESTRELIC_CLOUD_TIMEOUT;if(o){let d=parseInt(o,10);!isNaN(d)&&d>=1e3&&d<=12e4&&(r.timeout=d);}let i=Object.freeze(r);return core.isValidCloudConfig(i)?i:Er}var ka=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],Ca=["authorization","cookie","set-cookie","x-api-key"],Ta=["password","secret","token","apiKey","api_key"];function qr(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??[...Ca],e.redactBodyFields=t?.redactBodyFields??[...Ta],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Ur(t){if(t!==void 0&&!core.isValidConfig(t))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid reporter configuration");let e=Object.create(null);e.outputPath=t?.outputPath??"./test-results/analytics-timeline.json",e.includeStackTrace=t?.includeStackTrace??false,e.includeCodeSnippets=t?.includeCodeSnippets??true,e.codeContextLines=t?.codeContextLines??3,e.includeNetworkStats=t?.includeNetworkStats??true,e.captureNavigation=t?.captureNavigation??true,e.navigationTypes=t?.navigationTypes??null,e.redactPatterns=[...ka,...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=Nr(process.cwd()),s=n?Dr(n):null,a=s?rt(s):null,o=Or(a,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var Ce="1.6.0";function Hr(t,e,r){try{let s=fs$1.readFileSync(t,"utf-8").split(`
6
6
  `);if(e<1||e>s.length)return null;let a=Math.max(1,e-r),o=Math.min(s.length,e+r),i=[];for(let d=a;d<=o;d++){let l=d===e?">":" ",c=String(d).padStart(String(o).length," ");i.push(`${l} ${c} | ${s[d-1]}`);}return i.join(`
7
- `)}catch{return null}}function zr(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 Aa(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 _a(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 Ia(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 Ma(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 Ea(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 Pa=[Aa,_a,Ia,Ma,Ea];function V(t){let e=process.env;for(let r of Pa){let n=r(e);if(n)return n}return null}var nt=`
7
+ `)}catch{return null}}function zr(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 Ra(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 Aa(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 _a(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 Ia(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 Ma(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 Ea=[Ra,Aa,_a,Ia,Ma];function V(t){let e=process.env;for(let r of Ea){let n=r(e);if(n)return n}return null}var nt=`
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;
@@ -3999,7 +3999,7 @@ function _updateCard(cls,val){
3999
3999
  @media (max-width:1100px){
4000
4000
  .tband-3,.tband-2{grid-template-columns:1fr}
4001
4001
  }
4002
- `;var La=`
4002
+ `;var Pa=`
4003
4003
  (function(){
4004
4004
  var data=JSON.parse(document.getElementById('report-data').textContent);
4005
4005
  ${it}
@@ -4078,7 +4078,7 @@ ${""}
4078
4078
  </aside>
4079
4079
  <script id="report-data" type="application/json">${n}</script>
4080
4080
  ${s?`<script id="artifact-manifest-data" type="application/json">${s}</script>`:""}
4081
- <script>${La}</script>
4081
+ <script>${Pa}</script>
4082
4082
  </body>
4083
4083
  </html>`}function Ct(t,e,r,n){let s=t.replace(/<\//g,"<\\/"),a=e.replace(/<\//g,"<\\/"),o=n?n.replace(/<\//g,"<\\/"):null,i={};try{i=JSON.parse(t);}catch{}let d=`{
4084
4084
  "schemaVersion":"2.0",
@@ -4248,38 +4248,38 @@ ${o?`<script id="artifact-manifest-data" type="application/json">${o}</script>`:
4248
4248
  </body>
4249
4249
  </html>`}function Tt(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]),child_process.execFile(r,n,s=>{s&&process.stderr.write(`[testrelic] Failed to open browser: ${s.message}
4250
4250
  `);});}catch{}}var Vr=path.join(os$1.tmpdir(),"testrelic-data"),q=class{constructor(e){this.count=0;this.closed=false;fs$1.mkdirSync(Vr,{recursive:true}),this.filePath=path.join(Vr,`${e}-${crypto.randomUUID().substring(0,8)}.jsonl`),this.fd=fs$1.openSync(this.filePath,"w");}append(e){if(this.closed)return;let r=JSON.stringify(e)+`
4251
- `;fs$1.writeSync(this.fd,r),this.count++;}getPath(){return this.filePath}getCount(){return this.count}close(){if(!this.closed){this.closed=true;try{fs$1.closeSync(this.fd);}catch{}}}cleanup(){try{fs$1.unlinkSync(this.filePath);}catch{}}};async function Wr(t,e,r,n){let s=(e-1)*r,a=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let c of i)if(c.length!==0){if(o>=s&&a.length<r)try{a.push(JSON.parse(c));}catch{}if(o++,a.length>=r&&n!==void 0)break}let d=n??o,l=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:l}}var Yr=/^[a-f0-9]{12}$/,At=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Xr=500;function R(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Zr(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 Se(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function Re(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let n of r){let s=path.join(t,n.name);n.isFile()?e+=fs$1.statSync(s).size:n.isDirectory()&&(e+=Re(s));}}catch{}return e}function Qr(t,e,r,n){let s=Se(path.join(r,"index.json"));R(e,200,{status:"ok",reportMode:"streaming",testCount:s?.length??0,uptime:Math.floor((Date.now()-n)/1e3)});}function en(t,e,r){let n=Se(path.join(r,"summary.json"));if(!n){R(e,404,{error:"Summary not found"});return}R(e,200,n);}function tn(t,e,r){let n=Se(path.join(r,"index.json"));if(!n){R(e,404,{error:"Test index not found"});return}let a=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(a.get("page")??"1",10)||1),i=Math.min(Xr,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,l=a.get("file")??null,c=a.get("search")?.toLowerCase()??null,u=a.get("tag")?.split(",").filter(Boolean)??null,f=a.get("sort")??"file",p=a.get("order")==="desc"?-1:1,g=n;d&&d.length>0&&(g=g.filter(b=>d.includes(b.status))),l&&(g=g.filter(b=>b.filePath===l||b.filePath.startsWith(l+"/"))),c&&(g=g.filter(b=>b.title.toLowerCase().includes(c)||b.filePath.toLowerCase().includes(c))),u&&u.length>0&&(g=g.filter(b=>u.some(k=>b.tags.includes(k)))),g=[...g].sort((b,k)=>{let A=0;switch(f){case "duration":A=b.duration-k.duration;break;case "status":A=b.status.localeCompare(k.status);break;case "title":A=b.title.localeCompare(k.title);break;default:A=b.filePath.localeCompare(k.filePath);break}return A*p});let m=g.length,h=Math.max(1,Math.ceil(m/i)),v=(o-1)*i,y=g.slice(v,v+i);R(e,200,{tests:y,pagination:{page:o,pageSize:i,totalItems:m,totalPages:h},filters:{status:d,file:l,search:c,tag:u}});}function rn(t,e,r,n){if(!Yr.test(n)){R(e,400,{error:"Invalid test ID format"});return}let s=path.join(r,"tests",n,"meta.json"),a=path.join(r,"tests",`${n}.json`),o=fs$1.existsSync(s)?s:fs$1.existsSync(a)?a:null;if(!o){R(e,404,{error:`Test not found: ${n}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){R(e,500,{error:i instanceof Error?i.message:String(i)});}}async function nn(t,e,r,n,s){if(!Yr.test(n)){R(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",n,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[s]);if(!fs$1.existsSync(o)){R(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let d=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,l=Math.max(1,parseInt(d.get("page")??"1",10)||1),c=Math.min(Xr,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),u,f=path.join(r,"tests",n,"meta.json");if(fs$1.existsSync(f))try{let g=JSON.parse(fs$1.readFileSync(f,"utf-8"));switch(s){case "network":u=g.networkRequestsCount;break;case "console":u=g.consoleLogsCount;break;case "api-calls":u=g.apiCallsCount;break}}catch{}let p=await Wr(o,l,c,u);R(e,200,p);}catch(i){R(e,500,{error:i instanceof Error?i.message:String(i)});}}function sn(t,e,r){let n=Se(path.join(r,"index.json"));if(!n){R(e,404,{error:"Test index not found"});return}let s=new Map;for(let o of n){if(o.isRetry)continue;let i=s.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},s.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let a=Array.from(s.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));R(e,200,{files:a});}function an(t,e,r){if(!fs$1.existsSync(r)){R(e,200,{runs:[],totalSizeBytes:0});return}try{let n=[],s=0,a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!At.test(o.name))continue;let i=path.join(r,o.name),d=Re(i),l=fs$1.readdirSync(i,{withFileTypes:!0}).filter(c=>c.isDirectory());n.push({folderName:o.name,totalSizeBytes:d,testCount:l.length}),s+=d;}n.sort((o,i)=>i.folderName.localeCompare(o.folderName)),R(e,200,{runs:n,totalSizeBytes:s});}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function on(t,e,r){try{let n=0,s=0;if(fs$1.existsSync(r)){let a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!At.test(o.name))continue;let i=path.join(r,o.name),d=Re(i);fs$1.rmSync(i,{recursive:!0,force:!0}),s+=d,n++;}}R(e,200,{deletedCount:n,freedBytes:s});}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function ln(t,e,r,n){if(!At.test(n)){R(e,400,{error:"Invalid folder name"});return}let s=path.join(r,n);try{if(!fs$1.statSync(s).isDirectory()){R(e,404,{error:"Not found"});return}}catch{R(e,404,{error:"Not found"});return}try{let a=Re(s);fs$1.rmSync(s,{recursive:!0,force:!0}),R(e,200,{deleted:n,freedBytes:a});}catch(a){R(e,500,{error:a instanceof Error?a.message:String(a)});}}function dn(t,e,r){R(e,200,{status:"shutting_down"}),r.close();}function _t(t,e,r){if(!fs$1.existsSync(r)){R(e,404,{error:"File not found"});return}try{let n=fs$1.statSync(r).size,s=path.extname(r).toLowerCase(),a=Wa[s]??"application/octet-stream",o=$a(t.headers.range,n);if(o==="unsatisfiable"){e.writeHead(416,{"Content-Range":`bytes */${n}`,"Accept-Ranges":"bytes"}),e.end();return}if(o){e.writeHead(206,{"Content-Type":a,"Content-Length":o.end-o.start+1,"Content-Range":`bytes ${o.start}-${o.end}/${n}`,"Accept-Ranges":"bytes"}),Kr(fs$1.createReadStream(r,{start:o.start,end:o.end}),e);return}e.writeHead(200,{"Content-Type":a,"Content-Length":n,"Accept-Ranges":"bytes"}),Kr(fs$1.createReadStream(r),e);}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function Kr(t,e){t.on("error",()=>{t.destroy(),e.destroy();}),e.on("close",()=>{t.destroy();}),t.pipe(e);}function $a(t,e){if(!t)return null;let r=/^bytes=(\d*)-(\d*)$/.exec(t.trim());if(!r)return null;let[,n,s]=r;if(n===""&&s==="")return null;let a,o;if(n===""){let i=Number(s);if(i<=0)return "unsatisfiable";a=Math.max(0,e-i),o=e-1;}else a=Number(n),o=s===""?e-1:Math.min(Number(s),e-1);return !Number.isFinite(a)||!Number.isFinite(o)?null:e===0||a>=e||a>o?"unsatisfiable":{start:a,end:o}}var Wa={".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 Ya=9323,Xa=10,Za=1800*1e3;function me(t,e){return new Promise((r,n)=>{let s=e?.port??Ya,a=Date.now(),o,i=0,d=fs$1.existsSync(path.join(t,"artifacts"))?path.join(t,"artifacts"):fs$1.existsSync(path.join(t,"..","artifacts"))?path.join(t,"..","artifacts"):path.join(t,"artifacts");function l(){clearTimeout(o),o=setTimeout(()=>{u.close();},Za);}let c=e?.htmlPath??null;if(!c){let p=path.dirname(t);try{let g=fs$1.readdirSync(p).find(m=>m.endsWith(".html"));g&&(c=path.join(p,g));}catch{}}let u=http.createServer((p,g)=>{if(l(),Zr(g),p.method==="OPTIONS"){g.writeHead(204),g.end();return}let m;try{m=new URL(p.url??"/",`http://${p.headers.host??"localhost"}`).pathname;}catch{R(g,400,{error:"Invalid URL"});return}if(p.method==="GET"&&(m==="/"||m==="/index.html")){if(c&&fs$1.existsSync(c)){_t(p,g,c);return}R(g,404,{error:"HTML report not found"});return}if(p.method==="GET"&&m==="/api/health"){Qr(p,g,t,a);return}if(p.method==="GET"&&m==="/api/summary"){en(p,g,t);return}if(p.method==="GET"&&m==="/api/tests"){tn(p,g,t);return}if(p.method==="GET"&&m==="/api/files"){sn(p,g,t);return}let h=m.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(p.method==="GET"&&h){nn(p,g,t,h[1],h[2]);return}let v=m.match(/^\/api\/tests\/([a-f0-9]+)$/);if(p.method==="GET"&&v){rn(p,g,t,v[1]);return}if(p.method==="GET"&&m==="/api/artifacts"){an(p,g,d);return}if(p.method==="DELETE"&&m==="/api/artifacts"){on(p,g,d);return}let y=m.match(/^\/api\/artifacts\/(.+)$/);if(p.method==="DELETE"&&y){ln(p,g,d,decodeURIComponent(y[1]));return}if(p.method==="GET"&&m.startsWith("/artifacts/")){let b=decodeURIComponent(m.slice(11));if(b.includes("..")||b.includes("\0")){R(g,400,{error:"Invalid path"});return}_t(p,g,path.join(d,b));return}if(p.method==="POST"&&m==="/api/shutdown"){dn(p,g,u);return}R(g,404,{error:"Not found"});});function f(p){let g=m=>{m.code==="EADDRINUSE"&&i<Xa?(i++,f(p+1)):n(m);};u.once("error",g),u.listen(p,"127.0.0.1",()=>{u.removeListener("error",g);let m=u.address();if(!m||typeof m=="string"){n(new Error("Failed to get server address"));return}l(),r({port:m.port,dispose:()=>new Promise(h=>{clearTimeout(o),u.close(()=>h());})});});}f(s);})}async function cn(t){let e=await me(t);return {port:e.port,dispose:e.dispose}}function ti(t,e,r){let n=JSON.stringify(t),s=r?JSON.stringify(r):null;return jr(n,e,s)}async function Mt(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,o,i=e.htmlReportPath,d=path.dirname(i);fs$1.mkdirSync(d,{recursive:!0});let l="",c="[]",u=null;if(a){l=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 p=path.dirname(e.outputPath),g=path.join(p,".testrelic-report");try{let m=path.join(g,"index-compact.json"),h=path.join(g,"index.json");fs$1.existsSync(m)?c=fs$1.readFileSync(m,"utf-8"):fs$1.existsSync(h)&&(c=fs$1.readFileSync(h,"utf-8"));}catch{}u=r?JSON.stringify(r):null,o=Ct(l,c,null,u);}else o=ti(t,null,r);let f=i+".tmp";if(fs$1.writeFileSync(f,o,"utf-8"),fs$1.renameSync(f,i),a){if(t.ci===null){let p=path.dirname(e.outputPath),g=path.join(p,".testrelic-report"),m=path.resolve(i);try{if(await ni(),n=await si(g),!n){s=await me(g,{htmlPath:m}),n=s.port;let h=setInterval(()=>{},6e4),v=()=>{clearInterval(h),s?.dispose();};process.on("SIGINT",v),process.on("SIGTERM",v),setTimeout(v,1800*1e3).unref();}if(n){process.stderr.write(`
4251
+ `;fs$1.writeSync(this.fd,r),this.count++;}getPath(){return this.filePath}getCount(){return this.count}close(){if(!this.closed){this.closed=true;try{fs$1.closeSync(this.fd);}catch{}}}cleanup(){try{fs$1.unlinkSync(this.filePath);}catch{}}};async function Wr(t,e,r,n){let s=(e-1)*r,a=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let c of i)if(c.length!==0){if(o>=s&&a.length<r)try{a.push(JSON.parse(c));}catch{}if(o++,a.length>=r&&n!==void 0)break}let d=n??o,l=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:l}}var Yr=/^[a-f0-9]{12}$/,At=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Xr=500;function R(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Zr(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 Se(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function Re(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let n of r){let s=path.join(t,n.name);n.isFile()?e+=fs$1.statSync(s).size:n.isDirectory()&&(e+=Re(s));}}catch{}return e}function Qr(t,e,r,n){let s=Se(path.join(r,"index.json"));R(e,200,{status:"ok",reportMode:"streaming",testCount:s?.length??0,uptime:Math.floor((Date.now()-n)/1e3)});}function en(t,e,r){let n=Se(path.join(r,"summary.json"));if(!n){R(e,404,{error:"Summary not found"});return}R(e,200,n);}function tn(t,e,r){let n=Se(path.join(r,"index.json"));if(!n){R(e,404,{error:"Test index not found"});return}let a=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,o=Math.max(1,parseInt(a.get("page")??"1",10)||1),i=Math.min(Xr,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,l=a.get("file")??null,c=a.get("search")?.toLowerCase()??null,u=a.get("tag")?.split(",").filter(Boolean)??null,f=a.get("sort")??"file",p=a.get("order")==="desc"?-1:1,g=n;d&&d.length>0&&(g=g.filter(b=>d.includes(b.status))),l&&(g=g.filter(b=>b.filePath===l||b.filePath.startsWith(l+"/"))),c&&(g=g.filter(b=>b.title.toLowerCase().includes(c)||b.filePath.toLowerCase().includes(c))),u&&u.length>0&&(g=g.filter(b=>u.some(k=>b.tags.includes(k)))),g=[...g].sort((b,k)=>{let A=0;switch(f){case "duration":A=b.duration-k.duration;break;case "status":A=b.status.localeCompare(k.status);break;case "title":A=b.title.localeCompare(k.title);break;default:A=b.filePath.localeCompare(k.filePath);break}return A*p});let m=g.length,h=Math.max(1,Math.ceil(m/i)),v=(o-1)*i,y=g.slice(v,v+i);R(e,200,{tests:y,pagination:{page:o,pageSize:i,totalItems:m,totalPages:h},filters:{status:d,file:l,search:c,tag:u}});}function rn(t,e,r,n){if(!Yr.test(n)){R(e,400,{error:"Invalid test ID format"});return}let s=path.join(r,"tests",n,"meta.json"),a=path.join(r,"tests",`${n}.json`),o=fs$1.existsSync(s)?s:fs$1.existsSync(a)?a:null;if(!o){R(e,404,{error:`Test not found: ${n}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){R(e,500,{error:i instanceof Error?i.message:String(i)});}}async function nn(t,e,r,n,s){if(!Yr.test(n)){R(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",n,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[s]);if(!fs$1.existsSync(o)){R(e,200,{items:[],total:0,page:1,pageSize:50,totalPages:0});return}try{let d=new URL(t.url??"/",`http://${t.headers.host}`).searchParams,l=Math.max(1,parseInt(d.get("page")??"1",10)||1),c=Math.min(Xr,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),u,f=path.join(r,"tests",n,"meta.json");if(fs$1.existsSync(f))try{let g=JSON.parse(fs$1.readFileSync(f,"utf-8"));switch(s){case "network":u=g.networkRequestsCount;break;case "console":u=g.consoleLogsCount;break;case "api-calls":u=g.apiCallsCount;break}}catch{}let p=await Wr(o,l,c,u);R(e,200,p);}catch(i){R(e,500,{error:i instanceof Error?i.message:String(i)});}}function sn(t,e,r){let n=Se(path.join(r,"index.json"));if(!n){R(e,404,{error:"Test index not found"});return}let s=new Map;for(let o of n){if(o.isRetry)continue;let i=s.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},s.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let a=Array.from(s.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));R(e,200,{files:a});}function an(t,e,r){if(!fs$1.existsSync(r)){R(e,200,{runs:[],totalSizeBytes:0});return}try{let n=[],s=0,a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!At.test(o.name))continue;let i=path.join(r,o.name),d=Re(i),l=fs$1.readdirSync(i,{withFileTypes:!0}).filter(c=>c.isDirectory());n.push({folderName:o.name,totalSizeBytes:d,testCount:l.length}),s+=d;}n.sort((o,i)=>i.folderName.localeCompare(o.folderName)),R(e,200,{runs:n,totalSizeBytes:s});}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function on(t,e,r){try{let n=0,s=0;if(fs$1.existsSync(r)){let a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!At.test(o.name))continue;let i=path.join(r,o.name),d=Re(i);fs$1.rmSync(i,{recursive:!0,force:!0}),s+=d,n++;}}R(e,200,{deletedCount:n,freedBytes:s});}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function ln(t,e,r,n){if(!At.test(n)){R(e,400,{error:"Invalid folder name"});return}let s=path.join(r,n);try{if(!fs$1.statSync(s).isDirectory()){R(e,404,{error:"Not found"});return}}catch{R(e,404,{error:"Not found"});return}try{let a=Re(s);fs$1.rmSync(s,{recursive:!0,force:!0}),R(e,200,{deleted:n,freedBytes:a});}catch(a){R(e,500,{error:a instanceof Error?a.message:String(a)});}}function dn(t,e,r){R(e,200,{status:"shutting_down"}),r.close();}function _t(t,e,r){if(!fs$1.existsSync(r)){R(e,404,{error:"File not found"});return}try{let n=fs$1.statSync(r).size,s=path.extname(r).toLowerCase(),a=$a[s]??"application/octet-stream",o=Va(t.headers.range,n);if(o==="unsatisfiable"){e.writeHead(416,{"Content-Range":`bytes */${n}`,"Accept-Ranges":"bytes"}),e.end();return}if(o){e.writeHead(206,{"Content-Type":a,"Content-Length":o.end-o.start+1,"Content-Range":`bytes ${o.start}-${o.end}/${n}`,"Accept-Ranges":"bytes"}),Kr(fs$1.createReadStream(r,{start:o.start,end:o.end}),e);return}e.writeHead(200,{"Content-Type":a,"Content-Length":n,"Accept-Ranges":"bytes"}),Kr(fs$1.createReadStream(r),e);}catch(n){R(e,500,{error:n instanceof Error?n.message:String(n)});}}function Kr(t,e){t.on("error",()=>{t.destroy(),e.destroy();}),e.on("close",()=>{t.destroy();}),t.pipe(e);}function Va(t,e){if(!t)return null;let r=/^bytes=(\d*)-(\d*)$/.exec(t.trim());if(!r)return null;let[,n,s]=r;if(n===""&&s==="")return null;let a,o;if(n===""){let i=Number(s);if(i<=0)return "unsatisfiable";a=Math.max(0,e-i),o=e-1;}else a=Number(n),o=s===""?e-1:Math.min(Number(s),e-1);return !Number.isFinite(a)||!Number.isFinite(o)?null:e===0||a>=e||a>o?"unsatisfiable":{start:a,end:o}}var $a={".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 Ja=9323,Ya=10,Xa=1800*1e3;function me(t,e){return new Promise((r,n)=>{let s=e?.port??Ja,a=Date.now(),o,i=0,d=fs$1.existsSync(path.join(t,"artifacts"))?path.join(t,"artifacts"):fs$1.existsSync(path.join(t,"..","artifacts"))?path.join(t,"..","artifacts"):path.join(t,"artifacts");function l(){clearTimeout(o),o=setTimeout(()=>{u.close();},Xa);}let c=e?.htmlPath??null;if(!c){let p=path.dirname(t);try{let g=fs$1.readdirSync(p).find(m=>m.endsWith(".html"));g&&(c=path.join(p,g));}catch{}}let u=http.createServer((p,g)=>{if(l(),Zr(g),p.method==="OPTIONS"){g.writeHead(204),g.end();return}let m;try{m=new URL(p.url??"/",`http://${p.headers.host??"localhost"}`).pathname;}catch{R(g,400,{error:"Invalid URL"});return}if(p.method==="GET"&&(m==="/"||m==="/index.html")){if(c&&fs$1.existsSync(c)){_t(p,g,c);return}R(g,404,{error:"HTML report not found"});return}if(p.method==="GET"&&m==="/api/health"){Qr(p,g,t,a);return}if(p.method==="GET"&&m==="/api/summary"){en(p,g,t);return}if(p.method==="GET"&&m==="/api/tests"){tn(p,g,t);return}if(p.method==="GET"&&m==="/api/files"){sn(p,g,t);return}let h=m.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(p.method==="GET"&&h){nn(p,g,t,h[1],h[2]);return}let v=m.match(/^\/api\/tests\/([a-f0-9]+)$/);if(p.method==="GET"&&v){rn(p,g,t,v[1]);return}if(p.method==="GET"&&m==="/api/artifacts"){an(p,g,d);return}if(p.method==="DELETE"&&m==="/api/artifacts"){on(p,g,d);return}let y=m.match(/^\/api\/artifacts\/(.+)$/);if(p.method==="DELETE"&&y){ln(p,g,d,decodeURIComponent(y[1]));return}if(p.method==="GET"&&m.startsWith("/artifacts/")){let b=decodeURIComponent(m.slice(11));if(b.includes("..")||b.includes("\0")){R(g,400,{error:"Invalid path"});return}_t(p,g,path.join(d,b));return}if(p.method==="POST"&&m==="/api/shutdown"){dn(p,g,u);return}R(g,404,{error:"Not found"});});function f(p){let g=m=>{m.code==="EADDRINUSE"&&i<Ya?(i++,f(p+1)):n(m);};u.once("error",g),u.listen(p,"127.0.0.1",()=>{u.removeListener("error",g);let m=u.address();if(!m||typeof m=="string"){n(new Error("Failed to get server address"));return}l(),r({port:m.port,dispose:()=>new Promise(h=>{clearTimeout(o),u.close(()=>h());})});});}f(s);})}async function cn(t){let e=await me(t);return {port:e.port,dispose:e.dispose}}function ei(t,e,r){let n=JSON.stringify(t),s=r?JSON.stringify(r):null;return jr(n,e,s)}async function Mt(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,o,i=e.htmlReportPath,d=path.dirname(i);fs$1.mkdirSync(d,{recursive:!0});let l="",c="[]",u=null;if(a){l=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 p=path.dirname(e.outputPath),g=path.join(p,".testrelic-report");try{let m=path.join(g,"index-compact.json"),h=path.join(g,"index.json");fs$1.existsSync(m)?c=fs$1.readFileSync(m,"utf-8"):fs$1.existsSync(h)&&(c=fs$1.readFileSync(h,"utf-8"));}catch{}u=r?JSON.stringify(r):null,o=Ct(l,c,null,u);}else o=ei(t,null,r);let f=i+".tmp";if(fs$1.writeFileSync(f,o,"utf-8"),fs$1.renameSync(f,i),a){if(t.ci===null){let p=path.dirname(e.outputPath),g=path.join(p,".testrelic-report"),m=path.resolve(i);try{if(await ri(),n=await ni(g),!n){s=await me(g,{htmlPath:m}),n=s.port;let h=setInterval(()=>{},6e4),v=()=>{clearInterval(h),s?.dispose();};process.on("SIGINT",v),process.on("SIGTERM",v),setTimeout(v,1800*1e3).unref();}if(n){process.stderr.write(`
4252
4252
  Report server: http://127.0.0.1:${n}
4253
4253
  `);try{let h=Ct(l,c,n,u),v=i+".tmp";fs$1.writeFileSync(v,h,"utf-8"),fs$1.renameSync(v,i);}catch{}}}catch{}}}else if(e.openReport&&t.ci===null&&e.includeArtifacts){let p=path.dirname(e.outputPath),g=path.join(p,"artifacts");if(fs$1.existsSync(g))try{let m=await cn(g);n=m.port,process.on("exit",()=>{m.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(a&&n)Tt(`http://127.0.0.1:${n}`);else {let p=path.resolve(i);Tt(p);}}catch(n){process.stderr.write(`[testrelic] Failed to write HTML report: ${n instanceof Error?n.message:String(n)}
4254
- `);}}var Ie=9323,hn=10;async function ri(){for(let t=Ie;t<Ie+hn;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 ni(){for(let t=Ie;t<Ie+hn;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 si(t){let r=[path.join(__dirname,"cli.cjs"),path.join(__dirname,"cli.js"),path.join(__dirname,"..","dist","cli.cjs"),path.join(__dirname,"..","dist","cli.js")].find(n=>fs$1.existsSync(n));if(!r){let n=await me(t);return process.on("exit",()=>{n?.dispose();}),n.port}return new Promise(n=>{let s=child_process.spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),a="",o=false,i=setTimeout(()=>{o||(o=true,s.stderr?.removeAllListeners(),ri().then(n));},5e3);s.stderr?.on("data",d=>{a+=d.toString();let l=a.match(/127\.0\.0\.1:(\d+)/);l&&!o&&(o=true,clearTimeout(i),s.stderr?.removeAllListeners(),s.unref(),n(Number(l[1])));}),s.on("error",()=>{o||(o=true,clearTimeout(i),n(null));}),s.on("exit",()=>{o||(o=true,clearTimeout(i),n(null));}),s.unref();})}var mn=Buffer.from([137,80,78,71,13,10,26,10]),ai=16,ii=20,Me=24;function vn(t){if(t.length<Me||!t.subarray(0,mn.length).equals(mn))return null;let e=t.readUInt32BE(ai),r=t.readUInt32BE(ii);return e===0||r===0?null:{width:e,height:r}}var oi=/(\d+) pixels \(ratio [\d.]+ of all image pixels\) are different/,yn=/Expected an image (\d+)px by (\d+)px, received (\d+)px by (\d+)px/;function Ee(t){return t?yn.test(t):false}var li=/^\s*Snapshot:\s*(.+?)\s*$/m;function bn(t){if(!t)return {};let e={},r=oi.exec(t);if(r){let a=Number.parseInt(r[1],10);Number.isFinite(a)&&(e.diffPixels=a);}let n=yn.exec(t);if(n){let[,a,o,i,d]=n,l=[a,o,i,d].map(c=>Number.parseInt(c,10));l.every(c=>Number.isFinite(c))&&(e.expectedWidth=l[0],e.expectedHeight=l[1],e.actualWidth=l[2],e.actualHeight=l[3]);}let s=li.exec(t);return s&&(e.snapshotName=s[1]),e}function xn(t,e){if(t===void 0||!e)return;let r=e.width*e.height;if(!(r<=0))return t/r}var gi=20,Et=0,Pt=[];async function ve(t,e){Et>=gi&&await new Promise(r=>Pt.push(r)),Et++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{Et--,Pt.length>0&&Pt.shift()();}}var W=[];async function kn(){W.length!==0&&(await Promise.allSettled(W),W.length=0);}function Cn(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(!fs$1.existsSync(path.join(t,n)))return n;let s=1;for(;fs$1.existsSync(path.join(t,`${n}-${s}`));)s++;return `${n}-${s}`}function Lt(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"}var hi=8;function Tn(t,e,r){let n=Lt(t),s=r?Lt(r).substring(0,hi):"";return s&&(n+=`--${s}`),e>0&&(n+=`--retry-${e}`),n}function Sn(t,e,r,n,s,a){let o=t.find(g=>g.name==="screenshot"&&g.path),i=t.find(g=>g.name==="video"&&g.path),d=t.find(g=>g.name==="trace"&&g.path);if(!o&&!i&&!d)return null;let l=Tn(e,r,a),c=s?["artifacts",s,l]:["artifacts",l],u=path.join(n,...c),f=c,p={};try{fs$1.mkdirSync(u,{recursive:!0});}catch{return null}if(o?.path&&fs$1.existsSync(o.path)){let m=`screenshot${path.extname(o.path)||".png"}`,h=path.join(u,m);W.push(ve(o.path,h).then(()=>{})),p.screenshot=`${f.join("/")}/${m}`;}if(i?.path&&fs$1.existsSync(i.path)){let m=`video${path.extname(i.path)||".webm"}`,h=path.join(u,m);W.push(ve(i.path,h).then(()=>{})),p.video=`${f.join("/")}/${m}`;}if(d?.path&&fs$1.existsSync(d.path)){let m=`trace${path.extname(d.path)||".zip"}`,h=path.join(u,m);W.push(ve(d.path,h).then(()=>{})),p.trace=`${f.join("/")}/${m}`;}return !p.screenshot&&!p.video&&!p.trace?null:p}var Nt="visual",mi=6;function vi(t){let e=crypto.createHash("sha256").update(t).digest("hex").substring(0,mi);return `${Lt(t)}--${e}`}function wn(t){let e=null;try{e=fs$1.openSync(t,"r");let r=Buffer.alloc(Me),n=fs$1.readSync(e,r,0,Me,0);return vn(r.subarray(0,n))}catch{return null}finally{if(e!==null)try{fs$1.closeSync(e);}catch{}}}var yi=[{key:"expectedPath",dest:"baseline",field:"baseline"},{key:"actualPath",dest:"actual",field:"actual"},{key:"diffPath",dest:"diff",field:"diff"},{key:"previousPath",dest:"previous",field:"previous"}],bi=[{key:"baselineDomPath",dest:"baseline.dom.json",field:"baselineDom"},{key:"actualDomPath",dest:"actual.dom.json",field:"actualDom"}];function xi(t,e,r){let n=vi(t.name),s=path.join(e,n);try{fs$1.mkdirSync(s,{recursive:!0});}catch{return null}let a={},o=false;for(let c of yi){let u=t[c.key];if(!u||!fs$1.existsSync(u))continue;let f=path.extname(u)||".png",p=`${c.dest}${f}`;W.push(ve(u,path.join(s,p)).then(()=>{})),a[c.field]=`${r}/${Nt}/${n}/${p}`,o=true;}let i=t.dom;if(i)for(let c of bi){let u=i[c.key];!u||!fs$1.existsSync(u)||(W.push(ve(u,path.join(s,c.dest)).then(()=>{})),a[c.field]=`${r}/${Nt}/${n}/${c.dest}`);}if(!o)return null;let d=t.expectedPath?wn(t.expectedPath):t.actualPath?wn(t.actualPath):null,l=xn(t.diffPixels,d);return {name:t.name,status:t.status,source:t.source,...a,...d?{width:d.width,height:d.height}:{},...t.actualWidth!==void 0?{actualWidth:t.actualWidth}:{},...t.actualHeight!==void 0?{actualHeight:t.actualHeight}:{},...t.diffPixels!==void 0?{diffPixels:t.diffPixels}:{},...l!==void 0?{diffPixelRatio:l}:{},...i?{domChanges:i.changes,domChangeCount:i.total,domRootCauses:i.rootCauses,domTruncated:i.truncated,domCaptureBox:i.captureBox}:{}}}function Rn(t,e,r,n,s,a){if(t.length===0)return null;let o=Tn(e,r,a),i=s?["artifacts",s,o]:["artifacts",o],d=path.join(n,...i,Nt),l=i.join("/");try{fs$1.mkdirSync(d,{recursive:!0});}catch{return null}let c=[];for(let u of t){let f=xi(u,d,l);f&&c.push(f);}return c.length>0?c:null}function An(t){let{styleProps:e,defaults:r,inherited:n,maxNodes:s,maxText:a,maskBoxes:o,viewportBox:i,fullPage:d}=t,l={};for(let T=0;T<n.length;T++)l[n[T]]=true;let c=window.scrollX||window.pageXOffset||0,u=window.scrollY||window.pageYOffset||0,f=[],p=0,g=[];for(let T=0;T<o.length;T++){let w=o[T];g.push([w[0]+c,w[1]+u,w[2],w[3]]);}function m(T,w,S,x){for(let C=0;C<g.length;C++){let _=g[C];if(T<_[0]+_[2]&&T+S>_[0]&&w<_[1]+_[3]&&w+x>_[1])return true}return false}function h(T){let w=T.parentElement;if(!w)return 0;let S=w.children,x=0;for(let C=0;C<S.length;C++){let _=S[C];if(_===T)break;_.tagName===T.tagName&&x++;}return x}function v(T){let w="",S=T.childNodes;for(let x=0;x<S.length;x++){let C=S[x];C.nodeType===3&&(w+=C.nodeValue??"");}return w=w.replace(/\s+/g," ").trim(),w.length>a?w.slice(0,a):w}function y(T,w){let S;for(let x=0;x<e.length;x++){let C=e[x],_=T.getPropertyValue(C);if(_){if(l[C]){if(w&&w.getPropertyValue(C)===_)continue}else if(r[C]===_)continue;S||(S={}),S[C]=_;}}return S}let b=[{el:document.body,parentPath:"",parentComputed:null}];for(;b.length>0;){let T=b.pop(),w=T.el,S=window.getComputedStyle(w);if(S.display==="none")continue;let x=w.tagName.toLowerCase(),C=w.id?"#"+w.id:T.parentPath?T.parentPath+">"+x+"["+h(w)+"]":x,_=w.children;for(let P=_.length-1;P>=0;P--)b.push({el:_[P],parentPath:C,parentComputed:S});if(S.visibility==="hidden")continue;let L=w.getBoundingClientRect();if(L.width<=0||L.height<=0)continue;if(f.length>=s){p++;continue}let z=Math.round(L.left+c),ce=Math.round(L.top+u),ue=Math.round(L.width),pe=Math.round(L.height),I={p:C,t:x,r:[z,ce,ue,pe]};w.id&&(I.i=w.id);let M=w.getAttribute("class");M&&(I.c=M.replace(/\s+/g," ").trim());let N=v(w);N&&(I.x=N);let j=y(S,T.parentComputed);j&&(I.s=j),m(z,ce,ue,pe)&&(I.m=1),f.push(I);}let k=Math.max(document.documentElement.scrollWidth,window.innerWidth),A=Math.max(document.documentElement.scrollHeight,window.innerHeight),E;return i?E=[Math.round(i[0]+c),Math.round(i[1]+u),Math.round(i[2]),Math.round(i[3])]:d?E=[0,0,k,A]:E=[Math.round(c),Math.round(u),window.innerWidth,window.innerHeight],{version:"1.0",url:location.href,viewport:{width:window.innerWidth,height:window.innerHeight},content:{width:k,height:A},captureBox:E,nodes:f,truncatedNodes:p}}var Ri=["display","position","color","background-color","background-image","border-top-width","border-right-width","border-bottom-width","border-left-width","border-color","border-style","border-radius","box-shadow","opacity","transform","margin-top","margin-right","margin-bottom","margin-left","padding-top","padding-right","padding-bottom","padding-left","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-decoration-line","text-transform","flex-direction","justify-content","align-items","gap","z-index","overflow"],Ai={position:"static","background-color":"rgba(0, 0, 0, 0)","background-image":"none","border-top-width":"0px","border-right-width":"0px","border-bottom-width":"0px","border-left-width":"0px","border-style":"none","border-radius":"0px","box-shadow":"none",opacity:"1",transform:"none","margin-top":"0px","margin-right":"0px","margin-bottom":"0px","margin-left":"0px","padding-top":"0px","padding-right":"0px","padding-bottom":"0px","padding-left":"0px","text-decoration-line":"none","flex-direction":"row","justify-content":"normal","align-items":"normal",gap:"normal","z-index":"auto",overflow:"visible"},_i=["color","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-transform"],Ii=1024*1024,Mi=1500,Ei=200;async function Pi(t){let e=[];for(let r of t)try{let n=await r.boundingBox();n&&e.push([n.x,n.y,n.width,n.height]);}catch{}return e}async function _n(t){let e=t.config??{};try{let r=t.maskLocators?.length?await Pi(t.maskLocators):[],n=null;if(t.bounded){let a=await t.bounded.boundingBox();a&&(n=[a.x,a.y,a.width,a.height]);}let s={styleProps:Ri,defaults:Ai,inherited:_i,maxNodes:e.maxNodes??Mi,maxText:e.maxText??Ei,maskBoxes:r,viewportBox:n,fullPage:t.fullPage===!0};return await t.target.evaluate(An,s)}catch{return null}}function In(t,e=Ii){let r=JSON.stringify(t);if(Buffer.byteLength(r,"utf-8")<=e)return {json:r,truncatedBytes:false};let n=t.nodes.slice(),s=0;for(;n.length>0&&Buffer.byteLength(r,"utf-8")>e;){let a=Math.max(1,Math.floor(n.length*.1));n.splice(-a,a),s+=a,r=JSON.stringify({...t,nodes:n,truncatedNodes:t.truncatedNodes+s});}return {json:r,truncatedBytes:true}}function Mn(t){return t.replace(/\.[A-Za-z0-9]+$/,"")+".dom.json"}function En(t){try{if(!fs$1.existsSync(t))return null;let e=JSON.parse(fs$1.readFileSync(t,"utf-8"));return Li(e)?e:null}catch{return null}}function Pn(t,e){try{return fs$1.mkdirSync(path.dirname(t),{recursive:!0}),fs$1.writeFileSync(t,e,"utf-8"),!0}catch{return false}}function Li(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.version=="string"&&Array.isArray(e.nodes)&&Array.isArray(e.captureBox)&&e.captureBox.length===4}var Ni=new Set(["moved","resized"]);function Le(t){return t.some(e=>!Ni.has(e))}function Ft(t){let e=t.t;if(t.i&&(e+="#"+t.i),t.c){let r=t.c.split(" ").filter(Boolean).slice(0,3);r.length>0&&(e+="."+r.join("."));}return e}function Di(t,e){let r=[],n=Math.abs(t.r[0]-e.r[0]),s=Math.abs(t.r[1]-e.r[1]),a=Math.abs(t.r[2]-e.r[2]),o=Math.abs(t.r[3]-e.r[3]);return (n>1||s>1)&&r.push("moved"),(a>1||o>1)&&r.push("resized"),r}function Fi(t,e){let r=t.s??{},n=e.s??{},s=new Set([...Object.keys(r),...Object.keys(n)]),a=[];for(let o of s){let i=r[o],d=n[o];i!==d&&a.push({prop:o,from:i??"(initial)",to:d??"(initial)"});}return a.sort((o,i)=>o.prop.localeCompare(i.prop)),a}function Ln(t){return t.i?"i:"+t.t+"#"+t.i:t.c?"c:"+t.t+"."+t.c:null}function Bi(t,e){let r=new Map;for(let u of t)r.set(u.p,u);let n=[],s=[],a=new Set;for(let u of e){let f=r.get(u.p);if(f&&f.t!==u.t){s.push(u);continue}f&&!a.has(f)?(a.add(f),n.push({before:f,after:u})):s.push(u);}let o=t.filter(u=>!a.has(u)),i=new Map;for(let u of o){let f=Ln(u);if(!f)continue;let p=i.get(f);p?p.push(u):i.set(f,[u]);}let d=[],l=new Set;for(let u of s){let f=Ln(u),g=(f?i.get(f):void 0)?.find(m=>!l.has(m));g?(l.add(g),n.push({before:g,after:u})):d.push(u);}let c=o.filter(u=>!l.has(u));return {pairs:n,removed:c,added:d}}function Oi(t,e){let r=[];return (t.i??"")!==(e.i??"")&&r.push({prop:"id",from:t.i??"(none)",to:e.i??"(none)"}),(t.c??"")!==(e.c??"")&&r.push({prop:"class",from:t.c??"(none)",to:e.c??"(none)"}),r}function Bt(t,e){let r=(e[2]??0)*(e[3]??0);return r<=0?0:Math.min(1,t.r[2]*t.r[3]/r)}function Nn(t,e,r={}){let n=r.maxChanges??50,s=r.includeText!==false,a=r.includeStyles!==false,o=t.nodes.filter(g=>g.m!==1),i=e.nodes.filter(g=>g.m!==1),{pairs:d,removed:l,added:c}=Bi(o,i),u=[];for(let{before:g,after:m}of d){let h=Di(g,m),v=a?Fi(g,m):[];v.length>0&&h.push("restyled");let y=Oi(g,m);y.length>0&&h.push("attrs");let b=s&&(g.x??"")!==(m.x??"");if(b&&h.push("text"),h.length===0)continue;let k=Bt(m,e.captureBox);u.push({score:k,change:{path:m.p,label:Ft(m),kinds:h,rect:m.r,baselineRect:g.r,areaPct:k,...y.length>0?{attrs:y}:{},...v.length>0?{styles:v}:{},...b?{text:{from:g.x??"",to:m.x??""}}:{}}});}for(let g of c){let m=Bt(g,e.captureBox);u.push({score:m,change:{path:g.p,label:Ft(g),kinds:["added"],rect:g.r,areaPct:m}});}for(let g of l){let m=Bt(g,t.captureBox);u.push({score:m,change:{path:g.p,label:Ft(g),kinds:["removed"],baselineRect:g.r,areaPct:m}});}let f=u.filter(g=>Le(g.change.kinds)).length;return u.sort((g,m)=>{if(f>0){let h=Le(g.change.kinds)?1:0,v=Le(m.change.kinds)?1:0;if(h!==v)return v-h}return m.score-g.score}),{changes:u.slice(0,n).map((g,m)=>({rank:m+1,...g.change,...f>0&&!Le(g.change.kinds)?{consequence:true}:{}})),total:u.length,rootCauses:f}}var Dn="__testrelic_snapshot_path_probe__.png",Fn=Symbol.for("testrelic.snapshotPathWarned");function qi(){let t=globalThis,e=t[Fn];return e||(e={warned:false},t[Fn]=e),e}function Ne(t){try{let e=t.snapshotPath(Dn,{kind:"screenshot"});return typeof e=="string"&&e.endsWith(Dn)}catch{return false}}function De(t){let e=qi();e.warned||(e.warned=true,process.stderr.write(`[testrelic] ${t} needs Playwright >= 1.51 for testInfo.snapshotPath(name, { kind }); this project's Playwright resolves that call the older way. Everything else in the reporter is unaffected \u2014 upgrade Playwright to enable it.
4255
- `));}var Ot="testrelic-visual-dom",Vi=new Set(["toHaveScreenshot","toMatchVisualBaseline"]);function Bn(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.boundingBox=="function"&&typeof e.page=="function"}function $i(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.evaluate=="function"&&typeof e.screenshot=="function"}function Wi(t){let e=t[0];if(typeof e=="string")return e;if(Array.isArray(e))return e.join("/");if(typeof e=="object"&&e!==null){let r=e.name;if(typeof r=="string")return r}return null}function Gi(t){for(let e of t)if(typeof e=="object"&&e!==null&&!Array.isArray(e))return e;return {}}function Ki(t){let e=t.mask;return Array.isArray(e)?e.filter(r=>typeof r=="object"&&r!==null&&typeof r.boundingBox=="function"):[]}function Ji(t){return /\.(png|jpg|jpeg)$/i.test(t)?t:`${t}.png`}var Yi=/^(.+)-(expected|actual|diff|previous)\.[A-Za-z0-9]+$/;function Xi(t,e,r){let n=t.attachments;for(let s=e;s<n.length;s++){let a=Yi.exec(n[s]?.name??"");if(a)return a[1]}return r}async function Zi(t){let e=Gi(t.args),r=Bn(t.received)?t.received:null,n=r?r.page():t.received;return _n({target:n,bounded:r,maskLocators:Ki(e),fullPage:e.fullPage===true})}function Qi(t){let e=t.config?.updateSnapshots;return e==="all"||e==="changed"}async function eo(t,e){let r=Wi(t.args);if(!r)return;if(!Ne(t.testInfo)){De("DOM comparison");return}let n=t.testInfo.snapshotPath(Ji(r),{kind:"screenshot"}),s=Mn(n),a=Xi(t.testInfo,t.attachedBefore,path.basename(n,path.extname(n))),o=In(e),d=Qi(t.testInfo)?null:En(s);if(!d){Pn(s,o.json);return}let{changes:l,total:c,rootCauses:u}=Nn(d,e),f;try{f=t.testInfo.outputPath(`${a}.actual.dom.json`),fs$1.writeFileSync(f,o.json,"utf-8");}catch{f=void 0;}let p={stem:a,changes:l,total:c,rootCauses:u,truncated:o.truncatedBytes||e.truncatedNodes>0,captureBox:e.captureBox,...fs$1.existsSync(s)?{baselineDomPath:s}:{},...f?{actualDomPath:f}:{}};await t.testInfo.attach(Ot,{body:Buffer.from(JSON.stringify([p])),contentType:"application/json"});}function On(t,e){let r=function(o,...i){let d=t(o,...i);return !(Bn(o)||$i(o))||typeof d!="object"||d===null?d:new Proxy(d,{get(c,u,f){let p=Reflect.get(c,u,f);if(typeof u!="string"||!Vi.has(u)||typeof p!="function")return p;let g=p;return async function(...h){let v=e(),y=null,b=v?.attachments.length??0;if(v)try{y=await Zi({received:o,args:h,testInfo:v,attachedBefore:b});}catch{}try{return await g.apply(c,h)}finally{if(v&&y)try{await eo({received:o,args:h,testInfo:v,attachedBefore:b},y);}catch{}}}}})},n=t,s=r;for(let a of Object.keys(n))s[a]=n[a];return r}var qt="testrelic-visual",to=/^(.+)-(expected|actual|diff|previous)(\.[A-Za-z0-9]+)$/;function ro(t){let e=new Map;for(let r of t)if(!(r.name!==qt||!r.body))try{let n=JSON.parse(r.body.toString("utf-8"));if(!Array.isArray(n))continue;for(let s of n){let a=so(s);a&&e.set(a.stem,a);}}catch{}return e}var no=["passed","failed","new","updated"];function so(t){if(typeof t!="object"||t===null)return null;let e=t;return typeof e.stem!="string"||!e.stem||typeof e.name!="string"||!e.name||typeof e.status!="string"||!no.includes(e.status)?null:{stem:e.stem,name:e.name,status:e.status}}function ao(t){let e=new Map;for(let r of t)if(!(r.name!==Ot||!r.body))try{let n=JSON.parse(r.body.toString("utf-8"));if(!Array.isArray(n))continue;for(let s of n){if(typeof s!="object"||s===null)continue;let a=s;typeof a.stem!="string"||!Array.isArray(a.changes)||e.set(a.stem,s);}}catch{}return e}function io(t){let e=new Map;for(let r of t){if(!r.path)continue;let n=to.exec(r.name);if(!n)continue;let[,s,a]=n,o=e.get(s)??{};o[a]=r.path,e.set(s,o);}return e}function oo(t){return !!(t.actual&&(t.expected||t.diff))}function lo(t,e,r){return t.diff||Ee(r)?"failed":e?"updated":"new"}function co(t,e){if(t.length===0)return null;if(t.length===1)return t[0];if(!e)return null;let r=e.replace(/\.[A-Za-z0-9]+$/,""),n=t.filter(s=>s===r||s.endsWith(`/${r}`));return n.length===1?n[0]:null}function Hn(t,e={}){if(t.length===0)return [];let r=ro(t),n=ao(t),s=io(t);if(s.size===0)return [];let a=e.updatingSnapshots===true,o=[];for(let[i,d]of s){let l=r.get(i);!l&&!oo(d)||o.push({name:l?.name??i,status:l?.status??lo(d,a,e.failureMessage),source:l?"toMatchVisualBaseline":"toHaveScreenshot",...d.expected?{expectedPath:d.expected}:{},...d.actual?{actualPath:d.actual}:{},...d.diff?{diffPath:d.diff}:{},...d.previous?{previousPath:d.previous}:{},...n.has(i)?{dom:n.get(i)}:{}});}return uo(o,s,e.failureMessage)}function uo(t,e,r){let n=bn(r);if(n.diffPixels===void 0&&n.actualWidth===void 0)return [...t];let s=t.filter(o=>o.status==="failed").map(o=>qn(o,e)),a=co(s,n.snapshotName);return a===null?[...t]:t.map(o=>qn(o,e)===a?{...o,...n.diffPixels!==void 0?{diffPixels:n.diffPixels}:{},...n.actualWidth!==void 0?{actualWidth:n.actualWidth}:{},...n.actualHeight!==void 0?{actualHeight:n.actualHeight}:{}}:o)}function qn(t,e){if(e.has(t.name))return t.name;for(let[r,n]of e)if(n.actual===t.actualPath&&n.expected===t.expectedPath&&n.diff===t.diffPath)return r;return t.name}var po=new RegExp("[\x1B\x9B][[\\]()#;?]*(?:\\d{1,4}(?:;\\d{0,4})*)?[0-9A-PR-TZcf-nqry=><]","g");function se(t){return !t||t.indexOf("\x1B")===-1&&t.indexOf("\x9B")===-1?t:t.replace(po,"")}function Un(t){return t==null?null:se(t)}var fo=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,go="1.0",Ht="visual";function $n(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":e===".zip"&&path.basename(t,e)==="trace"?"trace":"other"}function ho(t){if(t.endsWith(".dom.json"))return "dom";let e=path.basename(t,path.extname(t));return e==="baseline"?"baseline":e==="diff"?"diff":$n(t)}function mo(t,e,r){let n=[];try{for(let s of fs$1.readdirSync(t,{withFileTypes:!0})){if(!s.isFile())continue;let a=fs$1.statSync(path.join(t,s.name));n.push({name:`${Ht}/${r}/${s.name}`,type:ho(s.name),relativePath:`${e}/${Ht}/${r}/${s.name}`,sizeBytes:a.size});}}catch{}return n}function Wn(t,e,r){let n=[],s=`artifacts/${e}/${r}`;try{let a=fs$1.readdirSync(t,{withFileTypes:!0});for(let o of a){if(o.isDirectory()&&o.name===Ht){let l=path.join(t,o.name);for(let c of fs$1.readdirSync(l,{withFileTypes:!0}))c.isDirectory()&&n.push(...mo(path.join(l,c.name),s,c.name));continue}if(!o.isFile())continue;let i=path.join(t,o.name),d=fs$1.statSync(i);n.push({name:o.name,type:$n(o.name),relativePath:`${s}/${o.name}`,sizeBytes:d.size});}}catch{}return {testName:r,files:n}}function vo(t,e){let r=path.join(t,e),n=[],s=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let d=Wn(path.join(r,i.name),e,i.name);n.push(d);for(let l of d.files)s+=l.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((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:s,testCount:n.length,tests:n,isCurrentRun:false}}function Gn(t,e){let r=path.join(t,"artifacts"),n=[],s=[],a=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(fo.test(d.name)){let l=vo(r,d.name);n.push({...l,isCurrentRun:d.name===e});}else {let l=Wn(path.join(r,d.name),d.name,d.name);s.push(l);for(let c of l.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 o=n.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:go,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:n,serverPort:null}}var Co=256;function To(t){let e=path.resolve(t);for(let r=0;r<Co;r++){if(fs$1.existsSync(path.join(e,".git")))return e;let n=path.dirname(e);if(n===e)return null;e=n;}return null}function Yn(t){try{let e=To(t);if(!e)return;let r=path.join(e,".gitignore"),n=path.relative(e,t).replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
4254
+ `);}}var Ie=9323,hn=10;async function ti(){for(let t=Ie;t<Ie+hn;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 ri(){for(let t=Ie;t<Ie+hn;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 ni(t){let r=[path.join(__dirname,"cli.cjs"),path.join(__dirname,"cli.js"),path.join(__dirname,"..","dist","cli.cjs"),path.join(__dirname,"..","dist","cli.js")].find(n=>fs$1.existsSync(n));if(!r){let n=await me(t);return process.on("exit",()=>{n?.dispose();}),n.port}return new Promise(n=>{let s=child_process.spawn(process.execPath,[r,"serve",t],{detached:true,stdio:["ignore","ignore","pipe"],env:{...process.env}}),a="",o=false,i=setTimeout(()=>{o||(o=true,s.stderr?.removeAllListeners(),ti().then(n));},5e3);s.stderr?.on("data",d=>{a+=d.toString();let l=a.match(/127\.0\.0\.1:(\d+)/);l&&!o&&(o=true,clearTimeout(i),s.stderr?.removeAllListeners(),s.unref(),n(Number(l[1])));}),s.on("error",()=>{o||(o=true,clearTimeout(i),n(null));}),s.on("exit",()=>{o||(o=true,clearTimeout(i),n(null));}),s.unref();})}var mn=Buffer.from([137,80,78,71,13,10,26,10]),si=16,ai=20,Me=24;function vn(t){if(t.length<Me||!t.subarray(0,mn.length).equals(mn))return null;let e=t.readUInt32BE(si),r=t.readUInt32BE(ai);return e===0||r===0?null:{width:e,height:r}}var ii=/(\d+) pixels \(ratio [\d.]+ of all image pixels\) are different/,yn=/Expected an image (\d+)px by (\d+)px, received (\d+)px by (\d+)px/;function Ee(t){return t?yn.test(t):false}var oi=/^\s*Snapshot:\s*(.+?)\s*$/m;function bn(t){if(!t)return {};let e={},r=ii.exec(t);if(r){let a=Number.parseInt(r[1],10);Number.isFinite(a)&&(e.diffPixels=a);}let n=yn.exec(t);if(n){let[,a,o,i,d]=n,l=[a,o,i,d].map(c=>Number.parseInt(c,10));l.every(c=>Number.isFinite(c))&&(e.expectedWidth=l[0],e.expectedHeight=l[1],e.actualWidth=l[2],e.actualHeight=l[3]);}let s=oi.exec(t);return s&&(e.snapshotName=s[1]),e}function xn(t,e){if(t===void 0||!e)return;let r=e.width*e.height;if(!(r<=0))return t/r}var fi=20,Et=0,Pt=[];async function ve(t,e){Et>=fi&&await new Promise(r=>Pt.push(r)),Et++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{Et--,Pt.length>0&&Pt.shift()();}}var W=[];async function kn(){W.length!==0&&(await Promise.allSettled(W),W.length=0);}function Cn(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(!fs$1.existsSync(path.join(t,n)))return n;let s=1;for(;fs$1.existsSync(path.join(t,`${n}-${s}`));)s++;return `${n}-${s}`}function Lt(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"}var gi=8;function Tn(t,e,r){let n=Lt(t),s=r?Lt(r).substring(0,gi):"";return s&&(n+=`--${s}`),e>0&&(n+=`--retry-${e}`),n}function Sn(t,e,r,n,s,a){let o=t.find(g=>g.name==="screenshot"&&g.path),i=t.find(g=>g.name==="video"&&g.path),d=t.find(g=>g.name==="trace"&&g.path);if(!o&&!i&&!d)return null;let l=Tn(e,r,a),c=s?["artifacts",s,l]:["artifacts",l],u=path.join(n,...c),f=c,p={};try{fs$1.mkdirSync(u,{recursive:!0});}catch{return null}if(o?.path&&fs$1.existsSync(o.path)){let m=`screenshot${path.extname(o.path)||".png"}`,h=path.join(u,m);W.push(ve(o.path,h).then(()=>{})),p.screenshot=`${f.join("/")}/${m}`;}if(i?.path&&fs$1.existsSync(i.path)){let m=`video${path.extname(i.path)||".webm"}`,h=path.join(u,m);W.push(ve(i.path,h).then(()=>{})),p.video=`${f.join("/")}/${m}`;}if(d?.path&&fs$1.existsSync(d.path)){let m=`trace${path.extname(d.path)||".zip"}`,h=path.join(u,m);W.push(ve(d.path,h).then(()=>{})),p.trace=`${f.join("/")}/${m}`;}return !p.screenshot&&!p.video&&!p.trace?null:p}var Nt="visual",hi=6;function mi(t){let e=crypto.createHash("sha256").update(t).digest("hex").substring(0,hi);return `${Lt(t)}--${e}`}function wn(t){let e=null;try{e=fs$1.openSync(t,"r");let r=Buffer.alloc(Me),n=fs$1.readSync(e,r,0,Me,0);return vn(r.subarray(0,n))}catch{return null}finally{if(e!==null)try{fs$1.closeSync(e);}catch{}}}var vi=[{key:"expectedPath",dest:"baseline",field:"baseline"},{key:"actualPath",dest:"actual",field:"actual"},{key:"diffPath",dest:"diff",field:"diff"},{key:"previousPath",dest:"previous",field:"previous"}],yi=[{key:"baselineDomPath",dest:"baseline.dom.json",field:"baselineDom"},{key:"actualDomPath",dest:"actual.dom.json",field:"actualDom"}];function bi(t,e,r){let n=mi(t.name),s=path.join(e,n);try{fs$1.mkdirSync(s,{recursive:!0});}catch{return null}let a={},o=false;for(let c of vi){let u=t[c.key];if(!u||!fs$1.existsSync(u))continue;let f=path.extname(u)||".png",p=`${c.dest}${f}`;W.push(ve(u,path.join(s,p)).then(()=>{})),a[c.field]=`${r}/${Nt}/${n}/${p}`,o=true;}let i=t.dom;if(i)for(let c of yi){let u=i[c.key];!u||!fs$1.existsSync(u)||(W.push(ve(u,path.join(s,c.dest)).then(()=>{})),a[c.field]=`${r}/${Nt}/${n}/${c.dest}`);}if(!o)return null;let d=t.expectedPath?wn(t.expectedPath):t.actualPath?wn(t.actualPath):null,l=xn(t.diffPixels,d);return {name:t.name,status:t.status,source:t.source,...a,...d?{width:d.width,height:d.height}:{},...t.actualWidth!==void 0?{actualWidth:t.actualWidth}:{},...t.actualHeight!==void 0?{actualHeight:t.actualHeight}:{},...t.diffPixels!==void 0?{diffPixels:t.diffPixels}:{},...l!==void 0?{diffPixelRatio:l}:{},...i?{domChanges:i.changes,domChangeCount:i.total,domRootCauses:i.rootCauses,domTruncated:i.truncated,domCaptureBox:i.captureBox}:{}}}function Rn(t,e,r,n,s,a){if(t.length===0)return null;let o=Tn(e,r,a),i=s?["artifacts",s,o]:["artifacts",o],d=path.join(n,...i,Nt),l=i.join("/");try{fs$1.mkdirSync(d,{recursive:!0});}catch{return null}let c=[];for(let u of t){let f=bi(u,d,l);f&&c.push(f);}return c.length>0?c:null}function An(t){let{styleProps:e,defaults:r,inherited:n,maxNodes:s,maxText:a,maskBoxes:o,viewportBox:i,fullPage:d}=t,l={};for(let T=0;T<n.length;T++)l[n[T]]=true;let c=window.scrollX||window.pageXOffset||0,u=window.scrollY||window.pageYOffset||0,f=[],p=0,g=[];for(let T=0;T<o.length;T++){let x=o[T];g.push([x[0]+c,x[1]+u,x[2],x[3]]);}function m(T,x,S,w){for(let C=0;C<g.length;C++){let _=g[C];if(T<_[0]+_[2]&&T+S>_[0]&&x<_[1]+_[3]&&x+w>_[1])return true}return false}function h(T){let x=T.parentElement;if(!x)return 0;let S=x.children,w=0;for(let C=0;C<S.length;C++){let _=S[C];if(_===T)break;_.tagName===T.tagName&&w++;}return w}function v(T){let x="",S=T.childNodes;for(let w=0;w<S.length;w++){let C=S[w];C.nodeType===3&&(x+=C.nodeValue??"");}return x=x.replace(/\s+/g," ").trim(),x.length>a?x.slice(0,a):x}function y(T,x){let S;for(let w=0;w<e.length;w++){let C=e[w],_=T.getPropertyValue(C);if(_){if(l[C]){if(x&&x.getPropertyValue(C)===_)continue}else if(r[C]===_)continue;S||(S={}),S[C]=_;}}return S}let b=[{el:document.body,parentPath:"",parentComputed:null}];for(;b.length>0;){let T=b.pop(),x=T.el,S=window.getComputedStyle(x);if(S.display==="none")continue;let w=x.tagName.toLowerCase(),C=x.id?"#"+x.id:T.parentPath?T.parentPath+">"+w+"["+h(x)+"]":w,_=x.children;for(let P=_.length-1;P>=0;P--)b.push({el:_[P],parentPath:C,parentComputed:S});if(S.visibility==="hidden")continue;let L=x.getBoundingClientRect();if(L.width<=0||L.height<=0)continue;if(f.length>=s){p++;continue}let z=Math.round(L.left+c),ce=Math.round(L.top+u),ue=Math.round(L.width),pe=Math.round(L.height),I={p:C,t:w,r:[z,ce,ue,pe]};x.id&&(I.i=x.id);let M=x.getAttribute("class");M&&(I.c=M.replace(/\s+/g," ").trim());let N=v(x);N&&(I.x=N);let j=y(S,T.parentComputed);j&&(I.s=j),m(z,ce,ue,pe)&&(I.m=1),f.push(I);}let k=Math.max(document.documentElement.scrollWidth,window.innerWidth),A=Math.max(document.documentElement.scrollHeight,window.innerHeight),E;return i?E=[Math.round(i[0]+c),Math.round(i[1]+u),Math.round(i[2]),Math.round(i[3])]:d?E=[0,0,k,A]:E=[Math.round(c),Math.round(u),window.innerWidth,window.innerHeight],{version:"1.0",url:location.href,viewport:{width:window.innerWidth,height:window.innerHeight},content:{width:k,height:A},captureBox:E,nodes:f,truncatedNodes:p}}var Si=["display","position","color","background-color","background-image","border-top-width","border-right-width","border-bottom-width","border-left-width","border-color","border-style","border-radius","box-shadow","opacity","transform","margin-top","margin-right","margin-bottom","margin-left","padding-top","padding-right","padding-bottom","padding-left","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-decoration-line","text-transform","flex-direction","justify-content","align-items","gap","z-index","overflow"],Ri={position:"static","background-color":"rgba(0, 0, 0, 0)","background-image":"none","border-top-width":"0px","border-right-width":"0px","border-bottom-width":"0px","border-left-width":"0px","border-style":"none","border-radius":"0px","box-shadow":"none",opacity:"1",transform:"none","margin-top":"0px","margin-right":"0px","margin-bottom":"0px","margin-left":"0px","padding-top":"0px","padding-right":"0px","padding-bottom":"0px","padding-left":"0px","text-decoration-line":"none","flex-direction":"row","justify-content":"normal","align-items":"normal",gap:"normal","z-index":"auto",overflow:"visible"},Ai=["color","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-transform"],_i=1024*1024,Ii=1500,Mi=200;async function Ei(t){let e=[];for(let r of t)try{let n=await r.boundingBox();n&&e.push([n.x,n.y,n.width,n.height]);}catch{}return e}async function _n(t){let e=t.config??{};try{let r=t.maskLocators?.length?await Ei(t.maskLocators):[],n=null;if(t.bounded){let a=await t.bounded.boundingBox();a&&(n=[a.x,a.y,a.width,a.height]);}let s={styleProps:Si,defaults:Ri,inherited:Ai,maxNodes:e.maxNodes??Ii,maxText:e.maxText??Mi,maskBoxes:r,viewportBox:n,fullPage:t.fullPage===!0};return await t.target.evaluate(An,s)}catch{return null}}function In(t,e=_i){let r=JSON.stringify(t);if(Buffer.byteLength(r,"utf-8")<=e)return {json:r,truncatedBytes:false};let n=t.nodes.slice(),s=0;for(;n.length>0&&Buffer.byteLength(r,"utf-8")>e;){let a=Math.max(1,Math.floor(n.length*.1));n.splice(-a,a),s+=a,r=JSON.stringify({...t,nodes:n,truncatedNodes:t.truncatedNodes+s});}return {json:r,truncatedBytes:true}}function Mn(t){return t.replace(/\.[A-Za-z0-9]+$/,"")+".dom.json"}function En(t){try{if(!fs$1.existsSync(t))return null;let e=JSON.parse(fs$1.readFileSync(t,"utf-8"));return Pi(e)?e:null}catch{return null}}function Pn(t,e){try{return fs$1.mkdirSync(path.dirname(t),{recursive:!0}),fs$1.writeFileSync(t,e,"utf-8"),!0}catch{return false}}function Pi(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.version=="string"&&Array.isArray(e.nodes)&&Array.isArray(e.captureBox)&&e.captureBox.length===4}var Li=new Set(["moved","resized"]);function Le(t){return t.some(e=>!Li.has(e))}function Ft(t){let e=t.t;if(t.i&&(e+="#"+t.i),t.c){let r=t.c.split(" ").filter(Boolean).slice(0,3);r.length>0&&(e+="."+r.join("."));}return e}function Ni(t,e){let r=[],n=Math.abs(t.r[0]-e.r[0]),s=Math.abs(t.r[1]-e.r[1]),a=Math.abs(t.r[2]-e.r[2]),o=Math.abs(t.r[3]-e.r[3]);return (n>1||s>1)&&r.push("moved"),(a>1||o>1)&&r.push("resized"),r}function Di(t,e){let r=t.s??{},n=e.s??{},s=new Set([...Object.keys(r),...Object.keys(n)]),a=[];for(let o of s){let i=r[o],d=n[o];i!==d&&a.push({prop:o,from:i??"(initial)",to:d??"(initial)"});}return a.sort((o,i)=>o.prop.localeCompare(i.prop)),a}function Ln(t){return t.i?"i:"+t.t+"#"+t.i:t.c?"c:"+t.t+"."+t.c:null}function Fi(t,e){let r=new Map;for(let u of t)r.set(u.p,u);let n=[],s=[],a=new Set;for(let u of e){let f=r.get(u.p);if(f&&f.t!==u.t){s.push(u);continue}f&&!a.has(f)?(a.add(f),n.push({before:f,after:u})):s.push(u);}let o=t.filter(u=>!a.has(u)),i=new Map;for(let u of o){let f=Ln(u);if(!f)continue;let p=i.get(f);p?p.push(u):i.set(f,[u]);}let d=[],l=new Set;for(let u of s){let f=Ln(u),g=(f?i.get(f):void 0)?.find(m=>!l.has(m));g?(l.add(g),n.push({before:g,after:u})):d.push(u);}let c=o.filter(u=>!l.has(u));return {pairs:n,removed:c,added:d}}function Bi(t,e){let r=[];return (t.i??"")!==(e.i??"")&&r.push({prop:"id",from:t.i??"(none)",to:e.i??"(none)"}),(t.c??"")!==(e.c??"")&&r.push({prop:"class",from:t.c??"(none)",to:e.c??"(none)"}),r}function Bt(t,e){let r=(e[2]??0)*(e[3]??0);return r<=0?0:Math.min(1,t.r[2]*t.r[3]/r)}function Nn(t,e,r={}){let n=r.maxChanges??50,s=r.includeText!==false,a=r.includeStyles!==false,o=t.nodes.filter(g=>g.m!==1),i=e.nodes.filter(g=>g.m!==1),{pairs:d,removed:l,added:c}=Fi(o,i),u=[];for(let{before:g,after:m}of d){let h=Ni(g,m),v=a?Di(g,m):[];v.length>0&&h.push("restyled");let y=Bi(g,m);y.length>0&&h.push("attrs");let b=s&&(g.x??"")!==(m.x??"");if(b&&h.push("text"),h.length===0)continue;let k=Bt(m,e.captureBox);u.push({score:k,change:{path:m.p,label:Ft(m),kinds:h,rect:m.r,baselineRect:g.r,areaPct:k,...y.length>0?{attrs:y}:{},...v.length>0?{styles:v}:{},...b?{text:{from:g.x??"",to:m.x??""}}:{}}});}for(let g of c){let m=Bt(g,e.captureBox);u.push({score:m,change:{path:g.p,label:Ft(g),kinds:["added"],rect:g.r,areaPct:m}});}for(let g of l){let m=Bt(g,t.captureBox);u.push({score:m,change:{path:g.p,label:Ft(g),kinds:["removed"],baselineRect:g.r,areaPct:m}});}let f=u.filter(g=>Le(g.change.kinds)).length;return u.sort((g,m)=>{if(f>0){let h=Le(g.change.kinds)?1:0,v=Le(m.change.kinds)?1:0;if(h!==v)return v-h}return m.score-g.score}),{changes:u.slice(0,n).map((g,m)=>({rank:m+1,...g.change,...f>0&&!Le(g.change.kinds)?{consequence:true}:{}})),total:u.length,rootCauses:f}}var Oi="__testrelic_snapshot_path_probe__.png",Dn=Symbol.for("testrelic.snapshotPathWarned");function qi(){let t=globalThis,e=t[Dn];return e||(e={warned:false},t[Dn]=e),e}function Ne(t){try{let e=t.snapshotPath(Oi,{kind:"screenshot"});return typeof e=="string"&&!e.includes("[object Object]")}catch{return false}}function De(t){let e=qi();e.warned||(e.warned=true,process.stderr.write(`[testrelic] ${t} needs Playwright >= 1.51 for testInfo.snapshotPath(name, { kind }); this project's Playwright resolves that call the older way. Everything else in the reporter is unaffected \u2014 upgrade Playwright to enable it.
4255
+ `));}var Ot="testrelic-visual-dom",Vi=new Set(["toHaveScreenshot","toMatchVisualBaseline"]);function Fn(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.boundingBox=="function"&&typeof e.page=="function"}function $i(t){if(typeof t!="object"||t===null)return false;let e=t;return typeof e.evaluate=="function"&&typeof e.screenshot=="function"}function Wi(t){let e=t[0];if(typeof e=="string")return e;if(Array.isArray(e))return e.join("/");if(typeof e=="object"&&e!==null){let r=e.name;if(typeof r=="string")return r}return null}function Gi(t){for(let e of t)if(typeof e=="object"&&e!==null&&!Array.isArray(e))return e;return {}}function Ki(t){let e=t.mask;return Array.isArray(e)?e.filter(r=>typeof r=="object"&&r!==null&&typeof r.boundingBox=="function"):[]}function Ji(t){return /\.(png|jpg|jpeg)$/i.test(t)?t:`${t}.png`}var Yi=/^(.+)-(expected|actual|diff|previous)\.[A-Za-z0-9]+$/;function Xi(t,e,r){let n=t.attachments;for(let s=e;s<n.length;s++){let a=Yi.exec(n[s]?.name??"");if(a)return a[1]}return r}async function Zi(t){let e=Gi(t.args),r=Fn(t.received)?t.received:null,n=r?r.page():t.received;return _n({target:n,bounded:r,maskLocators:Ki(e),fullPage:e.fullPage===true})}function Qi(t){let e=t.config?.updateSnapshots;return e==="all"||e==="changed"}async function eo(t,e){let r=Wi(t.args);if(!r)return;if(!Ne(t.testInfo)){De("DOM comparison");return}let n=t.testInfo.snapshotPath(Ji(r),{kind:"screenshot"}),s=Mn(n),a=Xi(t.testInfo,t.attachedBefore,path.basename(n,path.extname(n))),o=In(e),d=Qi(t.testInfo)?null:En(s);if(!d){Pn(s,o.json);return}let{changes:l,total:c,rootCauses:u}=Nn(d,e),f;try{f=t.testInfo.outputPath(`${a}.actual.dom.json`),fs$1.writeFileSync(f,o.json,"utf-8");}catch{f=void 0;}let p={stem:a,changes:l,total:c,rootCauses:u,truncated:o.truncatedBytes||e.truncatedNodes>0,captureBox:e.captureBox,...fs$1.existsSync(s)?{baselineDomPath:s}:{},...f?{actualDomPath:f}:{}};await t.testInfo.attach(Ot,{body:Buffer.from(JSON.stringify([p])),contentType:"application/json"});}function Bn(t,e){let r=function(o,...i){let d=t(o,...i);return !(Fn(o)||$i(o))||typeof d!="object"||d===null?d:new Proxy(d,{get(c,u,f){let p=Reflect.get(c,u,f);if(typeof u!="string"||!Vi.has(u)||typeof p!="function")return p;let g=p;return async function(...h){let v=e(),y=null,b=v?.attachments.length??0;if(v)try{y=await Zi({received:o,args:h,testInfo:v,attachedBefore:b});}catch{}try{return await g.apply(c,h)}finally{if(v&&y)try{await eo({received:o,args:h,testInfo:v,attachedBefore:b},y);}catch{}}}}})},n=t,s=r;for(let a of Object.keys(n))s[a]=n[a];return r}var qt="testrelic-visual",to=/^(.+)-(expected|actual|diff|previous)(\.[A-Za-z0-9]+)$/;function ro(t){let e=new Map;for(let r of t)if(!(r.name!==qt||!r.body))try{let n=JSON.parse(r.body.toString("utf-8"));if(!Array.isArray(n))continue;for(let s of n){let a=so(s);a&&e.set(a.stem,a);}}catch{}return e}var no=["passed","failed","new","updated"];function so(t){if(typeof t!="object"||t===null)return null;let e=t;return typeof e.stem!="string"||!e.stem||typeof e.name!="string"||!e.name||typeof e.status!="string"||!no.includes(e.status)?null:{stem:e.stem,name:e.name,status:e.status}}function ao(t){let e=new Map;for(let r of t)if(!(r.name!==Ot||!r.body))try{let n=JSON.parse(r.body.toString("utf-8"));if(!Array.isArray(n))continue;for(let s of n){if(typeof s!="object"||s===null)continue;let a=s;typeof a.stem!="string"||!Array.isArray(a.changes)||e.set(a.stem,s);}}catch{}return e}function io(t){let e=new Map;for(let r of t){if(!r.path)continue;let n=to.exec(r.name);if(!n)continue;let[,s,a]=n,o=e.get(s)??{};o[a]=r.path,e.set(s,o);}return e}function oo(t){return !!(t.actual&&(t.expected||t.diff))}function lo(t,e,r){return t.diff||Ee(r)?"failed":e?"updated":"new"}function co(t,e){if(t.length===0)return null;if(t.length===1)return t[0];if(!e)return null;let r=e.replace(/\.[A-Za-z0-9]+$/,""),n=t.filter(s=>s===r||s.endsWith(`/${r}`));return n.length===1?n[0]:null}function qn(t,e={}){if(t.length===0)return [];let r=ro(t),n=ao(t),s=io(t);if(s.size===0)return [];let a=e.updatingSnapshots===true,o=[];for(let[i,d]of s){let l=r.get(i);!l&&!oo(d)||o.push({name:l?.name??i,status:l?.status??lo(d,a,e.failureMessage),source:l?"toMatchVisualBaseline":"toHaveScreenshot",...d.expected?{expectedPath:d.expected}:{},...d.actual?{actualPath:d.actual}:{},...d.diff?{diffPath:d.diff}:{},...d.previous?{previousPath:d.previous}:{},...n.has(i)?{dom:n.get(i)}:{}});}return uo(o,s,e.failureMessage)}function uo(t,e,r){let n=bn(r);if(n.diffPixels===void 0&&n.actualWidth===void 0)return [...t];let s=t.filter(o=>o.status==="failed").map(o=>On(o,e)),a=co(s,n.snapshotName);return a===null?[...t]:t.map(o=>On(o,e)===a?{...o,...n.diffPixels!==void 0?{diffPixels:n.diffPixels}:{},...n.actualWidth!==void 0?{actualWidth:n.actualWidth}:{},...n.actualHeight!==void 0?{actualHeight:n.actualHeight}:{}}:o)}function On(t,e){if(e.has(t.name))return t.name;for(let[r,n]of e)if(n.actual===t.actualPath&&n.expected===t.expectedPath&&n.diff===t.diffPath)return r;return t.name}var po=new RegExp("[\x1B\x9B][[\\]()#;?]*(?:\\d{1,4}(?:;\\d{0,4})*)?[0-9A-PR-TZcf-nqry=><]","g");function se(t){return !t||t.indexOf("\x1B")===-1&&t.indexOf("\x9B")===-1?t:t.replace(po,"")}function Un(t){return t==null?null:se(t)}var fo=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,go="1.0",Ut="visual";function Vn(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":e===".zip"&&path.basename(t,e)==="trace"?"trace":"other"}function ho(t){if(t.endsWith(".dom.json"))return "dom";let e=path.basename(t,path.extname(t));return e==="baseline"?"baseline":e==="diff"?"diff":Vn(t)}function mo(t,e,r){let n=[];try{for(let s of fs$1.readdirSync(t,{withFileTypes:!0})){if(!s.isFile())continue;let a=fs$1.statSync(path.join(t,s.name));n.push({name:`${Ut}/${r}/${s.name}`,type:ho(s.name),relativePath:`${e}/${Ut}/${r}/${s.name}`,sizeBytes:a.size});}}catch{}return n}function $n(t,e,r){let n=[],s=`artifacts/${e}/${r}`;try{let a=fs$1.readdirSync(t,{withFileTypes:!0});for(let o of a){if(o.isDirectory()&&o.name===Ut){let l=path.join(t,o.name);for(let c of fs$1.readdirSync(l,{withFileTypes:!0}))c.isDirectory()&&n.push(...mo(path.join(l,c.name),s,c.name));continue}if(!o.isFile())continue;let i=path.join(t,o.name),d=fs$1.statSync(i);n.push({name:o.name,type:Vn(o.name),relativePath:`${s}/${o.name}`,sizeBytes:d.size});}}catch{}return {testName:r,files:n}}function vo(t,e){let r=path.join(t,e),n=[],s=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let d=$n(path.join(r,i.name),e,i.name);n.push(d);for(let l of d.files)s+=l.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((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:s,testCount:n.length,tests:n,isCurrentRun:false}}function Wn(t,e){let r=path.join(t,"artifacts"),n=[],s=[],a=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(fo.test(d.name)){let l=vo(r,d.name);n.push({...l,isCurrentRun:d.name===e});}else {let l=$n(path.join(r,d.name),d.name,d.name);s.push(l);for(let c of l.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 o=n.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:go,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:n,serverPort:null}}var Co=256;function To(t){let e=path.resolve(t);for(let r=0;r<Co;r++){if(fs$1.existsSync(path.join(e,".git")))return e;let n=path.dirname(e);if(n===e)return null;e=n;}return null}function Jn(t){try{let e=To(t);if(!e)return;let r=path.join(e,".gitignore"),n=path.relative(e,t).replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
4256
4256
  `).map(d=>d.trim()).some(d=>d===s||d===n))return;let a=`
4257
4257
  # TestRelic test artifacts
4258
4258
  ${s}
4259
- `;fs$1.appendFileSync(r,a,"utf-8");}catch{}}var Xn=Symbol("testrelic.timeout"),Zn=3e4,Ut=12e4,zt=6e4,Qn=15e3;async function Q(t,e,r){let n,s=new Promise(a=>{n=setTimeout(()=>a(Xn),e),typeof n?.unref=="function"&&n.unref();});try{let a=await Promise.race([t(),s]);if(a===Xn){process.stderr.write(`[testrelic] ${r} timed out after ${Math.round(e/1e3)}s \u2014 continuing without it. Your tests are unaffected.
4259
+ `;fs$1.appendFileSync(r,a,"utf-8");}catch{}}var Yn=Symbol("testrelic.timeout"),Xn=3e4,Ht=12e4,zt=6e4,Zn=15e3;async function Q(t,e,r){let n,s=new Promise(a=>{n=setTimeout(()=>a(Yn),e),typeof n?.unref=="function"&&n.unref();});try{let a=await Promise.race([t(),s]);if(a===Yn){process.stderr.write(`[testrelic] ${r} timed out after ${Math.round(e/1e3)}s \u2014 continuing without it. Your tests are unaffected.
4260
4260
  `);return}return a}catch(a){process.stderr.write(`[testrelic] ${r} failed \u2014 continuing without it. Your tests are unaffected. (${a instanceof Error?a.message:String(a)})
4261
- `);return}finally{n&&clearTimeout(n);}}function rs(t,e){let r=[];for(let n of t){let s=So(n),a=Ro(n),o=Ao(n,s,a,e),i=_o(n,s,a);if(o.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(...o,...i);}return r.sort(Io),Mo(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 So(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 Ro(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 Ao(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 _o(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}:{}})),o=null;return s.responseStatusCode!==null&&s.responseStatusText!==null&&(o={statusCode:s.responseStatusCode,statusText:s.responseStatusText,headers:s.responseHeaders,body:ts(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:ts(s.requestBody)},response:o,...s.error?{error:s.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function Io(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],o=s[e.type];return a!==o?a-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?es(t.callId)-es(e.callId):0}function es(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Mo(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 o=r+1;o<t.length;o++)if(t[o]._testTitle===n._testTitle){a=new Date(t[o].timestamp).getTime();break}if(a!==null)n.durationOnUrl=Math.max(0,a-s);else {let o=e.find(i=>i.title===n._testTitle);if(o){let i=new Date(o.completedAt).getTime();n.durationOnUrl=Math.max(0,i-s);}}}}function ts(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function ee(t,e){let r=t.length,n=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,n)]}function jt(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function Eo(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 ns(t,e){let r=0,n=0,s=0,a=0,o=0;for(let x of t)switch(x.status){case "passed":r++;break;case "failed":n++;break;case "flaky":s++;break;case "skipped":a++;break;case "timedout":o++;break}let i=[];for(let x of t)x.apiCalls&&i.push(...x.apiCalls);let d=i.length,l=new Set,c={},u={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},f=[];for(let x of i)l.add(jt(x.url)),c[x.method]=(c[x.method]??0)+1,u[Eo(x.responseStatusCode)]+=1,f.push(x.responseTimeMs);let p=null;if(f.length>0){let x=[...f].sort((_,L)=>_-L),C=x.reduce((_,L)=>_+L,0);p={avg:Math.round(C/x.length),min:x[0],max:x[x.length-1],p50:ee(x,50),p95:ee(x,95),p99:ee(x,99)};}let g=0,m=0,h=0;for(let x of t)if(x.apiAssertions)for(let C of x.apiAssertions)g++,C.status==="passed"?m++:h++;let v=0,y=new Set;for(let x of t){v+=x.navigations.length;for(let C of x.navigations)y.add(C.url);}let b=0,k={};function A(x){for(let C of x)b++,k[C.category]=(k[C.category]??0)+1,C.children.length>0&&A(C.children);}for(let x of t)x.actions&&A(x.actions);let E=0,T=0,w=0,S=0;for(let x of t)if(x.visual)for(let C of x.visual)E++,C.status==="failed"?T++:(C.status==="new"||C.status==="updated")&&w++,S+=C.domChangeCount??0;return {total:t.length,passed:r,failed:n,flaky:s,skipped:a,timedout:o,totalApiCalls:d,uniqueApiUrls:l.size,apiCallsByMethod:c,apiCallsByStatusRange:u,apiResponseTime:p,totalAssertions:g,passedAssertions:m,failedAssertions:h,totalNavigations:v,uniqueNavigationUrls:y.size,totalTimelineSteps:e,totalActionSteps:b,actionStepsByCategory:k,visualChecks:E,visualFailures:T,visualNew:w,visualDomChanges:S}}function Po(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function F(t){return `\u2502 ${Po(t)} \u2502
4261
+ `);return}finally{n&&clearTimeout(n);}}function ts(t,e){let r=[];for(let n of t){let s=So(n),a=Ro(n),o=Ao(n,s,a,e),i=_o(n,s,a);if(o.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(...o,...i);}return r.sort(Io),Mo(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 So(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 Ro(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 Ao(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 _o(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}:{}})),o=null;return s.responseStatusCode!==null&&s.responseStatusText!==null&&(o={statusCode:s.responseStatusCode,statusText:s.responseStatusText,headers:s.responseHeaders,body:es(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:es(s.requestBody)},response:o,...s.error?{error:s.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function Io(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],o=s[e.type];return a!==o?a-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?Qn(t.callId)-Qn(e.callId):0}function Qn(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function Mo(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 o=r+1;o<t.length;o++)if(t[o]._testTitle===n._testTitle){a=new Date(t[o].timestamp).getTime();break}if(a!==null)n.durationOnUrl=Math.max(0,a-s);else {let o=e.find(i=>i.title===n._testTitle);if(o){let i=new Date(o.completedAt).getTime();n.durationOnUrl=Math.max(0,i-s);}}}}function es(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function ee(t,e){let r=t.length,n=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,n)]}function jt(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function Eo(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 rs(t,e){let r=0,n=0,s=0,a=0,o=0;for(let w of t)switch(w.status){case "passed":r++;break;case "failed":n++;break;case "flaky":s++;break;case "skipped":a++;break;case "timedout":o++;break}let i=[];for(let w of t)w.apiCalls&&i.push(...w.apiCalls);let d=i.length,l=new Set,c={},u={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},f=[];for(let w of i)l.add(jt(w.url)),c[w.method]=(c[w.method]??0)+1,u[Eo(w.responseStatusCode)]+=1,f.push(w.responseTimeMs);let p=null;if(f.length>0){let w=[...f].sort((_,L)=>_-L),C=w.reduce((_,L)=>_+L,0);p={avg:Math.round(C/w.length),min:w[0],max:w[w.length-1],p50:ee(w,50),p95:ee(w,95),p99:ee(w,99)};}let g=0,m=0,h=0;for(let w of t)if(w.apiAssertions)for(let C of w.apiAssertions)g++,C.status==="passed"?m++:h++;let v=0,y=new Set;for(let w of t){v+=w.navigations.length;for(let C of w.navigations)y.add(C.url);}let b=0,k={};function A(w){for(let C of w)b++,k[C.category]=(k[C.category]??0)+1,C.children.length>0&&A(C.children);}for(let w of t)w.actions&&A(w.actions);let E=0,T=0,x=0,S=0;for(let w of t)if(w.visual)for(let C of w.visual)E++,C.status==="failed"?T++:(C.status==="new"||C.status==="updated")&&x++,S+=C.domChangeCount??0;return {total:t.length,passed:r,failed:n,flaky:s,skipped:a,timedout:o,totalApiCalls:d,uniqueApiUrls:l.size,apiCallsByMethod:c,apiCallsByStatusRange:u,apiResponseTime:p,totalAssertions:g,passedAssertions:m,failedAssertions:h,totalNavigations:v,uniqueNavigationUrls:y.size,totalTimelineSteps:e,totalActionSteps:b,actionStepsByCategory:k,visualChecks:E,visualFailures:T,visualNew:x,visualDomChanges:S}}function Po(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function F(t){return `\u2502 ${Po(t)} \u2502
4262
4262
  `}function Vt(t,e,r,n){if(n||t.total===0)return;let s=`\u250C${"\u2500".repeat(58)}\u2510
4263
4263
  `,a=`\u2514${"\u2500".repeat(58)}\u2518
4264
4264
  `,o=F(""),i=s;i+=F("TestRelic AI - Playwright Test Report"),i+=o;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+=F(`Tests: ${t.total} total (${d.join(" ")})`),t.totalNavigations>0&&(i+=F(`Navigations: ${t.totalNavigations} visits across ${t.uniqueNavigationUrls} unique URLs`)),t.totalApiCalls>0){i+=F(`API Calls: ${t.totalApiCalls} calls across ${t.uniqueApiUrls} unique endpoints`);let l=Object.entries(t.apiCallsByMethod).filter(([,u])=>u>0).map(([u,f])=>`${u}: ${f}`);l.length>0&&(i+=F(` ${l.join(" ")}`));let c=Object.entries(t.apiCallsByStatusRange).filter(([,u])=>u>0).map(([u,f])=>`${u}: ${f}`);c.length>0&&(i+=F(` ${c.join(" ")}`)),t.apiResponseTime&&(i+=F(` Avg response: ${t.apiResponseTime.avg}ms P95: ${t.apiResponseTime.p95}ms`));}if(t.totalAssertions>0&&(i+=F(`Assertions: ${t.totalAssertions} total (${t.passedAssertions} \u2713 ${t.failedAssertions} \u2717)`)),t.totalActionSteps>0){let l=[],c=t.actionStepsByCategory;c.ui_action&&l.push(`${c.ui_action} UI`),c.assertion&&l.push(`${c.assertion} assertions`),c.custom_step&&l.push(`${c.custom_step} custom`);let u=l.length>0?` (${l.join(" ")})`:"";i+=F(`Actions: ${t.totalActionSteps} steps${u}`);}i+=F(`Report: ${r}`),i+=F(`Data: ${e}`),i+=a,i+=`For more information visit us at https://docs.testrelic.ai
4265
- `,process.stderr.write(i);}var Lo=new Set(["pw:api","expect","test.step"]);function No(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function $t(t,e,r){if(Lo.has(t.category)){let n=[];for(let a of t.steps)$t(a,e,n);let s=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:No(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:s>=0?s/1e3:null,status:t.error?"failed":"passed",error:Un(t.error?.message),children:n});}else for(let n of t.steps)$t(n,e,r);}function ss(t,e){let r=[];for(let n of t)$t(n,e,r);return r}var Bo=new Set(["localhost","127.0.0.1","0.0.0.0"]);function is(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&Bo.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var Oo=3e3;async function Wt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),Oo);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function os(t){return new Promise(e=>setTimeout(e,t))}async function as(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 Gt(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 os(d);let l=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(l.ok){let c=await l.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 as(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 as(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 Kt(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 ls(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 os(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 o=await a.json();return {accessToken:o.accessToken,refreshToken:o.refreshToken,expiresIn:o.expiresIn}}catch{return null}finally{clearTimeout(s);}}async function ds(t,e,r,n,s,a){let o=new AbortController,i=setTimeout(()=>o.abort(),s);try{let d={gitId:r,displayName:n};a&&(d.branch=a);let l=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(d),signal:o.signal});if(!l.ok)return null;let c=await l.json();return {repoId:c.repoId,displayName:c.displayName}}catch{return null}finally{clearTimeout(i);}}var jo=5e3;function K(t,e){try{return child_process.execSync(t,{cwd:e,timeout:jo,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function cs(t){let e=K("git rev-parse --abbrev-ref HEAD",t),r=K("git rev-parse --short HEAD",t),n=K("git log -1 --pretty=%s",t),s=K("git log -1 --format=%an",t)??K("git config user.name",t),a=Vo(t),o=a?be(a):null;return {branch:e,commitSha:r,commitMessage:n,commitAuthor:s,remoteUrl:o}}function Vo(t){let e=K("git remote get-url origin",t);if(e)return e;let r=K("git remote",t);if(!r)return null;let n=r.split(`
4266
- `)[0]?.trim();return n?K(`git remote get-url ${n}`,t):null}function be(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 us(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Jt(t){try{let e=fs$1.readFileSync(path.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return typeof r.name=="string"&&r.name.length>0?r.name:null}catch{return null}}function xe(t){let e=Jt(t);return e||`local/${path.basename(t)}`}var $o=new Set(["smoke","regression","nightly","ci"]);function Fe(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&$o.has(t))return t}async function J(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),Math.max(1,r));try{return await fetch(t,{...e,signal:n.signal})}finally{clearTimeout(s);}}function ps(t,e){let r=e+Math.ceil(Math.max(0,t)/1e3);return Math.min(6e5,Math.max(3e4,r))}var Be=class{constructor(e=12e4,r=Date.now()){this.deadline=r+Math.max(0,e);}remaining(e=Date.now()){return Math.max(0,this.deadline-e)}expired(e=Date.now()){return this.remaining(e)===0}slice(e,r=Date.now()){return Math.min(e,this.remaining(r))}};var Ko=1048576,Oe=[1e3,3e3,9e3],qe=3,gs=3e4,Jo=90*1048576,Yo=new Set(["e2e","mobile","unit"]);function Xt(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",o=0;for(let[i,d]of s)d>o&&(o=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let s of t??[])Yo.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 Zt(t,e,r,n,s,a){let o=a?.cloudPlatform?a.cloudPlatform:n?.provider&&n.provider!=="unknown"?n.provider:"local",i=Fe(),d=Xt(s),l=d.testType==="api"?d:null,c=l&&s?s.map(f=>f.apiProtocol?f:{...f,apiProtocol:l.apiProtocol}):s;return {runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:o,...i?{runType:i}:{},...l?{testType:l.testType,apiProtocol:l.apiProtocol,metadata:l.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 Yt(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function Qt(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:Yt(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Yt(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 er(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:Yt(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 tr(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",o=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:o}})}async function He(t){return new Promise(e=>setTimeout(e,t))}function Xo(t){let e={};for(let[r,n]of Object.entries(t))n!=null&&(e[r]=n);return e}async function hs(t,e,r,n=gs,s){for(let a=0;a<qe;a++){if(s?.expired())return null;let o=s?s.slice(n):n;if(o<=0)return null;try{let i=await J(t,e,o);if(i.ok)return i;if(i.status===401&&r&&a===0){let d=await r();if(d){let l={...e,headers:{...e.headers,Authorization:`Bearer ${d}`}},c=await J(t,l,o);if(c.ok)return c}return null}if(i.status===429&&a<qe-1){let d=i.headers.get("Retry-After"),l=d?parseInt(d,10)*1e3:Oe[a];!isNaN(l)&&l>0?await He(l):await He(Oe[a]);continue}if(i.status>=500&&a<qe-1){await He(Oe[a]);continue}return i}catch{if(a<qe-1){await He(Oe[a]);continue}return null}}return null}var Zo=util.promisify(zlib.gzip);function fs(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(n=>{let{consoleLogs:s,networkRequests:a,apiCalls:o,...i}=n;return e?i:{...i,...o!==void 0?{apiCalls:o}:{}}});return {...t,tests:r}}var Qo=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions"];function el(t){if(!Array.isArray(t.tests))return t;let e=new Set(Qo),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 o=n[a];s.failure={message:o.message??null,line:o.line??null};}else s[a]=n[a];return s});return {...t,tests:r}}function tl(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 rr(t,e=Jo){let r={"Content-Type":"application/json"},n=JSON.stringify(t),s=t,a=Array.isArray(s?.tests)?s.tests.length:0,o=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&o(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.
4267
- `),n=JSON.stringify(fs(s,false)),o(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.
4268
- `),n=JSON.stringify(fs(s,true))),o(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.
4265
+ `,process.stderr.write(i);}var Lo=new Set(["pw:api","expect","test.step"]);function No(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function $t(t,e,r){if(Lo.has(t.category)){let n=[];for(let a of t.steps)$t(a,e,n);let s=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:No(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:s>=0?s/1e3:null,status:t.error?"failed":"passed",error:Un(t.error?.message),children:n});}else for(let n of t.steps)$t(n,e,r);}function ns(t,e){let r=[];for(let n of t)$t(n,e,r);return r}var Bo=new Set(["localhost","127.0.0.1","0.0.0.0"]);function as(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&Bo.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var Oo=3e3;async function Wt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),Oo);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function is(t){return new Promise(e=>setTimeout(e,t))}async function ss(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 Gt(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 is(d);let l=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:n.signal});if(l.ok){let c=await l.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 ss(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 ss(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 Kt(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 os(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 is(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 o=await a.json();return {accessToken:o.accessToken,refreshToken:o.refreshToken,expiresIn:o.expiresIn}}catch{return null}finally{clearTimeout(s);}}async function ls(t,e,r,n,s,a){let o=new AbortController,i=setTimeout(()=>o.abort(),s);try{let d={gitId:r,displayName:n};a&&(d.branch=a);let l=await fetch(`${t}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(d),signal:o.signal});if(!l.ok)return null;let c=await l.json();return {repoId:c.repoId,displayName:c.displayName}}catch{return null}finally{clearTimeout(i);}}var jo=5e3;function K(t,e){try{return child_process.execSync(t,{cwd:e,timeout:jo,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function ds(t){let e=K("git rev-parse --abbrev-ref HEAD",t),r=K("git rev-parse --short HEAD",t),n=K("git log -1 --pretty=%s",t),s=K("git log -1 --format=%an",t)??K("git config user.name",t),a=Vo(t),o=a?be(a):null;return {branch:e,commitSha:r,commitMessage:n,commitAuthor:s,remoteUrl:o}}function Vo(t){let e=K("git remote get-url origin",t);if(e)return e;let r=K("git remote",t);if(!r)return null;let n=r.split(`
4266
+ `)[0]?.trim();return n?K(`git remote get-url ${n}`,t):null}function be(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 cs(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Jt(t){try{let e=fs$1.readFileSync(path.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return typeof r.name=="string"&&r.name.length>0?r.name:null}catch{return null}}function xe(t){let e=Jt(t);return e||`local/${path.basename(t)}`}var $o=new Set(["smoke","regression","nightly","ci"]);function Fe(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&$o.has(t))return t}async function J(t,e,r){let n=new AbortController,s=setTimeout(()=>n.abort(),Math.max(1,r));try{return await fetch(t,{...e,signal:n.signal})}finally{clearTimeout(s);}}function us(t,e){let r=e+Math.ceil(Math.max(0,t)/1e3);return Math.min(6e5,Math.max(3e4,r))}var Be=class{constructor(e=12e4,r=Date.now()){this.deadline=r+Math.max(0,e);}remaining(e=Date.now()){return Math.max(0,this.deadline-e)}expired(e=Date.now()){return this.remaining(e)===0}slice(e,r=Date.now()){return Math.min(e,this.remaining(r))}};var Ko=1048576,Oe=[1e3,3e3,9e3],qe=3,fs=3e4,Jo=90*1048576,Yo=new Set(["e2e","mobile","unit"]);function Xt(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",o=0;for(let[i,d]of s)d>o&&(o=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let s of t??[])Yo.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 Zt(t,e,r,n,s,a){let o=a?.cloudPlatform?a.cloudPlatform:n?.provider&&n.provider!=="unknown"?n.provider:"local",i=Fe(),d=Xt(s),l=d.testType==="api"?d:null,c=l&&s?s.map(f=>f.apiProtocol?f:{...f,apiProtocol:l.apiProtocol}):s;return {runId:t.testRunId,repoGitId:e,startedAt:t.startedAt,summary:t.summary,timeline:t.timeline,environment:o,...i?{runType:i}:{},...l?{testType:l.testType,apiProtocol:l.apiProtocol,metadata:l.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 Yt(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function Qt(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:Yt(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Yt(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 er(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:Yt(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 tr(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",o=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:o}})}async function Ue(t){return new Promise(e=>setTimeout(e,t))}function Xo(t){let e={};for(let[r,n]of Object.entries(t))n!=null&&(e[r]=n);return e}async function gs(t,e,r,n=fs,s){for(let a=0;a<qe;a++){if(s?.expired())return null;let o=s?s.slice(n):n;if(o<=0)return null;try{let i=await J(t,e,o);if(i.ok)return i;if(i.status===401&&r&&a===0){let d=await r();if(d){let l={...e,headers:{...e.headers,Authorization:`Bearer ${d}`}},c=await J(t,l,o);if(c.ok)return c}return null}if(i.status===429&&a<qe-1){let d=i.headers.get("Retry-After"),l=d?parseInt(d,10)*1e3:Oe[a];!isNaN(l)&&l>0?await Ue(l):await Ue(Oe[a]);continue}if(i.status>=500&&a<qe-1){await Ue(Oe[a]);continue}return i}catch{if(a<qe-1){await Ue(Oe[a]);continue}return null}}return null}var Zo=util.promisify(zlib.gzip);function ps(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(n=>{let{consoleLogs:s,networkRequests:a,apiCalls:o,...i}=n;return e?i:{...i,...o!==void 0?{apiCalls:o}:{}}});return {...t,tests:r}}var Qo=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions","visual"];function el(t){if(!Array.isArray(t.tests))return t;let e=new Set(Qo),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 o=n[a];s.failure={message:o.message??null,line:o.line??null};}else s[a]=n[a];return s});return {...t,tests:r}}function tl(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 rr(t,e=Jo){let r={"Content-Type":"application/json"},n=JSON.stringify(t),s=t,a=Array.isArray(s?.tests)?s.tests.length:0,o=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&o(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.
4267
+ `),n=JSON.stringify(ps(s,false)),o(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.
4268
+ `),n=JSON.stringify(ps(s,true))),o(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.
4269
4269
  `),n=JSON.stringify(el(s))),o(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.
4270
- `),n=JSON.stringify(tl(s)));}if(Buffer.byteLength(n,"utf-8")>Ko){r["Content-Encoding"]="gzip";let i=await Zo(Buffer.from(n,"utf-8")),d=i.buffer;return {body:new Uint8Array(d,i.byteOffset,i.byteLength),headers:r}}return {body:n,headers:r}}async function ms(t,e,r,n,s,a){let o=`${t}/runs`,{body:i,headers:d}=await rr(r);d.Authorization=`Bearer ${e}`;let l=await hs(o,{method:"POST",headers:d,body:i},n,s,a);return l?.ok?{success:true,statusCode:l.status,error:null}:l?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:l?`Upload failed with status ${l.status}`:"Upload failed after retries",statusCode:l?.status??null,payload:r,targetEndpoint:o,method:"POST"}}async function vs(t,e,r,n){let s=`${t}/runs/init`;try{let a=await J(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(Xo(r))},n??gs);return a.ok?{runId:(await a.json()).runId}:null}catch{return null}}function ys(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 bs(t,e,r,n){let s=`${t}/runs/${r}/finalize`;return (await hs(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}))?.ok??false}function nr(t,e,r,n){let s=`${t}/runs/${r}/finalize`,a=new Date,o={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(o)}).catch(()=>{});}var il="1.0.0",xs=10;function ws(t){return t instanceof Error?t.message:String(t)}function ol(t){return t>=400&&t<500&&t!==408&&t!==429}function we(t,e,r,n,s,a,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let d=Date.now(),l=`${d}-${e}-${r}.json`,c=path.join(t,l),u={version:il,queuedAt:new Date(d).toISOString(),reason:n,retryCount:0,targetEndpoint:s,method:a,payload:o,headers:i},f=c+".tmp";fs$1.writeFileSync(f,JSON.stringify(u,null,2),"utf-8"),fs$1.renameSync(f,c);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
4270
+ `),n=JSON.stringify(tl(s)));}if(Buffer.byteLength(n,"utf-8")>Ko){r["Content-Encoding"]="gzip";let i=await Zo(Buffer.from(n,"utf-8")),d=i.buffer;return {body:new Uint8Array(d,i.byteOffset,i.byteLength),headers:r}}return {body:n,headers:r}}async function hs(t,e,r,n,s,a){let o=`${t}/runs`,{body:i,headers:d}=await rr(r);d.Authorization=`Bearer ${e}`;let l=await gs(o,{method:"POST",headers:d,body:i},n,s,a);return l?.ok?{success:true,statusCode:l.status,error:null}:l?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:l?`Upload failed with status ${l.status}`:"Upload failed after retries",statusCode:l?.status??null,payload:r,targetEndpoint:o,method:"POST"}}async function ms(t,e,r,n){let s=`${t}/runs/init`;try{let a=await J(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(Xo(r))},n??fs);return a.ok?{runId:(await a.json()).runId}:null}catch{return null}}function vs(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 ys(t,e,r,n){let s=`${t}/runs/${r}/finalize`;return (await gs(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}))?.ok??false}function nr(t,e,r,n){let s=`${t}/runs/${r}/finalize`,a=new Date,o={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(o)}).catch(()=>{});}var il="1.0.0",bs=10;function xs(t){return t instanceof Error?t.message:String(t)}function ol(t){return t>=400&&t<500&&t!==408&&t!==429}function we(t,e,r,n,s,a,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let d=Date.now(),l=`${d}-${e}-${r}.json`,c=path.join(t,l),u={version:il,queuedAt:new Date(d).toISOString(),reason:n,retryCount:0,targetEndpoint:s,method:a,payload:o,headers:i},f=c+".tmp";fs$1.writeFileSync(f,JSON.stringify(u,null,2),"utf-8"),fs$1.renameSync(f,c);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
4271
4271
  `):process.stderr.write(`\u26A0 TestRelic: Unable to queue upload data.
4272
- `);}}async function Ss(t,e,r){let n;try{n=fs$1.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+=xs)s.push(n.slice(a,a+xs));for(let a of s)for(let o of a){let i=path.join(t,o),d;try{if(!fs$1.statSync(i).isFile())continue;let c=JSON.parse(fs$1.readFileSync(i,"utf-8"));if(!core.isValidQueueEntry(c)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${o}
4273
- `),fs$1.unlinkSync(i);continue}d=c;}catch(l){process.stderr.write(`\u26A0 TestRelic: Skipping unreadable queue file ${o}: ${ws(l)}
4272
+ `);}}async function Ts(t,e,r){let n;try{n=fs$1.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+=bs)s.push(n.slice(a,a+bs));for(let a of s)for(let o of a){let i=path.join(t,o),d;try{if(!fs$1.statSync(i).isFile())continue;let c=JSON.parse(fs$1.readFileSync(i,"utf-8"));if(!core.isValidQueueEntry(c)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${o}
4273
+ `),fs$1.unlinkSync(i);continue}d=c;}catch(l){process.stderr.write(`\u26A0 TestRelic: Skipping unreadable queue file ${o}: ${xs(l)}
4274
4274
  `);try{fs$1.unlinkSync(i);}catch{}continue}try{let{body:l,headers:c}=await rr(d.payload),u={...d.headers,...c,Authorization:`Bearer ${r}`},f=await fetch(d.targetEndpoint,{method:d.method,headers:u,body:l});if(f.ok)fs$1.unlinkSync(i);else if(ol(f.status)){process.stderr.write(`\u26A0 TestRelic: Queue entry ${o} rejected (HTTP ${f.status}) \u2014 moving aside; it will not be retried.
4275
4275
  `);try{fs$1.renameSync(i,`${i}.failed`);}catch{try{fs$1.unlinkSync(i);}catch{}}}else {process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 server returned HTTP ${f.status} for ${o}; will retry later.
4276
- `);return}}catch(l){process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 ${ws(l)}; will retry later.
4277
- `);return}}}function Rs(t,e){try{let r=fs$1.readdirSync(t).filter(s=>(s.endsWith(".json")||s.endsWith(".failed"))&&!s.endsWith(".tmp")),n=Date.now();for(let s of r){let a=path.join(t,s);try{let o=fs$1.readFileSync(a,"utf-8"),d=JSON.parse(o).queuedAt;if(typeof d=="string"){let l=new Date(d).getTime();n-l>e&&fs$1.unlinkSync(a);}}catch{try{fs$1.unlinkSync(a);}catch{}}}}catch{}}var gl=3e5,hl=864e5,ml=6e4,As=3e4,ir="https://platform.testrelic.ai/settings/api-keys";function _s(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r?.unref=="function"&&r.unref();})}var Ue=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.
4278
- `);return}try{if(is(this.config.endpoint),this.gitMetadata=cs(),!await Wt(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.
4276
+ `);return}}catch(l){process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 ${xs(l)}; will retry later.
4277
+ `);return}}}function Ss(t,e){try{let r=fs$1.readdirSync(t).filter(s=>(s.endsWith(".json")||s.endsWith(".failed"))&&!s.endsWith(".tmp")),n=Date.now();for(let s of r){let a=path.join(t,s);try{let o=fs$1.readFileSync(a,"utf-8"),d=JSON.parse(o).queuedAt;if(typeof d=="string"){let l=new Date(d).getTime();n-l>e&&fs$1.unlinkSync(a);}}catch{try{fs$1.unlinkSync(a);}catch{}}}}catch{}}var gl=3e5,hl=864e5,ml=6e4,Rs=3e4,ir="https://platform.testrelic.ai/settings/api-keys";function As(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r?.unref=="function"&&r.unref();})}var He=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.
4278
+ `);return}try{if(as(this.config.endpoint),this.gitMetadata=ds(),!await Wt(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.
4279
4279
  `);return}let r=await Gt(this.config.endpoint,this.config.apiKey,this.config.timeout);if(Kt(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})
4280
- `),await this.resolveRepoId(),this.config.queueDirectory&&(Rs(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)}
4281
- `);}}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()+gl<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await ls(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}).
4282
- `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,_s(As)]);}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.
4280
+ `),await this.resolveRepoId(),this.config.queueDirectory&&(Ss(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)}
4281
+ `);}}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()+gl<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await os(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}).
4282
+ `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,As(Rs)]);}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.
4283
4283
  \u2192 Manage keys: ${ir}
4284
4284
  `);break;case "expired_key":this.setLocalMode("expired_api_key"),process.stderr.write(`\u26A0 TestRelic: API key has expired. Running in local mode.
4285
4285
  \u2192 Generate a new key: ${ir}
@@ -4288,16 +4288,16 @@ ${s}
4288
4288
  `);break;case "rate_limited":this.setLocalMode("rate_limited"),process.stderr.write(`\u26A0 TestRelic: Rate limited during authentication. Running in local mode.
4289
4289
  `);break;case "timeout":this.setLocalMode("auth_timeout"),process.stderr.write(`\u26A0 TestRelic: Authentication timed out. Running in local mode.
4290
4290
  `);break;default:this.setLocalMode(`auth_error_${r??"unknown"}`),process.stderr.write(`\u26A0 TestRelic: Cloud authentication failed. Running in local mode.
4291
- `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?be(this.gitMetadata.remoteUrl):null,r=e?us(e):this.config.projectName??xe(process.cwd()),n=e??this.config.projectName??xe(process.cwd()),s=this.readRepoCache(n);if(s){this.repoId=s.repoId;return}try{let a=await ds(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&&!Jt(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
4292
- `);}readRepoCache(e){if(!this.config)return null;let r=path.join(this.config.queueDirectory,"..","cache","repo.json");try{if(!fs$1.existsSync(r))return null;let n=fs$1.readFileSync(r,"utf-8"),s=JSON.parse(n);if(s.gitId!==e||Date.now()-s.resolvedAt>hl)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=path.join(this.config.queueDirectory,"..","cache"),a=path.join(s,"repo.json");try{fs$1.mkdirSync(s,{recursive:!0});let o={repoId:r,gitId:e,displayName:n,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=a+".tmp";fs$1.writeFileSync(i,JSON.stringify(o,null,2),"utf-8"),fs$1.renameSync(i,a);}catch{}}hashApiKey(){return this.config?.apiKey?crypto.createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let e=this.authState.accessToken,r=this.config.queueDirectory,n=this.config.endpoint;this.flushPromise=Promise.race([Ss(r,n,e),_s(As)]).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 Wt(e))return;if(this.config?.apiKey){let n=await Gt(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Kt(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.
4293
- `),this.startBackgroundFlush();}}}catch{}},ml),typeof this.healthCheckTimer?.unref=="function"&&this.healthCheckTimer.unref();}};function xl(t,e){return e?t?{"2xx":t["2xx"]+e["2xx"],"3xx":t["3xx"]+e["3xx"],"4xx":t["4xx"]+e["4xx"],"5xx":t["5xx"]+e["5xx"],error:t.error+e.error}:{...e}:t}function Is(t,e,r,n){let s=[],a=[],o=null,i=0,d=null,l=0,c=null,u=0,f=null,p=t.filter(h=>h.name===core.ATTACHMENT_NAME&&h.body),g=false;if(p.length>0)for(let h of p)try{let v=JSON.parse(h.body.toString());if(core.isTestRelicFilePayload(v)){s=s.concat(v.navigations),a=a.concat(v.apiAssertions),v.networkRequestsFile&&(o=v.networkRequestsFile,i+=v.networkRequestsCount),v.consoleLogsFile&&(d=v.consoleLogsFile,l+=v.consoleLogsCount),v.apiCallsFile&&(c=v.apiCallsFile,u+=v.apiCallsCount),f=xl(f,v.apiStatusMix),g=!0;continue}if(core.isTestRelicDataPayload(v)){s=s.concat(v.navigations),Array.isArray(v.apiAssertions)&&(a=a.concat(v.apiAssertions)),i+=v.networkRequests?.length??0,u+=v.apiCalls?.length??0;let y=v.consoleLogs;Array.isArray(y)&&(l+=y.length),g=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
4291
+ `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?be(this.gitMetadata.remoteUrl):null,r=e?cs(e):this.config.projectName??xe(process.cwd()),n=e??this.config.projectName??xe(process.cwd()),s=this.readRepoCache(n);if(s){this.repoId=s.repoId;return}try{let a=await ls(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&&!Jt(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
4292
+ `);}readRepoCache(e){if(!this.config)return null;let r=path.join(this.config.queueDirectory,"..","cache","repo.json");try{if(!fs$1.existsSync(r))return null;let n=fs$1.readFileSync(r,"utf-8"),s=JSON.parse(n);if(s.gitId!==e||Date.now()-s.resolvedAt>hl)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=path.join(this.config.queueDirectory,"..","cache"),a=path.join(s,"repo.json");try{fs$1.mkdirSync(s,{recursive:!0});let o={repoId:r,gitId:e,displayName:n,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},i=a+".tmp";fs$1.writeFileSync(i,JSON.stringify(o,null,2),"utf-8"),fs$1.renameSync(i,a);}catch{}}hashApiKey(){return this.config?.apiKey?crypto.createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let e=this.authState.accessToken,r=this.config.queueDirectory,n=this.config.endpoint;this.flushPromise=Promise.race([Ts(r,n,e),As(Rs)]).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 Wt(e))return;if(this.config?.apiKey){let n=await Gt(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Kt(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.
4293
+ `),this.startBackgroundFlush();}}}catch{}},ml),typeof this.healthCheckTimer?.unref=="function"&&this.healthCheckTimer.unref();}};function xl(t,e){return e?t?{"2xx":t["2xx"]+e["2xx"],"3xx":t["3xx"]+e["3xx"],"4xx":t["4xx"]+e["4xx"],"5xx":t["5xx"]+e["5xx"],error:t.error+e.error}:{...e}:t}function _s(t,e,r,n){let s=[],a=[],o=null,i=0,d=null,l=0,c=null,u=0,f=null,p=t.filter(h=>h.name===core.ATTACHMENT_NAME&&h.body),g=false;if(p.length>0)for(let h of p)try{let v=JSON.parse(h.body.toString());if(core.isTestRelicFilePayload(v)){s=s.concat(v.navigations),a=a.concat(v.apiAssertions),v.networkRequestsFile&&(o=v.networkRequestsFile,i+=v.networkRequestsCount),v.consoleLogsFile&&(d=v.consoleLogsFile,l+=v.consoleLogsCount),v.apiCallsFile&&(c=v.apiCallsFile,u+=v.apiCallsCount),f=xl(f,v.apiStatusMix),g=!0;continue}if(core.isTestRelicDataPayload(v)){s=s.concat(v.navigations),Array.isArray(v.apiAssertions)&&(a=a.concat(v.apiAssertions)),i+=v.networkRequests?.length??0,u+=v.apiCalls?.length??0;let y=v.consoleLogs;Array.isArray(y)&&(l+=y.length),g=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
4294
4294
  `);}return g||(s=e.filter(h=>h.type==="lambdatest-navigation"&&h.description).map(h=>{try{return JSON.parse(h.description)}catch{return null}}).filter(h=>h!==null)),s.length===0&&i===0&&u===0&&!n&&!g&&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.
4295
- `),{navigations:s,apiAssertions:a,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:l,apiCallsFile:c,apiCallsCount:u,apiStatusMix:f}}function ze(t=process.env){let e=wl(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 wl(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Rl=5,je=[1e3,3e3,9e3],ie=3,dr=3e4,Al={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip",".json":"application/json"},or=0,lr=[];async function _l(){or>=Rl&&await new Promise(t=>lr.push(t)),or++;}function Il(){or--,lr.length>0&&lr.shift()();}async function Ve(t){return new Promise(e=>setTimeout(e,t))}function Ml(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return Al[e]??"application/octet-stream"}function El(t){try{return fs$1.statSync(t).size}catch{return 0}}async function Pl(t,e,r,n,s){let a=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:s,type:r.type,sizeBytes:n});for(let i=0;i<ie;i++)try{let d=await J(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o},dr);if(d.ok)return await d.json();if(d.status>=500&&i<ie-1){await Ve(je[i]);continue}return null}catch{if(i<ie-1){await Ve(je[i]);continue}return null}return null}async function Ll(t,e,r,n){let s=ps(n,dr);for(let a=0;a<ie;a++)try{let o=fs$1.createReadStream(e),i=stream.Readable.toWeb(o),d=await J(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(n)},body:i,duplex:"half"},s);if(d.ok)return !0;if(d.status>=500&&a<ie-1){await Ve(je[a]);continue}return !1}catch{if(a<ie-1){await Ve(je[a]);continue}return false}return false}async function Nl(t,e,r){let n=`${t}/artifacts/confirm`;try{return (await J(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})},dr)).ok}catch{return false}}async function Dl(t,e,r,n){let s=El(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=Ml(r.filePath);await _l();try{let o=await Pl(t,e,r,s,a);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await Ll(o.uploadUrl,r.filePath,a,s))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let d=await Nl(t,e,o.artifactId);return {success:d,storageKey:o.storageKey,artifactId:o.artifactId,error:d?null:"confirm_failed"}}finally{Il();}}async function Ms(t,e,r,n,s){let a=new Map,o=r.map(async i=>{if(s?.expired()){a.set(i.filePath,{success:false,storageKey:null,artifactId:null,error:"upload_budget_exhausted"});return}let d=await Dl(t,e,i,n);a.set(i.filePath,d);});return await Promise.allSettled(o),a}function ur(t){let r=t.getGitMetadata()?.remoteUrl;return r?be(r):t.getConfig()?.projectName??xe(process.cwd())}async function Es(t,e,r,n,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=V(),d=ze(),l=Fe();return (await vs(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:ur(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:n,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...l?{runType:l}:{},testType:"e2e"}))?.runId??null}var Bl=[{field:"baseline",keyField:"baselineKey",type:"baseline"},{field:"actual",keyField:"actualKey",type:"screenshot"},{field:"diff",keyField:"diffKey",type:"diff"},{field:"baselineDom",keyField:"baselineDomKey",type:"dom"},{field:"actualDom",keyField:"actualDomKey",type:"dom"}],Ol=true,ql=50,cr={keyMap:new Map,visualKeyMap:new Map,total:0,uploaded:0};async function Hl(t,e,r,n,s){let a=new Map,o=new Map;if(!(e?.uploadArtifacts??Ol)||!await t.ensureValidToken())return cr;let l=[],c=new Map,u=new Map;for(let h of n){if(h.artifacts.screenshot){let y=path.join(h.outputDir,h.artifacts.screenshot);l.push({filePath:y,runId:r,testId:h.testId,type:"screenshot"}),c.set(y,{testId:h.testId,field:"screenshot"});}if(h.artifacts.video){let y=path.join(h.outputDir,h.artifacts.video);l.push({filePath:y,runId:r,testId:h.testId,type:"video"}),c.set(y,{testId:h.testId,field:"video"});}if(h.artifacts.trace){let y=path.join(h.outputDir,h.artifacts.trace);l.push({filePath:y,runId:r,testId:h.testId,type:"trace"}),c.set(y,{testId:h.testId,field:"trace"});}let v=h.visual??[];for(let y=0;y<v.length;y++){let b=v[y];if(b)for(let k of Bl){let A=b[k.field];if(!A)continue;let E=path.join(h.outputDir,A);l.push({filePath:E,runId:r,testId:h.testId,type:k.type}),c.set(E,{testId:h.testId,field:"visual",visualIndex:y,visualKey:k.keyField});}}}if(l.length===0)return cr;let f=e?.artifactMaxSizeMb??ql,p=await Ms(t.getEndpoint(),t.getAccessToken(),l,f,s),g=new Map;for(let[h,v]of p){if(!v.success||!v.storageKey)continue;let y=c.get(h);if(!y)continue;let b=g.get(y.testId)??{};if(y.field==="screenshot"&&(b.screenshotKey=v.storageKey),y.field==="video"&&(b.videoKey=v.storageKey),y.field==="trace"&&(b.traceKey=v.storageKey),y.field==="visual"&&y.visualIndex!==void 0&&y.visualKey){let k=u.get(y.testId)??new Map,A=k.get(y.visualIndex)??{};A[y.visualKey]=v.storageKey,k.set(y.visualIndex,A),u.set(y.testId,k);}g.set(y.testId,b);}for(let h of n){if(h.visual&&h.visual.length>0){let y=u.get(h.testId);o.set(h.testId,h.visual.map((b,k)=>({...b,...y?.get(k)??{}})));}let v=g.get(h.testId);a.set(h.testId,{...h.artifacts,...v?.screenshotKey?{screenshotKey:v.screenshotKey}:{},...v?.videoKey?{videoKey:v.videoKey}:{},...v?.traceKey?{traceKey:v.traceKey}:{}});}let m=Array.from(p.values()).filter(h=>h.success).length;return m>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${m} artifact(s) to cloud storage.
4296
- `),{keyMap:a,visualKeyMap:o,total:l.length,uploaded:m}}async function pr(t,e,r,n,s,a,o,i,d,l,c){let u={realtimeFinalizeAttempted:false,realtimeFinalized:false,batchAttempted:false,batchAcknowledged:false,artifactsTotal:0,artifactsUploaded:0,failureReason:null},f=new Be(e?.uploadBudgetMs??12e4),p=g=>{u.failureReason||(u.failureReason=g);};try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){u.realtimeFinalizeAttempted=!0;let h=await t.ensureValidToken(),v=t.getGitMetadata(),y=Xt(c),b={finishedAt:o,duration:i,summary:d,...v?.commitMessage?{commitMessage:v.commitMessage}:{},testType:y.testType,...y.testType==="api"?{apiProtocol:y.apiProtocol,metadata:y.metadata}:{}};if(h){let k=await bs(t.getEndpoint(),t.getAccessToken(),s,b);if(u.realtimeFinalized=k,!k){p("finalize_failed_after_retries");let A=e?.queueDirectory??".testrelic/queue";we(A,n,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",b,{"Content-Type":"application/json"});}}else {p(t.getFailureReason()??"token_invalid");let k=e?.queueDirectory??".testrelic/queue";we(k,n,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",b,{"Content-Type":"application/json"});}}let g=new Map,m=new Map;if(t.isCloudMode()&&l&&l.length>0){let h=await Hl(t,e,n,l,f);g=h.keyMap,m=h.visualKeyMap,u.artifactsTotal=h.total,u.artifactsUploaded=h.uploaded;}if(t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(u.batchAttempted=!0,await t.ensureValidToken()){let v=t.getGitMetadata(),y=V(),b=ur(t),k=Ul(zl(a,g),m),A=Zt(k,b,v,y,c,ze()),E=await ms(t.getEndpoint(),t.getAccessToken(),A,async()=>await t.ensureValidToken()?t.getAccessToken():null,e?.timeout,f);if(u.batchAcknowledged=E.success,!E.success){let T=E;p(T.reason);let w=e?.queueDirectory??".testrelic/queue";we(w,n,"batch",T.reason,T.targetEndpoint,T.method,T.payload,{"Content-Type":"application/json"});}}else {p(t.getFailureReason()??"token_invalid");let v=e?.queueDirectory??".testrelic/queue",y=t.getGitMetadata(),b=V(),k=ur(t),A=Zt(a,k,y,b,void 0,ze());we(v,n,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",A,{"Content-Type":"application/json"});}await t.dispose();}catch(g){p(g instanceof Error?g.message:"unexpected_upload_error");try{await t.dispose();}catch{}}return u}function Ul(t,e){if(e.size===0)return t;let r=t.timeline.map(n=>{let s=n.tests;if(!Array.isArray(s))return n;let a=false,o=s.map(i=>{let d=i.testId;if(!d)return i;let l=e.get(d);return l?(a=true,{...i,visual:l}):i});return a?{...n,tests:o}:n});return {...t,timeline:r}}function zl(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}}var jl=new Set(["batch","realtime","both"]),ke=Object.freeze({attempted:false,acknowledged:false,runId:null,endpoint:null,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:"cloud reporting was never initialised"});function Vl(t){switch(t){case "no_api_key":return "cloud mode off \u2014 no API key configured";case "cloud_unreachable":case "network_error":return "cloud endpoint unreachable \u2014 the run stayed local";case "invalid_api_key":return "API key rejected as invalid or revoked \u2014 the run stayed local";case "expired_api_key":return "API key has expired \u2014 the run stayed local";case "validation_error":return "API key format rejected \u2014 the run stayed local";case "rate_limited":return "rate limited during authentication \u2014 the run stayed local";case "auth_timeout":return "authentication timed out \u2014 the run stayed local";case "token_expired_no_refresh":case "token_refresh_failed":case "token_refresh_error":return "access token could not be refreshed \u2014 the run stayed local";case "init_error":return "cloud initialisation timed out \u2014 the run stayed local";case "unexpected_error":return "cloud initialisation failed \u2014 the run stayed local";default:return t?`cloud mode off (${t}) \u2014 the run stayed local`:"cloud mode off \u2014 the run stayed local"}}function Ps(t,e,r){if(!t)return ke;if(!t.isCloudMode())return {...ke,detail:Vl(t.getFailureReason())};let n=e??"batch";if(!jl.has(n))return {...ke,detail:`upload strategy '${n}' is not recognised \u2014 nothing was sent`};let s=t.getEndpoint(),a=n==="realtime"||n==="both";return a&&r?{attempted:true,acknowledged:true,runId:r,endpoint:s,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:null}:{attempted:true,acknowledged:false,runId:null,endpoint:s,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:a?"run init failed \u2014 the platform did not acknowledge this run":`upload runs at the end of the run under the '${n}' strategy \u2014 not sent yet`}}function fr(t,e,r){if(!t.attempted)return t;if(!e)return {...t,detail:t.acknowledged?"upload timed out before it completed \u2014 the run may be incomplete on the platform":"upload timed out before the platform acknowledged this run",acknowledged:t.acknowledged};let n=t.acknowledged||e.batchAcknowledged,s=t.runId??(e.batchAcknowledged?r:null),a=e.realtimeFinalizeAttempted?e.realtimeFinalized:e.batchAcknowledged,o=null;return n?a||(o="run acknowledged but not closed out \u2014 finalize failed and was queued for retry"):o=e.failureReason?`upload failed (${e.failureReason}) \u2014 queued locally for retry`:"upload failed \u2014 the platform did not acknowledge this run",{attempted:true,acknowledged:n,runId:s,endpoint:t.endpoint,finalized:a,artifactsUploaded:e.artifactsUploaded,artifactsTotal:e.artifactsTotal,detail:o}}function Y(t){try{return fs$1.readFileSync(t,"utf-8").split(`
4297
- `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function Xl(t){if(!t)return null;let e=t.split(`
4298
- `).map(a=>a.trim()).filter(Boolean);if(e.length===0)return null;let r=e.filter(a=>!/^Error:\s*expect\(/.test(a));if(r.length===0)return e[0]??null;let n=r[0],s=r[1];return s!==void 0&&/^Received:/.test(s)&&/^Expected:/.test(n)?`${n} \xB7 ${s}`:n}function hr(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 Zl(t,e,r){let n=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,16)}function Ql(t){return t.length<=3?"":t[t.length-2]}function ed(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function qs(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 td(t){let e={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},r=e;for(let n of t){let s=typeof n.responseStatusCode=="number"?n.responseStatusCode:null;r[qs(s)]++;}return e}function Fs(t){if(t){for(let e of t)if(e.status==="failed")return {type:e.type,expected:Bs(e.expected),actual:Bs(e.actual),...e.expression?{expression:e.expression}:{}}}}function Bs(t){if(t===void 0)return "undefined";if(t===null)return "null";let e;if(typeof t=="string")e=t;else try{e=JSON.stringify(t)??String(t);}catch{e=String(t);}return e.length>200?e.slice(0,200)+"\u2026":e}function We(t,e){if(!t)return 0;let r=0;for(let n of t)n.status===e&&r++;return r}function Hs(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&Hs(r.children,e);}function rd(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:ee(e,50),p95:ee(e,95),p99:ee(e,99)}}var Us=2e5,Ge=1e5;function Os(t,e,r,n,s,a,o){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:o?.length??0,actionCategories:{}};if(e){let l=new Set;for(let c of e){let u=typeof c.method=="string"?c.method:"OTHER";i.methodCounts[u]=(i.methodCounts[u]??0)+1;let f=typeof c.url=="string"?c.url:null;f&&l.size<Ge&&l.add(jt(f));let p=typeof c.responseStatusCode=="number"?c.responseStatusCode:typeof c.statusCode=="number"?c.statusCode:null,g=p!==null&&Number.isFinite(p)?p:null;i.statusRanges[qs(g)]++;let m=typeof c.responseTimeMs=="number"?c.responseTimeMs:typeof c.durationMs=="number"?c.durationMs:null;m!==null&&Number.isFinite(m)&&i.responseTimes.length<Us&&i.responseTimes.push(m);}i.apiUrls=Array.from(l);}for(let l of r)l.status==="passed"?i.passedAssertions++:i.failedAssertions++;let d=new Set;for(let l of n)l.url&&d.size<Ge&&d.add(l.url);return i.navUrls=Array.from(d),o&&Hs(o,i.actionCategories),i}function nd(){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 sd(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 ad(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function id(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 od(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(l=>l===`@${d}`||l===d))return d;let o=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let d of i)if(o.includes(`/${d}/`))return d;return s}var ld="__testrelic_api_config";function dd(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var Ke=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.navigationsCaptured=false;this.memoryPressureWarned=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.updatingSnapshots=false;this.cloudReceipt=ke;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,visualChecks:0,visualFailures:0,visualDomChanges:0};this.streamingTestAgg=new Map;this.config=Hr(e),this.apiConfig=qr(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{this.rootDir=e.rootDir;let n=e.updateSnapshots;if(this.updatingSnapshots=n==="all"||n==="changed",this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let i=r.allTests().length;this.activeReportMode=i>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let s=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${s} tests)
4299
- `),this.activeReportMode==="streaming"){let i=path.dirname(this.config.outputPath);this.streamingWriter=new he(i);let d=()=>{if(this.streamingWriter){try{this.streamingWriter.writeIndex(this.testIndex);let l={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(),cloudUpload:this.cloudReceipt};this.streamingWriter.writeSummary(l);}catch{}this.streamingWriter.dispose();}try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let l=this.cloudClient.getAccessToken();l&&nr(this.cloudClient.getEndpoint(),l,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",d),process.on("SIGINT",d);}if(this.config.includeArtifacts){let i=path.dirname(this.config.outputPath);this.runTimestamp=Cn(path.join(i,"artifacts"));try{Yn(path.join(i,"artifacts"));}catch{}}let a=V();this.detectedOs=ad(),this.detectedSource=sd(a);let o=await Q(async()=>(this.cloudClient=new Ue(this.config.cloud),await this.cloudClient.initialize(),Es(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource)),Zn,"Cloud initialization");if(this.cloudRunId=o??null,o===void 0&&this.cloudClient?.switchToLocalMode("init_error"),this.cloudReceipt=Ps(this.cloudClient,this.config.cloud?.uploadStrategy,this.cloudRunId),this.activeReportMode!=="streaming"){let i=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let d=this.cloudClient.getAccessToken();d&&nr(this.cloudClient.getEndpoint(),d,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",i),process.on("SIGINT",i);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:ld,description:dd(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let n=r,s=e.outcome(),a;s==="flaky"?a="flaky":s==="skipped"?a="skipped":a=hr(n.status);let o=n.startTime.toISOString(),i=new Date(n.startTime.getTime()+n.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(I=>I.type==="tag").map(I=>I.description??""),l=Is(n.attachments,e.annotations,e.title,a==="skipped");(l.navigations.length>0||l.networkRequestsCount>0||l.apiCallsCount>0)&&(this.fixtureDataReceived=!0),l.navigations.length>0&&(this.navigationsCaptured=!0),!this.config.captureNavigation&&l.navigations.length>0&&(l={...l,navigations:[]});let c=null;if(a==="failed"||a==="flaky"){let M=(a==="flaky"?e.results.find(N=>N.status!=="passed")?.errors??[]:n.errors)[0];if(M){let N=zr(this.config.redactPatterns),j=M.location?.file??null,P=l.apiAssertions.find(ia=>ia.status==="failed")?.location??null,re=P!==null&&(j===null||path.resolve(j)!==path.resolve(e.location.file)),Sr=re?P.file:j,Qe=re?P.line:M.location?.line??null,fe=null;this.config.includeCodeSnippets&&Qe!==null&&Sr&&(fe=Ur(Sr,Qe,this.config.codeContextLines),fe&&(fe=N(fe))),c={message:N(se(M.message??"Unknown error")),line:Qe,code:fe,stack:this.config.includeStackTrace&&M.stack?N(se(M.stack)):null};}}let u=e.titlePath().filter(Boolean),f=path.relative(this.rootDir||".",e.location.file).replace(/\\/g,"/"),p=Ql(u),g=u.join(" > "),m=f,h=Zl(m,p,g),v=od(d,m,e),y=v!=="mobile"&&l.apiCallsCount>0?"api":v,b=s==="flaky",k=ed(e.results),A=hr(e.expectedStatus),E=hr(n.status),T=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments){let I=path.dirname(this.config.outputPath),M=u[u.length-1]??e.title;T=Sn(n.attachments,M,n.retry,I,this.runTimestamp||void 0,h);}let w=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments)try{let I=Hn(n.attachments,{updatingSnapshots:this.updatingSnapshots,failureMessage:n.errors.map(M=>M.message??"").join(`
4300
- `)});if(I.length>0){let M=path.dirname(this.config.outputPath),N=u[u.length-1]??e.title;w=Rn(I,N,n.retry,M,this.runTimestamp||void 0,h);}}catch{}let S=this.config.includeActionSteps&&n.steps?ss(n.steps,n.startTime):null,x=id(e),C={titlePath:u,title:g,status:a,duration:n.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:n.retry,tags:d,failure:c,specFile:f,navigations:l.navigations,testId:h,filePath:m,suiteName:p,testType:y,isFlaky:b,retryStatus:k,expectedStatus:A,actualStatus:E,artifacts:T,visual:w,apiAssertions:l.apiAssertions,actions:S,networkRequestsFile:l.networkRequestsFile,networkRequestsCount:l.networkRequestsCount,consoleLogsFile:l.consoleLogsFile,consoleLogsCount:l.consoleLogsCount,apiCallsFile:l.apiCallsFile,apiCallsCount:l.apiCallsCount,apiStatusMix:l.apiStatusMix,browser:x,os:this.detectedOs||void 0,source:this.detectedSource||void 0},_=l.consoleLogsFile&&l.consoleLogsCount>0?Y(l.consoleLogsFile):void 0,L=l.networkRequestsFile&&l.networkRequestsCount>0?Y(l.networkRequestsFile):void 0,z=l.apiCallsFile&&l.apiCallsCount>0?Y(l.apiCallsFile):void 0,ce=z?Qt(z):void 0,ue=!L&&z?er(z):void 0,pe=l.apiAssertions&&l.apiAssertions.length>0?tr(l.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:h,title:g,status:a,duration:n.duration,suiteName:p,filePath:m,testType:y,isFlaky:b,startedAt:o,completedAt:i,tags:d,failure:c,retry:n.retry,retryCount:e.results.length-1,retryStatus:k,browser:x,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...S&&S.length>0?{actions:S}:{},...l.navigations&&l.navigations.length>0?{navigations:l.navigations}:{},..._?{consoleLogs:_}:{},...L?{networkRequests:L}:ue?{networkRequests:ue}:{},...ce?{apiCalls:ce}:{},...pe?{protocolAssertions:pe}:{}});try{let I=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(I==="realtime"||I==="both")){let M=this.cloudClient.getAccessToken();M&&ys(this.cloudClient.getEndpoint(),M,this.cloudRunId,this.buildCloudTestPayload(C));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let I=et(m,u,e.id??"",n.retry),M=n.retry===e.results.length-1,N={id:I,navigations:l.navigations,apiAssertions:l.apiAssertions,actions:S??[],artifacts:T,visual:w,failureDiagnostic:c,hasNetworkFile:l.networkRequestsFile!==null,networkRequestsCount:l.networkRequestsCount,hasConsoleFile:l.consoleLogsFile!==null,consoleLogsCount:l.consoleLogsCount,hasApiCallsFile:l.apiCallsFile!==null,apiCallsCount:l.apiCallsCount,startedAt:o};this.streamingWriter.writeTestDetail(I,N,{networkRequestsFile:l.networkRequestsFile,consoleLogsFile:l.consoleLogsFile,apiCallsFile:l.apiCallsFile});let j={id:I,title:u[u.length-1]??e.title,titlePath:u,filePath:m,status:a,duration:n.duration,project:u[1]??"",retryIndex:n.retry,tags:d,hasNetworkData:l.networkRequestsCount>0,hasConsoleData:l.consoleLogsCount>0,hasArtifacts:T!==null,hasActionSteps:(S?.length??0)>0,visualCount:w?.length??0,visualFailedCount:w?.filter(P=>P.status==="failed").length??0,domChangeCount:w?.reduce((P,re)=>P+(re.domChangeCount??0),0)??0,...(()=>{let P=w?.find(re=>re.diff);return P?.diff?{visualDiffPath:P.diff}:{}})(),errorMessage:Xl(c?.message),networkCount:l.networkRequestsCount,consoleCount:l.consoleLogsCount,actionCount:S?.length??0,testType:y,apiCallCount:l.apiCallsCount,...l.apiStatusMix?{apiStatusMix:l.apiStatusMix}:{},assertionsPassed:We(l.apiAssertions,"passed"),assertionsFailed:We(l.apiAssertions,"failed"),...(()=>{let P=Fs(l.apiAssertions);return P?{firstFailedAssertion:P}:{}})(),isRetry:!M,retryGroupKey:tt(m,u,e.id??"")};if(this.testIndex.push(j),M)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(`${m}::${u.join(" > ")}`,Os(n.retry,z,l.apiAssertions,l.navigations,l.networkRequestsCount,l.consoleLogsCount,S)),(T||w)&&this.pendingArtifactEntries.push({testId:h,artifacts:T??{},visual:w,outputDir:path.dirname(this.config.outputPath)}),C.actions=null,C.apiAssertions=null,C.navigations=[],C.artifacts=null,C.failure=null,C.networkRequestsFile=null,C.consoleLogsFile=null,C.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(C),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),n=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-n,o=this.activeReportMode==="streaming"?this.testIndex.some(d=>d.status!=="skipped"):this.collectedTests.some(d=>d.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
4295
+ `),{navigations:s,apiAssertions:a,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:l,apiCallsFile:c,apiCallsCount:u,apiStatusMix:f}}function ze(t=process.env){let e=wl(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 wl(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var Rl=5,je=[1e3,3e3,9e3],ie=3,dr=3e4,Al={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip",".json":"application/json"},or=0,lr=[];async function _l(){or>=Rl&&await new Promise(t=>lr.push(t)),or++;}function Il(){or--,lr.length>0&&lr.shift()();}async function Ve(t){return new Promise(e=>setTimeout(e,t))}function Ml(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return Al[e]??"application/octet-stream"}function El(t){try{return fs$1.statSync(t).size}catch{return 0}}async function Pl(t,e,r,n,s){let a=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:s,type:r.type,sizeBytes:n});for(let i=0;i<ie;i++)try{let d=await J(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o},dr);if(d.ok)return await d.json();if(d.status>=500&&i<ie-1){await Ve(je[i]);continue}return null}catch{if(i<ie-1){await Ve(je[i]);continue}return null}return null}async function Ll(t,e,r,n){let s=us(n,dr);for(let a=0;a<ie;a++)try{let o=fs$1.createReadStream(e),i=stream.Readable.toWeb(o),d=await J(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(n)},body:i,duplex:"half"},s);if(d.ok)return !0;if(d.status>=500&&a<ie-1){await Ve(je[a]);continue}return !1}catch{if(a<ie-1){await Ve(je[a]);continue}return false}return false}async function Nl(t,e,r){let n=`${t}/artifacts/confirm`;try{return (await J(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})},dr)).ok}catch{return false}}async function Dl(t,e,r,n){let s=El(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=Ml(r.filePath);await _l();try{let o=await Pl(t,e,r,s,a);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await Ll(o.uploadUrl,r.filePath,a,s))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let d=await Nl(t,e,o.artifactId);return {success:d,storageKey:o.storageKey,artifactId:o.artifactId,error:d?null:"confirm_failed"}}finally{Il();}}async function Is(t,e,r,n,s){let a=new Map,o=r.map(async i=>{if(s?.expired()){a.set(i.filePath,{success:false,storageKey:null,artifactId:null,error:"upload_budget_exhausted"});return}let d=await Dl(t,e,i,n);a.set(i.filePath,d);});return await Promise.allSettled(o),a}function ur(t){let r=t.getGitMetadata()?.remoteUrl;return r?be(r):t.getConfig()?.projectName??xe(process.cwd())}async function Ms(t,e,r,n,s){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=V(),d=ze(),l=Fe();return (await ms(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:ur(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:n,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:s??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...l?{runType:l}:{},testType:"e2e"}))?.runId??null}var Bl=[{field:"baseline",keyField:"baselineKey",type:"baseline"},{field:"actual",keyField:"actualKey",type:"screenshot"},{field:"diff",keyField:"diffKey",type:"diff"},{field:"baselineDom",keyField:"baselineDomKey",type:"dom"},{field:"actualDom",keyField:"actualDomKey",type:"dom"}],Ol=true,ql=50,cr={keyMap:new Map,visualKeyMap:new Map,total:0,uploaded:0};async function Ul(t,e,r,n,s){let a=new Map,o=new Map;if(!(e?.uploadArtifacts??Ol)||!await t.ensureValidToken())return cr;let l=[],c=new Map,u=new Map;for(let h of n){if(h.artifacts.screenshot){let y=path.join(h.outputDir,h.artifacts.screenshot);l.push({filePath:y,runId:r,testId:h.testId,type:"screenshot"}),c.set(y,{testId:h.testId,field:"screenshot"});}if(h.artifacts.video){let y=path.join(h.outputDir,h.artifacts.video);l.push({filePath:y,runId:r,testId:h.testId,type:"video"}),c.set(y,{testId:h.testId,field:"video"});}if(h.artifacts.trace){let y=path.join(h.outputDir,h.artifacts.trace);l.push({filePath:y,runId:r,testId:h.testId,type:"trace"}),c.set(y,{testId:h.testId,field:"trace"});}let v=h.visual??[];for(let y=0;y<v.length;y++){let b=v[y];if(b)for(let k of Bl){let A=b[k.field];if(!A)continue;let E=path.join(h.outputDir,A);l.push({filePath:E,runId:r,testId:h.testId,type:k.type}),c.set(E,{testId:h.testId,field:"visual",visualIndex:y,visualKey:k.keyField});}}}if(l.length===0)return cr;let f=e?.artifactMaxSizeMb??ql,p=await Is(t.getEndpoint(),t.getAccessToken(),l,f,s),g=new Map;for(let[h,v]of p){if(!v.success||!v.storageKey)continue;let y=c.get(h);if(!y)continue;let b=g.get(y.testId)??{};if(y.field==="screenshot"&&(b.screenshotKey=v.storageKey),y.field==="video"&&(b.videoKey=v.storageKey),y.field==="trace"&&(b.traceKey=v.storageKey),y.field==="visual"&&y.visualIndex!==void 0&&y.visualKey){let k=u.get(y.testId)??new Map,A=k.get(y.visualIndex)??{};A[y.visualKey]=v.storageKey,k.set(y.visualIndex,A),u.set(y.testId,k);}g.set(y.testId,b);}for(let h of n){if(h.visual&&h.visual.length>0){let y=u.get(h.testId);o.set(h.testId,h.visual.map((b,k)=>({...b,...y?.get(k)??{}})));}let v=g.get(h.testId);a.set(h.testId,{...h.artifacts,...v?.screenshotKey?{screenshotKey:v.screenshotKey}:{},...v?.videoKey?{videoKey:v.videoKey}:{},...v?.traceKey?{traceKey:v.traceKey}:{}});}let m=Array.from(p.values()).filter(h=>h.success).length;return m>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${m} artifact(s) to cloud storage.
4296
+ `),{keyMap:a,visualKeyMap:o,total:l.length,uploaded:m}}async function pr(t,e,r,n,s,a,o,i,d,l,c){let u={realtimeFinalizeAttempted:false,realtimeFinalized:false,batchAttempted:false,batchAcknowledged:false,artifactsTotal:0,artifactsUploaded:0,failureReason:null},f=new Be(e?.uploadBudgetMs??12e4),p=g=>{u.failureReason||(u.failureReason=g);};try{if(t.isCloudMode()&&s&&(r==="realtime"||r==="both")){u.realtimeFinalizeAttempted=!0;let h=await t.ensureValidToken(),v=t.getGitMetadata(),y=Xt(c),b={finishedAt:o,duration:i,summary:d,...v?.commitMessage?{commitMessage:v.commitMessage}:{},testType:y.testType,...y.testType==="api"?{apiProtocol:y.apiProtocol,metadata:y.metadata}:{}};if(h){let k=await ys(t.getEndpoint(),t.getAccessToken(),s,b);if(u.realtimeFinalized=k,!k){p("finalize_failed_after_retries");let A=e?.queueDirectory??".testrelic/queue";we(A,n,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",b,{"Content-Type":"application/json"});}}else {p(t.getFailureReason()??"token_invalid");let k=e?.queueDirectory??".testrelic/queue";we(k,n,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${s}/finalize`,"POST",b,{"Content-Type":"application/json"});}}let g=new Map,m=new Map;if(t.isCloudMode()&&l&&l.length>0){let h=await Ul(t,e,n,l,f);g=h.keyMap,m=h.visualKeyMap,u.artifactsTotal=h.total,u.artifactsUploaded=h.uploaded;}if(t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(u.batchAttempted=!0,await t.ensureValidToken()){let v=t.getGitMetadata(),y=V(),b=ur(t),k=zl(jl(a,g),m),A=Zt(k,b,v,y,Hl(c,m),ze()),E=await hs(t.getEndpoint(),t.getAccessToken(),A,async()=>await t.ensureValidToken()?t.getAccessToken():null,e?.timeout,f);if(u.batchAcknowledged=E.success,!E.success){let T=E;p(T.reason);let x=e?.queueDirectory??".testrelic/queue";we(x,n,"batch",T.reason,T.targetEndpoint,T.method,T.payload,{"Content-Type":"application/json"});}}else {p(t.getFailureReason()??"token_invalid");let v=e?.queueDirectory??".testrelic/queue",y=t.getGitMetadata(),b=V(),k=ur(t),A=Zt(a,k,y,b,void 0,ze());we(v,n,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",A,{"Content-Type":"application/json"});}await t.dispose();}catch(g){p(g instanceof Error?g.message:"unexpected_upload_error");try{await t.dispose();}catch{}}return u}function Hl(t,e){return !t||e.size===0?t:t.map(r=>{let n=e.get(r.testId);return n?{...r,visual:n}:r})}function zl(t,e){if(e.size===0)return t;let r=t.timeline.map(n=>{let s=n.tests;if(!Array.isArray(s))return n;let a=false,o=s.map(i=>{let d=i.testId;if(!d)return i;let l=e.get(d);return l?(a=true,{...i,visual:l}):i});return a?{...n,tests:o}:n});return {...t,timeline:r}}function jl(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}}var Vl=new Set(["batch","realtime","both"]),ke=Object.freeze({attempted:false,acknowledged:false,runId:null,endpoint:null,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:"cloud reporting was never initialised"});function $l(t){switch(t){case "no_api_key":return "cloud mode off \u2014 no API key configured";case "cloud_unreachable":case "network_error":return "cloud endpoint unreachable \u2014 the run stayed local";case "invalid_api_key":return "API key rejected as invalid or revoked \u2014 the run stayed local";case "expired_api_key":return "API key has expired \u2014 the run stayed local";case "validation_error":return "API key format rejected \u2014 the run stayed local";case "rate_limited":return "rate limited during authentication \u2014 the run stayed local";case "auth_timeout":return "authentication timed out \u2014 the run stayed local";case "token_expired_no_refresh":case "token_refresh_failed":case "token_refresh_error":return "access token could not be refreshed \u2014 the run stayed local";case "init_error":return "cloud initialisation timed out \u2014 the run stayed local";case "unexpected_error":return "cloud initialisation failed \u2014 the run stayed local";default:return t?`cloud mode off (${t}) \u2014 the run stayed local`:"cloud mode off \u2014 the run stayed local"}}function Es(t,e,r){if(!t)return ke;if(!t.isCloudMode())return {...ke,detail:$l(t.getFailureReason())};let n=e??"batch";if(!Vl.has(n))return {...ke,detail:`upload strategy '${n}' is not recognised \u2014 nothing was sent`};let s=t.getEndpoint(),a=n==="realtime"||n==="both";return a&&r?{attempted:true,acknowledged:true,runId:r,endpoint:s,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:null}:{attempted:true,acknowledged:false,runId:null,endpoint:s,finalized:false,artifactsUploaded:0,artifactsTotal:0,detail:a?"run init failed \u2014 the platform did not acknowledge this run":`upload runs at the end of the run under the '${n}' strategy \u2014 not sent yet`}}function fr(t,e,r){if(!t.attempted)return t;if(!e)return {...t,detail:t.acknowledged?"upload timed out before it completed \u2014 the run may be incomplete on the platform":"upload timed out before the platform acknowledged this run",acknowledged:t.acknowledged};let n=t.acknowledged||e.batchAcknowledged,s=t.runId??(e.batchAcknowledged?r:null),a=e.realtimeFinalizeAttempted?e.realtimeFinalized:e.batchAcknowledged,o=null;return n?a||(o="run acknowledged but not closed out \u2014 finalize failed and was queued for retry"):o=e.failureReason?`upload failed (${e.failureReason}) \u2014 queued locally for retry`:"upload failed \u2014 the platform did not acknowledge this run",{attempted:true,acknowledged:n,runId:s,endpoint:t.endpoint,finalized:a,artifactsUploaded:e.artifactsUploaded,artifactsTotal:e.artifactsTotal,detail:o}}function Y(t){try{return fs$1.readFileSync(t,"utf-8").split(`
4297
+ `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function Zl(t){if(!t)return null;let e=t.split(`
4298
+ `).map(a=>a.trim()).filter(Boolean);if(e.length===0)return null;let r=e.filter(a=>!/^Error:\s*expect\(/.test(a));if(r.length===0)return e[0]??null;let n=r[0],s=r[1];return s!==void 0&&/^Received:/.test(s)&&/^Expected:/.test(n)?`${n} \xB7 ${s}`:n}function hr(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 Ql(t,e,r){let n=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,16)}function ed(t){return t.length<=3?"":t[t.length-2]}function td(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function Os(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 rd(t){let e={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},r=e;for(let n of t){let s=typeof n.responseStatusCode=="number"?n.responseStatusCode:null;r[Os(s)]++;}return e}function Ds(t){if(t){for(let e of t)if(e.status==="failed")return {type:e.type,expected:Fs(e.expected),actual:Fs(e.actual),...e.expression?{expression:e.expression}:{}}}}function Fs(t){if(t===void 0)return "undefined";if(t===null)return "null";let e;if(typeof t=="string")e=t;else try{e=JSON.stringify(t)??String(t);}catch{e=String(t);}return e.length>200?e.slice(0,200)+"\u2026":e}function We(t,e){if(!t)return 0;let r=0;for(let n of t)n.status===e&&r++;return r}function qs(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&qs(r.children,e);}function nd(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:ee(e,50),p95:ee(e,95),p99:ee(e,99)}}var Us=2e5,Ge=1e5;function Bs(t,e,r,n,s,a,o){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:o?.length??0,actionCategories:{}};if(e){let l=new Set;for(let c of e){let u=typeof c.method=="string"?c.method:"OTHER";i.methodCounts[u]=(i.methodCounts[u]??0)+1;let f=typeof c.url=="string"?c.url:null;f&&l.size<Ge&&l.add(jt(f));let p=typeof c.responseStatusCode=="number"?c.responseStatusCode:typeof c.statusCode=="number"?c.statusCode:null,g=p!==null&&Number.isFinite(p)?p:null;i.statusRanges[Os(g)]++;let m=typeof c.responseTimeMs=="number"?c.responseTimeMs:typeof c.durationMs=="number"?c.durationMs:null;m!==null&&Number.isFinite(m)&&i.responseTimes.length<Us&&i.responseTimes.push(m);}i.apiUrls=Array.from(l);}for(let l of r)l.status==="passed"?i.passedAssertions++:i.failedAssertions++;let d=new Set;for(let l of n)l.url&&d.size<Ge&&d.add(l.url);return i.navUrls=Array.from(d),o&&qs(o,i.actionCategories),i}function sd(){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 ad(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 id(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function od(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 ld(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(l=>l===`@${d}`||l===d))return d;let o=e.replace(/\\/g,"/"),i=["e2e","api","unit"];for(let d of i)if(o.includes(`/${d}/`))return d;return s}var dd="__testrelic_api_config";function cd(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var Ke=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.navigationsCaptured=false;this.memoryPressureWarned=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.updatingSnapshots=false;this.cloudReceipt=ke;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,visualChecks:0,visualFailures:0,visualDomChanges:0};this.streamingTestAgg=new Map;this.config=Ur(e),this.apiConfig=qr(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{this.rootDir=e.rootDir;let n=e.updateSnapshots;if(this.updatingSnapshots=n==="all"||n==="changed",this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let i=r.allTests().length;this.activeReportMode=i>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let s=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${s} tests)
4299
+ `),this.activeReportMode==="streaming"){let i=path.dirname(this.config.outputPath);this.streamingWriter=new he(i);let d=()=>{if(this.streamingWriter){try{this.streamingWriter.writeIndex(this.testIndex);let l={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(),cloudUpload:this.cloudReceipt};this.streamingWriter.writeSummary(l);}catch{}this.streamingWriter.dispose();}try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let l=this.cloudClient.getAccessToken();l&&nr(this.cloudClient.getEndpoint(),l,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",d),process.on("SIGINT",d);}if(this.config.includeArtifacts){let i=path.dirname(this.config.outputPath);this.runTimestamp=Cn(path.join(i,"artifacts"));try{Jn(path.join(i,"artifacts"));}catch{}}let a=V();this.detectedOs=id(),this.detectedSource=ad(a);let o=await Q(async()=>(this.cloudClient=new He(this.config.cloud),await this.cloudClient.initialize(),Ms(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource)),Xn,"Cloud initialization");if(this.cloudRunId=o??null,o===void 0&&this.cloudClient?.switchToLocalMode("init_error"),this.cloudReceipt=Es(this.cloudClient,this.config.cloud?.uploadStrategy,this.cloudRunId),this.activeReportMode!=="streaming"){let i=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let d=this.cloudClient.getAccessToken();d&&nr(this.cloudClient.getEndpoint(),d,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",i),process.on("SIGINT",i);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:dd,description:cd(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let n=r,s=e.outcome(),a;s==="flaky"?a="flaky":s==="skipped"?a="skipped":a=hr(n.status);let o=n.startTime.toISOString(),i=new Date(n.startTime.getTime()+n.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(I=>I.type==="tag").map(I=>I.description??""),l=_s(n.attachments,e.annotations,e.title,a==="skipped");(l.navigations.length>0||l.networkRequestsCount>0||l.apiCallsCount>0)&&(this.fixtureDataReceived=!0),l.navigations.length>0&&(this.navigationsCaptured=!0),!this.config.captureNavigation&&l.navigations.length>0&&(l={...l,navigations:[]});let c=null;if(a==="failed"||a==="flaky"){let M=(a==="flaky"?e.results.find(N=>N.status!=="passed")?.errors??[]:n.errors)[0];if(M){let N=zr(this.config.redactPatterns),j=M.location?.file??null,P=l.apiAssertions.find(aa=>aa.status==="failed")?.location??null,re=P!==null&&(j===null||path.resolve(j)!==path.resolve(e.location.file)),Sr=re?P.file:j,Qe=re?P.line:M.location?.line??null,fe=null;this.config.includeCodeSnippets&&Qe!==null&&Sr&&(fe=Hr(Sr,Qe,this.config.codeContextLines),fe&&(fe=N(fe))),c={message:N(se(M.message??"Unknown error")),line:Qe,code:fe,stack:this.config.includeStackTrace&&M.stack?N(se(M.stack)):null};}}let u=e.titlePath().filter(Boolean),f=path.relative(this.rootDir||".",e.location.file).replace(/\\/g,"/"),p=ed(u),g=u.join(" > "),m=f,h=Ql(m,p,g),v=ld(d,m,e),y=v!=="mobile"&&l.apiCallsCount>0?"api":v,b=s==="flaky",k=td(e.results),A=hr(e.expectedStatus),E=hr(n.status),T=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments){let I=path.dirname(this.config.outputPath),M=u[u.length-1]??e.title;T=Sn(n.attachments,M,n.retry,I,this.runTimestamp||void 0,h);}let x=null;if(this.config.includeArtifacts&&a!=="skipped"&&n.attachments)try{let I=qn(n.attachments,{updatingSnapshots:this.updatingSnapshots,failureMessage:n.errors.map(M=>M.message??"").join(`
4300
+ `)});if(I.length>0){let M=path.dirname(this.config.outputPath),N=u[u.length-1]??e.title;x=Rn(I,N,n.retry,M,this.runTimestamp||void 0,h);}}catch{}let S=this.config.includeActionSteps&&n.steps?ns(n.steps,n.startTime):null,w=od(e),C={titlePath:u,title:g,status:a,duration:n.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:n.retry,tags:d,failure:c,specFile:f,navigations:l.navigations,testId:h,filePath:m,suiteName:p,testType:y,isFlaky:b,retryStatus:k,expectedStatus:A,actualStatus:E,artifacts:T,visual:x,apiAssertions:l.apiAssertions,actions:S,networkRequestsFile:l.networkRequestsFile,networkRequestsCount:l.networkRequestsCount,consoleLogsFile:l.consoleLogsFile,consoleLogsCount:l.consoleLogsCount,apiCallsFile:l.apiCallsFile,apiCallsCount:l.apiCallsCount,apiStatusMix:l.apiStatusMix,browser:w,os:this.detectedOs||void 0,source:this.detectedSource||void 0},_=l.consoleLogsFile&&l.consoleLogsCount>0?Y(l.consoleLogsFile):void 0,L=l.networkRequestsFile&&l.networkRequestsCount>0?Y(l.networkRequestsFile):void 0,z=l.apiCallsFile&&l.apiCallsCount>0?Y(l.apiCallsFile):void 0,ce=z?Qt(z):void 0,ue=!L&&z?er(z):void 0,pe=l.apiAssertions&&l.apiAssertions.length>0?tr(l.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:h,title:g,status:a,duration:n.duration,suiteName:p,filePath:m,testType:y,isFlaky:b,startedAt:o,completedAt:i,tags:d,failure:c,retry:n.retry,retryCount:e.results.length-1,retryStatus:k,browser:w,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...S&&S.length>0?{actions:S}:{},...l.navigations&&l.navigations.length>0?{navigations:l.navigations}:{},..._?{consoleLogs:_}:{},...L?{networkRequests:L}:ue?{networkRequests:ue}:{},...ce?{apiCalls:ce}:{},...pe?{protocolAssertions:pe}:{},...x&&x.length>0?{visual:x}:{}});try{let I=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(I==="realtime"||I==="both")){let M=this.cloudClient.getAccessToken();M&&vs(this.cloudClient.getEndpoint(),M,this.cloudRunId,this.buildCloudTestPayload(C));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let I=et(m,u,e.id??"",n.retry),M=n.retry===e.results.length-1,N={id:I,navigations:l.navigations,apiAssertions:l.apiAssertions,actions:S??[],artifacts:T,visual:x,failureDiagnostic:c,hasNetworkFile:l.networkRequestsFile!==null,networkRequestsCount:l.networkRequestsCount,hasConsoleFile:l.consoleLogsFile!==null,consoleLogsCount:l.consoleLogsCount,hasApiCallsFile:l.apiCallsFile!==null,apiCallsCount:l.apiCallsCount,startedAt:o};this.streamingWriter.writeTestDetail(I,N,{networkRequestsFile:l.networkRequestsFile,consoleLogsFile:l.consoleLogsFile,apiCallsFile:l.apiCallsFile});let j={id:I,title:u[u.length-1]??e.title,titlePath:u,filePath:m,status:a,duration:n.duration,project:u[1]??"",retryIndex:n.retry,tags:d,hasNetworkData:l.networkRequestsCount>0,hasConsoleData:l.consoleLogsCount>0,hasArtifacts:T!==null,hasActionSteps:(S?.length??0)>0,visualCount:x?.length??0,visualFailedCount:x?.filter(P=>P.status==="failed").length??0,domChangeCount:x?.reduce((P,re)=>P+(re.domChangeCount??0),0)??0,...(()=>{let P=x?.find(re=>re.diff);return P?.diff?{visualDiffPath:P.diff}:{}})(),errorMessage:Zl(c?.message),networkCount:l.networkRequestsCount,consoleCount:l.consoleLogsCount,actionCount:S?.length??0,testType:y,apiCallCount:l.apiCallsCount,...l.apiStatusMix?{apiStatusMix:l.apiStatusMix}:{},assertionsPassed:We(l.apiAssertions,"passed"),assertionsFailed:We(l.apiAssertions,"failed"),...(()=>{let P=Ds(l.apiAssertions);return P?{firstFailedAssertion:P}:{}})(),isRetry:!M,retryGroupKey:tt(m,u,e.id??"")};if(this.testIndex.push(j),M)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(`${m}::${u.join(" > ")}`,Bs(n.retry,z,l.apiAssertions,l.navigations,l.networkRequestsCount,l.consoleLogsCount,S)),(T||x)&&this.pendingArtifactEntries.push({testId:h,artifacts:T??{},visual:x,outputDir:path.dirname(this.config.outputPath)}),C.actions=null,C.apiAssertions=null,C.navigations=[],C.artifacts=null,C.failure=null,C.networkRequestsFile=null,C.consoleLogsFile=null,C.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(C),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),n=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-n,o=this.activeReportMode==="streaming"?this.testIndex.some(d=>d.status!=="skipped"):this.collectedTests.some(d=>d.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
4301
4301
  \u26A0 TestRelic: No fixture data received from any test.
4302
4302
  To enable network logs, video sync, and Test Navigation tracking, import the TestRelic fixture:
4303
4303
  import { test, expect } from '@testrelic/playwright-analytics/fixture';
@@ -4306,18 +4306,18 @@ ${s}
4306
4306
 
4307
4307
  `),this.config.captureNavigation?this.fixtureDataReceived&&!this.navigationsCaptured&&o&&process.stderr.write(`[testrelic] Test Navigation: 0 navigation events captured this run. Navigation is recorded automatically on page.goto()/clicks; if you expected a navigation graph, ensure your tests drive page navigations (and use the '@testrelic/playwright-analytics/fixture' import).
4308
4308
  `):process.stderr.write(`[testrelic] Test Navigation capture is disabled (captureNavigation: false). Remove the option or set it to true to capture the navigation graph.
4309
- `),await Q(()=>kn(),zt,"Artifact flush");let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=path.dirname(this.config.outputPath);i=Gn(d,this.runTimestamp);let l=path.join(d,"artifact-manifest.json"),c=JSON.stringify(i),u=l+".tmp";fs$1.writeFileSync(u,c,"utf-8"),fs$1.renameSync(u,l);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await Q(()=>this.finalizeStreamingReport(r,a,e,i),Ut,"Report finalization");else {let d=this.buildTimeline(),l=new Map;for(let p of this.collectedTests){let g=l.get(p.testId);(!g||p.retry>g.retry)&&l.set(p.testId,p);}let c=Array.from(l.values()),u=ns(c,d.length),f={schemaVersion:Ce,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:u,ci:V(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(f),await Q(()=>Mt(f,this.config,i),zt,"HTML report write"),Vt(u,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let p=this.collectArtifactEntries(),g=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0;let m=await Q(()=>pr(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,f,r,a,u,p,g),Ut,"Cloud upload");this.cloudReceipt=fr(this.cloudReceipt,m,this.testRunId);}}}catch{}finally{await this.disposeCloudClient();}}async disposeCloudClient(){let e=this.cloudClient;e&&(this.cloudClient=null,await Q(()=>e.dispose(),Qn,"Cloud client shutdown"));}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let n of this.collectedTests)(n.artifacts||n.visual)&&r.push({testId:n.testId,artifacts:n.artifacts??{},visual:n.visual,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,visualChecks:0,visualFailures:0,visualDomChanges:0};let a=new Map,o=new Map;for(let h of this.testIndex){let v=`${h.filePath}::${h.titlePath.join(" > ")}`,y=a.get(v);(y===void 0||h.retryIndex>y)&&a.set(v,h.retryIndex);}let i=0;for(let h of this.testIndex){let v=`${h.filePath}::${h.titlePath.join(" > ")}`,y=a.get(v);if(h.isRetry=h.retryIndex<y,h.isRetry)continue;switch(i++,this.summaryCounters.total++,h.status){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.summaryCounters.visualChecks+=h.visualCount??0,this.summaryCounters.visualFailures+=h.visualFailedCount??0,this.summaryCounters.visualDomChanges+=h.domChangeCount??0;let b=o.get(h.filePath);switch(b||(b={filePath:h.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},o.set(h.filePath,b)),b.total++,h.status){case "passed":b.passed++;break;case "failed":b.failed++;break;case "flaky":b.flaky++;break;case "skipped":b.skipped++;break;case "timedout":b.timedOut++;break}}let d=Array.from(o.values()),l=nd();for(let h of this.streamingTestAgg.values()){l.volApiCalls+=h.apiCalls,l.volAssertions+=h.assertions,l.volNavigations+=h.navigations,l.volNetworkRequests+=h.networkRequests,l.volConsoleLogs+=h.consoleLogs,l.volActionSteps+=h.actionSteps;for(let v in h.methodCounts)l.methodCounts[v]=(l.methodCounts[v]??0)+h.methodCounts[v];l.statusRanges["2xx"]+=h.statusRanges["2xx"],l.statusRanges["3xx"]+=h.statusRanges["3xx"],l.statusRanges["4xx"]+=h.statusRanges["4xx"],l.statusRanges["5xx"]+=h.statusRanges["5xx"],l.statusRanges.error+=h.statusRanges.error,l.passedAssertions+=h.passedAssertions,l.failedAssertions+=h.failedAssertions;for(let v in h.actionCategories)l.actionCategoryCounts[v]=(l.actionCategoryCounts[v]??0)+h.actionCategories[v];for(let v of h.apiUrls){if(l.apiUrlSet.size>=Ge)break;l.apiUrlSet.add(v);}for(let v of h.navUrls){if(l.navUrlSet.size>=Ge)break;l.navUrlSet.add(v);}for(let v of h.responseTimes){if(l.responseTimes.length>=Us)break;l.responseTimes.push(v);}}this.summaryCounters.totalApiCalls=l.volApiCalls,this.summaryCounters.totalAssertions=l.volAssertions,this.summaryCounters.totalNavigations=l.volNavigations,this.summaryCounters.totalNetworkRequests=l.volNetworkRequests,this.summaryCounters.totalConsoleLogs=l.volConsoleLogs,this.summaryCounters.totalActionSteps=l.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}
4310
- `);let u={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:l.apiUrlSet.size,apiCallsByMethod:{...l.methodCounts},apiCallsByStatusRange:{"2xx":l.statusRanges["2xx"],"3xx":l.statusRanges["3xx"],"4xx":l.statusRanges["4xx"],"5xx":l.statusRanges["5xx"],error:l.statusRanges.error},apiResponseTime:rd(l.responseTimes),totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:l.passedAssertions,failedAssertions:l.failedAssertions,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:l.navUrlSet.size,totalTimelineSteps:i,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{...l.actionCategoryCounts},visualChecks:this.summaryCounters.visualChecks,visualFailures:this.summaryCounters.visualFailures,visualDomChanges:this.summaryCounters.visualDomChanges},f={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:u,validation:c,writeErrors:this.streamingWriter.getWriteErrors(),cloudUpload:this.cloudReceipt};this.streamingWriter.writeSummary(f);let p={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(p),await Mt(this.buildStreamingReport(f,u,e,r),this.config,s),Vt(u,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let g=this.streamingWriter.getReportDir();process.stderr.write(`[testrelic] Streaming report written to ${g}
4309
+ `),await Q(()=>kn(),zt,"Artifact flush");let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=path.dirname(this.config.outputPath);i=Wn(d,this.runTimestamp);let l=path.join(d,"artifact-manifest.json"),c=JSON.stringify(i),u=l+".tmp";fs$1.writeFileSync(u,c,"utf-8"),fs$1.renameSync(u,l);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await Q(()=>this.finalizeStreamingReport(r,a,e,i),Ht,"Report finalization");else {let d=this.buildTimeline(),l=new Map;for(let p of this.collectedTests){let g=l.get(p.testId);(!g||p.retry>g.retry)&&l.set(p.testId,p);}let c=Array.from(l.values()),u=rs(c,d.length),f={schemaVersion:Ce,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:u,ci:V(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(f),await Q(()=>Mt(f,this.config,i),zt,"HTML report write"),Vt(u,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let p=this.collectArtifactEntries(),g=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0;let m=await Q(()=>pr(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,f,r,a,u,p,g),Ht,"Cloud upload");this.cloudReceipt=fr(this.cloudReceipt,m,this.testRunId);}}}catch{}finally{await this.disposeCloudClient();}}async disposeCloudClient(){let e=this.cloudClient;e&&(this.cloudClient=null,await Q(()=>e.dispose(),Zn,"Cloud client shutdown"));}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let n of this.collectedTests)(n.artifacts||n.visual)&&r.push({testId:n.testId,artifacts:n.artifacts??{},visual:n.visual,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,visualChecks:0,visualFailures:0,visualDomChanges:0};let a=new Map,o=new Map;for(let h of this.testIndex){let v=`${h.filePath}::${h.titlePath.join(" > ")}`,y=a.get(v);(y===void 0||h.retryIndex>y)&&a.set(v,h.retryIndex);}let i=0;for(let h of this.testIndex){let v=`${h.filePath}::${h.titlePath.join(" > ")}`,y=a.get(v);if(h.isRetry=h.retryIndex<y,h.isRetry)continue;switch(i++,this.summaryCounters.total++,h.status){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.summaryCounters.visualChecks+=h.visualCount??0,this.summaryCounters.visualFailures+=h.visualFailedCount??0,this.summaryCounters.visualDomChanges+=h.domChangeCount??0;let b=o.get(h.filePath);switch(b||(b={filePath:h.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},o.set(h.filePath,b)),b.total++,h.status){case "passed":b.passed++;break;case "failed":b.failed++;break;case "flaky":b.flaky++;break;case "skipped":b.skipped++;break;case "timedout":b.timedOut++;break}}let d=Array.from(o.values()),l=sd();for(let h of this.streamingTestAgg.values()){l.volApiCalls+=h.apiCalls,l.volAssertions+=h.assertions,l.volNavigations+=h.navigations,l.volNetworkRequests+=h.networkRequests,l.volConsoleLogs+=h.consoleLogs,l.volActionSteps+=h.actionSteps;for(let v in h.methodCounts)l.methodCounts[v]=(l.methodCounts[v]??0)+h.methodCounts[v];l.statusRanges["2xx"]+=h.statusRanges["2xx"],l.statusRanges["3xx"]+=h.statusRanges["3xx"],l.statusRanges["4xx"]+=h.statusRanges["4xx"],l.statusRanges["5xx"]+=h.statusRanges["5xx"],l.statusRanges.error+=h.statusRanges.error,l.passedAssertions+=h.passedAssertions,l.failedAssertions+=h.failedAssertions;for(let v in h.actionCategories)l.actionCategoryCounts[v]=(l.actionCategoryCounts[v]??0)+h.actionCategories[v];for(let v of h.apiUrls){if(l.apiUrlSet.size>=Ge)break;l.apiUrlSet.add(v);}for(let v of h.navUrls){if(l.navUrlSet.size>=Ge)break;l.navUrlSet.add(v);}for(let v of h.responseTimes){if(l.responseTimes.length>=Us)break;l.responseTimes.push(v);}}this.summaryCounters.totalApiCalls=l.volApiCalls,this.summaryCounters.totalAssertions=l.volAssertions,this.summaryCounters.totalNavigations=l.volNavigations,this.summaryCounters.totalNetworkRequests=l.volNetworkRequests,this.summaryCounters.totalConsoleLogs=l.volConsoleLogs,this.summaryCounters.totalActionSteps=l.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}
4310
+ `);let u={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:l.apiUrlSet.size,apiCallsByMethod:{...l.methodCounts},apiCallsByStatusRange:{"2xx":l.statusRanges["2xx"],"3xx":l.statusRanges["3xx"],"4xx":l.statusRanges["4xx"],"5xx":l.statusRanges["5xx"],error:l.statusRanges.error},apiResponseTime:nd(l.responseTimes),totalAssertions:this.summaryCounters.totalAssertions,passedAssertions:l.passedAssertions,failedAssertions:l.failedAssertions,totalNavigations:this.summaryCounters.totalNavigations,uniqueNavigationUrls:l.navUrlSet.size,totalTimelineSteps:i,totalActionSteps:this.summaryCounters.totalActionSteps,actionStepsByCategory:{...l.actionCategoryCounts},visualChecks:this.summaryCounters.visualChecks,visualFailures:this.summaryCounters.visualFailures,visualDomChanges:this.summaryCounters.visualDomChanges},f={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:u,validation:c,writeErrors:this.streamingWriter.getWriteErrors(),cloudUpload:this.cloudReceipt};this.streamingWriter.writeSummary(f);let p={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(p),await Mt(this.buildStreamingReport(f,u,e,r),this.config,s),Vt(u,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let g=this.streamingWriter.getReportDir();process.stderr.write(`[testrelic] Streaming report written to ${g}
4311
4311
  [testrelic] ${this.testIndex.length} test detail files on disk
4312
4312
  [testrelic] View report: npx testrelic serve ${g}
4313
4313
  `),this.streamingWriter.getWriteErrors().length>0&&process.stderr.write(`[testrelic] WARNING: ${this.streamingWriter.getWriteErrors().length} write error(s) during streaming
4314
4314
  `);let m=this.streamingWriter;try{if(this.cloudClient){let h=this.buildStreamingReport(f,u,e,r),v=this.collectArtifactEntries(),y=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0;let b=await pr(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,h,e,r,u,v,y);this.cloudReceipt=fr(this.cloudReceipt,b,this.testRunId);let k={...f,cloudUpload:this.cloudReceipt};try{m.writeSummary(k);}catch{}}}finally{m.dispose();}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:Ce,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:n,totalDuration:s,summary:r,ci:V(),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.
4315
4315
  `),this.switchToStreamingMode()):n>.8&&r>=500&&!this.memoryPressureWarned&&(this.memoryPressureWarned=!0,process.stderr.write(`[testrelic] WARNING: Memory pressure detected (${Math.round(r)} MB used).
4316
4316
  `));}catch{}}switchToStreamingMode(){try{if(this.activeReportMode==="streaming")return;this.activeReportMode="streaming";let e=path.dirname(this.config.outputPath);this.streamingWriter=new he(e);for(let r of this.collectedTests){let n=et(r.filePath,r.titlePath,r.testId,r.retry),s=r.apiCallsFile&&r.apiCallsCount>0?Y(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 o={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(`
4317
- `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,testType:r.testType,apiCallCount:r.apiCallsCount,...r.apiStatusMix?{apiStatusMix:r.apiStatusMix}:s?{apiStatusMix:td(s)}:{},assertionsPassed:We(r.apiAssertions,"passed"),assertionsFailed:We(r.apiAssertions,"failed"),...(()=>{let i=Fs(r.apiAssertions);return i?{firstFailedAssertion:i}:{}})(),isRetry:!1,retryGroupKey:tt(r.filePath,r.titlePath,r.testId)};switch(this.testIndex.push(o),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(" > ")}`,Os(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 rs(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=Y(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,visual:e.visual,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,visual:e.visual??[],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=tr(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=Y(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=Y(e.networkRequestsFile)),e.apiCallsFile){let n=Y(e.apiCallsFile);r.apiCalls=Qt(n),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=er(n));}return r}writeReport(e){try{let r=JSON.stringify(e),n=this.config.outputPath,s=path.dirname(n);fs$1.mkdirSync(s,{recursive:!0});let a=n+".tmp";fs$1.writeFileSync(a,r,"utf-8"),fs$1.renameSync(a,n);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
4318
- `);}}};var gd=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function hd(t){let e=t.toLowerCase();return gd.some(r=>e.includes(r))}var Je=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 q("network")),this.consoleWriter=new q("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(){let e=t.asPatchable(this.page);e.goto=this.origGoto,e.goBack=this.origGoBack,e.goForward=this.origGoForward,e.reload=this.origReload;for(let{event:r,handler:n}of this.listeners)this.page.off(r,n);this.listeners=[],this.records=[],this.pendingRequests.clear(),this.pendingBodyReads=[],this.networkWriter?.close(),this.consoleWriter?.close();}getRecords(){return this.assembleNetworkStats(),this.records}static asPatchable(e){return e}interceptMethods(){let e=this,r=this.page,n=t.asPatchable(r);n.goto=async function(s,a){return e.recordNavigation(s,"goto"),e.origGoto(s,a)},n.goBack=async function(s){let a=await e.origGoBack(s);return e.recordNavigation(r.url(),"back"),a},n.goForward=async function(s){let a=await e.origGoForward(s);return e.recordNavigation(r.url(),"forward"),a},n.reload=async function(s){return e.recordNavigation(r.url(),"refresh"),e.origReload(s)};}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 o=a.url(),i=this.records[this.records.length-1];if(i&&Date.now()-new Date(i.timestamp).getTime()<50&&i.url===o)return;this.recordNavigation(o,"navigation");}catch{}};this.page.on("framenavigated",r),this.listeners.push({event:"framenavigated",handler:r});let n=s=>{try{let a=s,o=a.type(),i=a.text();if(o==="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 l=t.mapConsoleType(o);this.consoleWriter&&(this.consoleWriter.append({level:l,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,l=this.counterForNav(d);l&&l.totalRequests++;try{let c=i,u=String(this.requestIdCounter++),f=c.postData()??null,p={url:c.url(),method:c.method(),resourceType:this.mapResourceType(c.resourceType()),headers:c.headers(),postData:f,postDataTruncated:!1,startedAt:new Date().toISOString(),startTimeMs:Date.now(),navIndex:d};this.pendingRequests.set(u,p),i.__testrelic_id=u;}catch{}};this.page.on("request",s),this.listeners.push({event:"request",handler:s});let a=i=>{try{let d=i,l=d.request().__testrelic_id,c=l?this.pendingRequests.get(l):void 0,u=this.counterForNav(c?c.navIndex:this.records.length-1);if(u){let y=d.status();y>=400&&(u.failedRequests++,u.failedRequestUrls.push(y+" "+d.url()));let b=d.headers()["content-length"];b&&(u.totalBytes+=parseInt(b,10)||0);let k=d.request().resourceType(),A=this.mapResourceType(k);u.byType[A]++;}if(!l||!c)return;this.pendingRequests.delete(l);let f=Date.now()-c.startTimeMs,p=d.headers(),g=p["content-type"]??null,m=parseInt(p["content-length"]??"0",10)||0,h=g?!hd(g):!1,v=(async()=>{let y=null;if(!h)try{y=(await d.body()).toString("utf-8");}catch{}let b={url:c.url,method:c.method,resourceType:c.resourceType,statusCode:d.status(),responseTimeMs:f,startedAt:c.startedAt,requestHeaders:c.headers,requestBody:c.postData,responseBody:y,responseHeaders:p,contentType:g,responseSize:m,requestBodyTruncated:c.postDataTruncated,responseBodyTruncated:!1,isBinary:h,error:null};this.networkWriter&&(this.networkWriter.append(b),this.networkRequestCount++);})();this.pendingBodyReads.push(v);}catch{}};this.page.on("response",a),this.listeners.push({event:"response",handler:a});let o=i=>{let d=i.__testrelic_id,l=d?this.pendingRequests.get(d):void 0,c=this.counterForNav(l?l.navIndex:this.records.length-1);if(c){c.failedRequests++;try{let u=i;c.failedRequestUrls.push("ERR "+u.url());}catch{}}try{let u=i;if(!d||!l)return;this.pendingRequests.delete(d);let f={url:l.url,method:l.method,resourceType:l.resourceType,statusCode:0,responseTimeMs:Date.now()-l.startTimeMs,startedAt:l.startedAt,requestHeaders:l.headers,requestBody:l.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:l.postDataTruncated,responseBodyTruncated:!1,isBinary:!1,error:u.failure()?.errorText??"Unknown error"};this.networkWriter&&(this.networkWriter.append(f),this.networkRequestCount++);}catch{}};this.page.on("requestfailed",o),this.listeners.push({event:"requestfailed",handler:o});}}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 yr=Symbol.for("__testrelic_call_id"),vd="__testrelic_api_assertions",te=new WeakMap,oe=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:vd,description:JSON.stringify(this.assertions)});}dispose(){this.assertions=[],this.currentCallId=null;}},zs=new Map;function yd(t){let e=zs.get(t);if(e)return e;try{let r=t.startsWith("file://")?url.fileURLToPath(t):t,s=fs$1.readFileSync(r,"utf-8").split(`
4319
- `);return zs.set(t,s),s}catch{return null}}var js=(()=>{let t=new Error().stack;if(!t)return null;for(let e of t.split(`
4320
- `)){let r=e.match(/at\s+(?:.*?\s+\()?(.+?):\d+:\d+\)?$/);if(!r||r[1].startsWith("node:"))continue;let n=Math.max(r[1].lastIndexOf("/"),r[1].lastIndexOf("\\"));return n>0?r[1].slice(0,n+1):null}return null})();function bd(t){if(!t.startsWith("file:"))return t;try{return url.fileURLToPath(t)}catch{return t}}function xd(){let e=new Error().stack;if(!e)return null;let r=e.split(`
4321
- `);return Vs(r,true)??Vs(r,false)}function Vs(t,e){for(let r of t){if(e&&js!==null&&r.includes(js)||r.includes("node_modules")||r.includes("node:internal")||r.includes(" at new Error")||r.includes(" at captureAssertionLocation")||r.includes(" at findFrame")||r.includes(" at expectWrapper")||r.includes(" at wrappedMatcher"))continue;let n=r.match(/at\s+(?:.*?\s+\()?(.+?):(\d+):(\d+)\)?$/);if(n)return {file:bd(n[1]),line:parseInt(n[2],10),column:parseInt(n[3],10)}}return null}function wd(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 kd(t,e,r){let n=function(i,...d){let l=t(),c=e();if(!l||!c)return r(i,...d);let u=null;if(i!=null&&typeof i=="object"){let m=i[yr];typeof m=="string"&&(u=m);}if(!u&&i!==null&&i!==void 0&&typeof i=="object"&&(u=te.get(i)??null),u||(u=c.getCallIdForValue(i)),u||(u=l.getCurrentCallId()),!u)return r(i,...d);let f=xd(),p;if(f){let m=yd(f.file);m&&f.line>0&&f.line<=m.length&&(p=m[f.line-1].trim());}let g=r(i,...d);return u?Ks(g,{tracker:l,callId:u,received:i,location:f??{file:"unknown",line:0},expression:p}):g},s=r,a=n;for(let o of Object.keys(s))a[o]=s[o];return n}var $s=Symbol.for("testrelic.activeAssertionContext");function vr(){let t=globalThis,e=t[$s];return e||(e={tracker:null,apiTracker:null},t[$s]=e),e}function le(t,e){let r=vr();r.tracker=t,r.apiTracker=e;}function Ye(t){return kd(()=>vr().tracker,()=>vr().apiTracker,t)}function Ks(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"?Ks(a,e):function(...i){let d=i[0],l="passed",c=e.received,u=null;try{let f=a.apply(this??r,i);return f&&typeof f=="object"&&typeof f.then=="function"?f.then(()=>{mr(e,n,d,c,"passed");},p=>{throw mr(e,n,d,c,"failed"),p}):f}catch(f){if(l="failed",u=f,f instanceof Error&&f.message){let p=f.message.match(/Received:\s*(.+)/);p&&(c=p[1]);}throw f}finally{(u!==null||l==="passed")&&mr(e,n,d,c,l);}}}})}function mr(t,e,r,n,s){let a=wd(t.expression,t.received),o={callId:t.callId,type:a,expected:Ws(r),actual:Ws(n),status:s,location:t.location,expression:t.expression};t.tracker.recordAssertion(o);}function Ws(t){if(t==null)return t;if(typeof t=="string")return se(t);if(typeof t=="number"||typeof t=="boolean")return t;try{return JSON.stringify(t),t}catch{return String(t)}}var Js="[REDACTED]";function xr(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.prototype.hasOwnProperty.call(t,s)&&(n[s]=r.has(s.toLowerCase())?Js:t[s]);return n}function Xe(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=br(r,n);return JSON.stringify(s)}function br(t,e){if(Array.isArray(t))return t.map(r=>br(r,e));if(typeof t=="object"&&t!==null){let r={};for(let n of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,n))continue;let s=t[n];e.has(n.toLowerCase())?r[n]=Js:r[n]=br(s,e);}return r}return t}var Cd=new Set(["access_token","api_key","token","sig"]);function wr(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()])Cd.has(n.toLowerCase())&&(e.searchParams.delete(n),r=true);return r?e.toString():t}function Xs(t,e,r){if(r.length>0){for(let n of r)if(Ys(t,n))return false}if(e.length>0){for(let n of e)if(Ys(t,n))return true;return false}return true}function Ys(t,e){try{return e instanceof RegExp?e.test(t):Td(e).test(t)}catch{return console.warn(`[testrelic] Invalid URL filter pattern: ${String(e)}`),false}}function Td(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 Sd=["get","post","put","patch","delete","head","fetch"],Rd=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function Ad(t){let e=t.toLowerCase();return Rd.some(r=>e.includes(r))}function _d(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 Zs(t){return t?"\u2022\u2022\u2022\u2022":""}function Id(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("="),o=a===-1?s:s.slice(0,a).trim(),i=a===-1?"":s.slice(a+1).trim();o&&r.push({name:o,value:Zs(i)});}return r}function Md(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(";"),o=a[0].indexOf("=");if(o===-1)continue;let i=a[0].slice(0,o).trim(),d=a[0].slice(o+1).trim(),l=a.slice(1).map(c=>c.trim()).filter(Boolean).join(" \xB7 ")||void 0;i&&e.push({name:i,value:Zs(d),attributes:l});}return e}var Ze=class Ze{constructor(e,r,n){this.originals=new Map;this.apiCallWriter=null;this.statusMix={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0};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??Ze.DEFAULT_API_CONFIG;try{this.apiCallWriter=new q("api-calls");}catch{}}get lastCallId(){return this._lastCallId}getCallIdForValue(e){return e!=null&&typeof e=="object"?te.get(e)??null:this.primitiveCallIds.get(e)??null}intercept(){for(let r of Sd){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));}tallyStatus(e){if(e===null||e<=0){this.statusMix.error++;return}if(e>=500){this.statusMix["5xx"]++;return}if(e>=400){this.statusMix["4xx"]++;return}if(e>=300){this.statusMix["3xx"]++;return}if(e>=200){this.statusMix["2xx"]++;return}this.statusMix.error++;}getFileData(){return this.apiCallWriter?.close(),{apiCallsFile:this.apiCallWriter?.getCount()?this.apiCallWriter.getPath():null,apiCallsCount:this.apiCallWriter?.getCount()??0,apiStatusMix:{...this.statusMix}}}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 p=s();return te.set(p,r),p};let a=e.headersArray.bind(e);e.headersArray=function(){let p=a();return te.set(p,r),p};let o=e.json.bind(e);e.json=async function(){let p=await o();return p!=null&&typeof p=="object"&&te.set(p,r),p};let i=e.status.bind(e);e.status=function(){let p=i();return n.primitiveCallIds.set(p,r),p};let d=e.statusText.bind(e);e.statusText=function(){let p=d();return n.primitiveCallIds.set(p,r),p};let l=e.ok.bind(e);e.ok=function(){let p=l();return n.primitiveCallIds.set(p,r),p};let c=e.text.bind(e);e.text=async function(){let p=await c();return n.primitiveCallIds.set(p,r),p};let u=e.body.bind(e);e.body=async function(){let p=await u();return te.set(p,r),p};}createWrapper(e,r){let n=this;return async function(a,o){if(!Xs(a,n.apiConfig.apiIncludeUrls,n.apiConfig.apiExcludeUrls))return r(a,o);let i=`api-call-${n.callCounter++}`,d=new Date().toISOString(),l=e==="fetch"?(o?.method??"GET").toUpperCase():e.toUpperCase(),c=_d(o),u=perf_hooks.performance.now();n._lastCallId=i,n.assertionTracker&&n.assertionTracker.setCurrentCallId(i);let f;try{f=await r(a,o);}catch(p){let g=perf_hooks.performance.now();try{let m=n.apiConfig.captureRequestBody?Xe(c,n.apiConfig.redactBodyFields):null,h={id:i,timestamp:d,method:l,url:wr(a),requestHeaders:null,requestBody:m,responseStatusCode:null,responseStatusText:null,responseHeaders:null,responseBody:null,responseTimeMs:Math.round((g-u)*100)/100,isBinary:!1,error:p instanceof Error?p.message:String(p)};n.apiCallWriter&&(n.apiCallWriter.append(h),n.apiCallCount++,n.tallyStatus(null));}catch{}throw p}try{let p=perf_hooks.performance.now(),g=f.headers(),m=g["content-type"]??null,h=m?!Ad(m):!1,v=null;n.apiConfig.captureRequestHeaders&&o?.headers&&(v=o.headers);let y=null;n.apiConfig.captureResponseHeaders&&(y=g);let b=n.apiConfig.captureRequestBody?c:null,k=null;if(n.apiConfig.captureResponseBody)try{h?k=(await f.body()).toString("base64"):k=await f.text();}catch{}let A=[],E=[];try{if(n.apiConfig.captureRequestHeaders&&(A=Id(o?.headers)),n.apiConfig.captureResponseHeaders){let w=f.headersArray().filter(S=>S.name.toLowerCase()==="set-cookie").map(S=>S.value);E=Md(w);}}catch{}v=xr(v,n.apiConfig.redactHeaders),y=xr(y,n.apiConfig.redactHeaders),b=Xe(b,n.apiConfig.redactBodyFields),k=Xe(k,n.apiConfig.redactBodyFields);let T={id:i,timestamp:d,method:l,url:wr(f.url()),requestHeaders:v,requestBody:b,responseStatusCode:f.status(),responseStatusText:f.statusText(),responseHeaders:y,responseBody:k,requestCookies:A.length?A:null,responseCookies:E.length?E:null,responseTimeMs:Math.round((p-u)*100)/100,isBinary:h,error:null};n.apiCallWriter&&(n.apiCallWriter.append(T),n.apiCallCount++,n.tallyStatus(T.responseStatusCode));}catch{}try{f[yr]=i,n.tagResponseMethods(f,i);}catch{}return f}}};Ze.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 de=Ze;var Dd=[".png",".jpg",".jpeg"];function Fd(t){let e=t.toLowerCase();return Dd.some(r=>e.endsWith(r))?t:`${t}.png`}function Bd(){try{return test.test.info()}catch{return null}}function Od(t,e){for(let r=e;r<t.length;r++){let n=/^(.+)-(expected|actual|diff|previous)\.[A-Za-z0-9]+$/.exec(t[r]?.name??"");if(n)return n[1]}return null}async function qd(t,e){if(!Ne(t))return De("Attaching the baseline of a passing comparison"),null;try{let r=t.snapshotPath(e,{kind:"screenshot"}),n=path.extname(r)||".png",s=path.basename(r,n);return await t.attach(`${s}-expected${n}`,{path:r}),s}catch{return null}}async function Hd(t,e){try{await t.attach(qt,{body:Buffer.from(JSON.stringify([e])),contentType:"application/json"});}catch{}}async function Cr(t,e,r={}){let n={...r};delete n.tags;let s=Fd(e),a=Bd(),o=a?.attachments.length??0,i=true,d="";try{await test.expect(t).toHaveScreenshot(s,n);}catch(l){i=false,d=l instanceof Error?l.message:String(l);}if(a){let l=i?await qd(a,s):Od(a.attachments,o);if(l){let c=!i&&!Ee(d)&&!a.attachments.some((u,f)=>f>=o&&u.name.startsWith(`${l}-diff.`));await Hd(a,{stem:l,name:e,status:i?"passed":c?"new":"failed"});}}return {pass:i,name:"toMatchVisualBaseline",message:()=>i?`Expected "${e}" to differ from its visual baseline, but it matched.`:d}}test.expect.extend({toMatchVisualBaseline:Cr});function jd(){try{return test.test.info()}catch{return null}}On(Ye(test.expect),jd);var Vd="__testrelic_api_config",$d="__testrelic_config_trackApiCalls";function Tr(t){let e=t.annotations.find(n=>n.type===Vd&&n.description!==void 0);if(e)try{return JSON.parse(e.description,Wd)}catch{}let r=t.annotations.find(n=>n.type===$d&&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 Wd(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 na={page:async({page:t},e,r)=>{let n=new Je(t);try{await n.init();}catch{}await e(t);try{let{navigations:s,networkRequestsFile:a,networkRequestsCount:o,consoleLogsFile:i,consoleLogsCount:d}=await n.getFileData(),l={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:s,apiAssertions:[],networkRequestsFile:a,networkRequestsCount:o,consoleLogsFile:i,consoleLogsCount:d,apiCallsFile:null,apiCallsCount:0};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(l)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}n.dispose();},request:async({request:t},e,r)=>{let n=Tr(r);if(!n.trackApiCalls){await e(t);return}let s=new oe,a=new de(t,s,n);a.intercept(),le(s,a);try{await e(t);}finally{le(null,null);}try{let{apiCallsFile:o,apiCallsCount:i,apiStatusMix:d}=a.getFileData(),l=n.captureAssertions?s.getData():[],c={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:[],apiAssertions:l,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:null,consoleLogsCount:0,apiCallsFile:o,apiCallsCount:i,apiStatusMix:d};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(c)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};test.test.extend(na);Ye(test.expect);var Xd={request:async({request:t},e,r)=>{let n=Tr(r);if(!n.trackApiCalls){await e(t);return}let s=new oe,a=new de(t,s,n);a.intercept(),le(s,a);let o=null;try{o=new q("api-console");}catch{}let i=0,d=process.stdout.write,l=process.stderr.write;process.stdout.write=function(c,...u){try{let f=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!f.startsWith("[testrelic]")&&!f.startsWith("\u2139 TestRelic")&&!f.startsWith("\u2713 TestRelic")&&!f.startsWith("\u26A0 TestRelic")&&o&&(o.append({level:"stdout",text:f.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return d.apply(process.stdout,[c,...u])},process.stderr.write=function(c,...u){try{let f=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!f.startsWith("[testrelic]")&&!f.startsWith("\u26A0 TestRelic")&&o&&(o.append({level:"stderr",text:f.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return l.apply(process.stderr,[c,...u])};try{await e(t);}finally{process.stdout.write=d,process.stderr.write=l,le(null,null);}try{o?.close();let{apiCallsFile:c,apiCallsCount:u,apiStatusMix:f}=a.getFileData(),p=n.captureAssertions?s.getData():[],g={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:[],apiAssertions:p,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:i>0?o?.getPath()??null:null,consoleLogsCount:i,apiCallsFile:c,apiCallsCount:u,apiStatusMix:f};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(g)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};var sa="@testrelic/playwright-analytics";function Qd(t){return Array.isArray(t)?t.some(e=>Array.isArray(e)&&typeof e[0]=="string"&&e[0]===sa):false}function ec(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=Qd(s)?s:[...s,[sa,e??{}]];return test.defineConfig({...t,use:n,reporter:a})}var aa=false;function kg(t,e,r="manual_record"){if(!t||!t.annotations){aa||(aa=true,process.stderr.write(`[testrelic] recordNavigation: reporter not active, navigation not recorded
4322
- `));return}let n={url:e,navigationType:r,timestamp:new Date().toISOString()};t.annotations.push({type:"lambdatest-navigation",description:JSON.stringify(n)});}Object.defineProperty(exports,"ATTACHMENT_CONTENT_TYPE",{enumerable:true,get:function(){return core.ATTACHMENT_CONTENT_TYPE}});Object.defineProperty(exports,"ATTACHMENT_NAME",{enumerable:true,get:function(){return core.ATTACHMENT_NAME}});Object.defineProperty(exports,"PAYLOAD_VERSION",{enumerable:true,get:function(){return core.PAYLOAD_VERSION}});Object.defineProperty(exports,"isTestRelicDataPayload",{enumerable:true,get:function(){return core.isTestRelicDataPayload}});exports.SCHEMA_VERSION=Ce;exports.default=Ke;exports.defineConfig=ec;exports.recordNavigation=kg;exports.testRelicApiFixture=Xd;exports.testRelicFixture=na;//# sourceMappingURL=index.cjs.map
4317
+ `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,testType:r.testType,apiCallCount:r.apiCallsCount,...r.apiStatusMix?{apiStatusMix:r.apiStatusMix}:s?{apiStatusMix:rd(s)}:{},assertionsPassed:We(r.apiAssertions,"passed"),assertionsFailed:We(r.apiAssertions,"failed"),...(()=>{let i=Ds(r.apiAssertions);return i?{firstFailedAssertion:i}:{}})(),isRetry:!1,retryGroupKey:tt(r.filePath,r.titlePath,r.testId)};switch(this.testIndex.push(o),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(" > ")}`,Bs(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 ts(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=Y(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,visual:e.visual,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,visual:e.visual??[],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=tr(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=Y(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=Y(e.networkRequestsFile)),e.apiCallsFile){let n=Y(e.apiCallsFile);r.apiCalls=Qt(n),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=er(n));}return r}writeReport(e){try{let r=JSON.stringify(e),n=this.config.outputPath,s=path.dirname(n);fs$1.mkdirSync(s,{recursive:!0});let a=n+".tmp";fs$1.writeFileSync(a,r,"utf-8"),fs$1.renameSync(a,n);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
4318
+ `);}}};var hd=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function md(t){let e=t.toLowerCase();return hd.some(r=>e.includes(r))}var Je=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 q("network")),this.consoleWriter=new q("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(){let e=t.asPatchable(this.page);e.goto=this.origGoto,e.goBack=this.origGoBack,e.goForward=this.origGoForward,e.reload=this.origReload;for(let{event:r,handler:n}of this.listeners)this.page.off(r,n);this.listeners=[],this.records=[],this.pendingRequests.clear(),this.pendingBodyReads=[],this.networkWriter?.close(),this.consoleWriter?.close();}getRecords(){return this.assembleNetworkStats(),this.records}static asPatchable(e){return e}interceptMethods(){let e=this,r=this.page,n=t.asPatchable(r);n.goto=async function(s,a){return e.recordNavigation(s,"goto"),e.origGoto(s,a)},n.goBack=async function(s){let a=await e.origGoBack(s);return e.recordNavigation(r.url(),"back"),a},n.goForward=async function(s){let a=await e.origGoForward(s);return e.recordNavigation(r.url(),"forward"),a},n.reload=async function(s){return e.recordNavigation(r.url(),"refresh"),e.origReload(s)};}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 o=a.url(),i=this.records[this.records.length-1];if(i&&Date.now()-new Date(i.timestamp).getTime()<50&&i.url===o)return;this.recordNavigation(o,"navigation");}catch{}};this.page.on("framenavigated",r),this.listeners.push({event:"framenavigated",handler:r});let n=s=>{try{let a=s,o=a.type(),i=a.text();if(o==="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 l=t.mapConsoleType(o);this.consoleWriter&&(this.consoleWriter.append({level:l,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,l=this.counterForNav(d);l&&l.totalRequests++;try{let c=i,u=String(this.requestIdCounter++),f=c.postData()??null,p={url:c.url(),method:c.method(),resourceType:this.mapResourceType(c.resourceType()),headers:c.headers(),postData:f,postDataTruncated:!1,startedAt:new Date().toISOString(),startTimeMs:Date.now(),navIndex:d};this.pendingRequests.set(u,p),i.__testrelic_id=u;}catch{}};this.page.on("request",s),this.listeners.push({event:"request",handler:s});let a=i=>{try{let d=i,l=d.request().__testrelic_id,c=l?this.pendingRequests.get(l):void 0,u=this.counterForNav(c?c.navIndex:this.records.length-1);if(u){let y=d.status();y>=400&&(u.failedRequests++,u.failedRequestUrls.push(y+" "+d.url()));let b=d.headers()["content-length"];b&&(u.totalBytes+=parseInt(b,10)||0);let k=d.request().resourceType(),A=this.mapResourceType(k);u.byType[A]++;}if(!l||!c)return;this.pendingRequests.delete(l);let f=Date.now()-c.startTimeMs,p=d.headers(),g=p["content-type"]??null,m=parseInt(p["content-length"]??"0",10)||0,h=g?!md(g):!1,v=(async()=>{let y=null;if(!h)try{y=(await d.body()).toString("utf-8");}catch{}let b={url:c.url,method:c.method,resourceType:c.resourceType,statusCode:d.status(),responseTimeMs:f,startedAt:c.startedAt,requestHeaders:c.headers,requestBody:c.postData,responseBody:y,responseHeaders:p,contentType:g,responseSize:m,requestBodyTruncated:c.postDataTruncated,responseBodyTruncated:!1,isBinary:h,error:null};this.networkWriter&&(this.networkWriter.append(b),this.networkRequestCount++);})();this.pendingBodyReads.push(v);}catch{}};this.page.on("response",a),this.listeners.push({event:"response",handler:a});let o=i=>{let d=i.__testrelic_id,l=d?this.pendingRequests.get(d):void 0,c=this.counterForNav(l?l.navIndex:this.records.length-1);if(c){c.failedRequests++;try{let u=i;c.failedRequestUrls.push("ERR "+u.url());}catch{}}try{let u=i;if(!d||!l)return;this.pendingRequests.delete(d);let f={url:l.url,method:l.method,resourceType:l.resourceType,statusCode:0,responseTimeMs:Date.now()-l.startTimeMs,startedAt:l.startedAt,requestHeaders:l.headers,requestBody:l.postData,responseBody:null,responseHeaders:null,contentType:null,responseSize:0,requestBodyTruncated:l.postDataTruncated,responseBodyTruncated:!1,isBinary:!1,error:u.failure()?.errorText??"Unknown error"};this.networkWriter&&(this.networkWriter.append(f),this.networkRequestCount++);}catch{}};this.page.on("requestfailed",o),this.listeners.push({event:"requestfailed",handler:o});}}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 yr=Symbol.for("__testrelic_call_id"),yd="__testrelic_api_assertions",te=new WeakMap,oe=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:yd,description:JSON.stringify(this.assertions)});}dispose(){this.assertions=[],this.currentCallId=null;}},Hs=new Map;function bd(t){let e=Hs.get(t);if(e)return e;try{let r=t.startsWith("file://")?url.fileURLToPath(t):t,s=fs$1.readFileSync(r,"utf-8").split(`
4319
+ `);return Hs.set(t,s),s}catch{return null}}var zs=(()=>{let t=new Error().stack;if(!t)return null;for(let e of t.split(`
4320
+ `)){let r=e.match(/at\s+(?:.*?\s+\()?(.+?):\d+:\d+\)?$/);if(!r||r[1].startsWith("node:"))continue;let n=Math.max(r[1].lastIndexOf("/"),r[1].lastIndexOf("\\"));return n>0?r[1].slice(0,n+1):null}return null})();function xd(t){if(!t.startsWith("file:"))return t;try{return url.fileURLToPath(t)}catch{return t}}function wd(){let e=new Error().stack;if(!e)return null;let r=e.split(`
4321
+ `);return js(r,true)??js(r,false)}function js(t,e){for(let r of t){if(e&&zs!==null&&r.includes(zs)||r.includes("node_modules")||r.includes("node:internal")||r.includes(" at new Error")||r.includes(" at captureAssertionLocation")||r.includes(" at findFrame")||r.includes(" at expectWrapper")||r.includes(" at wrappedMatcher"))continue;let n=r.match(/at\s+(?:.*?\s+\()?(.+?):(\d+):(\d+)\)?$/);if(n)return {file:xd(n[1]),line:parseInt(n[2],10),column:parseInt(n[3],10)}}return null}function kd(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 Cd(t,e,r){let n=function(i,...d){let l=t(),c=e();if(!l||!c)return r(i,...d);let u=null;if(i!=null&&typeof i=="object"){let m=i[yr];typeof m=="string"&&(u=m);}if(!u&&i!==null&&i!==void 0&&typeof i=="object"&&(u=te.get(i)??null),u||(u=c.getCallIdForValue(i)),u||(u=l.getCurrentCallId()),!u)return r(i,...d);let f=wd(),p;if(f){let m=bd(f.file);m&&f.line>0&&f.line<=m.length&&(p=m[f.line-1].trim());}let g=r(i,...d);return u?Gs(g,{tracker:l,callId:u,received:i,location:f??{file:"unknown",line:0},expression:p}):g},s=r,a=n;for(let o of Object.keys(s))a[o]=s[o];return n}var Vs=Symbol.for("testrelic.activeAssertionContext");function vr(){let t=globalThis,e=t[Vs];return e||(e={tracker:null,apiTracker:null},t[Vs]=e),e}function le(t,e){let r=vr();r.tracker=t,r.apiTracker=e;}function Ye(t){return Cd(()=>vr().tracker,()=>vr().apiTracker,t)}function Gs(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"?Gs(a,e):function(...i){let d=i[0],l="passed",c=e.received,u=null;try{let f=a.apply(this??r,i);return f&&typeof f=="object"&&typeof f.then=="function"?f.then(()=>{mr(e,n,d,c,"passed");},p=>{throw mr(e,n,d,c,"failed"),p}):f}catch(f){if(l="failed",u=f,f instanceof Error&&f.message){let p=f.message.match(/Received:\s*(.+)/);p&&(c=p[1]);}throw f}finally{(u!==null||l==="passed")&&mr(e,n,d,c,l);}}}})}function mr(t,e,r,n,s){let a=kd(t.expression,t.received),o={callId:t.callId,type:a,expected:$s(r),actual:$s(n),status:s,location:t.location,expression:t.expression};t.tracker.recordAssertion(o);}function $s(t){if(t==null)return t;if(typeof t=="string")return se(t);if(typeof t=="number"||typeof t=="boolean")return t;try{return JSON.stringify(t),t}catch{return String(t)}}var Ks="[REDACTED]";function xr(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.prototype.hasOwnProperty.call(t,s)&&(n[s]=r.has(s.toLowerCase())?Ks:t[s]);return n}function Xe(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=br(r,n);return JSON.stringify(s)}function br(t,e){if(Array.isArray(t))return t.map(r=>br(r,e));if(typeof t=="object"&&t!==null){let r={};for(let n of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,n))continue;let s=t[n];e.has(n.toLowerCase())?r[n]=Ks:r[n]=br(s,e);}return r}return t}var Td=new Set(["access_token","api_key","token","sig"]);function wr(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()])Td.has(n.toLowerCase())&&(e.searchParams.delete(n),r=true);return r?e.toString():t}function Ys(t,e,r){if(r.length>0){for(let n of r)if(Js(t,n))return false}if(e.length>0){for(let n of e)if(Js(t,n))return true;return false}return true}function Js(t,e){try{return e instanceof RegExp?e.test(t):Sd(e).test(t)}catch{return console.warn(`[testrelic] Invalid URL filter pattern: ${String(e)}`),false}}function Sd(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 Rd=["get","post","put","patch","delete","head","fetch"],Ad=["text/","application/json","application/xml","application/javascript","application/x-www-form-urlencoded","application/graphql"];function _d(t){let e=t.toLowerCase();return Ad.some(r=>e.includes(r))}function Id(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 Xs(t){return t?"\u2022\u2022\u2022\u2022":""}function Md(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("="),o=a===-1?s:s.slice(0,a).trim(),i=a===-1?"":s.slice(a+1).trim();o&&r.push({name:o,value:Xs(i)});}return r}function Ed(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(";"),o=a[0].indexOf("=");if(o===-1)continue;let i=a[0].slice(0,o).trim(),d=a[0].slice(o+1).trim(),l=a.slice(1).map(c=>c.trim()).filter(Boolean).join(" \xB7 ")||void 0;i&&e.push({name:i,value:Xs(d),attributes:l});}return e}var Ze=class Ze{constructor(e,r,n){this.originals=new Map;this.apiCallWriter=null;this.statusMix={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0};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??Ze.DEFAULT_API_CONFIG;try{this.apiCallWriter=new q("api-calls");}catch{}}get lastCallId(){return this._lastCallId}getCallIdForValue(e){return e!=null&&typeof e=="object"?te.get(e)??null:this.primitiveCallIds.get(e)??null}intercept(){for(let r of Rd){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));}tallyStatus(e){if(e===null||e<=0){this.statusMix.error++;return}if(e>=500){this.statusMix["5xx"]++;return}if(e>=400){this.statusMix["4xx"]++;return}if(e>=300){this.statusMix["3xx"]++;return}if(e>=200){this.statusMix["2xx"]++;return}this.statusMix.error++;}getFileData(){return this.apiCallWriter?.close(),{apiCallsFile:this.apiCallWriter?.getCount()?this.apiCallWriter.getPath():null,apiCallsCount:this.apiCallWriter?.getCount()??0,apiStatusMix:{...this.statusMix}}}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 p=s();return te.set(p,r),p};let a=e.headersArray.bind(e);e.headersArray=function(){let p=a();return te.set(p,r),p};let o=e.json.bind(e);e.json=async function(){let p=await o();return p!=null&&typeof p=="object"&&te.set(p,r),p};let i=e.status.bind(e);e.status=function(){let p=i();return n.primitiveCallIds.set(p,r),p};let d=e.statusText.bind(e);e.statusText=function(){let p=d();return n.primitiveCallIds.set(p,r),p};let l=e.ok.bind(e);e.ok=function(){let p=l();return n.primitiveCallIds.set(p,r),p};let c=e.text.bind(e);e.text=async function(){let p=await c();return n.primitiveCallIds.set(p,r),p};let u=e.body.bind(e);e.body=async function(){let p=await u();return te.set(p,r),p};}createWrapper(e,r){let n=this;return async function(a,o){if(!Ys(a,n.apiConfig.apiIncludeUrls,n.apiConfig.apiExcludeUrls))return r(a,o);let i=`api-call-${n.callCounter++}`,d=new Date().toISOString(),l=e==="fetch"?(o?.method??"GET").toUpperCase():e.toUpperCase(),c=Id(o),u=perf_hooks.performance.now();n._lastCallId=i,n.assertionTracker&&n.assertionTracker.setCurrentCallId(i);let f;try{f=await r(a,o);}catch(p){let g=perf_hooks.performance.now();try{let m=n.apiConfig.captureRequestBody?Xe(c,n.apiConfig.redactBodyFields):null,h={id:i,timestamp:d,method:l,url:wr(a),requestHeaders:null,requestBody:m,responseStatusCode:null,responseStatusText:null,responseHeaders:null,responseBody:null,responseTimeMs:Math.round((g-u)*100)/100,isBinary:!1,error:p instanceof Error?p.message:String(p)};n.apiCallWriter&&(n.apiCallWriter.append(h),n.apiCallCount++,n.tallyStatus(null));}catch{}throw p}try{let p=perf_hooks.performance.now(),g=f.headers(),m=g["content-type"]??null,h=m?!_d(m):!1,v=null;n.apiConfig.captureRequestHeaders&&o?.headers&&(v=o.headers);let y=null;n.apiConfig.captureResponseHeaders&&(y=g);let b=n.apiConfig.captureRequestBody?c:null,k=null;if(n.apiConfig.captureResponseBody)try{h?k=(await f.body()).toString("base64"):k=await f.text();}catch{}let A=[],E=[];try{if(n.apiConfig.captureRequestHeaders&&(A=Md(o?.headers)),n.apiConfig.captureResponseHeaders){let x=f.headersArray().filter(S=>S.name.toLowerCase()==="set-cookie").map(S=>S.value);E=Ed(x);}}catch{}v=xr(v,n.apiConfig.redactHeaders),y=xr(y,n.apiConfig.redactHeaders),b=Xe(b,n.apiConfig.redactBodyFields),k=Xe(k,n.apiConfig.redactBodyFields);let T={id:i,timestamp:d,method:l,url:wr(f.url()),requestHeaders:v,requestBody:b,responseStatusCode:f.status(),responseStatusText:f.statusText(),responseHeaders:y,responseBody:k,requestCookies:A.length?A:null,responseCookies:E.length?E:null,responseTimeMs:Math.round((p-u)*100)/100,isBinary:h,error:null};n.apiCallWriter&&(n.apiCallWriter.append(T),n.apiCallCount++,n.tallyStatus(T.responseStatusCode));}catch{}try{f[yr]=i,n.tagResponseMethods(f,i);}catch{}return f}}};Ze.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 de=Ze;var Fd=[".png",".jpg",".jpeg"];function Bd(t){let e=t.toLowerCase();return Fd.some(r=>e.endsWith(r))?t:`${t}.png`}function Od(){try{return test.test.info()}catch{return null}}function qd(t,e){for(let r=e;r<t.length;r++){let n=/^(.+)-(expected|actual|diff|previous)\.[A-Za-z0-9]+$/.exec(t[r]?.name??"");if(n)return n[1]}return null}async function Ud(t,e){if(!Ne(t))return De("Attaching the baseline of a passing comparison"),null;try{let r=t.snapshotPath(e,{kind:"screenshot"}),n=path.extname(r)||".png",s=path.basename(r,n);return await t.attach(`${s}-expected${n}`,{path:r}),s}catch{return null}}async function Hd(t,e){try{await t.attach(qt,{body:Buffer.from(JSON.stringify([e])),contentType:"application/json"});}catch{}}async function Cr(t,e,r={}){let n={...r};delete n.tags;let s=Bd(e),a=Od(),o=a?.attachments.length??0,i=true,d="";try{await test.expect(t).toHaveScreenshot(s,n);}catch(l){i=false,d=l instanceof Error?l.message:String(l);}if(a){let l=i?await Ud(a,s):qd(a.attachments,o);if(l){let c=!i&&!Ee(d)&&!a.attachments.some((u,f)=>f>=o&&u.name.startsWith(`${l}-diff.`));await Hd(a,{stem:l,name:e,status:i?"passed":c?"new":"failed"});}}return {pass:i,name:"toMatchVisualBaseline",message:()=>i?`Expected "${e}" to differ from its visual baseline, but it matched.`:d}}test.expect.extend({toMatchVisualBaseline:Cr});function Vd(){try{return test.test.info()}catch{return null}}Bn(Ye(test.expect),Vd);var $d="__testrelic_api_config",Wd="__testrelic_config_trackApiCalls";function Tr(t){let e=t.annotations.find(n=>n.type===$d&&n.description!==void 0);if(e)try{return JSON.parse(e.description,Gd)}catch{}let r=t.annotations.find(n=>n.type===Wd&&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 Gd(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 ra={page:async({page:t},e,r)=>{let n=new Je(t);try{await n.init();}catch{}await e(t);try{let{navigations:s,networkRequestsFile:a,networkRequestsCount:o,consoleLogsFile:i,consoleLogsCount:d}=await n.getFileData(),l={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:s,apiAssertions:[],networkRequestsFile:a,networkRequestsCount:o,consoleLogsFile:i,consoleLogsCount:d,apiCallsFile:null,apiCallsCount:0};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(l)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}n.dispose();},request:async({request:t},e,r)=>{let n=Tr(r);if(!n.trackApiCalls){await e(t);return}let s=new oe,a=new de(t,s,n);a.intercept(),le(s,a);try{await e(t);}finally{le(null,null);}try{let{apiCallsFile:o,apiCallsCount:i,apiStatusMix:d}=a.getFileData(),l=n.captureAssertions?s.getData():[],c={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:[],apiAssertions:l,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:null,consoleLogsCount:0,apiCallsFile:o,apiCallsCount:i,apiStatusMix:d};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(c)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};test.test.extend(ra);Ye(test.expect);var Zd={request:async({request:t},e,r)=>{let n=Tr(r);if(!n.trackApiCalls){await e(t);return}let s=new oe,a=new de(t,s,n);a.intercept(),le(s,a);let o=null;try{o=new q("api-console");}catch{}let i=0,d=process.stdout.write,l=process.stderr.write;process.stdout.write=function(c,...u){try{let f=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!f.startsWith("[testrelic]")&&!f.startsWith("\u2139 TestRelic")&&!f.startsWith("\u2713 TestRelic")&&!f.startsWith("\u26A0 TestRelic")&&o&&(o.append({level:"stdout",text:f.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return d.apply(process.stdout,[c,...u])},process.stderr.write=function(c,...u){try{let f=typeof c=="string"?c:Buffer.isBuffer(c)?c.toString("utf-8"):String(c);!f.startsWith("[testrelic]")&&!f.startsWith("\u26A0 TestRelic")&&o&&(o.append({level:"stderr",text:f.replace(/\n$/,""),timestamp:new Date().toISOString(),location:null}),i++);}catch{}return l.apply(process.stderr,[c,...u])};try{await e(t);}finally{process.stdout.write=d,process.stderr.write=l,le(null,null);}try{o?.close();let{apiCallsFile:c,apiCallsCount:u,apiStatusMix:f}=a.getFileData(),p=n.captureAssertions?s.getData():[],g={testRelicData:!0,version:core.PAYLOAD_VERSION,navigations:[],apiAssertions:p,networkRequestsFile:null,networkRequestsCount:0,consoleLogsFile:i>0?o?.getPath()??null:null,consoleLogsCount:i,apiCallsFile:c,apiCallsCount:u,apiStatusMix:f};await r.attach(core.ATTACHMENT_NAME,{body:Buffer.from(JSON.stringify(g)),contentType:core.ATTACHMENT_CONTENT_TYPE});}catch{}a.dispose(),s.dispose();}};var na="@testrelic/playwright-analytics";function ec(t){return Array.isArray(t)?t.some(e=>Array.isArray(e)&&typeof e[0]=="string"&&e[0]===na):false}function tc(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=ec(s)?s:[...s,[na,e??{}]];return test.defineConfig({...t,use:n,reporter:a})}var sa=false;function kg(t,e,r="manual_record"){if(!t||!t.annotations){sa||(sa=true,process.stderr.write(`[testrelic] recordNavigation: reporter not active, navigation not recorded
4322
+ `));return}let n={url:e,navigationType:r,timestamp:new Date().toISOString()};t.annotations.push({type:"lambdatest-navigation",description:JSON.stringify(n)});}Object.defineProperty(exports,"ATTACHMENT_CONTENT_TYPE",{enumerable:true,get:function(){return core.ATTACHMENT_CONTENT_TYPE}});Object.defineProperty(exports,"ATTACHMENT_NAME",{enumerable:true,get:function(){return core.ATTACHMENT_NAME}});Object.defineProperty(exports,"PAYLOAD_VERSION",{enumerable:true,get:function(){return core.PAYLOAD_VERSION}});Object.defineProperty(exports,"isTestRelicDataPayload",{enumerable:true,get:function(){return core.isTestRelicDataPayload}});exports.SCHEMA_VERSION=Ce;exports.default=Ke;exports.defineConfig=tc;exports.recordNavigation=kg;exports.testRelicApiFixture=Zd;exports.testRelicFixture=ra;//# sourceMappingURL=index.cjs.map
4323
4323
  //# sourceMappingURL=index.cjs.map