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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  'use strict';var crypto=require('crypto'),fs$1=require('fs'),path=require('path'),os$1=require('os'),core=require('@testrelic/core'),child_process=require('child_process'),http=require('http'),readline=require('readline'),promises=require('fs/promises'),zlib=require('zlib'),util=require('util'),stream=require('stream');var Kr=(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 Qr=".testrelic-report";function ke(t,e,r,s){let n=`${t}|${e.join("|")}|${r}|${s}`;return crypto.createHash("sha256").update(n).digest("hex").substring(0,12)}var J=class{constructor(e){this.writeErrors=[];this.totalBytesWritten=0;this.reportDir=path.join(e,Qr),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,s){try{let n=path.join(this.testsDir,e);fs$1.mkdirSync(n,{recursive:!0});let a=path.join(n,"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"),s?.networkRequestsFile&&this.moveFile(s.networkRequestsFile,path.join(n,"network.jsonl")),s?.consoleLogsFile&&this.moveFile(s.consoleLogsFile,path.join(n,"console.jsonl")),s?.apiCallsFile&&this.moveFile(s.apiCallsFile,path.join(n,"api-calls.jsonl")),!0}catch(n){let a=n instanceof Error?n.message:String(n);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
2
  `),false}}moveFile(e,r){try{fs$1.renameSync(e,r);}catch{try{let{copyFileSync:s}=Kr("fs");s(e,r);try{fs$1.unlinkSync(e);}catch{}}catch(s){process.stderr.write(`[testrelic] Failed to move file ${e} \u2192 ${r}: ${s instanceof Error?s.message:String(s)}
3
- `);}}}writeIndex(e){let r=path.join(this.reportDir,"index.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),s=r+".tmp",n=e.map(({titlePath:o,project:i,...d})=>d),a=JSON.stringify(n);fs$1.writeFileSync(s,a,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var Ct=".testrelic",ss="testrelic-config.json",ns=".testrelic",as=5,is=new Set(["__proto__","constructor","prototype"]),Tt=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${Ct}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),os={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Rt(t){let e=path.resolve(t);for(let r=0;r<=as;r++){let s=path.join(e,Ct,ss);if(fs$1.existsSync(s))try{if(fs$1.statSync(s).isFile())return s}catch{}let n=path.join(e,ns);if(fs$1.existsSync(n))try{if(fs$1.statSync(n).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
- `),n}catch{}let a=path.dirname(e);if(a===e)break;e=a;}return null}function At(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!It(r)?null:r}catch{return null}}function It(t){for(let e of Object.keys(t)){if(is.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!It(r))return false}return true}function _t(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 Te(t){let e=Object.create(null);for(let r of Object.keys(t)){let s=t[r];typeof s=="string"&&s.startsWith("$")?e[r]=_t(s):typeof s=="object"&&s!==null&&!Array.isArray(s)?e[r]=Te(s):e[r]=s;}return e}function St(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),s=e[2],n=os[s];return !n||r<=0?null:r*n}function Mt(t,e){let r=Object.create(null);if(Object.assign(r,Tt),t){let d=t.cloud;d&&typeof d=="object"&&(typeof d.endpoint=="string"&&(r.endpoint=d.endpoint),typeof d.upload=="string"&&(r.uploadStrategy=d.upload),typeof d.timeout=="number"&&(r.timeout=d.timeout),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let 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 u=t.queue;if(u&&typeof u=="object"){if(typeof u.maxAge=="string"){let g=St(u.maxAge);g!==null&&(r.queueMaxAge=g);}typeof u.directory=="string"&&(r.queueDirectory=u.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?_t(e.apiKey):e.apiKey;d&&(r.apiKey=d);}if(typeof e.endpoint=="string"&&(r.endpoint=e.endpoint),typeof e.upload=="string"&&(r.uploadStrategy=e.upload),typeof e.timeout=="number"&&(r.timeout=e.timeout),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let d=St(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 s=process.env.TESTRELIC_API_KEY;s&&s.length>0&&(r.apiKey=s);let n=process.env.TESTRELIC_CLOUD_ENDPOINT;n&&core.isValidEndpointUrl(n)&&(r.endpoint=n);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:Tt}var us=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],ps=["authorization","cookie","set-cookie","x-api-key"],fs=["password","secret","token","apiKey","api_key"];function Lt(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??[...ps],e.redactBodyFields=t?.redactBodyFields??[...fs],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Et(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=[...us,...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 s=Rt(process.cwd()),n=s?At(s):null,a=n?Te(n):null,o=Mt(a,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var Se="1.3.0";function Pt(t,e,r){try{let n=fs$1.readFileSync(t,"utf-8").split(`
3
+ `);}}}writeIndex(e){let r=path.join(this.reportDir,"index.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeCompactIndex(e){let r=path.join(this.reportDir,"index-compact.json"),s=r+".tmp",n=e.map(({titlePath:o,project:i,...d})=>d),a=JSON.stringify(n);fs$1.writeFileSync(s,a,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(a,"utf-8");}writeSummary(e){let r=path.join(this.reportDir,"summary.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}writeManifest(e){let r=path.join(this.reportDir,"manifest.json"),s=r+".tmp",n=JSON.stringify(e);fs$1.writeFileSync(s,n,"utf-8"),fs$1.renameSync(s,r),this.totalBytesWritten+=Buffer.byteLength(n,"utf-8");}computeTotalSize(){return this.totalBytesWritten}dispose(){}};var St=".testrelic",ss="testrelic-config.json",ns=".testrelic",as=5,is=new Set(["__proto__","constructor","prototype"]),kt=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${St}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),os={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function Ct(t){let e=path.resolve(t);for(let r=0;r<=as;r++){let s=path.join(e,St,ss);if(fs$1.existsSync(s))try{if(fs$1.statSync(s).isFile())return s}catch{}let n=path.join(e,ns);if(fs$1.existsSync(n))try{if(fs$1.statSync(n).isFile())return process.stderr.write(`[testrelic] Deprecation: config file ".testrelic" has moved to ".testrelic/testrelic-config.json". Please migrate your config file to the new location.
4
+ `),n}catch{}let a=path.dirname(e);if(a===e)break;e=a;}return null}function Rt(t){try{let e=fs$1.readFileSync(t,"utf-8"),r=JSON.parse(e);return typeof r!="object"||r===null||Array.isArray(r)||!At(r)?null:r}catch{return null}}function At(t){for(let e of Object.keys(t)){if(is.has(e))return false;let r=t[e];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!At(r))return false}return true}function It(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 Te(t){let e=Object.create(null);for(let r of Object.keys(t)){let s=t[r];typeof s=="string"&&s.startsWith("$")?e[r]=It(s):typeof s=="object"&&s!==null&&!Array.isArray(s)?e[r]=Te(s):e[r]=s;}return e}function Tt(t){let e=/^(\d+)\s*([smhd])$/.exec(t.trim());if(!e)return null;let r=parseInt(e[1],10),s=e[2],n=os[s];return !n||r<=0?null:r*n}function _t(t,e){let r=Object.create(null);if(Object.assign(r,kt),t){let d=t.cloud;d&&typeof d=="object"&&(typeof d.endpoint=="string"&&(r.endpoint=d.endpoint),typeof d.upload=="string"&&(r.uploadStrategy=d.upload),typeof d.timeout=="number"&&(r.timeout=d.timeout),typeof d.apiKey=="string"&&d.apiKey.length>0&&(r.apiKey=d.apiKey));let 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 u=t.queue;if(u&&typeof u=="object"){if(typeof u.maxAge=="string"){let g=Tt(u.maxAge);g!==null&&(r.queueMaxAge=g);}typeof u.directory=="string"&&(r.queueDirectory=u.directory);}}if(e){if(typeof e.apiKey=="string"&&e.apiKey.length>0){let d=e.apiKey.startsWith("$")?It(e.apiKey):e.apiKey;d&&(r.apiKey=d);}if(typeof e.endpoint=="string"&&(r.endpoint=e.endpoint),typeof e.upload=="string"&&(r.uploadStrategy=e.upload),typeof e.timeout=="number"&&(r.timeout=e.timeout),typeof e.projectName=="string"&&(r.projectName=e.projectName),typeof e.queueMaxAge=="string"){let d=Tt(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 s=process.env.TESTRELIC_API_KEY;s&&s.length>0&&(r.apiKey=s);let n=process.env.TESTRELIC_CLOUD_ENDPOINT;n&&core.isValidEndpointUrl(n)&&(r.endpoint=n);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:kt}var us=[/AKIA[A-Z0-9]{16}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,/-----BEGIN\s+(RSA\s+)?PRIVATE\sKEY-----[\s\S]*?-----END/g,/\/\/[^:]+:[^@]+@/g],ps=["authorization","cookie","set-cookie","x-api-key"],fs=["password","secret","token","apiKey","api_key"];function Mt(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??[...ps],e.redactBodyFields=t?.redactBodyFields??[...fs],e.apiIncludeUrls=t?.apiIncludeUrls??[],e.apiExcludeUrls=t?.apiExcludeUrls??[],Object.freeze(e)}function Lt(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=[...us,...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 s=Ct(process.cwd()),n=s?Rt(s):null,a=n?Te(n):null,o=_t(a,t?.cloud);return e.cloud=o.apiKey?o:null,e.reportMode=t?.reportMode??"streaming",e.streamingThreshold=t?.streamingThreshold??0,Object.freeze(e)}var Se="1.3.0";function Et(t,e,r){try{let n=fs$1.readFileSync(t,"utf-8").split(`
6
6
  `);if(e<1||e>n.length)return null;let a=Math.max(1,e-r),o=Math.min(n.length,e+r),i=[];for(let d=a;d<=o;d++){let l=d===e?">":" ",u=String(d).padStart(String(o).length," ");i.push(`${l} ${u} | ${n[d-1]}`);}return i.join(`
7
- `)}catch{return null}}function Nt(t){return e=>{let r=e;for(let s of t)if(typeof s=="string"){let n=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(n,"g"),"[REDACTED]");}else {let n=s.flags.includes("g")?s.flags:s.flags+"g",a=new RegExp(s.source,n);r=r.replace(a,"[REDACTED]");}return r}}function hs(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 ms(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 vs(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 ys(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 bs(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 xs=[hs,ms,vs,ys,bs];function P(t){let e=process.env;for(let r of xs){let s=r(e);if(s)return s}return null}var Ce=`
7
+ `)}catch{return null}}function Pt(t){return e=>{let r=e;for(let s of t)if(typeof s=="string"){let n=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(n,"g"),"[REDACTED]");}else {let n=s.flags.includes("g")?s.flags:s.flags+"g",a=new RegExp(s.source,n);r=r.replace(a,"[REDACTED]");}return r}}function hs(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 ms(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 vs(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 ys(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 bs(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 xs=[hs,ms,vs,ys,bs];function P(t){let e=process.env;for(let r of xs){let s=r(e);if(s)return s}return null}var Ce=`
8
8
  /* Theme Variables */
9
9
  :root,[data-theme="dark"]{
10
10
  --bg:#0f1117;--bg-1:#161b22;--bg-2:#1c2128;--bg-3:#21262d;--bg-code:#13111c;
@@ -2331,7 +2331,7 @@ function _updateCard(cls,val){
2331
2331
  renderFilterBar();
2332
2332
  renderTestGrid();
2333
2333
  var _lo=document.getElementById('loading-overlay');if(_lo)_lo.remove();
2334
- })();`;function Ft(t,e,r){let s=t.replace(/<\//g,"<\\/"),n=r?r.replace(/<\//g,"<\\/"):null;return `<!-- TestRelic AI Analytics Report \u2014 self-contained, no external dependencies -->
2334
+ })();`;function Nt(t,e,r){let s=t.replace(/<\//g,"<\\/"),n=r?r.replace(/<\//g,"<\\/"):null;return `<!-- TestRelic AI Analytics Report \u2014 self-contained, no external dependencies -->
2335
2335
  <!DOCTYPE html>
2336
2336
  <html lang="en" data-theme="">
2337
2337
  <head>
@@ -2544,51 +2544,51 @@ ${o?`<script id="artifact-manifest-data" type="application/json">${o}</script>`:
2544
2544
  <script>${l}</script>
2545
2545
  </body>
2546
2546
  </html>`}function De(t){try{let e=process.platform,r,s;e==="darwin"?(r="open",s=[t]):e==="win32"?(r="cmd",s=["/c","start","",t]):(r="xdg-open",s=[t]),child_process.execFile(r,s,n=>{n&&process.stderr.write(`[testrelic] Failed to open browser: ${n.message}
2547
- `);});}catch{}}path.join(os$1.tmpdir(),"testrelic-data");async function Dt(t,e,r,s){let n=(e-1)*r,a=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let u of i)if(u.length!==0){if(o>=n&&a.length<r)try{a.push(JSON.parse(u));}catch{}if(o++,a.length>=r&&s!==void 0)break}let d=s??o,l=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:l}}var qt=/^[a-f0-9]{12}$/,Be=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Ht=500;function b(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Ut(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Allow-Methods","GET, DELETE, OPTIONS"),t.setHeader("Access-Control-Allow-Headers","Content-Type");}function ae(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function ie(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let s of r){let n=path.join(t,s.name);s.isFile()?e+=fs$1.statSync(n).size:s.isDirectory()&&(e+=ie(n));}}catch{}return e}function $t(t,e,r,s){let n=ae(path.join(r,"index.json"));b(e,200,{status:"ok",reportMode:"streaming",testCount:n?.length??0,uptime:Math.floor((Date.now()-s)/1e3)});}function zt(t,e,r){let s=ae(path.join(r,"summary.json"));if(!s){b(e,404,{error:"Summary not found"});return}b(e,200,s);}function jt(t,e,r){let s=ae(path.join(r,"index.json"));if(!s){b(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(Ht,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,l=a.get("file")??null,u=a.get("search")?.toLowerCase()??null,g=a.get("tag")?.split(",").filter(Boolean)??null,m=a.get("sort")??"file",p=a.get("order")==="desc"?-1:1,f=s;d&&d.length>0&&(f=f.filter(x=>d.includes(x.status))),l&&(f=f.filter(x=>x.filePath===l||x.filePath.startsWith(l+"/"))),u&&(f=f.filter(x=>x.title.toLowerCase().includes(u)||x.filePath.toLowerCase().includes(u))),g&&g.length>0&&(f=f.filter(x=>g.some(T=>x.tags.includes(T)))),f=[...f].sort((x,T)=>{let M=0;switch(m){case "duration":M=x.duration-T.duration;break;case "status":M=x.status.localeCompare(T.status);break;case "title":M=x.title.localeCompare(T.title);break;default:M=x.filePath.localeCompare(T.filePath);break}return M*p});let c=f.length,h=Math.max(1,Math.ceil(c/i)),v=(o-1)*i,w=f.slice(v,v+i);b(e,200,{tests:w,pagination:{page:o,pageSize:i,totalItems:c,totalPages:h},filters:{status:d,file:l,search:u,tag:g}});}function Vt(t,e,r,s){if(!qt.test(s)){b(e,400,{error:"Invalid test ID format"});return}let n=path.join(r,"tests",s,"meta.json"),a=path.join(r,"tests",`${s}.json`),o=fs$1.existsSync(n)?n:fs$1.existsSync(a)?a:null;if(!o){b(e,404,{error:`Test not found: ${s}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){b(e,500,{error:i instanceof Error?i.message:String(i)});}}async function Gt(t,e,r,s,n){if(!qt.test(s)){b(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",s,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[n]);if(!fs$1.existsSync(o)){b(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),u=Math.min(Ht,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),g,m=path.join(r,"tests",s,"meta.json");if(fs$1.existsSync(m))try{let f=JSON.parse(fs$1.readFileSync(m,"utf-8"));switch(n){case "network":g=f.networkRequestsCount;break;case "console":g=f.consoleLogsCount;break;case "api-calls":g=f.apiCallsCount;break}}catch{}let p=await Dt(o,l,u,g);b(e,200,p);}catch(i){b(e,500,{error:i instanceof Error?i.message:String(i)});}}function Wt(t,e,r){let s=ae(path.join(r,"index.json"));if(!s){b(e,404,{error:"Test index not found"});return}let n=new Map;for(let o of s){if(o.isRetry)continue;let i=n.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},n.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let a=Array.from(n.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));b(e,200,{files:a});}function Kt(t,e,r){if(!fs$1.existsSync(r)){b(e,200,{runs:[],totalSizeBytes:0});return}try{let s=[],n=0,a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!Be.test(o.name))continue;let i=path.join(r,o.name),d=ie(i),l=fs$1.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory());s.push({folderName:o.name,totalSizeBytes:d,testCount:l.length}),n+=d;}s.sort((o,i)=>i.folderName.localeCompare(o.folderName)),b(e,200,{runs:s,totalSizeBytes:n});}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}function Jt(t,e,r){try{let s=0,n=0;if(fs$1.existsSync(r)){let a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!Be.test(o.name))continue;let i=path.join(r,o.name),d=ie(i);fs$1.rmSync(i,{recursive:!0,force:!0}),n+=d,s++;}}b(e,200,{deletedCount:s,freedBytes:n});}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}function Yt(t,e,r,s){if(!Be.test(s)){b(e,400,{error:"Invalid folder name"});return}let n=path.join(r,s);try{if(!fs$1.statSync(n).isDirectory()){b(e,404,{error:"Not found"});return}}catch{b(e,404,{error:"Not found"});return}try{let a=ie(n);fs$1.rmSync(n,{recursive:!0,force:!0}),b(e,200,{deleted:s,freedBytes:a});}catch(a){b(e,500,{error:a instanceof Error?a.message:String(a)});}}function Qt(t,e,r){b(e,200,{status:"shutting_down"}),r.close();}function Oe(t,e,r){if(!fs$1.existsSync(r)){b(e,404,{error:"File not found"});return}try{let s=fs$1.readFileSync(r),n=path.extname(r).toLowerCase(),a=Is[n]??"application/octet-stream";e.writeHead(200,{"Content-Type":a}),e.end(s);}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}var Is={".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 Es=9323,Ps=10,Ns=1800*1e3;function Y(t,e){return new Promise((r,s)=>{let n=e?.port??Es,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(()=>{g.close();},Ns);}let u=e?.htmlPath??null;if(!u){let p=path.dirname(t);try{let f=fs$1.readdirSync(p).find(c=>c.endsWith(".html"));f&&(u=path.join(p,f));}catch{}}let g=http.createServer((p,f)=>{if(l(),Ut(f),p.method==="OPTIONS"){f.writeHead(204),f.end();return}let c;try{c=new URL(p.url??"/",`http://${p.headers.host??"localhost"}`).pathname;}catch{b(f,400,{error:"Invalid URL"});return}if(p.method==="GET"&&(c==="/"||c==="/index.html")){if(u&&fs$1.existsSync(u)){Oe(p,f,u);return}b(f,404,{error:"HTML report not found"});return}if(p.method==="GET"&&c==="/api/health"){$t(p,f,t,a);return}if(p.method==="GET"&&c==="/api/summary"){zt(p,f,t);return}if(p.method==="GET"&&c==="/api/tests"){jt(p,f,t);return}if(p.method==="GET"&&c==="/api/files"){Wt(p,f,t);return}let h=c.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(p.method==="GET"&&h){Gt(p,f,t,h[1],h[2]);return}let v=c.match(/^\/api\/tests\/([a-f0-9]+)$/);if(p.method==="GET"&&v){Vt(p,f,t,v[1]);return}if(p.method==="GET"&&c==="/api/artifacts"){Kt(p,f,d);return}if(p.method==="DELETE"&&c==="/api/artifacts"){Jt(p,f,d);return}let w=c.match(/^\/api\/artifacts\/(.+)$/);if(p.method==="DELETE"&&w){Yt(p,f,d,decodeURIComponent(w[1]));return}if(p.method==="GET"&&c.startsWith("/artifacts/")){let x=decodeURIComponent(c.slice(11));if(x.includes("..")||x.includes("\0")){b(f,400,{error:"Invalid path"});return}Oe(p,f,path.join(d,x));return}if(p.method==="POST"&&c==="/api/shutdown"){Qt(p,f,g);return}b(f,404,{error:"Not found"});});function m(p){let f=c=>{c.code==="EADDRINUSE"&&i<Ps?(i++,m(p+1)):s(c);};g.once("error",f),g.listen(p,"127.0.0.1",()=>{g.removeListener("error",f);let c=g.address();if(!c||typeof c=="string"){s(new Error("Failed to get server address"));return}l(),r({port:c.port,dispose:()=>new Promise(h=>{clearTimeout(o),g.close(()=>h());})});});}m(n);})}async function Zt(t){let e=await Y(t);return {port:e.port,dispose:e.dispose}}function Bs(t,e,r){let s=JSON.stringify(t),n=r?JSON.stringify(r):null;return Ft(s,e,n)}async function He(t,e,r){try{let s=null,n=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="",u="[]",g=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),f=path.join(p,".testrelic-report");try{let c=path.join(f,"index-compact.json"),h=path.join(f,"index.json");fs$1.existsSync(c)?u=fs$1.readFileSync(c,"utf-8"):fs$1.existsSync(h)&&(u=fs$1.readFileSync(h,"utf-8"));}catch{}g=r?JSON.stringify(r):null,o=Fe(l,u,null,g);}else o=Bs(t,null,r);let m=i+".tmp";if(fs$1.writeFileSync(m,o,"utf-8"),fs$1.renameSync(m,i),a){if(t.ci===null){let p=path.dirname(e.outputPath),f=path.join(p,".testrelic-report"),c=path.resolve(i);try{if(await qs(),s=await Hs(f),!s){n=await Y(f,{htmlPath:c}),s=n.port;let h=setInterval(()=>{},6e4),v=()=>{clearInterval(h),n?.dispose();};process.on("SIGINT",v),process.on("SIGTERM",v),setTimeout(v,1800*1e3).unref();}if(s){process.stderr.write(`
2547
+ `);});}catch{}}path.join(os$1.tmpdir(),"testrelic-data");async function Ft(t,e,r,s){let n=(e-1)*r,a=[],o=0,i=readline.createInterface({input:fs$1.createReadStream(t,{encoding:"utf-8"}),crlfDelay:1/0});for await(let u of i)if(u.length!==0){if(o>=n&&a.length<r)try{a.push(JSON.parse(u));}catch{}if(o++,a.length>=r&&s!==void 0)break}let d=s??o,l=Math.max(1,Math.ceil(d/r));return {items:a,total:d,page:e,pageSize:r,totalPages:l}}var Ot=/^[a-f0-9]{12}$/,Be=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,qt=500;function b(t,e,r){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r));}function Ht(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Allow-Methods","GET, DELETE, OPTIONS"),t.setHeader("Access-Control-Allow-Headers","Content-Type");}function ae(t){try{return fs$1.existsSync(t)?JSON.parse(fs$1.readFileSync(t,"utf-8")):null}catch{return null}}function ie(t){let e=0;try{let r=fs$1.readdirSync(t,{withFileTypes:!0});for(let s of r){let n=path.join(t,s.name);s.isFile()?e+=fs$1.statSync(n).size:s.isDirectory()&&(e+=ie(n));}}catch{}return e}function Ut(t,e,r,s){let n=ae(path.join(r,"index.json"));b(e,200,{status:"ok",reportMode:"streaming",testCount:n?.length??0,uptime:Math.floor((Date.now()-s)/1e3)});}function $t(t,e,r){let s=ae(path.join(r,"summary.json"));if(!s){b(e,404,{error:"Summary not found"});return}b(e,200,s);}function zt(t,e,r){let s=ae(path.join(r,"index.json"));if(!s){b(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(qt,Math.max(1,parseInt(a.get("pageSize")??"100",10)||100)),d=a.get("status")?.split(",").filter(Boolean)??null,l=a.get("file")??null,u=a.get("search")?.toLowerCase()??null,g=a.get("tag")?.split(",").filter(Boolean)??null,m=a.get("sort")??"file",p=a.get("order")==="desc"?-1:1,f=s;d&&d.length>0&&(f=f.filter(x=>d.includes(x.status))),l&&(f=f.filter(x=>x.filePath===l||x.filePath.startsWith(l+"/"))),u&&(f=f.filter(x=>x.title.toLowerCase().includes(u)||x.filePath.toLowerCase().includes(u))),g&&g.length>0&&(f=f.filter(x=>g.some(T=>x.tags.includes(T)))),f=[...f].sort((x,T)=>{let M=0;switch(m){case "duration":M=x.duration-T.duration;break;case "status":M=x.status.localeCompare(T.status);break;case "title":M=x.title.localeCompare(T.title);break;default:M=x.filePath.localeCompare(T.filePath);break}return M*p});let c=f.length,h=Math.max(1,Math.ceil(c/i)),v=(o-1)*i,w=f.slice(v,v+i);b(e,200,{tests:w,pagination:{page:o,pageSize:i,totalItems:c,totalPages:h},filters:{status:d,file:l,search:u,tag:g}});}function jt(t,e,r,s){if(!Ot.test(s)){b(e,400,{error:"Invalid test ID format"});return}let n=path.join(r,"tests",s,"meta.json"),a=path.join(r,"tests",`${s}.json`),o=fs$1.existsSync(n)?n:fs$1.existsSync(a)?a:null;if(!o){b(e,404,{error:`Test not found: ${s}`});return}try{let i=fs$1.readFileSync(o,"utf-8");e.writeHead(200,{"Content-Type":"application/json"}),e.end(i);}catch(i){b(e,500,{error:i instanceof Error?i.message:String(i)});}}async function Vt(t,e,r,s,n){if(!Ot.test(s)){b(e,400,{error:"Invalid test ID format"});return}let o=path.join(r,"tests",s,{network:"network.jsonl",console:"console.jsonl","api-calls":"api-calls.jsonl"}[n]);if(!fs$1.existsSync(o)){b(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),u=Math.min(qt,Math.max(1,parseInt(d.get("pageSize")??"50",10)||50)),g,m=path.join(r,"tests",s,"meta.json");if(fs$1.existsSync(m))try{let f=JSON.parse(fs$1.readFileSync(m,"utf-8"));switch(n){case "network":g=f.networkRequestsCount;break;case "console":g=f.consoleLogsCount;break;case "api-calls":g=f.apiCallsCount;break}}catch{}let p=await Ft(o,l,u,g);b(e,200,p);}catch(i){b(e,500,{error:i instanceof Error?i.message:String(i)});}}function Gt(t,e,r){let s=ae(path.join(r,"index.json"));if(!s){b(e,404,{error:"Test index not found"});return}let n=new Map;for(let o of s){if(o.isRetry)continue;let i=n.get(o.filePath);switch(i||(i={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},n.set(o.filePath,i)),i.total++,o.status){case "passed":i.passed++;break;case "failed":i.failed++;break;case "flaky":i.flaky++;break;case "skipped":i.skipped++;break;case "timedout":i.timedOut++;break}}let a=Array.from(n.entries()).map(([o,i])=>({filePath:o,...i})).sort((o,i)=>o.filePath.localeCompare(i.filePath));b(e,200,{files:a});}function Wt(t,e,r){if(!fs$1.existsSync(r)){b(e,200,{runs:[],totalSizeBytes:0});return}try{let s=[],n=0,a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!Be.test(o.name))continue;let i=path.join(r,o.name),d=ie(i),l=fs$1.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory());s.push({folderName:o.name,totalSizeBytes:d,testCount:l.length}),n+=d;}s.sort((o,i)=>i.folderName.localeCompare(o.folderName)),b(e,200,{runs:s,totalSizeBytes:n});}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}function Kt(t,e,r){try{let s=0,n=0;if(fs$1.existsSync(r)){let a=fs$1.readdirSync(r,{withFileTypes:!0});for(let o of a){if(!o.isDirectory()||!Be.test(o.name))continue;let i=path.join(r,o.name),d=ie(i);fs$1.rmSync(i,{recursive:!0,force:!0}),n+=d,s++;}}b(e,200,{deletedCount:s,freedBytes:n});}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}function Jt(t,e,r,s){if(!Be.test(s)){b(e,400,{error:"Invalid folder name"});return}let n=path.join(r,s);try{if(!fs$1.statSync(n).isDirectory()){b(e,404,{error:"Not found"});return}}catch{b(e,404,{error:"Not found"});return}try{let a=ie(n);fs$1.rmSync(n,{recursive:!0,force:!0}),b(e,200,{deleted:s,freedBytes:a});}catch(a){b(e,500,{error:a instanceof Error?a.message:String(a)});}}function Yt(t,e,r){b(e,200,{status:"shutting_down"}),r.close();}function Oe(t,e,r){if(!fs$1.existsSync(r)){b(e,404,{error:"File not found"});return}try{let s=fs$1.readFileSync(r),n=path.extname(r).toLowerCase(),a=Is[n]??"application/octet-stream";e.writeHead(200,{"Content-Type":a}),e.end(s);}catch(s){b(e,500,{error:s instanceof Error?s.message:String(s)});}}var Is={".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 Es=9323,Ps=10,Ns=1800*1e3;function Y(t,e){return new Promise((r,s)=>{let n=e?.port??Es,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(()=>{g.close();},Ns);}let u=e?.htmlPath??null;if(!u){let p=path.dirname(t);try{let f=fs$1.readdirSync(p).find(c=>c.endsWith(".html"));f&&(u=path.join(p,f));}catch{}}let g=http.createServer((p,f)=>{if(l(),Ht(f),p.method==="OPTIONS"){f.writeHead(204),f.end();return}let c;try{c=new URL(p.url??"/",`http://${p.headers.host??"localhost"}`).pathname;}catch{b(f,400,{error:"Invalid URL"});return}if(p.method==="GET"&&(c==="/"||c==="/index.html")){if(u&&fs$1.existsSync(u)){Oe(p,f,u);return}b(f,404,{error:"HTML report not found"});return}if(p.method==="GET"&&c==="/api/health"){Ut(p,f,t,a);return}if(p.method==="GET"&&c==="/api/summary"){$t(p,f,t);return}if(p.method==="GET"&&c==="/api/tests"){zt(p,f,t);return}if(p.method==="GET"&&c==="/api/files"){Gt(p,f,t);return}let h=c.match(/^\/api\/tests\/([a-f0-9]+)\/(network|console|api-calls)$/);if(p.method==="GET"&&h){Vt(p,f,t,h[1],h[2]);return}let v=c.match(/^\/api\/tests\/([a-f0-9]+)$/);if(p.method==="GET"&&v){jt(p,f,t,v[1]);return}if(p.method==="GET"&&c==="/api/artifacts"){Wt(p,f,d);return}if(p.method==="DELETE"&&c==="/api/artifacts"){Kt(p,f,d);return}let w=c.match(/^\/api\/artifacts\/(.+)$/);if(p.method==="DELETE"&&w){Jt(p,f,d,decodeURIComponent(w[1]));return}if(p.method==="GET"&&c.startsWith("/artifacts/")){let x=decodeURIComponent(c.slice(11));if(x.includes("..")||x.includes("\0")){b(f,400,{error:"Invalid path"});return}Oe(p,f,path.join(d,x));return}if(p.method==="POST"&&c==="/api/shutdown"){Yt(p,f,g);return}b(f,404,{error:"Not found"});});function m(p){let f=c=>{c.code==="EADDRINUSE"&&i<Ps?(i++,m(p+1)):s(c);};g.once("error",f),g.listen(p,"127.0.0.1",()=>{g.removeListener("error",f);let c=g.address();if(!c||typeof c=="string"){s(new Error("Failed to get server address"));return}l(),r({port:c.port,dispose:()=>new Promise(h=>{clearTimeout(o),g.close(()=>h());})});});}m(n);})}async function Qt(t){let e=await Y(t);return {port:e.port,dispose:e.dispose}}function Bs(t,e,r){let s=JSON.stringify(t),n=r?JSON.stringify(r):null;return Nt(s,e,n)}async function He(t,e,r){try{let s=null,n=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="",u="[]",g=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),f=path.join(p,".testrelic-report");try{let c=path.join(f,"index-compact.json"),h=path.join(f,"index.json");fs$1.existsSync(c)?u=fs$1.readFileSync(c,"utf-8"):fs$1.existsSync(h)&&(u=fs$1.readFileSync(h,"utf-8"));}catch{}g=r?JSON.stringify(r):null,o=Fe(l,u,null,g);}else o=Bs(t,null,r);let m=i+".tmp";if(fs$1.writeFileSync(m,o,"utf-8"),fs$1.renameSync(m,i),a){if(t.ci===null){let p=path.dirname(e.outputPath),f=path.join(p,".testrelic-report"),c=path.resolve(i);try{if(await qs(),s=await Hs(f),!s){n=await Y(f,{htmlPath:c}),s=n.port;let h=setInterval(()=>{},6e4),v=()=>{clearInterval(h),n?.dispose();};process.on("SIGINT",v),process.on("SIGTERM",v),setTimeout(v,1800*1e3).unref();}if(s){process.stderr.write(`
2548
2548
  Report server: http://127.0.0.1:${s}
2549
- `);try{let h=Fe(l,u,s,g),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),f=path.join(p,"artifacts");if(fs$1.existsSync(f))try{let c=await Zt(f);s=c.port,process.on("exit",()=>{c.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(a&&s)De(`http://127.0.0.1:${s}`);else {let p=path.resolve(i);De(p);}}catch(s){process.stderr.write(`[testrelic] Failed to write HTML report: ${s instanceof Error?s.message:String(s)}
2550
- `);}}var de=9323,sr=10;async function Os(){for(let t=de;t<de+sr;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),s=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),s.ok)return t}catch{}return null}async function qs(){for(let t=de;t<de+sr;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 Hs(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(s=>fs$1.existsSync(s));if(!r){let s=await Y(t);return process.on("exit",()=>{s?.dispose();}),s.port}return new Promise(s=>{let n=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,n.stderr?.removeAllListeners(),Os().then(s));},5e3);n.stderr?.on("data",d=>{a+=d.toString();let l=a.match(/127\.0\.0\.1:(\d+)/);l&&!o&&(o=true,clearTimeout(i),n.stderr?.removeAllListeners(),n.unref(),s(Number(l[1])));}),n.on("error",()=>{o||(o=true,clearTimeout(i),s(null));}),n.on("exit",()=>{o||(o=true,clearTimeout(i),s(null));}),n.unref();})}var zs=20,Ue=0,$e=[];async function ar(t,e){Ue>=zs&&await new Promise(r=>$e.push(r)),Ue++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{Ue--,$e.length>0&&$e.shift()();}}var Z=[];async function ir(){Z.length!==0&&(await Promise.allSettled(Z),Z.length=0);}function or(t){let e=new Date,r=a=>String(a).padStart(2,"0"),s=`${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,s)))return s;let n=1;for(;fs$1.existsSync(path.join(t,`${s}-${n}`));)n++;return `${s}-${n}`}function js(t){let e=t.replace(/[^a-zA-Z0-9\-_ ]/g,"-").replace(/\s+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"");return e.length>100&&(e=e.substring(0,100).replace(/-+$/,"")),e||"unnamed-test"}function lr(t,e,r,s,n){let a=t.find(m=>m.name==="screenshot"&&m.path),o=t.find(m=>m.name==="video"&&m.path);if(!a&&!o)return null;let i=js(e);r>0&&(i+=`--retry-${r}`);let d=n?["artifacts",n,i]:["artifacts",i],l=path.join(s,...d),u=d,g={};try{fs$1.mkdirSync(l,{recursive:!0});}catch{return null}if(a?.path&&fs$1.existsSync(a.path)){let p=`screenshot${path.extname(a.path)||".png"}`,f=path.join(l,p);Z.push(ar(a.path,f).then(()=>{})),g.screenshot=`${u.join("/")}/${p}`;}if(o?.path&&fs$1.existsSync(o.path)){let p=`video${path.extname(o.path)||".webm"}`,f=path.join(l,p);Z.push(ar(o.path,f).then(()=>{})),g.video=`${u.join("/")}/${p}`;}return !g.screenshot&&!g.video?null:g}var Ws=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Ks="1.0";function Js(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function dr(t,e,r){let s=[];try{let n=fs$1.readdirSync(t,{withFileTypes:!0});for(let a of n){if(!a.isFile())continue;let o=path.join(t,a.name),i=fs$1.statSync(o);s.push({name:a.name,type:Js(a.name),relativePath:`artifacts/${e}/${r}/${a.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:s}}function Ys(t,e){let r=path.join(t,e),s=[],n=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let d=dr(path.join(r,i.name),e,i.name);s.push(d);for(let l of d.files)n+=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 s.sort((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:n,testCount:s.length,tests:s,isCurrentRun:false}}function cr(t,e){let r=path.join(t,"artifacts"),s=[],n=[],a=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(Ws.test(d.name)){let l=Ys(r,d.name);s.push({...l,isCurrentRun:d.name===e});}else {let l=dr(path.join(r,d.name),d.name,d.name);n.push(l);for(let u of l.files)a+=u.sizeBytes;}}catch{}s.sort((i,d)=>d.timestamp.localeCompare(i.timestamp)),n.length>0&&(n.sort((i,d)=>i.testName.localeCompare(d.testName)),s.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:a,testCount:n.length,tests:n,isCurrentRun:false}));let o=s.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:Ks,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:s,serverPort:null}}function tn(t){let e=t,{root:r}=path.parse(e);for(;e!==r;){if(fs$1.existsSync(path.join(e,".git")))return e;e=path.join(e,"..");}return null}function pr(t){try{let e=tn(t);if(!e)return;let r=path.join(e,".gitignore"),s=path.relative(e,t).replace(/\\/g,"/"),n=s.endsWith("/")?s:`${s}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
2549
+ `);try{let h=Fe(l,u,s,g),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),f=path.join(p,"artifacts");if(fs$1.existsSync(f))try{let c=await Qt(f);s=c.port,process.on("exit",()=>{c.dispose();});}catch{}}if(e.openReport&&t.ci===null)if(a&&s)De(`http://127.0.0.1:${s}`);else {let p=path.resolve(i);De(p);}}catch(s){process.stderr.write(`[testrelic] Failed to write HTML report: ${s instanceof Error?s.message:String(s)}
2550
+ `);}}var de=9323,rr=10;async function Os(){for(let t=de;t<de+rr;t++)try{let e=new AbortController,r=setTimeout(()=>e.abort(),500),s=await fetch(`http://127.0.0.1:${t}/api/health`,{signal:e.signal});if(clearTimeout(r),s.ok)return t}catch{}return null}async function qs(){for(let t=de;t<de+rr;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 Hs(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(s=>fs$1.existsSync(s));if(!r){let s=await Y(t);return process.on("exit",()=>{s?.dispose();}),s.port}return new Promise(s=>{let n=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,n.stderr?.removeAllListeners(),Os().then(s));},5e3);n.stderr?.on("data",d=>{a+=d.toString();let l=a.match(/127\.0\.0\.1:(\d+)/);l&&!o&&(o=true,clearTimeout(i),n.stderr?.removeAllListeners(),n.unref(),s(Number(l[1])));}),n.on("error",()=>{o||(o=true,clearTimeout(i),s(null));}),n.on("exit",()=>{o||(o=true,clearTimeout(i),s(null));}),n.unref();})}var zs=20,Ue=0,$e=[];async function nr(t,e){Ue>=zs&&await new Promise(r=>$e.push(r)),Ue++;try{return await promises.copyFile(t,e),!0}catch{return false}finally{Ue--,$e.length>0&&$e.shift()();}}var Z=[];async function ar(){Z.length!==0&&(await Promise.allSettled(Z),Z.length=0);}function ir(t){let e=new Date,r=a=>String(a).padStart(2,"0"),s=`${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,s)))return s;let n=1;for(;fs$1.existsSync(path.join(t,`${s}-${n}`));)n++;return `${s}-${n}`}function js(t){let e=t.replace(/[^a-zA-Z0-9\-_ ]/g,"-").replace(/\s+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"");return e.length>100&&(e=e.substring(0,100).replace(/-+$/,"")),e||"unnamed-test"}function or(t,e,r,s,n){let a=t.find(m=>m.name==="screenshot"&&m.path),o=t.find(m=>m.name==="video"&&m.path);if(!a&&!o)return null;let i=js(e);r>0&&(i+=`--retry-${r}`);let d=n?["artifacts",n,i]:["artifacts",i],l=path.join(s,...d),u=d,g={};try{fs$1.mkdirSync(l,{recursive:!0});}catch{return null}if(a?.path&&fs$1.existsSync(a.path)){let p=`screenshot${path.extname(a.path)||".png"}`,f=path.join(l,p);Z.push(nr(a.path,f).then(()=>{})),g.screenshot=`${u.join("/")}/${p}`;}if(o?.path&&fs$1.existsSync(o.path)){let p=`video${path.extname(o.path)||".webm"}`,f=path.join(l,p);Z.push(nr(o.path,f).then(()=>{})),g.video=`${u.join("/")}/${p}`;}return !g.screenshot&&!g.video?null:g}var Ws=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(-\d+)?$/,Ks="1.0";function Js(t){let e=path.extname(t).toLowerCase();return [".png",".jpg",".jpeg",".gif",".bmp",".webp"].includes(e)?"screenshot":[".webm",".mp4",".avi",".mov"].includes(e)?"video":"other"}function lr(t,e,r){let s=[];try{let n=fs$1.readdirSync(t,{withFileTypes:!0});for(let a of n){if(!a.isFile())continue;let o=path.join(t,a.name),i=fs$1.statSync(o);s.push({name:a.name,type:Js(a.name),relativePath:`artifacts/${e}/${r}/${a.name}`,sizeBytes:i.size});}}catch{}return {testName:r,files:s}}function Ys(t,e){let r=path.join(t,e),s=[],n=0;try{let o=fs$1.readdirSync(r,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let d=lr(path.join(r,i.name),e,i.name);s.push(d);for(let l of d.files)n+=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 s.sort((o,i)=>o.testName.localeCompare(i.testName)),{folderName:e,timestamp:a,totalSizeBytes:n,testCount:s.length,tests:s,isCurrentRun:false}}function dr(t,e){let r=path.join(t,"artifacts"),s=[],n=[],a=0;try{let i=fs$1.readdirSync(r,{withFileTypes:!0});for(let d of i)if(d.isDirectory())if(Ws.test(d.name)){let l=Ys(r,d.name);s.push({...l,isCurrentRun:d.name===e});}else {let l=lr(path.join(r,d.name),d.name,d.name);n.push(l);for(let u of l.files)a+=u.sizeBytes;}}catch{}s.sort((i,d)=>d.timestamp.localeCompare(i.timestamp)),n.length>0&&(n.sort((i,d)=>i.testName.localeCompare(d.testName)),s.push({folderName:"__legacy__",timestamp:"1970-01-01T00:00:00",totalSizeBytes:a,testCount:n.length,tests:n,isCurrentRun:false}));let o=s.reduce((i,d)=>i+d.totalSizeBytes,0);return {schemaVersion:Ks,generatedAt:new Date().toISOString(),artifactBaseDir:"artifacts",totalSizeBytes:o,runs:s,serverPort:null}}function rn(t){let e=path.resolve(t);for(;;){if(fs$1.existsSync(path.join(e,".git")))return e;let r=path.dirname(e);if(r===e)return null;e=r;}}function pr(t){try{let e=rn(t);if(!e)return;let r=path.join(e,".gitignore"),s=path.relative(e,t).replace(/\\/g,"/"),n=s.endsWith("/")?s:`${s}/`;if(fs$1.existsSync(r)&&fs$1.readFileSync(r,"utf-8").split(`
2551
2551
  `).map(d=>d.trim()).some(d=>d===n||d===s))return;let a=`
2552
2552
  # TestRelic test artifacts
2553
2553
  ${n}
2554
- `;fs$1.appendFileSync(r,a,"utf-8");}catch{}}function hr(t,e){let r=[];for(let s of t){let n=rn(s),a=sn(s),o=nn(s,n,a,e),i=an(s,n,a);if(o.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:s.startedAt,durationOnUrl:s.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:s.specFile,test:n,tests:[a],_testTitle:s.title});continue}r.push(...o,...i);}return r.sort(on),ln(r,t),r.map((s,n)=>s.type==="navigation"?{...{index:n,type:"navigation",url:s.url,timestamp:s.timestamp,durationOnUrl:s.durationOnUrl??0,navigationType:s.navigationType,domContentLoadedAt:s.domContentLoadedAt??null,networkIdleAt:s.networkIdleAt??null,networkStats:s.networkStats??null,specFile:s.specFile,test:s.test},tests:s.tests}:{...{index:n,type:"api_call",callId:s.callId,method:s.method,url:s.url,timestamp:s.timestamp,responseTime:s.responseTime??null,request:s.request,response:s.response??null,...s.error?{error:s.error}:{},assertions:s.assertions??[],specFile:s.specFile,test:s.test},tests:s.tests})}function rn(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 sn(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 nn(t,e,r,s){let n=[];for(let a of t.navigations)s.navigationTypes!==null&&!s.navigationTypes.includes(a.navigationType)||n.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 n}function an(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let s=t.apiAssertions??[];return t.apiCalls.map(n=>{let a=s.filter(i=>i.callId===n.id).map(i=>({type:i.type,expected:i.expected,actual:i.actual,status:i.status,location:i.location,...i.expression!==void 0?{expression:i.expression}:{}})),o=null;return n.responseStatusCode!==null&&n.responseStatusText!==null&&(o={statusCode:n.responseStatusCode,statusText:n.responseStatusText,headers:n.responseHeaders,body:gr(n.responseBody)}),{type:"api_call",callId:n.id,method:n.method,url:n.url,timestamp:n.timestamp,responseTime:n.error?null:n.responseTimeMs,request:{headers:n.requestHeaders,body:gr(n.requestBody)},response:o,...n.error?{error:n.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function on(t,e){let r=new Date(t.timestamp).getTime(),s=new Date(e.timestamp).getTime();if(r!==s)return r-s;let n={navigation:0,api_call:1},a=n[t.type],o=n[e.type];return a!==o?a-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?fr(t.callId)-fr(e.callId):0}function fr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function ln(t,e){for(let r=0;r<t.length;r++){let s=t[r];if(s.type!=="navigation")continue;let n=new Date(s.timestamp).getTime(),a=null;for(let o=r+1;o<t.length;o++)if(t[o]._testTitle===s._testTitle){a=new Date(t[o].timestamp).getTime();break}if(a!==null)s.durationOnUrl=Math.max(0,a-n);else {let o=e.find(i=>i.title===s._testTitle);if(o){let i=new Date(o.completedAt).getTime();s.durationOnUrl=Math.max(0,i-n);}}}}function gr(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function H(t,e){let r=t.length,s=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,s)]}function Ve(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function dn(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 mr(t,e){let r=0,s=0,n=0,a=0,o=0;for(let y of t)switch(y.status){case "passed":r++;break;case "failed":s++;break;case "flaky":n++;break;case "skipped":a++;break;case "timedout":o++;break}let i=[];for(let y of t)y.apiCalls&&i.push(...y.apiCalls);let d=i.length,l=new Set,u={},g={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},m=[];for(let y of i)l.add(Ve(y.url)),u[y.method]=(u[y.method]??0)+1,g[dn(y.responseStatusCode)]+=1,m.push(y.responseTimeMs);let p=null;if(m.length>0){let y=[...m].sort((R,U)=>R-U),k=y.reduce((R,U)=>R+U,0);p={avg:Math.round(k/y.length),min:y[0],max:y[y.length-1],p50:H(y,50),p95:H(y,95),p99:H(y,99)};}let f=0,c=0,h=0;for(let y of t)if(y.apiAssertions)for(let k of y.apiAssertions)f++,k.status==="passed"?c++:h++;let v=0,w=new Set;for(let y of t){v+=y.navigations.length;for(let k of y.navigations)w.add(k.url);}let x=0,T={};function M(y){for(let k of y)x++,T[k.category]=(T[k.category]??0)+1,k.children.length>0&&M(k.children);}for(let y of t)y.actions&&M(y.actions);return {total:t.length,passed:r,failed:s,flaky:n,skipped:a,timedout:o,totalApiCalls:d,uniqueApiUrls:l.size,apiCallsByMethod:u,apiCallsByStatusRange:g,apiResponseTime:p,totalAssertions:f,passedAssertions:c,failedAssertions:h,totalNavigations:v,uniqueNavigationUrls:w.size,totalTimelineSteps:e,totalActionSteps:x,actionStepsByCategory:T}}function cn(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${cn(t)} \u2502
2555
- `}function Ge(t,e,r,s){if(s||t.total===0)return;let n=`\u250C${"\u2500".repeat(58)}\u2510
2554
+ `;fs$1.appendFileSync(r,a,"utf-8");}catch{}}function hr(t,e){let r=[];for(let s of t){let n=sn(s),a=nn(s),o=an(s,n,a,e),i=on(s,n,a);if(o.length===0&&i.length===0){r.push({type:"navigation",url:"about:blank",timestamp:s.startedAt,durationOnUrl:s.duration,navigationType:"dummy",domContentLoadedAt:null,networkIdleAt:null,networkStats:null,specFile:s.specFile,test:n,tests:[a],_testTitle:s.title});continue}r.push(...o,...i);}return r.sort(ln),dn(r,t),r.map((s,n)=>s.type==="navigation"?{...{index:n,type:"navigation",url:s.url,timestamp:s.timestamp,durationOnUrl:s.durationOnUrl??0,navigationType:s.navigationType,domContentLoadedAt:s.domContentLoadedAt??null,networkIdleAt:s.networkIdleAt??null,networkStats:s.networkStats??null,specFile:s.specFile,test:s.test},tests:s.tests}:{...{index:n,type:"api_call",callId:s.callId,method:s.method,url:s.url,timestamp:s.timestamp,responseTime:s.responseTime??null,request:s.request,response:s.response??null,...s.error?{error:s.error}:{},assertions:s.assertions??[],specFile:s.specFile,test:s.test},tests:s.tests})}function sn(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 nn(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 an(t,e,r,s){let n=[];for(let a of t.navigations)s.navigationTypes!==null&&!s.navigationTypes.includes(a.navigationType)||n.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 n}function on(t,e,r){if(!t.apiCalls||t.apiCalls.length===0)return [];let s=t.apiAssertions??[];return t.apiCalls.map(n=>{let a=s.filter(i=>i.callId===n.id).map(i=>({type:i.type,expected:i.expected,actual:i.actual,status:i.status,location:i.location,...i.expression!==void 0?{expression:i.expression}:{}})),o=null;return n.responseStatusCode!==null&&n.responseStatusText!==null&&(o={statusCode:n.responseStatusCode,statusText:n.responseStatusText,headers:n.responseHeaders,body:gr(n.responseBody)}),{type:"api_call",callId:n.id,method:n.method,url:n.url,timestamp:n.timestamp,responseTime:n.error?null:n.responseTimeMs,request:{headers:n.requestHeaders,body:gr(n.requestBody)},response:o,...n.error?{error:n.error}:{},assertions:a,specFile:t.specFile,test:e,tests:[r],_testTitle:t.title}})}function ln(t,e){let r=new Date(t.timestamp).getTime(),s=new Date(e.timestamp).getTime();if(r!==s)return r-s;let n={navigation:0,api_call:1},a=n[t.type],o=n[e.type];return a!==o?a-o:t.type==="api_call"&&e.type==="api_call"&&t.callId&&e.callId?fr(t.callId)-fr(e.callId):0}function fr(t){let e=t.match(/(\d+)$/);return e?parseInt(e[1],10):0}function dn(t,e){for(let r=0;r<t.length;r++){let s=t[r];if(s.type!=="navigation")continue;let n=new Date(s.timestamp).getTime(),a=null;for(let o=r+1;o<t.length;o++)if(t[o]._testTitle===s._testTitle){a=new Date(t[o].timestamp).getTime();break}if(a!==null)s.durationOnUrl=Math.max(0,a-n);else {let o=e.find(i=>i.title===s._testTitle);if(o){let i=new Date(o.completedAt).getTime();s.durationOnUrl=Math.max(0,i-n);}}}}function gr(t){if(t==null)return null;try{return JSON.parse(t)}catch{return t}}function H(t,e){let r=t.length,s=Math.min(Math.ceil(e/100*r)-1,r-1);return t[Math.max(0,s)]}function je(t){try{let e=new URL(t);return e.origin+e.pathname}catch{return t}}function cn(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 mr(t,e){let r=0,s=0,n=0,a=0,o=0;for(let y of t)switch(y.status){case "passed":r++;break;case "failed":s++;break;case "flaky":n++;break;case "skipped":a++;break;case "timedout":o++;break}let i=[];for(let y of t)y.apiCalls&&i.push(...y.apiCalls);let d=i.length,l=new Set,u={},g={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0},m=[];for(let y of i)l.add(je(y.url)),u[y.method]=(u[y.method]??0)+1,g[cn(y.responseStatusCode)]+=1,m.push(y.responseTimeMs);let p=null;if(m.length>0){let y=[...m].sort((R,U)=>R-U),k=y.reduce((R,U)=>R+U,0);p={avg:Math.round(k/y.length),min:y[0],max:y[y.length-1],p50:H(y,50),p95:H(y,95),p99:H(y,99)};}let f=0,c=0,h=0;for(let y of t)if(y.apiAssertions)for(let k of y.apiAssertions)f++,k.status==="passed"?c++:h++;let v=0,w=new Set;for(let y of t){v+=y.navigations.length;for(let k of y.navigations)w.add(k.url);}let x=0,T={};function M(y){for(let k of y)x++,T[k.category]=(T[k.category]??0)+1,k.children.length>0&&M(k.children);}for(let y of t)y.actions&&M(y.actions);return {total:t.length,passed:r,failed:s,flaky:n,skipped:a,timedout:o,totalApiCalls:d,uniqueApiUrls:l.size,apiCallsByMethod:u,apiCallsByStatusRange:g,apiResponseTime:p,totalAssertions:f,passedAssertions:c,failedAssertions:h,totalNavigations:v,uniqueNavigationUrls:w.size,totalTimelineSteps:e,totalActionSteps:x,actionStepsByCategory:T}}function un(t){let e=56-t.length;return e>0?t+" ".repeat(e):t}function I(t){return `\u2502 ${un(t)} \u2502
2555
+ `}function Ve(t,e,r,s){if(s||t.total===0)return;let n=`\u250C${"\u2500".repeat(58)}\u2510
2556
2556
  `,a=`\u2514${"\u2500".repeat(58)}\u2518
2557
2557
  `,o=I(""),i=n;i+=I("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+=I(`Tests: ${t.total} total (${d.join(" ")})`),t.totalNavigations>0&&(i+=I(`Navigations: ${t.totalNavigations} visits across ${t.uniqueNavigationUrls} unique URLs`)),t.totalApiCalls>0){i+=I(`API Calls: ${t.totalApiCalls} calls across ${t.uniqueApiUrls} unique endpoints`);let l=Object.entries(t.apiCallsByMethod).filter(([,g])=>g>0).map(([g,m])=>`${g}: ${m}`);l.length>0&&(i+=I(` ${l.join(" ")}`));let u=Object.entries(t.apiCallsByStatusRange).filter(([,g])=>g>0).map(([g,m])=>`${g}: ${m}`);u.length>0&&(i+=I(` ${u.join(" ")}`)),t.apiResponseTime&&(i+=I(` Avg response: ${t.apiResponseTime.avg}ms P95: ${t.apiResponseTime.p95}ms`));}if(t.totalAssertions>0&&(i+=I(`Assertions: ${t.totalAssertions} total (${t.passedAssertions} \u2713 ${t.failedAssertions} \u2717)`)),t.totalActionSteps>0){let l=[],u=t.actionStepsByCategory;u.ui_action&&l.push(`${u.ui_action} UI`),u.assertion&&l.push(`${u.assertion} assertions`),u.custom_step&&l.push(`${u.custom_step} custom`);let g=l.length>0?` (${l.join(" ")})`:"";i+=I(`Actions: ${t.totalActionSteps} steps${g}`);}i+=I(`Report: ${r}`),i+=I(`Data: ${e}`),i+=a,i+=`For more information visit us at https://docs.testrelic.ai
2558
- `,process.stderr.write(i);}var un=new Set(["pw:api","expect","test.step"]);function pn(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function We(t,e,r){if(un.has(t.category)){let s=[];for(let a of t.steps)We(a,e,s);let n=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:pn(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:n>=0?n/1e3:null,status:t.error?"failed":"passed",error:t.error?.message??null,children:s});}else for(let s of t.steps)We(s,e,r);}function vr(t,e){let r=[];for(let s of t)We(s,e,r);return r}var hn=new Set(["localhost","127.0.0.1","0.0.0.0"]);function br(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&hn.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var mn=3e3;async function Ke(t){let e=new AbortController,r=setTimeout(()=>e.abort(),mn);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function xr(t){return new Promise(e=>setTimeout(e,t))}async function yr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let s=r.details;if(Array.isArray(s)&&s.length>0){let n=s.map(a=>`${a.field}: ${a.message}`).join(", ");return `${r.message} (${n})`}return r.message}}catch{}return `HTTP ${t.status}`}async function Je(t,e,r){let s=new AbortController,n=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:s.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 xr(d);let l=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:s.signal});if(l.ok){let u=await l.json();return {accessToken:u.accessToken,refreshToken:u.refreshToken,expiresIn:u.expiresIn,orgId:u.orgId,orgName:u.orgName,userId:u.userId,userName:u.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return a.status===400?{code:"validation_error",message:await yr(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 yr(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(n);}}function Ye(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 wr(t,e,r){let s=new AbortController,n=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:s.signal});if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;!isNaN(d)&&d>0&&(await xr(d),a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:s.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(n);}}async function kr(t,e,r,s,n,a){let o=new AbortController,i=setTimeout(()=>o.abort(),n);try{let d={gitId:r,displayName:s};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 u=await l.json();return {repoId:u.repoId,displayName:u.displayName}}catch{return null}finally{clearTimeout(i);}}var wn=5e3;function F(t,e){try{return child_process.execSync(t,{cwd:e,timeout:wn,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Tr(t){let e=F("git rev-parse --abbrev-ref HEAD",t),r=F("git rev-parse --short HEAD",t),s=F("git log -1 --pretty=%s",t),n=F("git log -1 --format=%an",t)??F("git config user.name",t),a=kn(t),o=a?ee(a):null;return {branch:e,commitSha:r,commitMessage:s,commitAuthor:n,remoteUrl:o}}function kn(t){let e=F("git remote get-url origin",t);if(e)return e;let r=F("git remote",t);if(!r)return null;let s=r.split(`
2559
- `)[0]?.trim();return s?F(`git remote get-url ${s}`,t):null}function ee(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 Sr(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Qe(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 te(t){let e=Qe(t);return e||`local/${path.basename(t)}`}var Tn=new Set(["smoke","regression","nightly","ci"]);function ue(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&Tn.has(t))return t}var Rn=1048576,pe=[1e3,3e3,9e3],fe=3,An=90*1048576,In=new Set(["e2e","mobile","unit"]);function Xe(t){if(t&&t.length>0&&t.every(n=>n.testType==="api")){let n=new Map;for(let i of t){let d=i.apiProtocol??"rest";n.set(d,(n.get(d)??0)+1);}let a="rest",o=0;for(let[i,d]of n)d>o&&(o=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let n of t??[])In.has(n.testType)&&e.set(n.testType,(e.get(n.testType)??0)+1);let r=null,s=0;for(let[n,a]of e)a>s&&(s=a,r=n);return {testType:r??"e2e"}}function et(t,e,r,s,n,a){let o=a?.cloudPlatform?a.cloudPlatform:s?.provider&&s.provider!=="unknown"?s.provider:"local",i=ue(),d=Xe(n),l=d.testType==="api"?d:null,u=l&&n?n.map(m=>m.apiProtocol?m:{...m,apiProtocol:l.apiProtocol}):n;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},...u&&u.length>0?{tests:u}:{},...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}:{},...s?.provider?{ciProvider:s.provider}:{},...s?.runUrl?{ciRunUrl:s.runUrl}:{},...a?.cloudPlatform?{cloudPlatform:a.cloudPlatform}:{},...a?.cloudBuildId?{cloudBuildId:a.cloudBuildId}:{},...a?.cloudSessionId?{cloudSessionId:a.cloudSessionId}:{}}}function Ze(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function tt(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:Ze(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Ze(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 rt(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,s=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:Ze(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:s,startedAt:s}}):[]}function st(t){if(!Array.isArray(t))return [];let e=r=>{if(r==null)return String(r);if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}};return t.map(r=>{let s=r.status==="failed"?"failed":"passed",n=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,a=r.kind??r.type??"assertion",o=s==="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:n??r.description??`${a} assertion`,status:s,detail:o}})}async function ge(t){return new Promise(e=>setTimeout(e,t))}function _n(t){let e={};for(let[r,s]of Object.entries(t))s!=null&&(e[r]=s);return e}async function Rr(t,e,r){for(let s=0;s<fe;s++)try{let n=await fetch(t,e);if(n.ok)return n;if(n.status===401&&r&&s===0){let a=await r();if(a){let o={...e,headers:{...e.headers,Authorization:`Bearer ${a}`}},i=await fetch(t,o);if(i.ok)return i}return null}if(n.status===429&&s<fe-1){let a=n.headers.get("Retry-After"),o=a?parseInt(a,10)*1e3:pe[s];!isNaN(o)&&o>0?await ge(o):await ge(pe[s]);continue}if(n.status>=500&&s<fe-1){await ge(pe[s]);continue}return n}catch{if(s<fe-1){await ge(pe[s]);continue}return null}return null}var Mn=util.promisify(zlib.gzip);function Cr(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(s=>{let{consoleLogs:n,networkRequests:a,apiCalls:o,...i}=s;return e?i:{...i,...o!==void 0?{apiCalls:o}:{}}});return {...t,tests:r}}var Ln=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions"];function En(t){if(!Array.isArray(t.tests))return t;let e=new Set(Ln),r=t.tests.map(s=>{let n={};for(let a in s)if(!e.has(a))if(a==="failure"&&s[a]&&typeof s[a]=="object"){let o=s[a];n.failure={message:o.message??null,line:o.line??null};}else n[a]=s[a];return n});return {...t,tests:r}}function Pn(t){let e=new Set(["tests","timeline","unifiedTimeline","navigations"]),r={};for(let s in t)e.has(s)||(r[s]=t[s]);return r.tests=[],r}async function nt(t,e=An){let r={"Content-Type":"application/json"},s=JSON.stringify(t),n=t,a=Array.isArray(n?.tests)?n.tests.length:0,o=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&o(s)){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.
2558
+ `,process.stderr.write(i);}var pn=new Set(["pw:api","expect","test.step"]);function fn(t){return t==="expect"?"assertion":t==="test.step"?"custom_step":"ui_action"}function Ge(t,e,r){if(pn.has(t.category)){let s=[];for(let a of t.steps)Ge(a,e,s);let n=t.startTime.getTime()-e.getTime();r.push({title:t.title,category:fn(t.category),timestamp:t.startTime.toISOString(),duration:t.duration,videoOffset:n>=0?n/1e3:null,status:t.error?"failed":"passed",error:t.error?.message??null,children:s});}else for(let s of t.steps)Ge(s,e,r);}function vr(t,e){let r=[];for(let s of t)Ge(s,e,r);return r}var mn=new Set(["localhost","127.0.0.1","0.0.0.0"]);function br(t){let e=new URL(t);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&mn.has(e.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${e.protocol}//${e.hostname}`)}var vn=3e3;async function We(t){let e=new AbortController,r=setTimeout(()=>e.abort(),vn);try{return (await fetch(`${t}/health`,{method:"GET",signal:e.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function xr(t){return new Promise(e=>setTimeout(e,t))}async function yr(t){try{let r=(await t.json()).error;if(r&&typeof r.message=="string"){let s=r.details;if(Array.isArray(s)&&s.length>0){let n=s.map(a=>`${a.field}: ${a.message}`).join(", ");return `${r.message} (${n})`}return r.message}}catch{}return `HTTP ${t.status}`}async function Ke(t,e,r){let s=new AbortController,n=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:s.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 xr(d);let l=await fetch(`${t}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:e}),signal:s.signal});if(l.ok){let u=await l.json();return {accessToken:u.accessToken,refreshToken:u.refreshToken,expiresIn:u.expiresIn,orgId:u.orgId,orgName:u.orgName,userId:u.userId,userName:u.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return a.status===400?{code:"validation_error",message:await yr(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 yr(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(n);}}function Je(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 wr(t,e,r){let s=new AbortController,n=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:s.signal});if(a.status===429){let i=a.headers.get("Retry-After"),d=i?parseInt(i,10)*1e3:5e3;!isNaN(d)&&d>0&&(await xr(d),a=await fetch(`${t}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e}),signal:s.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(n);}}async function kr(t,e,r,s,n,a){let o=new AbortController,i=setTimeout(()=>o.abort(),n);try{let d={gitId:r,displayName:s};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 u=await l.json();return {repoId:u.repoId,displayName:u.displayName}}catch{return null}finally{clearTimeout(i);}}var kn=5e3;function F(t,e){try{return child_process.execSync(t,{cwd:e,timeout:kn,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Tr(t){let e=F("git rev-parse --abbrev-ref HEAD",t),r=F("git rev-parse --short HEAD",t),s=F("git log -1 --pretty=%s",t),n=F("git log -1 --format=%an",t)??F("git config user.name",t),a=Tn(t),o=a?ee(a):null;return {branch:e,commitSha:r,commitMessage:s,commitAuthor:n,remoteUrl:o}}function Tn(t){let e=F("git remote get-url origin",t);if(e)return e;let r=F("git remote",t);if(!r)return null;let s=r.split(`
2559
+ `)[0]?.trim();return s?F(`git remote get-url ${s}`,t):null}function ee(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 Sr(t){let e=t.split("/").filter(Boolean);return e[e.length-1]??t}function Ye(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 te(t){let e=Ye(t);return e||`local/${path.basename(t)}`}var Sn=new Set(["smoke","regression","nightly","ci"]);function ue(){let t=process.env.TESTRELIC_RUN_TYPE?.trim().toLowerCase();if(t&&Sn.has(t))return t}var An=1048576,pe=[1e3,3e3,9e3],fe=3,In=90*1048576,_n=new Set(["e2e","mobile","unit"]);function Ze(t){if(t&&t.length>0&&t.every(n=>n.testType==="api")){let n=new Map;for(let i of t){let d=i.apiProtocol??"rest";n.set(d,(n.get(d)??0)+1);}let a="rest",o=0;for(let[i,d]of n)d>o&&(o=d,a=i);return {testType:"api",apiProtocol:a,metadata:{testType:"api",primaryProtocol:a}}}let e=new Map;for(let n of t??[])_n.has(n.testType)&&e.set(n.testType,(e.get(n.testType)??0)+1);let r=null,s=0;for(let[n,a]of e)a>s&&(s=a,r=n);return {testType:r??"e2e"}}function Xe(t,e,r,s,n,a){let o=a?.cloudPlatform?a.cloudPlatform:s?.provider&&s.provider!=="unknown"?s.provider:"local",i=ue(),d=Ze(n),l=d.testType==="api"?d:null,u=l&&n?n.map(m=>m.apiProtocol?m:{...m,apiProtocol:l.apiProtocol}):n;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},...u&&u.length>0?{tests:u}:{},...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}:{},...s?.provider?{ciProvider:s.provider}:{},...s?.runUrl?{ciRunUrl:s.runUrl}:{},...a?.cloudPlatform?{cloudPlatform:a.cloudPlatform}:{},...a?.cloudBuildId?{cloudBuildId:a.cloudBuildId}:{},...a?.cloudSessionId?{cloudSessionId:a.cloudSessionId}:{}}}function Qe(t){return typeof t=="string"?Buffer.byteLength(t,"utf-8"):0}function et(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:Qe(e.responseBody),bytesOut:typeof e.bytesOut=="number"?e.bytesOut:Qe(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 tt(t){return Array.isArray(t)?t.map(e=>{let r=e.responseStatusCode??e.statusCode??0,s=e.timestamp??null;return {method:e.method??"GET",url:e.url??"",status:r,statusCode:r,type:"xhr",size:Qe(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:s,startedAt:s}}):[]}function rt(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 s=r.status==="failed"?"failed":"passed",n=typeof r.expression=="string"&&r.expression.trim()?r.expression.trim():null,a=r.kind??r.type??"assertion",o=s==="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:n??r.description??`${a} assertion`,status:s,detail:o}})}async function ge(t){return new Promise(e=>setTimeout(e,t))}function Mn(t){let e={};for(let[r,s]of Object.entries(t))s!=null&&(e[r]=s);return e}async function Rr(t,e,r){for(let s=0;s<fe;s++)try{let n=await fetch(t,e);if(n.ok)return n;if(n.status===401&&r&&s===0){let a=await r();if(a){let o={...e,headers:{...e.headers,Authorization:`Bearer ${a}`}},i=await fetch(t,o);if(i.ok)return i}return null}if(n.status===429&&s<fe-1){let a=n.headers.get("Retry-After"),o=a?parseInt(a,10)*1e3:pe[s];!isNaN(o)&&o>0?await ge(o):await ge(pe[s]);continue}if(n.status>=500&&s<fe-1){await ge(pe[s]);continue}return n}catch{if(s<fe-1){await ge(pe[s]);continue}return null}return null}var Ln=util.promisify(zlib.gzip);function Cr(t,e){if(!Array.isArray(t.tests))return t;let r=t.tests.map(s=>{let{consoleLogs:n,networkRequests:a,apiCalls:o,...i}=s;return e?i:{...i,...o!==void 0?{apiCalls:o}:{}}});return {...t,tests:r}}var En=["consoleLogs","networkRequests","apiCalls","actions","navigations","protocolAssertions"];function Pn(t){if(!Array.isArray(t.tests))return t;let e=new Set(En),r=t.tests.map(s=>{let n={};for(let a in s)if(!e.has(a))if(a==="failure"&&s[a]&&typeof s[a]=="object"){let o=s[a];n.failure={message:o.message??null,line:o.line??null};}else n[a]=s[a];return n});return {...t,tests:r}}function Nn(t){let e=new Set(["tests","timeline","unifiedTimeline","navigations"]),r={};for(let s in t)e.has(s)||(r[s]=t[s]);return r.tests=[],r}async function st(t,e=In){let r={"Content-Type":"application/json"},s=JSON.stringify(t),n=t,a=Array.isArray(n?.tests)?n.tests.length:0,o=i=>Buffer.byteLength(i,"utf-8")>e;if(a>0&&o(s)){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.
2560
2560
  `),s=JSON.stringify(Cr(n,false)),o(s)&&(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.
2561
2561
  `),s=JSON.stringify(Cr(n,true))),o(s)&&(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.
2562
- `),s=JSON.stringify(En(n))),o(s)&&(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.
2563
- `),s=JSON.stringify(Pn(n)));}return Buffer.byteLength(s,"utf-8")>Rn?(r["Content-Encoding"]="gzip",{body:await Mn(Buffer.from(s,"utf-8")),headers:r}):{body:s,headers:r}}async function Ar(t,e,r,s){let n=`${t}/runs`,{body:a,headers:o}=await nt(r);o.Authorization=`Bearer ${e}`;let i=await Rr(n,{method:"POST",headers:o,body:a},s);return i?.ok?{success:true,statusCode:i.status,error:null}:i?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:i?`Upload failed with status ${i.status}`:"Upload failed after retries",statusCode:i?.status??null,payload:r,targetEndpoint:n,method:"POST"}}async function Ir(t,e,r){let s=`${t}/runs/init`;try{let n=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(_n(r))});return n.ok?{runId:(await n.json()).runId}:null}catch{return null}}function _r(t,e,r,s){let n=`${t}/runs/${r}/tests`;fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(s)}).catch(()=>{});}async function Mr(t,e,r,s){let n=`${t}/runs/${r}/finalize`;return (await Rr(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(s)}))?.ok??false}function at(t,e,r,s){let n=`${t}/runs/${r}/finalize`,a=new Date,o={finishedAt:a.toISOString(),duration:a.getTime()-new Date(s).getTime(),summary:{}};fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)}).catch(()=>{});}var On="1.0.0",Lr=10;function Er(t){return t instanceof Error?t.message:String(t)}function qn(t){return t>=400&&t<500&&t!==408&&t!==429}function re(t,e,r,s,n,a,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let d=Date.now(),l=`${d}-${e}-${r}.json`,u=path.join(t,l),g={version:On,queuedAt:new Date(d).toISOString(),reason:s,retryCount:0,targetEndpoint:n,method:a,payload:o,headers:i},m=u+".tmp";fs$1.writeFileSync(m,JSON.stringify(g,null,2),"utf-8"),fs$1.renameSync(m,u);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2562
+ `),s=JSON.stringify(Pn(n))),o(s)&&(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.
2563
+ `),s=JSON.stringify(Nn(n)));}return Buffer.byteLength(s,"utf-8")>An?(r["Content-Encoding"]="gzip",{body:await Ln(Buffer.from(s,"utf-8")),headers:r}):{body:s,headers:r}}async function Ar(t,e,r,s){let n=`${t}/runs`,{body:a,headers:o}=await st(r);o.Authorization=`Bearer ${e}`;let i=await Rr(n,{method:"POST",headers:o,body:a},s);return i?.ok?{success:true,statusCode:i.status,error:null}:i?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:i?`Upload failed with status ${i.status}`:"Upload failed after retries",statusCode:i?.status??null,payload:r,targetEndpoint:n,method:"POST"}}async function Ir(t,e,r){let s=`${t}/runs/init`;try{let n=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(Mn(r))});return n.ok?{runId:(await n.json()).runId}:null}catch{return null}}function _r(t,e,r,s){let n=`${t}/runs/${r}/tests`;fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(s)}).catch(()=>{});}async function Mr(t,e,r,s){let n=`${t}/runs/${r}/finalize`;return (await Rr(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(s)}))?.ok??false}function nt(t,e,r,s){let n=`${t}/runs/${r}/finalize`,a=new Date,o={finishedAt:a.toISOString(),duration:a.getTime()-new Date(s).getTime(),summary:{}};fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)}).catch(()=>{});}var qn="1.0.0",Lr=10;function Er(t){return t instanceof Error?t.message:String(t)}function Hn(t){return t>=400&&t<500&&t!==408&&t!==429}function re(t,e,r,s,n,a,o,i){try{fs$1.mkdirSync(t,{recursive:!0});let d=Date.now(),l=`${d}-${e}-${r}.json`,u=path.join(t,l),g={version:qn,queuedAt:new Date(d).toISOString(),reason:s,retryCount:0,targetEndpoint:n,method:a,payload:o,headers:i},m=u+".tmp";fs$1.writeFileSync(m,JSON.stringify(g,null,2),"utf-8"),fs$1.renameSync(m,u);}catch(d){d.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
2564
2564
  `):process.stderr.write(`\u26A0 TestRelic: Unable to queue upload data.
2565
2565
  `);}}async function Dr(t,e,r){let s;try{s=fs$1.readdirSync(t).filter(a=>a.endsWith(".json")&&!a.endsWith(".tmp")).sort();}catch{return}if(s.length===0)return;let n=[];for(let a=0;a<s.length;a+=Lr)n.push(s.slice(a,a+Lr));for(let a of n)for(let o of a){let i=path.join(t,o),d;try{if(!fs$1.statSync(i).isFile())continue;let u=JSON.parse(fs$1.readFileSync(i,"utf-8"));if(!core.isValidQueueEntry(u)){process.stderr.write(`\u26A0 TestRelic: Corrupted queue file deleted: ${o}
2566
2566
  `),fs$1.unlinkSync(i);continue}d=u;}catch(l){process.stderr.write(`\u26A0 TestRelic: Skipping unreadable queue file ${o}: ${Er(l)}
2567
- `);try{fs$1.unlinkSync(i);}catch{}continue}try{let{body:l,headers:u}=await nt(d.payload),g={...d.headers,...u,Authorization:`Bearer ${r}`},m=await fetch(d.targetEndpoint,{method:d.method,headers:g,body:l});if(m.ok)fs$1.unlinkSync(i);else if(qn(m.status)){process.stderr.write(`\u26A0 TestRelic: Queue entry ${o} rejected (HTTP ${m.status}) \u2014 moving aside; it will not be retried.
2567
+ `);try{fs$1.unlinkSync(i);}catch{}continue}try{let{body:l,headers:u}=await st(d.payload),g={...d.headers,...u,Authorization:`Bearer ${r}`},m=await fetch(d.targetEndpoint,{method:d.method,headers:g,body:l});if(m.ok)fs$1.unlinkSync(i);else if(Hn(m.status)){process.stderr.write(`\u26A0 TestRelic: Queue entry ${o} rejected (HTTP ${m.status}) \u2014 moving aside; it will not be retried.
2568
2568
  `);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 ${m.status} for ${o}; will retry later.
2569
2569
  `);return}}catch(l){process.stderr.write(`\u26A0 TestRelic: Queue flush paused \u2014 ${Er(l)}; will retry later.
2570
- `);return}}}function Br(t,e){try{let r=fs$1.readdirSync(t).filter(n=>(n.endsWith(".json")||n.endsWith(".failed"))&&!n.endsWith(".tmp")),s=Date.now();for(let n of r){let a=path.join(t,n);try{let o=fs$1.readFileSync(a,"utf-8"),d=JSON.parse(o).queuedAt;if(typeof d=="string"){let l=new Date(d).getTime();s-l>e&&fs$1.unlinkSync(a);}}catch{try{fs$1.unlinkSync(a);}catch{}}}}catch{}}var Gn=3e5,Wn=864e5,Kn=6e4,Or=3e4,lt="https://platform.testrelic.ai/settings/api-keys",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.
2571
- `);return}try{if(br(this.config.endpoint),this.gitMetadata=Tr(),!await Ke(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.
2572
- `);return}let r=await Je(this.config.endpoint,this.config.apiKey,this.config.timeout);if(Ye(r)){this.handleAuthError(r.code,r.statusCode);return}let s=r;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},process.stderr.write(`\u2713 TestRelic: Connected to cloud (${s.orgName} / ${s.userName})
2570
+ `);return}}}function Br(t,e){try{let r=fs$1.readdirSync(t).filter(n=>(n.endsWith(".json")||n.endsWith(".failed"))&&!n.endsWith(".tmp")),s=Date.now();for(let n of r){let a=path.join(t,n);try{let o=fs$1.readFileSync(a,"utf-8"),d=JSON.parse(o).queuedAt;if(typeof d=="string"){let l=new Date(d).getTime();s-l>e&&fs$1.unlinkSync(a);}}catch{try{fs$1.unlinkSync(a);}catch{}}}}catch{}}var Wn=3e5,Kn=864e5,Jn=6e4,Or=3e4,ot="https://platform.testrelic.ai/settings/api-keys",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.
2571
+ `);return}try{if(br(this.config.endpoint),this.gitMetadata=Tr(),!await We(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.
2572
+ `);return}let r=await Ke(this.config.endpoint,this.config.apiKey,this.config.timeout);if(Je(r)){this.handleAuthError(r.code,r.statusCode);return}let s=r;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},process.stderr.write(`\u2713 TestRelic: Connected to cloud (${s.orgName} / ${s.userName})
2573
2573
  `),await this.resolveRepoId(),this.config.queueDirectory&&(Br(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)}
2574
- `);}}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()+Gn<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await wr(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}).
2574
+ `);}}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()+Wn<e)return true;if(!this.config||!this.authState.refreshToken)return this.switchToLocalMode("token_expired_no_refresh"),false;try{let r=await wr(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}).
2575
2575
  `));}async dispose(){if(this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.flushPromise){try{await Promise.race([this.flushPromise,new Promise(e=>setTimeout(e,Or))]);}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.
2576
- \u2192 Manage keys: ${lt}
2576
+ \u2192 Manage keys: ${ot}
2577
2577
  `);break;case "expired_key":this.setLocalMode("expired_api_key"),process.stderr.write(`\u26A0 TestRelic: API key has expired. Running in local mode.
2578
- \u2192 Generate a new key: ${lt}
2578
+ \u2192 Generate a new key: ${ot}
2579
2579
  `);break;case "validation_error":this.setLocalMode("validation_error"),process.stderr.write(`\u26A0 TestRelic: API key format invalid. Running in local mode.
2580
- \u2192 Manage keys: ${lt}
2580
+ \u2192 Manage keys: ${ot}
2581
2581
  `);break;case "rate_limited":this.setLocalMode("rate_limited"),process.stderr.write(`\u26A0 TestRelic: Rate limited during authentication. Running in local mode.
2582
2582
  `);break;case "timeout":this.setLocalMode("auth_timeout"),process.stderr.write(`\u26A0 TestRelic: Authentication timed out. Running in local mode.
2583
2583
  `);break;default:this.setLocalMode(`auth_error_${r??"unknown"}`),process.stderr.write(`\u26A0 TestRelic: Cloud authentication failed. Running in local mode.
2584
- `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?ee(this.gitMetadata.remoteUrl):null,r=e?Sr(e):this.config.projectName??te(process.cwd()),s=e??this.config.projectName??te(process.cwd()),n=this.readRepoCache(s);if(n){this.repoId=n.repoId;return}try{let a=await kr(this.config.endpoint,this.authState.accessToken,s,r,this.config.timeout,this.gitMetadata?.branch);a&&(this.repoId=a.repoId,this.writeRepoCache(s,a.repoId,a.displayName));}catch{}!e&&!this.config.projectName&&!Qe(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2585
- `);}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 s=fs$1.readFileSync(r,"utf-8"),n=JSON.parse(s);if(n.gitId!==e||Date.now()-n.resolvedAt>Wn)return null;let a=this.hashApiKey();return a&&n.apiKeyHash!==a?null:n}catch{return null}}writeRepoCache(e,r,s){if(!this.config)return;let n=path.join(this.config.queueDirectory,"..","cache"),a=path.join(n,"repo.json");try{fs$1.mkdirSync(n,{recursive:!0});let o={repoId:r,gitId:e,displayName:s,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,s=this.config.endpoint;this.flushPromise=Promise.race([Dr(r,s,e),new Promise(n=>setTimeout(n,Or))]).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 Ke(e))return;if(this.config?.apiKey){let s=await Je(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Ye(s)){let n=s;this.authState={mode:"cloud",accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:Date.now()+n.expiresIn*1e3,orgId:n.orgId,orgName:n.orgName,userId:n.userId,userName:n.userName},this.failureReason=null,process.stderr.write(`\u2713 TestRelic: Cloud connectivity restored.
2586
- `),this.startBackgroundFlush();}}}catch{}},Kn);}};function qr(t,e,r,s){let n=[],a=[],o=null,i=0,d=null,l=0,u=null,g=0,m=t.filter(c=>c.name===core.ATTACHMENT_NAME&&c.body),p=false;if(m.length>0)for(let c of m)try{let h=JSON.parse(c.body.toString());if(core.isTestRelicFilePayload(h)){n=n.concat(h.navigations),a=a.concat(h.apiAssertions),h.networkRequestsFile&&(o=h.networkRequestsFile,i+=h.networkRequestsCount),h.consoleLogsFile&&(d=h.consoleLogsFile,l+=h.consoleLogsCount),h.apiCallsFile&&(u=h.apiCallsFile,g+=h.apiCallsCount),p=!0;continue}if(core.isTestRelicDataPayload(h)){n=n.concat(h.navigations),Array.isArray(h.apiAssertions)&&(a=a.concat(h.apiAssertions)),i+=h.networkRequests?.length??0,g+=h.apiCalls?.length??0;let v=h.consoleLogs;Array.isArray(v)&&(l+=v.length),p=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2584
+ `);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let e=this.gitMetadata?.remoteUrl?ee(this.gitMetadata.remoteUrl):null,r=e?Sr(e):this.config.projectName??te(process.cwd()),s=e??this.config.projectName??te(process.cwd()),n=this.readRepoCache(s);if(n){this.repoId=n.repoId;return}try{let a=await kr(this.config.endpoint,this.authState.accessToken,s,r,this.config.timeout,this.gitMetadata?.branch);a&&(this.repoId=a.repoId,this.writeRepoCache(s,a.repoId,a.displayName));}catch{}!e&&!this.config.projectName&&!Ye(process.cwd())&&process.stderr.write(`\u2139 TestRelic: No git remote or package.json detected. Set project.name in .testrelic for stable project identity.
2585
+ `);}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 s=fs$1.readFileSync(r,"utf-8"),n=JSON.parse(s);if(n.gitId!==e||Date.now()-n.resolvedAt>Kn)return null;let a=this.hashApiKey();return a&&n.apiKeyHash!==a?null:n}catch{return null}}writeRepoCache(e,r,s){if(!this.config)return;let n=path.join(this.config.queueDirectory,"..","cache"),a=path.join(n,"repo.json");try{fs$1.mkdirSync(n,{recursive:!0});let o={repoId:r,gitId:e,displayName:s,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,s=this.config.endpoint;this.flushPromise=Promise.race([Dr(r,s,e),new Promise(n=>setTimeout(n,Or))]).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 We(e))return;if(this.config?.apiKey){let s=await Ke(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!Je(s)){let n=s;this.authState={mode:"cloud",accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:Date.now()+n.expiresIn*1e3,orgId:n.orgId,orgName:n.orgName,userId:n.userId,userName:n.userName},this.failureReason=null,process.stderr.write(`\u2713 TestRelic: Cloud connectivity restored.
2586
+ `),this.startBackgroundFlush();}}}catch{}},Jn);}};function qr(t,e,r,s){let n=[],a=[],o=null,i=0,d=null,l=0,u=null,g=0,m=t.filter(c=>c.name===core.ATTACHMENT_NAME&&c.body),p=false;if(m.length>0)for(let c of m)try{let h=JSON.parse(c.body.toString());if(core.isTestRelicFilePayload(h)){n=n.concat(h.navigations),a=a.concat(h.apiAssertions),h.networkRequestsFile&&(o=h.networkRequestsFile,i+=h.networkRequestsCount),h.consoleLogsFile&&(d=h.consoleLogsFile,l+=h.consoleLogsCount),h.apiCallsFile&&(u=h.apiCallsFile,g+=h.apiCallsCount),p=!0;continue}if(core.isTestRelicDataPayload(h)){n=n.concat(h.navigations),Array.isArray(h.apiAssertions)&&(a=a.concat(h.apiAssertions)),i+=h.networkRequests?.length??0,g+=h.apiCalls?.length??0;let v=h.consoleLogs;Array.isArray(v)&&(l+=v.length),p=!0;}}catch{process.stderr.write(`[testrelic] Warning: Corrupt attachment for test "${r}"
2587
2587
  `);}return p||(n=e.filter(c=>c.type==="lambdatest-navigation"&&c.description).map(c=>{try{return JSON.parse(c.description)}catch{return null}}).filter(c=>c!==null)),n.length===0&&i===0&&g===0&&!s&&!p&&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.
2588
- `),{navigations:n,apiAssertions:a,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:l,apiCallsFile:u,apiCallsCount:g}}function me(t=process.env){let e=Zn(t.TESTRELIC_CLOUD_PLATFORM);if(e)return {cloudPlatform:e,cloudBuildId:t.TESTRELIC_CLOUD_BUILD_ID||void 0,cloudSessionId:t.TESTRELIC_CLOUD_SESSION_ID||void 0};if(t.BROWSERSTACK_USERNAME||t.BROWSERSTACK_ACCESS_KEY)return {cloudPlatform:"browserstack",cloudBuildId:t.BROWSERSTACK_BUILD_NAME||t.BROWSERSTACK_BUILD_ID||void 0,cloudSessionId:t.BROWSERSTACK_SESSION_ID||void 0};if(t.LT_USERNAME||t.LAMBDATEST_USERNAME||t.LT_ACCESS_KEY||t.LAMBDATEST_ACCESS_KEY)return {cloudPlatform:"lambdatest",cloudBuildId:t.LT_BUILD||t.LAMBDATEST_BUILD||void 0,cloudSessionId:t.LT_SESSION_ID||t.LAMBDATEST_SESSION_ID||void 0};let r=t.PLAYWRIGHT_WS_ENDPOINT;if(r){if(/cdp\.lambdatest\.com/i.test(r))return {cloudPlatform:"lambdatest"};if(/cdp\.browserstack\.com/i.test(r))return {cloudPlatform:"browserstack"}}return {}}function Zn(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var sa=5,ve=[1e3,3e3,9e3],j=3,na={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},dt=0,ct=[];async function aa(){dt>=sa&&await new Promise(t=>ct.push(t)),dt++;}function ia(){dt--,ct.length>0&&ct.shift()();}async function ye(t){return new Promise(e=>setTimeout(e,t))}function oa(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return na[e]??"application/octet-stream"}function la(t){try{return fs$1.statSync(t).size}catch{return 0}}async function da(t,e,r,s,n){let a=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:n,type:r.type,sizeBytes:s});for(let i=0;i<j;i++)try{let d=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o});if(d.ok)return await d.json();if(d.status>=500&&i<j-1){await ye(ve[i]);continue}return null}catch{if(i<j-1){await ye(ve[i]);continue}return null}return null}async function ca(t,e,r,s){for(let n=0;n<j;n++)try{let a=fs$1.createReadStream(e),o=stream.Readable.toWeb(a),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(s)},body:o,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&n<j-1){await ye(ve[n]);continue}return !1}catch{if(n<j-1){await ye(ve[n]);continue}return false}return false}async function ua(t,e,r){let s=`${t}/artifacts/confirm`;try{return (await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function pa(t,e,r,s){let n=la(r.filePath);if(n===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(n>s*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let a=oa(r.filePath);await aa();try{let o=await da(t,e,r,n,a);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await ca(o.uploadUrl,r.filePath,a,n))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let d=await ua(t,e,o.artifactId);return {success:d,storageKey:o.storageKey,artifactId:o.artifactId,error:d?null:"confirm_failed"}}finally{ia();}}async function Hr(t,e,r,s){let n=new Map,a=r.map(async o=>{let i=await pa(t,e,o,s);n.set(o.filePath,i);});return await Promise.allSettled(a),n}function ut(t){let r=t.getGitMetadata()?.remoteUrl;return r?ee(r):t.getConfig()?.projectName??te(process.cwd())}async function $r(t,e,r,s,n){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=P(),d=me(),l=ue();return (await Ir(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:ut(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:s,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:n??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...l?{runType:l}:{},testType:"e2e"}))?.runId??null}var fa=true,ga=50;async function ha(t,e,r,s){let n=new Map;if(!(e?.uploadArtifacts??fa)||!await t.ensureValidToken())return n;let i=[],d=new Map;for(let p of s){if(p.artifacts.screenshot){let f=path.join(p.outputDir,p.artifacts.screenshot);i.push({filePath:f,runId:r,testId:p.testId,type:"screenshot"}),d.set(f,{testId:p.testId,field:"screenshot"});}if(p.artifacts.video){let f=path.join(p.outputDir,p.artifacts.video);i.push({filePath:f,runId:r,testId:p.testId,type:"video"}),d.set(f,{testId:p.testId,field:"video"});}}if(i.length===0)return n;let l=e?.artifactMaxSizeMb??ga,u=await Hr(t.getEndpoint(),t.getAccessToken(),i,l),g=new Map;for(let[p,f]of u){if(!f.success||!f.storageKey)continue;let c=d.get(p);if(!c)continue;let h=g.get(c.testId)??{};c.field==="screenshot"&&(h.screenshotKey=f.storageKey),c.field==="video"&&(h.videoKey=f.storageKey),g.set(c.testId,h);}for(let p of s){let f=g.get(p.testId);n.set(p.testId,{...p.artifacts,...f?.screenshotKey?{screenshotKey:f.screenshotKey}:{},...f?.videoKey?{videoKey:f.videoKey}:{}});}let m=Array.from(u.values()).filter(p=>p.success).length;return m>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${m} artifact(s) to cloud storage.
2589
- `),n}async function pt(t,e,r,s,n,a,o,i,d,l,u){try{if(t.isCloudMode()&&n&&(r==="realtime"||r==="both")){let m=await t.ensureValidToken(),p=t.getGitMetadata(),f=Xe(u),c={finishedAt:o,duration:i,summary:d,...p?.commitMessage?{commitMessage:p.commitMessage}:{},testType:f.testType,...f.testType==="api"?{apiProtocol:f.apiProtocol,metadata:f.metadata}:{}};if(m){if(!await Mr(t.getEndpoint(),t.getAccessToken(),n,c)){let v=e?.queueDirectory??".testrelic/queue";re(v,s,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",c,{"Content-Type":"application/json"});}}else {let h=e?.queueDirectory??".testrelic/queue";re(h,s,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",c,{"Content-Type":"application/json"});}}let g=new Map;if(t.isCloudMode()&&l&&l.length>0&&(g=await ha(t,e,s,l)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let p=t.getGitMetadata(),f=P(),c=ut(t),h=ma(a,g),v=et(h,c,p,f,u,me()),w=await Ar(t.getEndpoint(),t.getAccessToken(),v,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!w.success){let x=w,T=e?.queueDirectory??".testrelic/queue";re(T,s,"batch",x.reason,x.targetEndpoint,x.method,x.payload,{"Content-Type":"application/json"});}}else {let p=e?.queueDirectory??".testrelic/queue",f=t.getGitMetadata(),c=P(),h=ut(t),v=et(a,h,f,c,void 0,me());re(p,s,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",v,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function ma(t,e){if(e.size===0)return t;let r=t.timeline.map(s=>{let n=s.testId;if(!n)return s;let a=e.get(n);return a?{...s,...a.screenshotKey?{screenshotKey:a.screenshotKey}:{},...a.videoKey?{videoKey:a.videoKey}:{}}:s});return {...t,timeline:r}}function B(t){try{return fs$1.readFileSync(t,"utf-8").split(`
2590
- `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function gt(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 Ta(t,e,r){let s=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(s).digest("hex").substring(0,16)}function Sa(t){return t.length<=3?"":t[t.length-2]}function Ca(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function Ra(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 Gr(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&Gr(r.children,e);}function Aa(t){if(t.length===0)return null;let e=[...t].sort((s,n)=>s-n),r=e.reduce((s,n)=>s+n,0);return {avg:Math.round(r/e.length),min:e[0],max:e[e.length-1],p50:H(e,50),p95:H(e,95),p99:H(e,99)}}var Wr=2e5,be=1e5;function Vr(t,e,r,s,n,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:s.length,navUrls:[],networkRequests:n,consoleLogs:a,actionSteps:o?.length??0,actionCategories:{}};if(e){let l=new Set;for(let u of e){let g=typeof u.method=="string"?u.method:"OTHER";i.methodCounts[g]=(i.methodCounts[g]??0)+1;let m=typeof u.url=="string"?u.url:null;m&&l.size<be&&l.add(Ve(m));let p=typeof u.responseStatusCode=="number"?u.responseStatusCode:typeof u.statusCode=="number"?u.statusCode:null,f=p!==null&&Number.isFinite(p)?p:null;i.statusRanges[Ra(f)]++;let c=typeof u.responseTimeMs=="number"?u.responseTimeMs:typeof u.durationMs=="number"?u.durationMs:null;c!==null&&Number.isFinite(c)&&i.responseTimes.length<Wr&&i.responseTimes.push(c);}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 s)l.url&&d.size<be&&d.add(l.url);return i.navUrls=Array.from(d),o&&Gr(o,i.actionCategories),i}function Ia(){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 _a(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 Ma(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function La(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:s}=e;if(s){let a=s.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":s}if(r){let a=r.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":r}let n=e.defaultBrowserType;if(n){let a=n.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":n}}function Ea(t,e,r){let s=r.parent?.project?.(),n="unknown";s!==void 0&&(s.use.isMobile===true?n="mobile":n="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 n}var Pa="__testrelic_api_config";function Na(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var xe=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.navigationsCaptured=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.pendingArtifactEntries=[];this.detectedOs="";this.detectedSource="";this.cloudTestsBuffer=[];this.activeReportMode="embedded";this.streamingWriter=null;this.testIndex=[];this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};this.streamingTestAgg=new Map;this.config=Et(e),this.apiConfig=Lt(e);}upsertAggContribution(e,r){let s=this.streamingTestAgg.get(e);(!s||r.retryIndex>s.retryIndex)&&this.streamingTestAgg.set(e,r);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let s=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${s} tests)
2591
- `),this.activeReportMode==="streaming"){let a=path.dirname(this.config.outputPath);this.streamingWriter=new J(a);let o=()=>{if(this.streamingWriter){try{this.streamingWriter.writeIndex(this.testIndex);let i={testRunId:this.testRunId??"",startedAt:this.startedAt,completedAt:new Date().toISOString(),totalDuration:Date.now()-new Date(this.startedAt).getTime(),...this.summaryCounters,metadata:null,reportMode:"streaming",files:[],enrichedSummary:null,validation:null,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(i);}catch{}this.streamingWriter.dispose();}try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let i=this.cloudClient.getAccessToken();i&&at(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",o),process.on("SIGINT",o);}if(this.config.includeArtifacts){let a=path.dirname(this.config.outputPath);this.runTimestamp=or(path.join(a,"artifacts"));try{pr(path.join(a,"artifacts"));}catch{}}let n=P();this.detectedOs=Ma(),this.detectedSource=_a(n);try{this.cloudClient=new he(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await $r(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let a=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let o=this.cloudClient.getAccessToken();o&&at(this.cloudClient.getEndpoint(),o,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",a),process.on("SIGINT",a);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:Pa,description:Na(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let s=r,n=e.outcome(),a;n==="flaky"?a="flaky":n==="skipped"?a="skipped":a=gt(s.status);let o=s.startTime.toISOString(),i=new Date(s.startTime.getTime()+s.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(C=>C.type==="tag").map(C=>C.description??""),l=qr(s.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 u=null;if(a==="failed"||a==="flaky"){let S=(a==="flaky"?e.results.find(O=>O.status!=="passed")?.errors??[]:s.errors)[0];if(S){let O=Nt(this.config.redactPatterns),G=S.location?.line??null,W=null;this.config.includeCodeSnippets&&G!==null&&S.location?.file&&(W=Pt(S.location.file,G,this.config.codeContextLines),W&&(W=O(W))),u={message:O(S.message??"Unknown error"),line:G,code:W,stack:this.config.includeStackTrace&&S.stack?O(S.stack):null};}}let g=e.titlePath().filter(Boolean),m=path.relative(this.rootDir||".",e.location.file),p=Sa(g),f=g.join(" > "),c=m,h=Ta(c,p,f),v=Ea(d,c,e),w=v!=="mobile"&&l.apiCallsCount>0?"api":v,x=n==="flaky",T=Ca(e.results),M=gt(e.expectedStatus),y=gt(s.status),k=null;if(this.config.includeArtifacts&&a!=="skipped"&&s.attachments){let C=path.dirname(this.config.outputPath),S=g[g.length-1]??e.title;k=lr(s.attachments,S,s.retry,C,this.runTimestamp||void 0);}let R=this.config.includeActionSteps&&s.steps?vr(s.steps,s.startTime):null,U=La(e),L={titlePath:g,title:f,status:a,duration:s.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:s.retry,tags:d,failure:u,specFile:m,navigations:l.navigations,testId:h,filePath:c,suiteName:p,testType:w,isFlaky:x,retryStatus:T,expectedStatus:M,actualStatus:y,artifacts:k,apiAssertions:l.apiAssertions,actions:R,networkRequestsFile:l.networkRequestsFile,networkRequestsCount:l.networkRequestsCount,consoleLogsFile:l.consoleLogsFile,consoleLogsCount:l.consoleLogsCount,apiCallsFile:l.apiCallsFile,apiCallsCount:l.apiCallsCount,browser:U,os:this.detectedOs||void 0,source:this.detectedSource||void 0},ht=l.consoleLogsFile&&l.consoleLogsCount>0?B(l.consoleLogsFile):void 0,we=l.networkRequestsFile&&l.networkRequestsCount>0?B(l.networkRequestsFile):void 0,V=l.apiCallsFile&&l.apiCallsCount>0?B(l.apiCallsFile):void 0,mt=V?tt(V):void 0,vt=!we&&V?rt(V):void 0,yt=l.apiAssertions&&l.apiAssertions.length>0?st(l.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:h,title:f,status:a,duration:s.duration,suiteName:p,filePath:c,testType:w,isFlaky:x,startedAt:o,completedAt:i,tags:d,failure:u,retry:s.retry,retryCount:e.results.length-1,retryStatus:T,browser:U,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...R&&R.length>0?{actions:R}:{},...l.navigations&&l.navigations.length>0?{navigations:l.navigations}:{},...ht?{consoleLogs:ht}:{},...we?{networkRequests:we}:vt?{networkRequests:vt}:{},...mt?{apiCalls:mt}:{},...yt?{protocolAssertions:yt}:{}});try{let C=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(C==="realtime"||C==="both")){let S=this.cloudClient.getAccessToken();S&&_r(this.cloudClient.getEndpoint(),S,this.cloudRunId,this.buildCloudTestPayload(L));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let C=ke(c,g,e.id??"",s.retry),S=s.retry===e.results.length-1,O={id:C,navigations:l.navigations,apiAssertions:l.apiAssertions,actions:R??[],artifacts:k,failureDiagnostic:u,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(C,O,{networkRequestsFile:l.networkRequestsFile,consoleLogsFile:l.consoleLogsFile,apiCallsFile:l.apiCallsFile});let G={id:C,title:g[g.length-1]??e.title,titlePath:g,filePath:c,status:a,duration:s.duration,project:g[1]??"",retryIndex:s.retry,tags:d,hasNetworkData:l.networkRequestsCount>0,hasConsoleData:l.consoleLogsCount>0,hasArtifacts:k!==null,hasActionSteps:(R?.length??0)>0,errorMessage:u?.message?.split(`
2588
+ `),{navigations:n,apiAssertions:a,networkRequestsFile:o,networkRequestsCount:i,consoleLogsFile:d,consoleLogsCount:l,apiCallsFile:u,apiCallsCount:g}}function me(t=process.env){let e=Xn(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 Xn(t){if(!t)return;let e=t.toLowerCase().trim();if(e==="browserstack"||e==="bs")return "browserstack";if(e==="lambdatest"||e==="lt")return "lambdatest"}var na=5,ve=[1e3,3e3,9e3],j=3,aa={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".zip":"application/zip"},lt=0,dt=[];async function ia(){lt>=na&&await new Promise(t=>dt.push(t)),lt++;}function oa(){lt--,dt.length>0&&dt.shift()();}async function ye(t){return new Promise(e=>setTimeout(e,t))}function la(t){let e=t.substring(t.lastIndexOf(".")).toLowerCase();return aa[e]??"application/octet-stream"}function da(t){try{return fs$1.statSync(t).size}catch{return 0}}async function ca(t,e,r,s,n){let a=`${t}/artifacts/upload-url`,o=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:n,type:r.type,sizeBytes:s});for(let i=0;i<j;i++)try{let d=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:o});if(d.ok)return await d.json();if(d.status>=500&&i<j-1){await ye(ve[i]);continue}return null}catch{if(i<j-1){await ye(ve[i]);continue}return null}return null}async function ua(t,e,r,s){for(let n=0;n<j;n++)try{let a=fs$1.createReadStream(e),o=stream.Readable.toWeb(a),i=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(s)},body:o,duplex:"half"});if(i.ok)return !0;if(i.status>=500&&n<j-1){await ye(ve[n]);continue}return !1}catch{if(n<j-1){await ye(ve[n]);continue}return false}return false}async function pa(t,e,r){let s=`${t}/artifacts/confirm`;try{return (await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function fa(t,e,r,s){let n=da(r.filePath);if(n===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(n>s*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let a=la(r.filePath);await ia();try{let o=await ca(t,e,r,n,a);if(!o)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await ua(o.uploadUrl,r.filePath,a,n))return {success:!1,storageKey:o.storageKey,artifactId:o.artifactId,error:"presigned_put_failed"};let d=await pa(t,e,o.artifactId);return {success:d,storageKey:o.storageKey,artifactId:o.artifactId,error:d?null:"confirm_failed"}}finally{oa();}}async function Hr(t,e,r,s){let n=new Map,a=r.map(async o=>{let i=await fa(t,e,o,s);n.set(o.filePath,i);});return await Promise.allSettled(a),n}function ct(t){let r=t.getGitMetadata()?.remoteUrl;return r?ee(r):t.getConfig()?.projectName??te(process.cwd())}async function $r(t,e,r,s,n){if(!t.isCloudMode()||e!=="realtime"&&e!=="both"||!await t.ensureValidToken())return null;let o=t.getGitMetadata(),i=P(),d=me(),l=ue();return (await Ir(t.getEndpoint(),t.getAccessToken(),{runId:r,repoGitId:ct(t),branch:o?.branch??null,commit:o?.commitSha??null,commitMessage:o?.commitMessage??null,commitAuthor:o?.commitAuthor??null,startedAt:s,totalTests:null,ciProvider:i?.provider??null,ciRunUrl:i?.runUrl??null,environment:n??d.cloudPlatform??null,cloudPlatform:d.cloudPlatform??null,cloudBuildId:d.cloudBuildId??null,cloudSessionId:d.cloudSessionId??null,...l?{runType:l}:{},testType:"e2e"}))?.runId??null}var ga=true,ha=50;async function ma(t,e,r,s){let n=new Map;if(!(e?.uploadArtifacts??ga)||!await t.ensureValidToken())return n;let i=[],d=new Map;for(let p of s){if(p.artifacts.screenshot){let f=path.join(p.outputDir,p.artifacts.screenshot);i.push({filePath:f,runId:r,testId:p.testId,type:"screenshot"}),d.set(f,{testId:p.testId,field:"screenshot"});}if(p.artifacts.video){let f=path.join(p.outputDir,p.artifacts.video);i.push({filePath:f,runId:r,testId:p.testId,type:"video"}),d.set(f,{testId:p.testId,field:"video"});}}if(i.length===0)return n;let l=e?.artifactMaxSizeMb??ha,u=await Hr(t.getEndpoint(),t.getAccessToken(),i,l),g=new Map;for(let[p,f]of u){if(!f.success||!f.storageKey)continue;let c=d.get(p);if(!c)continue;let h=g.get(c.testId)??{};c.field==="screenshot"&&(h.screenshotKey=f.storageKey),c.field==="video"&&(h.videoKey=f.storageKey),g.set(c.testId,h);}for(let p of s){let f=g.get(p.testId);n.set(p.testId,{...p.artifacts,...f?.screenshotKey?{screenshotKey:f.screenshotKey}:{},...f?.videoKey?{videoKey:f.videoKey}:{}});}let m=Array.from(u.values()).filter(p=>p.success).length;return m>0&&process.stderr.write(`\u2713 TestRelic: Uploaded ${m} artifact(s) to cloud storage.
2589
+ `),n}async function ut(t,e,r,s,n,a,o,i,d,l,u){try{if(t.isCloudMode()&&n&&(r==="realtime"||r==="both")){let m=await t.ensureValidToken(),p=t.getGitMetadata(),f=Ze(u),c={finishedAt:o,duration:i,summary:d,...p?.commitMessage?{commitMessage:p.commitMessage}:{},testType:f.testType,...f.testType==="api"?{apiProtocol:f.apiProtocol,metadata:f.metadata}:{}};if(m){if(!await Mr(t.getEndpoint(),t.getAccessToken(),n,c)){let v=e?.queueDirectory??".testrelic/queue";re(v,s,"finalize","finalize_failed_after_retries",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",c,{"Content-Type":"application/json"});}}else {let h=e?.queueDirectory??".testrelic/queue";re(h,s,"finalize",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs/${n}/finalize`,"POST",c,{"Content-Type":"application/json"});}}let g=new Map;if(t.isCloudMode()&&l&&l.length>0&&(g=await ma(t,e,s,l)),t.isCloudMode()&&(!r||r==="batch"||r==="both"))if(await t.ensureValidToken()){let p=t.getGitMetadata(),f=P(),c=ct(t),h=va(a,g),v=Xe(h,c,p,f,u,me()),w=await Ar(t.getEndpoint(),t.getAccessToken(),v,async()=>await t.ensureValidToken()?t.getAccessToken():null);if(!w.success){let x=w,T=e?.queueDirectory??".testrelic/queue";re(T,s,"batch",x.reason,x.targetEndpoint,x.method,x.payload,{"Content-Type":"application/json"});}}else {let p=e?.queueDirectory??".testrelic/queue",f=t.getGitMetadata(),c=P(),h=ct(t),v=Xe(a,h,f,c,void 0,me());re(p,s,"batch",t.getFailureReason()??"token_invalid",`${t.getEndpoint()}/runs`,"POST",v,{"Content-Type":"application/json"});}await t.dispose();}catch{try{await t.dispose();}catch{}}}function va(t,e){if(e.size===0)return t;let r=t.timeline.map(s=>{let n=s.testId;if(!n)return s;let a=e.get(n);return a?{...s,...a.screenshotKey?{screenshotKey:a.screenshotKey}:{},...a.videoKey?{videoKey:a.videoKey}:{}}:s});return {...t,timeline:r}}function B(t){try{return fs$1.readFileSync(t,"utf-8").split(`
2590
+ `).filter(r=>r.length>0).map(r=>{try{return JSON.parse(r)}catch{return null}}).filter(r=>r!==null)}catch{return []}}function ft(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 Sa(t,e,r){let s=`${t}::${e}::${r}`;return crypto.createHash("sha256").update(s).digest("hex").substring(0,16)}function Ca(t){return t.length<=3?"":t[t.length-2]}function Ra(t){let e=t.findIndex(r=>r.status==="passed");return e>0?`passed on retry ${e}`:null}function Aa(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 Gr(t,e){for(let r of t)e[r.category]=(e[r.category]??0)+1,r.children.length>0&&Gr(r.children,e);}function Ia(t){if(t.length===0)return null;let e=[...t].sort((s,n)=>s-n),r=e.reduce((s,n)=>s+n,0);return {avg:Math.round(r/e.length),min:e[0],max:e[e.length-1],p50:H(e,50),p95:H(e,95),p99:H(e,99)}}var Wr=2e5,be=1e5;function Vr(t,e,r,s,n,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:s.length,navUrls:[],networkRequests:n,consoleLogs:a,actionSteps:o?.length??0,actionCategories:{}};if(e){let l=new Set;for(let u of e){let g=typeof u.method=="string"?u.method:"OTHER";i.methodCounts[g]=(i.methodCounts[g]??0)+1;let m=typeof u.url=="string"?u.url:null;m&&l.size<be&&l.add(je(m));let p=typeof u.responseStatusCode=="number"?u.responseStatusCode:typeof u.statusCode=="number"?u.statusCode:null,f=p!==null&&Number.isFinite(p)?p:null;i.statusRanges[Aa(f)]++;let c=typeof u.responseTimeMs=="number"?u.responseTimeMs:typeof u.durationMs=="number"?u.durationMs:null;c!==null&&Number.isFinite(c)&&i.responseTimes.length<Wr&&i.responseTimes.push(c);}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 s)l.url&&d.size<be&&d.add(l.url);return i.navUrls=Array.from(d),o&&Gr(o,i.actionCategories),i}function _a(){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 Ma(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 La(){let t=os$1.platform();return t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"}function Ea(t){let e=t.parent?.project?.()?.use;if(!e)return;let{browserName:r,channel:s}=e;if(s){let a=s.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":s}if(r){let a=r.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":r}let n=e.defaultBrowserType;if(n){let a=n.toLowerCase();return a==="chromium"?"Chromium":a==="firefox"?"Firefox":a==="webkit"?"WebKit":n}}function Pa(t,e,r){let s=r.parent?.project?.(),n="unknown";s!==void 0&&(s.use.isMobile===true?n="mobile":n="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 n}var Na="__testrelic_api_config";function Fa(t){return JSON.stringify(t,(e,r)=>r instanceof RegExp?{__regexp:true,source:r.source,flags:r.flags}:r)}var xe=class{constructor(e){this.rootDir="";this.startedAt="";this.testRunId="";this.collectedTests=[];this.fixtureDataReceived=false;this.navigationsCaptured=false;this.testCount=0;this.cloudClient=null;this.cloudRunId=null;this.runTimestamp="";this.pendingArtifactEntries=[];this.detectedOs="";this.detectedSource="";this.cloudTestsBuffer=[];this.activeReportMode="embedded";this.streamingWriter=null;this.testIndex=[];this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};this.streamingTestAgg=new Map;this.config=Lt(e),this.apiConfig=Mt(e);}upsertAggContribution(e,r){let s=this.streamingTestAgg.get(e);(!s||r.retryIndex>s.retryIndex)&&this.streamingTestAgg.set(e,r);}async onBegin(e,r){try{if(this.rootDir=e.rootDir,this.startedAt=new Date().toISOString(),this.testRunId=this.config.testRunId??crypto.randomUUID(),this.config.reportMode==="auto"){let a=r.allTests().length;this.activeReportMode=a>=this.config.streamingThreshold?"streaming":"embedded";}else this.activeReportMode=this.config.reportMode;let s=r.allTests().length;if(process.stderr.write(`[testrelic] Report mode: ${this.activeReportMode} (${s} tests)
2591
+ `),this.activeReportMode==="streaming"){let a=path.dirname(this.config.outputPath);this.streamingWriter=new J(a);let o=()=>{if(this.streamingWriter){try{this.streamingWriter.writeIndex(this.testIndex);let i={testRunId:this.testRunId??"",startedAt:this.startedAt,completedAt:new Date().toISOString(),totalDuration:Date.now()-new Date(this.startedAt).getTime(),...this.summaryCounters,metadata:null,reportMode:"streaming",files:[],enrichedSummary:null,validation:null,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(i);}catch{}this.streamingWriter.dispose();}try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let i=this.cloudClient.getAccessToken();i&&nt(this.cloudClient.getEndpoint(),i,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",o),process.on("SIGINT",o);}if(this.config.includeArtifacts){let a=path.dirname(this.config.outputPath);this.runTimestamp=ir(path.join(a,"artifacts"));try{pr(path.join(a,"artifacts"));}catch{}}let n=P();this.detectedOs=La(),this.detectedSource=Ma(n);try{this.cloudClient=new he(this.config.cloud),await this.cloudClient.initialize(),this.cloudRunId=await $r(this.cloudClient,this.config.cloud?.uploadStrategy,this.testRunId,this.startedAt,this.detectedSource);}catch{this.cloudClient?.switchToLocalMode("init_error");}if(this.activeReportMode!=="streaming"){let a=()=>{try{if(this.cloudClient?.isCloudMode()&&this.cloudRunId){let o=this.cloudClient.getAccessToken();o&&nt(this.cloudClient.getEndpoint(),o,this.cloudRunId,this.startedAt);}}catch{}};process.on("SIGTERM",a),process.on("SIGINT",a);}}catch{}}onTestBegin(e,r){try{e.annotations.push({type:Na,description:Fa(this.apiConfig)});}catch{}}onTestEnd(e,r){try{let s=r,n=e.outcome(),a;n==="flaky"?a="flaky":n==="skipped"?a="skipped":a=ft(s.status);let o=s.startTime.toISOString(),i=new Date(s.startTime.getTime()+s.duration).toISOString(),d=e.tags?[...e.tags]:e.annotations.filter(C=>C.type==="tag").map(C=>C.description??""),l=qr(s.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 u=null;if(a==="failed"||a==="flaky"){let S=(a==="flaky"?e.results.find(O=>O.status!=="passed")?.errors??[]:s.errors)[0];if(S){let O=Pt(this.config.redactPatterns),G=S.location?.line??null,W=null;this.config.includeCodeSnippets&&G!==null&&S.location?.file&&(W=Et(S.location.file,G,this.config.codeContextLines),W&&(W=O(W))),u={message:O(S.message??"Unknown error"),line:G,code:W,stack:this.config.includeStackTrace&&S.stack?O(S.stack):null};}}let g=e.titlePath().filter(Boolean),m=path.relative(this.rootDir||".",e.location.file),p=Ca(g),f=g.join(" > "),c=m,h=Sa(c,p,f),v=Pa(d,c,e),w=v!=="mobile"&&l.apiCallsCount>0?"api":v,x=n==="flaky",T=Ra(e.results),M=ft(e.expectedStatus),y=ft(s.status),k=null;if(this.config.includeArtifacts&&a!=="skipped"&&s.attachments){let C=path.dirname(this.config.outputPath),S=g[g.length-1]??e.title;k=or(s.attachments,S,s.retry,C,this.runTimestamp||void 0);}let R=this.config.includeActionSteps&&s.steps?vr(s.steps,s.startTime):null,U=Ea(e),L={titlePath:g,title:f,status:a,duration:s.duration,startedAt:o,completedAt:i,retryCount:e.results.length-1,retry:s.retry,tags:d,failure:u,specFile:m,navigations:l.navigations,testId:h,filePath:c,suiteName:p,testType:w,isFlaky:x,retryStatus:T,expectedStatus:M,actualStatus:y,artifacts:k,apiAssertions:l.apiAssertions,actions:R,networkRequestsFile:l.networkRequestsFile,networkRequestsCount:l.networkRequestsCount,consoleLogsFile:l.consoleLogsFile,consoleLogsCount:l.consoleLogsCount,apiCallsFile:l.apiCallsFile,apiCallsCount:l.apiCallsCount,browser:U,os:this.detectedOs||void 0,source:this.detectedSource||void 0},gt=l.consoleLogsFile&&l.consoleLogsCount>0?B(l.consoleLogsFile):void 0,we=l.networkRequestsFile&&l.networkRequestsCount>0?B(l.networkRequestsFile):void 0,V=l.apiCallsFile&&l.apiCallsCount>0?B(l.apiCallsFile):void 0,ht=V?et(V):void 0,mt=!we&&V?tt(V):void 0,vt=l.apiAssertions&&l.apiAssertions.length>0?rt(l.apiAssertions):void 0;this.cloudTestsBuffer.push({testId:h,title:f,status:a,duration:s.duration,suiteName:p,filePath:c,testType:w,isFlaky:x,startedAt:o,completedAt:i,tags:d,failure:u,retry:s.retry,retryCount:e.results.length-1,retryStatus:T,browser:U,os:this.detectedOs||void 0,source:this.detectedSource||void 0,...R&&R.length>0?{actions:R}:{},...l.navigations&&l.navigations.length>0?{navigations:l.navigations}:{},...gt?{consoleLogs:gt}:{},...we?{networkRequests:we}:mt?{networkRequests:mt}:{},...ht?{apiCalls:ht}:{},...vt?{protocolAssertions:vt}:{}});try{let C=this.config.cloud?.uploadStrategy;if(this.cloudClient?.isCloudMode()&&this.cloudRunId&&(C==="realtime"||C==="both")){let S=this.cloudClient.getAccessToken();S&&_r(this.cloudClient.getEndpoint(),S,this.cloudRunId,this.buildCloudTestPayload(L));}}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter){let C=ke(c,g,e.id??"",s.retry),S=s.retry===e.results.length-1,O={id:C,navigations:l.navigations,apiAssertions:l.apiAssertions,actions:R??[],artifacts:k,failureDiagnostic:u,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(C,O,{networkRequestsFile:l.networkRequestsFile,consoleLogsFile:l.consoleLogsFile,apiCallsFile:l.apiCallsFile});let G={id:C,title:g[g.length-1]??e.title,titlePath:g,filePath:c,status:a,duration:s.duration,project:g[1]??"",retryIndex:s.retry,tags:d,hasNetworkData:l.networkRequestsCount>0,hasConsoleData:l.consoleLogsCount>0,hasArtifacts:k!==null,hasActionSteps:(R?.length??0)>0,errorMessage:u?.message?.split(`
2592
2592
  `)[0]??null,networkCount:l.networkRequestsCount,consoleCount:l.consoleLogsCount,actionCount:R?.length??0,isRetry:!S};if(this.testIndex.push(G),S)switch(this.summaryCounters.total++,a){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}this.upsertAggContribution(`${c}::${g.join(" > ")}`,Vr(s.retry,V,l.apiAssertions,l.navigations,l.networkRequestsCount,l.consoleLogsCount,R)),k&&this.pendingArtifactEntries.push({testId:h,artifacts:k,outputDir:path.dirname(this.config.outputPath)}),L.actions=null,L.apiAssertions=null,L.navigations=[],L.artifacts=null,L.failure=null,L.networkRequestsFile=null,L.consoleLogsFile=null,L.apiCallsFile=null;}this.activeReportMode!=="streaming"&&this.collectedTests.push(L),this.testCount++,this.checkMemoryPressure();}catch{}}async onEnd(e){try{let r=new Date().toISOString(),s=new Date(this.startedAt).getTime(),a=new Date(r).getTime()-s,o=this.activeReportMode==="streaming"?this.testIndex.some(d=>d.status!=="skipped"):this.collectedTests.some(d=>d.status!=="skipped");!this.fixtureDataReceived&&o&&process.stderr.write(`
2593
2593
  \u26A0 TestRelic: No fixture data received from any test.
2594
2594
  To enable network logs, video sync, and Test Navigation tracking, import the TestRelic fixture:
@@ -2598,14 +2598,14 @@ ${n}
2598
2598
 
2599
2599
  `),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).
2600
2600
  `):process.stderr.write(`[testrelic] Test Navigation capture is disabled (captureNavigation: false). Remove the option or set it to true to capture the navigation graph.
2601
- `),await ir();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=path.dirname(this.config.outputPath);i=cr(d,this.runTimestamp);let l=path.join(d,"artifact-manifest.json"),u=JSON.stringify(i),g=l+".tmp";fs$1.writeFileSync(g,u,"utf-8"),fs$1.renameSync(g,l);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,a,e,i);else {let d=this.buildTimeline(),l=new Map;for(let p of this.collectedTests){let f=l.get(p.testId);(!f||p.retry>f.retry)&&l.set(p.testId,p);}let u=Array.from(l.values()),g=mr(u,d.length),m={schemaVersion:Se,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:g,ci:P(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(m),await He(m,this.config,i),Ge(g,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let p=this.collectArtifactEntries(),f=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await pt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,m,r,a,g,p,f);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let s of this.collectedTests)s.artifacts&&r.push({testId:s.testId,artifacts:s.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,s,n){if(!this.streamingWriter)return;this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};let a=new Map,o=new Map;for(let c of this.testIndex){let h=`${c.filePath}::${c.titlePath.join(" > ")}`,v=a.get(h);(v===void 0||c.retryIndex>v)&&a.set(h,c.retryIndex);}let i=0;for(let c of this.testIndex){let h=`${c.filePath}::${c.titlePath.join(" > ")}`,v=a.get(h);if(c.isRetry=c.retryIndex<v,c.isRetry)continue;switch(i++,this.summaryCounters.total++,c.status){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}let w=o.get(c.filePath);switch(w||(w={filePath:c.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},o.set(c.filePath,w)),w.total++,c.status){case "passed":w.passed++;break;case "failed":w.failed++;break;case "flaky":w.flaky++;break;case "skipped":w.skipped++;break;case "timedout":w.timedOut++;break}}let d=Array.from(o.values()),l=Ia();for(let c of this.streamingTestAgg.values()){l.volApiCalls+=c.apiCalls,l.volAssertions+=c.assertions,l.volNavigations+=c.navigations,l.volNetworkRequests+=c.networkRequests,l.volConsoleLogs+=c.consoleLogs,l.volActionSteps+=c.actionSteps;for(let h in c.methodCounts)l.methodCounts[h]=(l.methodCounts[h]??0)+c.methodCounts[h];l.statusRanges["2xx"]+=c.statusRanges["2xx"],l.statusRanges["3xx"]+=c.statusRanges["3xx"],l.statusRanges["4xx"]+=c.statusRanges["4xx"],l.statusRanges["5xx"]+=c.statusRanges["5xx"],l.statusRanges.error+=c.statusRanges.error,l.passedAssertions+=c.passedAssertions,l.failedAssertions+=c.failedAssertions;for(let h in c.actionCategories)l.actionCategoryCounts[h]=(l.actionCategoryCounts[h]??0)+c.actionCategories[h];for(let h of c.apiUrls){if(l.apiUrlSet.size>=be)break;l.apiUrlSet.add(h);}for(let h of c.navUrls){if(l.navUrlSet.size>=be)break;l.navUrlSet.add(h);}for(let h of c.responseTimes){if(l.responseTimes.length>=Wr)break;l.responseTimes.push(h);}}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 u={reporterTotal:this.summaryCounters.total,indexTotal:i,playwrightStatus:s.status,isValid:this.summaryCounters.total===i};u.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${u.reporterTotal}, index: ${u.indexTotal}
2602
- `);let g={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:Aa(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}},m={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:g,validation:u,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(m);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 He(this.buildStreamingReport(m,g,e,r),this.config,n),Ge(g,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let f=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${f}
2601
+ `),await ar();let i=null;if(this.config.includeArtifacts&&this.runTimestamp)try{let d=path.dirname(this.config.outputPath);i=dr(d,this.runTimestamp);let l=path.join(d,"artifact-manifest.json"),u=JSON.stringify(i),g=l+".tmp";fs$1.writeFileSync(g,u,"utf-8"),fs$1.renameSync(g,l);}catch{}if(this.activeReportMode==="streaming"&&this.streamingWriter)await this.finalizeStreamingReport(r,a,e,i);else {let d=this.buildTimeline(),l=new Map;for(let p of this.collectedTests){let f=l.get(p.testId);(!f||p.retry>f.retry)&&l.set(p.testId,p);}let u=Array.from(l.values()),g=mr(u,d.length),m={schemaVersion:Se,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:r,totalDuration:a,summary:g,ci:P(),metadata:this.config.metadata,timeline:d,shardRunIds:null};if(this.writeReport(m),await He(m,this.config,i),Ve(g,this.config.outputPath,this.config.htmlReportPath,this.config.quiet),this.cloudClient){let p=this.collectArtifactEntries(),f=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await ut(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,m,r,a,g,p,f);}}}catch{}}collectArtifactEntries(){if(this.activeReportMode==="streaming")return this.pendingArtifactEntries;let e=path.dirname(this.config.outputPath),r=[];for(let s of this.collectedTests)s.artifacts&&r.push({testId:s.testId,artifacts:s.artifacts,outputDir:e});return r}async finalizeStreamingReport(e,r,s,n){if(!this.streamingWriter)return;this.summaryCounters={total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0,interrupted:0,totalApiCalls:0,totalAssertions:0,totalNavigations:0,totalNetworkRequests:0,totalConsoleLogs:0,totalActionSteps:0};let a=new Map,o=new Map;for(let c of this.testIndex){let h=`${c.filePath}::${c.titlePath.join(" > ")}`,v=a.get(h);(v===void 0||c.retryIndex>v)&&a.set(h,c.retryIndex);}let i=0;for(let c of this.testIndex){let h=`${c.filePath}::${c.titlePath.join(" > ")}`,v=a.get(h);if(c.isRetry=c.retryIndex<v,c.isRetry)continue;switch(i++,this.summaryCounters.total++,c.status){case "passed":this.summaryCounters.passed++;break;case "failed":this.summaryCounters.failed++;break;case "flaky":this.summaryCounters.flaky++;break;case "skipped":this.summaryCounters.skipped++;break;case "timedout":this.summaryCounters.timedOut++;break;default:this.summaryCounters.interrupted++;break}let w=o.get(c.filePath);switch(w||(w={filePath:c.filePath,total:0,passed:0,failed:0,flaky:0,skipped:0,timedOut:0},o.set(c.filePath,w)),w.total++,c.status){case "passed":w.passed++;break;case "failed":w.failed++;break;case "flaky":w.flaky++;break;case "skipped":w.skipped++;break;case "timedout":w.timedOut++;break}}let d=Array.from(o.values()),l=_a();for(let c of this.streamingTestAgg.values()){l.volApiCalls+=c.apiCalls,l.volAssertions+=c.assertions,l.volNavigations+=c.navigations,l.volNetworkRequests+=c.networkRequests,l.volConsoleLogs+=c.consoleLogs,l.volActionSteps+=c.actionSteps;for(let h in c.methodCounts)l.methodCounts[h]=(l.methodCounts[h]??0)+c.methodCounts[h];l.statusRanges["2xx"]+=c.statusRanges["2xx"],l.statusRanges["3xx"]+=c.statusRanges["3xx"],l.statusRanges["4xx"]+=c.statusRanges["4xx"],l.statusRanges["5xx"]+=c.statusRanges["5xx"],l.statusRanges.error+=c.statusRanges.error,l.passedAssertions+=c.passedAssertions,l.failedAssertions+=c.failedAssertions;for(let h in c.actionCategories)l.actionCategoryCounts[h]=(l.actionCategoryCounts[h]??0)+c.actionCategories[h];for(let h of c.apiUrls){if(l.apiUrlSet.size>=be)break;l.apiUrlSet.add(h);}for(let h of c.navUrls){if(l.navUrlSet.size>=be)break;l.navUrlSet.add(h);}for(let h of c.responseTimes){if(l.responseTimes.length>=Wr)break;l.responseTimes.push(h);}}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 u={reporterTotal:this.summaryCounters.total,indexTotal:i,playwrightStatus:s.status,isValid:this.summaryCounters.total===i};u.isValid||process.stderr.write(`[testrelic] WARNING: Summary count mismatch \u2014 reporter: ${u.reporterTotal}, index: ${u.indexTotal}
2602
+ `);let g={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:Ia(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}},m={testRunId:this.testRunId,startedAt:this.startedAt,completedAt:e,totalDuration:r,...this.summaryCounters,metadata:this.config.metadata,reportMode:"streaming",files:d,enrichedSummary:g,validation:u,writeErrors:this.streamingWriter.getWriteErrors()};this.streamingWriter.writeSummary(m);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 He(this.buildStreamingReport(m,g,e,r),this.config,n),Ve(g,this.config.outputPath,this.config.htmlReportPath,this.config.quiet);let f=this.streamingWriter.getReportDir();if(process.stderr.write(`[testrelic] Streaming report written to ${f}
2603
2603
  [testrelic] ${this.testIndex.length} test detail files on disk
2604
2604
  [testrelic] View report: npx testrelic serve ${f}
2605
2605
  `),this.streamingWriter.getWriteErrors().length>0&&process.stderr.write(`[testrelic] WARNING: ${this.streamingWriter.getWriteErrors().length} write error(s) during streaming
2606
- `),this.streamingWriter.dispose(),this.cloudClient){let c=this.buildStreamingReport(m,g,e,r),h=this.collectArtifactEntries(),v=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await pt(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,c,e,r,g,h,v);}this.testIndex.length=0,this.collectedTests.length=0,this.pendingArtifactEntries.length=0,this.cloudTestsBuffer.length=0,this.streamingWriter=null,this.cloudClient=null;}buildStreamingReport(e,r,s,n){return {schemaVersion:Se,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:s,totalDuration:n,summary:r,ci:P(),metadata:this.config.metadata,timeline:[],shardRunIds:null}}printsToStdio(){return false}checkMemoryPressure(){try{let e=process.memoryUsage(),r=e.heapUsed/1024/1024;if(r<200)return;let s=e.heapUsed/e.heapTotal;s>.9&&this.activeReportMode==="embedded"?(process.stderr.write(`[testrelic] WARNING: High memory (${Math.round(r)} MB). Auto-switching to streaming mode.
2606
+ `),this.streamingWriter.dispose(),this.cloudClient){let c=this.buildStreamingReport(m,g,e,r),h=this.collectArtifactEntries(),v=this.cloudTestsBuffer.slice();this.cloudTestsBuffer.length=0,await ut(this.cloudClient,this.config.cloud,this.config.cloud?.uploadStrategy,this.testRunId,this.cloudRunId,c,e,r,g,h,v);}this.testIndex.length=0,this.collectedTests.length=0,this.pendingArtifactEntries.length=0,this.cloudTestsBuffer.length=0,this.streamingWriter=null,this.cloudClient=null;}buildStreamingReport(e,r,s,n){return {schemaVersion:Se,testRunId:this.testRunId,startedAt:this.startedAt,completedAt:s,totalDuration:n,summary:r,ci:P(),metadata:this.config.metadata,timeline:[],shardRunIds:null}}printsToStdio(){return false}checkMemoryPressure(){try{let e=process.memoryUsage(),r=e.heapUsed/1024/1024;if(r<200)return;let s=e.heapUsed/e.heapTotal;s>.9&&this.activeReportMode==="embedded"?(process.stderr.write(`[testrelic] WARNING: High memory (${Math.round(r)} MB). Auto-switching to streaming mode.
2607
2607
  `),this.switchToStreamingMode()):s>.8&&process.stderr.write(`[testrelic] WARNING: Memory pressure detected (${Math.round(r)} MB used).
2608
2608
  `);}catch{}}switchToStreamingMode(){try{if(this.activeReportMode==="streaming")return;this.activeReportMode="streaming";let e=path.dirname(this.config.outputPath);this.streamingWriter=new J(e);for(let r of this.collectedTests){let s=ke(r.filePath,r.titlePath,r.testId,r.retry),n=r.apiCallsFile&&r.apiCallsCount>0?B(r.apiCallsFile):void 0,a={id:s,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(s,a,{networkRequestsFile:r.networkRequestsFile,consoleLogsFile:r.consoleLogsFile,apiCallsFile:r.apiCallsFile});let o={id:s,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(`
2609
- `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};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(" > ")}`,Vr(r.retry,n,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 hr(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=B(e);return r.length>0?r:null}toTestResult(e,r){let s=null,n=null,a=null;return r?.loadFiles&&(s=this.readJsonlFile(e.networkRequestsFile),n=this.readJsonlFile(e.consoleLogsFile),a=this.readJsonlFile(e.apiCallsFile)),{title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:e.retryCount,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,retryStatus:e.retryStatus,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,networkRequests:s,apiCalls:a,apiAssertions:e.apiAssertions,actions:e.actions??null,consoleLogs:n}}buildCloudTestPayload(e){let r={title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retry:e.retry,retryCount:e.retryCount,retryStatus:e.retryStatus,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,actions:e.actions??[],navigations:e.navigations??[],steps:e.actions??[],browser:e.browser,os:e.os,source:e.source};if(e.apiAssertions&&e.apiAssertions.length>0&&(r.protocolAssertions=st(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=B(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=B(e.networkRequestsFile)),e.apiCallsFile){let s=B(e.apiCallsFile);r.apiCalls=tt(s),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=rt(s));}return r}writeReport(e){try{let r=JSON.stringify(e),s=this.config.outputPath,n=path.dirname(s);fs$1.mkdirSync(n,{recursive:!0});let a=s+".tmp";fs$1.writeFileSync(a,r,"utf-8"),fs$1.renameSync(a,s);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2609
+ `)[0]??null,networkCount:r.networkRequestsCount,consoleCount:r.consoleLogsCount,actionCount:r.actions?.length??0,isRetry:!1};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(" > ")}`,Vr(r.retry,n,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 hr(e,{navigationTypes:this.config.navigationTypes})}readJsonlFile(e){if(!e)return null;let r=B(e);return r.length>0?r:null}toTestResult(e,r){let s=null,n=null,a=null;return r?.loadFiles&&(s=this.readJsonlFile(e.networkRequestsFile),n=this.readJsonlFile(e.consoleLogsFile),a=this.readJsonlFile(e.apiCallsFile)),{title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:e.retryCount,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,retryStatus:e.retryStatus,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,networkRequests:s,apiCalls:a,apiAssertions:e.apiAssertions,actions:e.actions??null,consoleLogs:n}}buildCloudTestPayload(e){let r={title:e.title,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retry:e.retry,retryCount:e.retryCount,retryStatus:e.retryStatus,tags:e.tags,failure:e.failure,testId:e.testId,filePath:e.filePath,suiteName:e.suiteName,testType:e.testType,isFlaky:e.isFlaky,expectedStatus:e.expectedStatus,actualStatus:e.actualStatus,artifacts:e.artifacts,actions:e.actions??[],navigations:e.navigations??[],steps:e.actions??[],browser:e.browser,os:e.os,source:e.source};if(e.apiAssertions&&e.apiAssertions.length>0&&(r.protocolAssertions=rt(e.apiAssertions)),e.consoleLogsFile&&(r.consoleLogs=B(e.consoleLogsFile)),e.networkRequestsFile&&(r.networkRequests=B(e.networkRequestsFile)),e.apiCallsFile){let s=B(e.apiCallsFile);r.apiCalls=et(s),(!r.networkRequests||r.networkRequests.length===0)&&(r.networkRequests=tt(s));}return r}writeReport(e){try{let r=JSON.stringify(e),s=this.config.outputPath,n=path.dirname(s);fs$1.mkdirSync(n,{recursive:!0});let a=s+".tmp";fs$1.writeFileSync(a,r,"utf-8"),fs$1.renameSync(a,s);}catch(r){process.stderr.write(`[testrelic] Failed to write report: ${r instanceof Error?r.message:String(r)}
2610
2610
  `);}}};module.exports=xe;//# sourceMappingURL=reporter-entry.cjs.map
2611
2611
  //# sourceMappingURL=reporter-entry.cjs.map