@testream/playwright-reporter 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (()=>{"use strict";var t={649:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:true});const i=o(r(928));const n=o(r(896));const s=o(r(982));class GenerateCtrfReport{constructor(t){var e,r,o,i,n,a,u,l,c,d,p,f,h,m,g,y,b,_,v;this.reporterName="playwright-ctrf-json-reporter";this.defaultOutputFile="ctrf-report.json";this.defaultOutputDir="ctrf";this.reporterConfigOptions={outputFile:(e=t===null||t===void 0?void 0:t.outputFile)!==null&&e!==void 0?e:this.defaultOutputFile,outputDir:(r=t===null||t===void 0?void 0:t.outputDir)!==null&&r!==void 0?r:this.defaultOutputDir,minimal:(o=t===null||t===void 0?void 0:t.minimal)!==null&&o!==void 0?o:false,screenshot:(i=t===null||t===void 0?void 0:t.screenshot)!==null&&i!==void 0?i:false,annotations:(n=t===null||t===void 0?void 0:t.annotations)!==null&&n!==void 0?n:false,testType:(a=t===null||t===void 0?void 0:t.testType)!==null&&a!==void 0?a:"e2e",appName:(u=t===null||t===void 0?void 0:t.appName)!==null&&u!==void 0?u:undefined,appVersion:(l=t===null||t===void 0?void 0:t.appVersion)!==null&&l!==void 0?l:undefined,osPlatform:(c=t===null||t===void 0?void 0:t.osPlatform)!==null&&c!==void 0?c:undefined,osRelease:(d=t===null||t===void 0?void 0:t.osRelease)!==null&&d!==void 0?d:undefined,osVersion:(p=t===null||t===void 0?void 0:t.osVersion)!==null&&p!==void 0?p:undefined,buildName:(f=t===null||t===void 0?void 0:t.buildName)!==null&&f!==void 0?f:undefined,buildNumber:(h=t===null||t===void 0?void 0:t.buildNumber)!==null&&h!==void 0?h:undefined,buildUrl:(m=t===null||t===void 0?void 0:t.buildUrl)!==null&&m!==void 0?m:undefined,repositoryName:(g=t===null||t===void 0?void 0:t.repositoryName)!==null&&g!==void 0?g:undefined,repositoryUrl:(y=t===null||t===void 0?void 0:t.repositoryUrl)!==null&&y!==void 0?y:undefined,branchName:(b=t===null||t===void 0?void 0:t.branchName)!==null&&b!==void 0?b:undefined,commit:(_=t===null||t===void 0?void 0:t.commit)!==null&&_!==void 0?_:undefined,testEnvironment:(v=t===null||t===void 0?void 0:t.testEnvironment)!==null&&v!==void 0?v:undefined};this.ctrfReport={reportFormat:"CTRF",specVersion:"0.0.0",reportId:s.default.randomUUID(),timestamp:(new Date).toISOString(),generatedBy:"playwright-ctrf-json-reporter",results:{tool:{name:"playwright"},summary:{tests:0,passed:0,failed:0,pending:0,skipped:0,other:0,start:0,stop:0},tests:[]}};this.ctrfEnvironment={}}onBegin(t,e){var r,o,i;this.suite=e;this.startTime=Date.now();this.ctrfReport.results.summary.start=this.startTime;if(!n.default.existsSync((r=this.reporterConfigOptions.outputDir)!==null&&r!==void 0?r:this.defaultOutputDir)){n.default.mkdirSync((o=this.reporterConfigOptions.outputDir)!==null&&o!==void 0?o:this.defaultOutputDir,{recursive:true})}this.setEnvironmentDetails(this.reporterConfigOptions);if(this.hasEnvironmentDetails(this.ctrfEnvironment)){this.ctrfReport.results.environment=this.ctrfEnvironment}this.setFilename((i=this.reporterConfigOptions.outputFile)!==null&&i!==void 0?i:this.defaultOutputFile)}onEnd(){this.ctrfReport.results.summary.stop=Date.now();if(this.suite!==undefined){if(this.suite.allTests().length>0){this.processSuite(this.suite);this.ctrfReport.results.summary.suites=this.countSuites(this.suite)}}this.writeReportToFile(this.ctrfReport)}printsToStdio(){return false}processSuite(t){for(const e of t.tests){this.processTest(e)}for(const e of t.suites){this.processSuite(e)}}processTest(t){if(t.results.length===0){return}const e=t.results[t.results.length-1];if(e!==undefined){this.updateCtrfTestResultsFromTestResult(t,e,this.ctrfReport);this.updateSummaryFromTestResult(e,this.ctrfReport)}}setFilename(t){if(t.endsWith(".json")){this.reporterConfigOptions.outputFile=t}else{this.reporterConfigOptions.outputFile=`${t}.json`}}updateCtrfTestResultsFromTestResult(t,e,r){var o,i,n,s,a,u;const l={name:t.title,status:e.status===t.expectedStatus&&e.status!=="skipped"?"passed":this.mapPlaywrightStatusToCtrf(e.status),duration:e.duration};if(this.reporterConfigOptions.minimal===false){l.start=this.updateStart(e.startTime);l.stop=this.calculateStopTime(e.startTime,e.duration);l.message=this.extractFailureDetails(e).message;l.trace=this.extractFailureDetails(e).trace;l.snippet=this.extractFailureDetails(e).snippet;l.rawStatus=e.status;l.tags=(o=t.tags)!==null&&o!==void 0?o:[];l.type=(i=this.reporterConfigOptions.testType)!==null&&i!==void 0?i:"e2e";l.filePath=t.location.file;l.retries=e.retry;l.flaky=e.status==="passed"&&e.retry>0;l.steps=[];if(e.steps.length>0){e.steps.forEach((t=>{this.processStep(l,t)}))}if(this.reporterConfigOptions.screenshot===true){l.screenshot=this.extractScreenshotBase64(e)}l.suite=this.buildSuitePath(t);if(((n=this.extractMetadata(e))===null||n===void 0?void 0:n.name)!==undefined||((s=this.extractMetadata(e))===null||s===void 0?void 0:s.version)!==undefined)l.browser=`${(a=this.extractMetadata(e))===null||a===void 0?void 0:a.name} ${(u=this.extractMetadata(e))===null||u===void 0?void 0:u.version}`;l.attachments=this.filterValidAttachments(e.attachments);l.stdout=e.stdout.map((t=>Buffer.isBuffer(t)?t.toString():String(t)));l.stderr=e.stderr.map((t=>Buffer.isBuffer(t)?t.toString():String(t)));if(this.reporterConfigOptions.annotations!==undefined){l.extra={annotations:t.annotations}}if(t.results.length>1){const e=t.results.slice(0,-1);l.retryAttempts=[];for(const t of e){const e={status:this.mapPlaywrightStatusToCtrf(t.status),duration:t.duration,message:this.extractFailureDetails(t).message,trace:this.extractFailureDetails(t).trace,snippet:this.extractFailureDetails(t).snippet};l.retryAttempts.push(e)}}}r.results.tests.push(l)}updateSummaryFromTestResult(t,e){e.results.summary.tests++;const r=this.mapPlaywrightStatusToCtrf(t.status);if(r in e.results.summary){e.results.summary[r]++}else{e.results.summary.other++}}mapPlaywrightStatusToCtrf(t){switch(t){case"passed":return"passed";case"failed":case"timedOut":case"interrupted":return"failed";case"skipped":return"skipped";case"pending":return"pending";default:return"other"}}setEnvironmentDetails(t){if(t.appName!==undefined){this.ctrfEnvironment.appName=t.appName}if(t.appVersion!==undefined){this.ctrfEnvironment.appVersion=t.appVersion}if(t.osPlatform!==undefined){this.ctrfEnvironment.osPlatform=t.osPlatform}if(t.osRelease!==undefined){this.ctrfEnvironment.osRelease=t.osRelease}if(t.osVersion!==undefined){this.ctrfEnvironment.osVersion=t.osVersion}if(t.buildName!==undefined){this.ctrfEnvironment.buildName=t.buildName}if(t.buildNumber!==undefined){this.ctrfEnvironment.buildNumber=t.buildNumber}if(t.buildUrl!==undefined){this.ctrfEnvironment.buildUrl=t.buildUrl}if(t.repositoryName!==undefined){this.ctrfEnvironment.repositoryName=t.repositoryName}if(t.repositoryUrl!==undefined){this.ctrfEnvironment.repositoryUrl=t.repositoryUrl}if(t.branchName!==undefined){this.ctrfEnvironment.branchName=t.branchName}if(t.commit!==undefined){this.ctrfEnvironment.commit=t.commit}if(t.testEnvironment!==undefined){this.ctrfEnvironment.testEnvironment=t.testEnvironment}}hasEnvironmentDetails(t){return Object.keys(t).length>0}extractMetadata(t){const e=t.attachments.find((t=>t.name==="metadata.json"));if((e===null||e===void 0?void 0:e.body)!==null&&(e===null||e===void 0?void 0:e.body)!==undefined){try{const t=e.body.toString("utf-8");return JSON.parse(t)}catch(t){if(t instanceof Error){console.error(`Error parsing browser metadata: ${t.message}`)}else{console.error("An unknown error occurred in parsing browser metadata")}}}return null}updateStart(t){const e=new Date(t);const r=Math.floor(e.getTime()/1e3);return r}calculateStopTime(t,e){const r=new Date(t);const o=new Date(r.getTime()+e);return Math.floor(o.getTime()/1e3)}buildSuitePath(t){const e=[];let r=t.parent;while(r!==undefined){if(r.title!==""){e.unshift(r.title)}r=r.parent}return e.join(" > ")}extractScreenshotBase64(t){var e;const r=t.attachments.find((t=>t.name==="screenshot"&&(t.contentType==="image/jpeg"||t.contentType==="image/png")));return(e=r===null||r===void 0?void 0:r.body)===null||e===void 0?void 0:e.toString("base64")}extractFailureDetails(t){if((t.status==="failed"||t.status==="timedOut"||t.status==="interrupted")&&t.error!==undefined){const e={};if(t.error.message!==undefined){e.message=t.error.message}if(t.error.stack!==undefined){e.trace=t.error.stack}if(t.error.snippet!==undefined){e.snippet=t.error.snippet}return e}return{}}countSuites(t){let e=0;t.suites.forEach((t=>{e+=this.countSuites(t)}));return e}writeReportToFile(t){var e,r;const o=i.default.join((e=this.reporterConfigOptions.outputDir)!==null&&e!==void 0?e:this.defaultOutputDir,(r=this.reporterConfigOptions.outputFile)!==null&&r!==void 0?r:this.defaultOutputFile);const s=JSON.stringify(t,null,2);try{n.default.writeFileSync(o,s+"\n");console.log(`${this.reporterName}: successfully written ctrf json to %s/%s`,this.reporterConfigOptions.outputDir,this.reporterConfigOptions.outputFile)}catch(t){console.error(`Error writing ctrf json report:, ${String(t)}`)}}processStep(t,e){var r;if(e.category==="test.step"){const o=e.error===undefined?this.mapPlaywrightStatusToCtrf("passed"):this.mapPlaywrightStatusToCtrf("failed");const i={name:e.title,status:o};(r=t.steps)===null||r===void 0?void 0:r.push(i)}const o=e.steps;if(o.length>0){o.forEach((e=>{this.processStep(t,e)}))}}filterValidAttachments(t){return t.filter((t=>t.path!==undefined)).map((t=>{var e;return{name:t.name,contentType:t.contentType,path:(e=t.path)!==null&&e!==void 0?e:""}}))}}e["default"]=GenerateCtrfReport},197:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:true});e["default"]=void 0;var i=r(649);Object.defineProperty(e,"default",{enumerable:true,get:function(){return o(i).default}})},406:(t,e)=>{Object.defineProperty(e,"__esModule",{value:true});e.detectCIContext=detectCIContext;function removePrefix(t,e){if(!t){return undefined}return t.startsWith(e)?t.slice(e.length):t}function readEnvironment(){const t=globalThis;return t.process?.env??{}}function buildGithubRepositoryUrl(t){if(!t.GITHUB_SERVER_URL||!t.GITHUB_REPOSITORY){return undefined}return`${t.GITHUB_SERVER_URL}/${t.GITHUB_REPOSITORY}`}function buildGithubBuildUrl(t){if(!t.GITHUB_SERVER_URL||!t.GITHUB_REPOSITORY||!t.GITHUB_RUN_ID){return undefined}return`${t.GITHUB_SERVER_URL}/${t.GITHUB_REPOSITORY}/actions/runs/${t.GITHUB_RUN_ID}`}function detectGitHubBranch(t){if(t.GITHUB_HEAD_REF){return t.GITHUB_HEAD_REF}if(t.GITHUB_REF?.startsWith("refs/heads/")){return t.GITHUB_REF_NAME??removePrefix(t.GITHUB_REF,"refs/heads/")}return undefined}function detectGitHubActionsContext(t){return{branch:detectGitHubBranch(t),commitSha:t.GITHUB_SHA,repositoryUrl:buildGithubRepositoryUrl(t),buildNumber:t.GITHUB_RUN_NUMBER,buildUrl:buildGithubBuildUrl(t)}}function detectGitLabContext(t){return{branch:t.CI_COMMIT_BRANCH||t.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,commitSha:t.CI_COMMIT_SHA,repositoryUrl:t.CI_PROJECT_URL,buildNumber:t.CI_PIPELINE_IID,buildUrl:t.CI_PIPELINE_URL}}function detectAzurePipelinesContext(t){return{branch:removePrefix(t.BUILD_SOURCEBRANCH,"refs/heads/"),commitSha:t.BUILD_SOURCEVERSION,repositoryUrl:t.BUILD_REPOSITORY_URI,buildNumber:t.BUILD_BUILDNUMBER,buildUrl:t.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI&&t.SYSTEM_TEAMPROJECT&&t.BUILD_BUILDID?`${t.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${t.SYSTEM_TEAMPROJECT}/_build/results?buildId=${t.BUILD_BUILDID}`:undefined}}function detectCircleCIContext(t){return{branch:t.CIRCLE_BRANCH,commitSha:t.CIRCLE_SHA1,repositoryUrl:t.CIRCLE_REPOSITORY_URL,buildNumber:t.CIRCLE_BUILD_NUM,buildUrl:t.CIRCLE_BUILD_URL}}function detectJenkinsContext(t){return{branch:removePrefix(t.GIT_BRANCH,"origin/"),commitSha:t.GIT_COMMIT,repositoryUrl:t.GIT_URL,buildNumber:t.BUILD_NUMBER,buildUrl:t.BUILD_URL}}function detectBitbucketContext(t){return{branch:t.BITBUCKET_BRANCH,commitSha:t.BITBUCKET_COMMIT,repositoryUrl:t.BITBUCKET_GIT_HTTP_ORIGIN,buildNumber:t.BITBUCKET_BUILD_NUMBER,buildUrl:t.BITBUCKET_REPO_FULL_NAME&&t.BITBUCKET_BUILD_NUMBER?`https://bitbucket.org/${t.BITBUCKET_REPO_FULL_NAME}/pipelines/results/${t.BITBUCKET_BUILD_NUMBER}`:undefined}}const r=[{isMatch:t=>t.GITHUB_ACTIONS==="true",detect:detectGitHubActionsContext},{isMatch:t=>t.GITLAB_CI==="true",detect:detectGitLabContext},{isMatch:t=>t.TF_BUILD==="True",detect:detectAzurePipelinesContext},{isMatch:t=>t.CIRCLECI==="true",detect:detectCircleCIContext},{isMatch:t=>Boolean(t.JENKINS_URL),detect:detectJenkinsContext},{isMatch:t=>Boolean(t.BITBUCKET_BUILD_NUMBER),detect:detectBitbucketContext}];function detectCIContext(){const t=readEnvironment();for(const e of r){if(e.isMatch(t)){return e.detect(t)}}return{}}},827:(t,e)=>{Object.defineProperty(e,"__esModule",{value:true})},322:function(t,e,r){var o=this&&this.__createBinding||(Object.create?function(t,e,r,o){if(o===undefined)o=r;var i=Object.getOwnPropertyDescriptor(e,r);if(!i||("get"in i?!e.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return e[r]}}}Object.defineProperty(t,o,i)}:function(t,e,r,o){if(o===undefined)o=r;t[o]=e[r]});var i=this&&this.__exportStar||function(t,e){for(var r in t)if(r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r))o(e,t,r)};Object.defineProperty(e,"__esModule",{value:true});e.ensureReportId=e.mapAttachmentsToTestResults=e.uploadArtifacts=e.uploadTestRun=e.detectCIContext=void 0;i(r(827),e);var n=r(406);Object.defineProperty(e,"detectCIContext",{enumerable:true,get:function(){return n.detectCIContext}});var s=r(969);Object.defineProperty(e,"uploadTestRun",{enumerable:true,get:function(){return s.uploadTestRun}});Object.defineProperty(e,"uploadArtifacts",{enumerable:true,get:function(){return s.uploadArtifacts}});Object.defineProperty(e,"mapAttachmentsToTestResults",{enumerable:true,get:function(){return s.mapAttachmentsToTestResults}});Object.defineProperty(e,"ensureReportId",{enumerable:true,get:function(){return s.ensureReportId}})},969:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:true});e.ensureReportId=ensureReportId;e.uploadTestRun=uploadTestRun;e.mapAttachmentsToTestResults=mapAttachmentsToTestResults;e.uploadArtifacts=uploadArtifacts;const o=r(406);const i="https://test-manager-backend.fly.dev";function ensureReportId(t){if(typeof t.reportId==="string"&&t.reportId.trim().length>0){return t.reportId}const e=crypto.randomUUID();t.reportId=e;return e}function resolveApiUrl(t){const e=normalizeApiUrl(t);if(e){return e}const r=getEnvApiUrl();if(r){return r}return i}function getEnvApiUrl(){if(typeof process==="undefined"||!process?.env){return undefined}return normalizeApiUrl(process.env.TESTREAM_API_URL)}function normalizeApiUrl(t){if(!t){return undefined}const e=t.trim();if(!e){return undefined}return e.replace(/\/+$/,"")}function isReportAlreadyExistsConflict(t){return t.errorCode==="report_already_exists"}function formatUploadError(t){const e=t.detail||t.title||t.rawBody||"Unknown error";const r=t.errorCode?`, code=${t.errorCode}`:"";return`Upload failed (HTTP ${t.statusCode}${r}): ${e}`}async function parseHttpError(t){const e=await t.text();const r=t.headers.get("content-type")||"";if(r.toLowerCase().includes("json")&&e.trim().length>0){try{const r=JSON.parse(e);return{statusCode:t.status,title:r.title,detail:r.detail||r.details||r.error,errorCode:r.errorCode,rawBody:e}}catch{}}return{statusCode:t.status,rawBody:e}}function resolveUploadContext(t){const e=(0,o.detectCIContext)();return{commitSha:t.commitSha??e.commitSha,branch:t.branch??e.branch,repositoryUrl:t.repositoryUrl??e.repositoryUrl,buildName:t.buildName,buildNumber:t.buildNumber??e.buildNumber,buildUrl:t.buildUrl??e.buildUrl,testEnvironment:t.testEnvironment,appName:t.appName,appVersion:t.appVersion,testType:t.testType}}async function uploadTestRun(t){const{report:e,apiKey:r}=t;const o=resolveApiUrl(t.apiUrl);const i=ensureReportId(e);const n=resolveUploadContext(t);const s={report:e,reportId:i,...n};console.log("Uploading test results...");let a;try{a=await fetch(`${o}/api/v1/ingest`,{method:"POST",headers:{"X-API-KEY":r,"Content-Type":"application/json"},body:JSON.stringify(s)})}catch(t){const e=t instanceof Error?t.message:String(t);const r=`Connection failed: ${e}`;console.error(r);return{success:false,reportId:i,error:r}}if(!a.ok){const t=await parseHttpError(a);if(a.status===409&&isReportAlreadyExistsConflict(t)){console.warn("Report already exists (workflow may have been re-run)");return{success:true,reportId:i,summary:{passed:e.results.summary.passed,failed:e.results.summary.failed,skipped:e.results.summary.skipped,total:e.results.summary.tests},alreadyExists:true,statusCode:t.statusCode,errorCode:t.errorCode}}const r=formatUploadError(t);console.error(r);return{success:false,reportId:i,error:r,statusCode:t.statusCode,errorCode:t.errorCode,errorDetail:t.detail||t.rawBody}}const u=await a.json();console.log(`✓ Test results uploaded successfully`);console.log(` Report ID: ${u.reportId}`);console.log(` Test Run ID: ${u.testRunId}`);console.log(` Tests: ${u.summary.passed}/${u.summary.total} passed`);return{success:true,reportId:u.reportId,testRunId:u.testRunId,summary:{passed:u.summary.passed,failed:u.summary.failed,skipped:u.summary.skipped,total:u.summary.total},testResults:u.testResults}}function mapAttachmentsToTestResults(t,e){const r=new Map;for(const t of e){const e=r.get(t.name)??[];e.push(t.id);r.set(t.name,e)}const o=[];for(const e of t){const t=r.get(e.name);const i=t?.shift();if(!e.attachments||e.attachments.length===0){continue}if(!i){console.warn(`Skipping artifact upload: could not match test result for "${e.name}"`);continue}o.push({testResultId:i,attachments:e.attachments})}return o}async function uploadArtifacts(t){const{reportId:e,apiKey:r,testResults:o}=t;const i=resolveApiUrl(t.apiUrl);let n=0;for(const t of o){for(const o of t.attachments){try{const s=await uploadSingleArtifact({testResultId:t.testResultId,attachment:o,reportId:e,apiKey:r,apiUrl:i});if(s)n++}catch(t){const e=t instanceof Error?t.message:String(t);console.error(`Failed to upload artifact ${o.name}: ${e}`)}}}if(n>0){console.log(`✓ Uploaded ${n} artifact(s)`)}return n}async function uploadSingleArtifact(t){const{testResultId:e,attachment:o,reportId:i,apiKey:n,apiUrl:s}=t;const a=await Promise.resolve().then(r.t.bind(r,943,23));const u=await Promise.resolve().then(r.t.bind(r,928,23));const l=u.resolve(o.path);try{await a.access(l)}catch{console.warn(`Artifact not found: ${u.basename(l)}`);return false}let c;let d;const p=u.basename(l);const f=o.contentType||"application/octet-stream";try{c=await a.readFile(l);d=c.byteLength}catch(t){const e=t instanceof Error?t.message:String(t);throw new Error(`Failed to read file: ${e}`)}try{return await uploadWithPresignedUrl({testResultId:e,reportId:i,apiKey:n,apiUrl:s,attachmentName:o.name,fileName:p,contentType:f,sizeBytes:d,fileBuffer:c})}catch(t){if(!(t instanceof LegacyUploadRequiredError)){throw t}return await uploadWithLegacyEndpoint({testResultId:e,attachmentName:o.name,reportId:i,apiKey:n,apiUrl:s,fileName:p,contentType:f,fileBuffer:c})}}class LegacyUploadRequiredError extends Error{constructor(){super("Legacy upload endpoint required")}}async function uploadWithPresignedUrl(t){const{testResultId:e,reportId:r,apiKey:o,apiUrl:i,attachmentName:n,fileName:s,contentType:a,sizeBytes:u,fileBuffer:l}=t;const c={testResultId:e,ctrfAttachmentName:n,fileName:s,contentType:a,sizeBytes:u};const d=await fetch(`${i}/api/v1/artifacts/${r}/upload-url`,{method:"POST",headers:{"X-API-KEY":o,"Content-Type":"application/json"},body:JSON.stringify(c)});if(shouldFallbackToLegacyUpload(d.status)){throw new LegacyUploadRequiredError}if(!d.ok){const t=await d.text();throw new Error(`Failed to create direct upload URL (HTTP ${d.status}): ${t}`)}const p=await d.json();const f={...p.requiredHeaders??{}};if(!hasHeaderIgnoreCase(f,"Content-Type")){f["Content-Type"]=a}const h=await fetch(p.uploadUrl,{method:"PUT",headers:f,body:l});if(!h.ok){const t=await h.text();throw new Error(`Direct artifact upload failed (HTTP ${h.status}): ${t}`)}const m={testResultId:e,ctrfAttachmentName:n,fileName:s,contentType:a,sizeBytes:u,storageKey:p.storageKey};const g=await fetch(`${i}/api/v1/artifacts/${r}/complete`,{method:"POST",headers:{"X-API-KEY":o,"Content-Type":"application/json"},body:JSON.stringify(m)});if(!g.ok){const t=await g.text();throw new Error(`Failed to finalize artifact upload (HTTP ${g.status}): ${t}`)}return true}async function uploadWithLegacyEndpoint(t){const{testResultId:e,attachmentName:r,reportId:o,apiKey:i,apiUrl:n,fileName:s,contentType:a,fileBuffer:u}=t;const l=new Blob([new Uint8Array(u)],{type:a});const c=new FormData;c.append("testResultId",e);c.append("ctrfAttachmentName",r);c.append("file",l,s);const d=await fetch(`${n}/api/v1/artifacts/${o}`,{method:"POST",headers:{"X-API-KEY":i},body:c});if(!d.ok){const t=await d.text();throw new Error(`Legacy artifact upload failed (HTTP ${d.status}): ${t}`)}return true}function shouldFallbackToLegacyUpload(t){return t===404||t===405||t===501}function hasHeaderIgnoreCase(t,e){const r=e.toLowerCase();return Object.keys(t).some((t=>t.toLowerCase()===r))}},665:function(t,e,r){var o=this&&this.__createBinding||(Object.create?function(t,e,r,o){if(o===undefined)o=r;var i=Object.getOwnPropertyDescriptor(e,r);if(!i||("get"in i?!e.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return e[r]}}}Object.defineProperty(t,o,i)}:function(t,e,r,o){if(o===undefined)o=r;t[o]=e[r]});var i=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:true,value:e})}:function(t,e){t["default"]=e});var n=this&&this.__importStar||function(){var ownKeys=function(t){ownKeys=Object.getOwnPropertyNames||function(t){var e=[];for(var r in t)if(Object.prototype.hasOwnProperty.call(t,r))e[e.length]=r;return e};return ownKeys(t)};return function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r=ownKeys(t),n=0;n<r.length;n++)if(r[n]!=="default")o(e,t,r[n]);i(e,t);return e}}();var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:true});e.PlaywrightCTRFReporterWithUpload=void 0;const a=n(r(943));const u=n(r(928));const l=r(322);const c=r(10);const d=s(r(197));class PlaywrightCTRFReporterWithUpload{constructor(t){this.uploader=null;if(!t.apiKey){throw new Error("PlaywrightCTRFReporter: apiKey is required")}this.config={uploadEnabled:true,outputFile:"ctrf-report.json",outputDir:"ctrf",failOnUploadError:false,screenshot:true,annotations:false,testType:"e2e",...t};const e=(0,l.detectCIContext)();if(!this.config.branch&&e.branch){this.config.branch=e.branch}if(!this.config.commitSha&&e.commitSha){this.config.commitSha=e.commitSha}if(!this.config.repositoryUrl&&e.repositoryUrl){this.config.repositoryUrl=e.repositoryUrl}if(!this.config.buildNumber&&e.buildNumber){this.config.buildNumber=e.buildNumber}if(!this.config.buildUrl&&e.buildUrl){this.config.buildUrl=e.buildUrl}this.reportPath=u.join(this.config.outputDir,this.config.outputFile);const r={outputFile:this.config.outputFile,outputDir:this.config.outputDir,screenshot:this.config.screenshot,annotations:this.config.annotations,testType:this.config.testType};if(this.config.appName)r.appName=this.config.appName;if(this.config.appVersion)r.appVersion=this.config.appVersion;if(this.config.buildName)r.buildName=this.config.buildName;if(this.config.buildNumber)r.buildNumber=this.config.buildNumber;if(this.config.buildUrl)r.buildUrl=this.config.buildUrl;if(this.config.testEnvironment)r.testEnvironment=this.config.testEnvironment;if(this.config.branch)r.branchName=this.config.branch;if(this.config.commitSha)r.commit=this.config.commitSha;this.ctrfReporter=new d.default(r);if(this.config.uploadEnabled){this.uploader=new c.ReportUploader(this.config)}}onBegin(t,e){if(this.ctrfReporter.onBegin){this.ctrfReporter.onBegin(t,e)}console.log("");console.log("=".repeat(60));console.log("Playwright Test Manager Reporter");console.log("=".repeat(60));if(this.config.uploadEnabled){if(this.config.branch)console.log(`Branch: ${this.config.branch}`);if(this.config.commitSha)console.log(`Commit: ${this.config.commitSha.substring(0,7)}`);if(this.config.repositoryUrl)console.log(`Repository: ${this.config.repositoryUrl}`)}else{console.log("Upload: Disabled")}console.log(`Report: ${this.reportPath}`);console.log("=".repeat(60));console.log("")}onTestBegin(t,e){if(this.ctrfReporter.onTestBegin){this.ctrfReporter.onTestBegin(t,e)}}onTestEnd(t,e){if(this.ctrfReporter.onTestEnd){this.ctrfReporter.onTestEnd(t,e)}}onError(t){if(this.ctrfReporter.onError){this.ctrfReporter.onError(t)}}onStepBegin(t,e,r){if(this.ctrfReporter.onStepBegin){this.ctrfReporter.onStepBegin(t,e,r)}}onStepEnd(t,e,r){if(this.ctrfReporter.onStepEnd){this.ctrfReporter.onStepEnd(t,e,r)}}async onEnd(t){if(this.ctrfReporter.onEnd){await this.ctrfReporter.onEnd(t)}if(!this.config.uploadEnabled||!this.uploader){console.log("");console.log("CTRF report generated");console.log(` ${this.reportPath}`);return}console.log("");console.log("=".repeat(60));console.log("Uploading Test Results");console.log("=".repeat(60));try{const t=await a.readFile(this.reportPath,"utf-8");const e=JSON.parse(t);e.results.tool.name="playwright";e.generatedBy="@testream/playwright-reporter";if(!e.extra){e.extra={}}if(this.config.branch&&!e.extra.branch){e.extra.branch=this.config.branch}if(this.config.commitSha&&!e.extra.commitSha){e.extra.commitSha=this.config.commitSha}const r=await this.uploader.uploadReport(e);if(r.success){console.log("=".repeat(60));console.log("Upload Complete");console.log("=".repeat(60));console.log("")}else{console.error("Upload completed with errors");if(r.error){console.error(`Error: ${r.error}`)}if(r.errorCode){console.error(`Error code: ${r.errorCode}`)}console.error("")}}catch(t){const e=t instanceof Error?t.message:String(t);console.error("");console.error("=".repeat(60));console.error("Upload Failed");console.error("=".repeat(60));console.error(`Error: ${e}`);console.error("");if(this.config.failOnUploadError){throw t}}}}e.PlaywrightCTRFReporterWithUpload=PlaywrightCTRFReporterWithUpload;e["default"]=PlaywrightCTRFReporterWithUpload},10:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:true});e.ReportUploader=void 0;const o=r(322);class ReportUploader{constructor(t){this.config={apiKey:t.apiKey,branch:t.branch,commitSha:t.commitSha,repositoryUrl:t.repositoryUrl,failOnUploadError:t.failOnUploadError??false,buildName:t.buildName,buildNumber:t.buildNumber,buildUrl:t.buildUrl,testEnvironment:t.testEnvironment,appName:t.appName,appVersion:t.appVersion,testType:t.testType}}async uploadReport(t){try{const e=await(0,o.uploadTestRun)({report:t,apiKey:this.config.apiKey,commitSha:this.config.commitSha,branch:this.config.branch,repositoryUrl:this.config.repositoryUrl,buildName:this.config.buildName,buildNumber:this.config.buildNumber,buildUrl:this.config.buildUrl,testEnvironment:this.config.testEnvironment,appName:this.config.appName,appVersion:this.config.appVersion,testType:this.config.testType});if(!e.success){if(this.config.failOnUploadError){throw new Error(e.error||"Upload failed")}return e}let r=0;if(!e.alreadyExists&&e.testRunId&&e.testResults){const i=(0,o.mapAttachmentsToTestResults)(t.results.tests,e.testResults);if(i.length>0){r=await(0,o.uploadArtifacts)({reportId:e.reportId,apiKey:this.config.apiKey,testResults:i})}}return{...e,artifactCount:r}}catch(e){const r=e instanceof Error?e.message:String(e);if(this.config.failOnUploadError){throw new Error(`Failed to upload report: ${r}`)}return{success:false,reportId:(0,o.ensureReportId)(t),error:r}}}}e.ReportUploader=ReportUploader},982:t=>{t.exports=require("crypto")},896:t=>{t.exports=require("fs")},943:t=>{t.exports=require("fs/promises")},928:t=>{t.exports=require("path")}};var e={};function __nccwpck_require__(r){var o=e[r];if(o!==undefined){return o.exports}var i=e[r]={exports:{}};var n=true;try{t[r].call(i.exports,i,i.exports,__nccwpck_require__);n=false}finally{if(n)delete e[r]}return i.exports}(()=>{var t=Object.getPrototypeOf?t=>Object.getPrototypeOf(t):t=>t.__proto__;var e;__nccwpck_require__.t=function(r,o){if(o&1)r=this(r);if(o&8)return r;if(typeof r==="object"&&r){if(o&4&&r.__esModule)return r;if(o&16&&typeof r.then==="function")return r}var i=Object.create(null);__nccwpck_require__.r(i);var n={};e=e||[null,t({}),t([]),t(t)];for(var s=o&2&&r;typeof s=="object"&&!~e.indexOf(s);s=t(s)){Object.getOwnPropertyNames(s).forEach((t=>n[t]=()=>r[t]))}n["default"]=()=>r;__nccwpck_require__.d(i,n);return i}})();(()=>{__nccwpck_require__.d=(t,e)=>{for(var r in e){if(__nccwpck_require__.o(e,r)&&!__nccwpck_require__.o(t,r)){Object.defineProperty(t,r,{enumerable:true,get:e[r]})}}}})();(()=>{__nccwpck_require__.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e)})();(()=>{__nccwpck_require__.r=t=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(t,"__esModule",{value:true})}})();if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r={};(()=>{var t=r;Object.defineProperty(t,"__esModule",{value:true});t.PlaywrightCTRFReporterWithUpload=t["default"]=void 0;var e=__nccwpck_require__(665);Object.defineProperty(t,"default",{enumerable:true,get:function(){return e.PlaywrightCTRFReporterWithUpload}});var o=__nccwpck_require__(665);Object.defineProperty(t,"PlaywrightCTRFReporterWithUpload",{enumerable:true,get:function(){return o.PlaywrightCTRFReporterWithUpload}})})();module.exports=r})();
1
+ (()=>{"use strict";var e={649:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});const i=n(r(928));const o=n(r(896));const s=n(r(982));class GenerateCtrfReport{constructor(e){var t,r,n,i,o,a,u,l,c,d,p,f,h,m,g,b,y,T,_;this.reporterName="playwright-ctrf-json-reporter";this.defaultOutputFile="ctrf-report.json";this.defaultOutputDir="ctrf";this.reporterConfigOptions={outputFile:(t=e===null||e===void 0?void 0:e.outputFile)!==null&&t!==void 0?t:this.defaultOutputFile,outputDir:(r=e===null||e===void 0?void 0:e.outputDir)!==null&&r!==void 0?r:this.defaultOutputDir,minimal:(n=e===null||e===void 0?void 0:e.minimal)!==null&&n!==void 0?n:false,screenshot:(i=e===null||e===void 0?void 0:e.screenshot)!==null&&i!==void 0?i:false,annotations:(o=e===null||e===void 0?void 0:e.annotations)!==null&&o!==void 0?o:false,testType:(a=e===null||e===void 0?void 0:e.testType)!==null&&a!==void 0?a:"e2e",appName:(u=e===null||e===void 0?void 0:e.appName)!==null&&u!==void 0?u:undefined,appVersion:(l=e===null||e===void 0?void 0:e.appVersion)!==null&&l!==void 0?l:undefined,osPlatform:(c=e===null||e===void 0?void 0:e.osPlatform)!==null&&c!==void 0?c:undefined,osRelease:(d=e===null||e===void 0?void 0:e.osRelease)!==null&&d!==void 0?d:undefined,osVersion:(p=e===null||e===void 0?void 0:e.osVersion)!==null&&p!==void 0?p:undefined,buildName:(f=e===null||e===void 0?void 0:e.buildName)!==null&&f!==void 0?f:undefined,buildNumber:(h=e===null||e===void 0?void 0:e.buildNumber)!==null&&h!==void 0?h:undefined,buildUrl:(m=e===null||e===void 0?void 0:e.buildUrl)!==null&&m!==void 0?m:undefined,repositoryName:(g=e===null||e===void 0?void 0:e.repositoryName)!==null&&g!==void 0?g:undefined,repositoryUrl:(b=e===null||e===void 0?void 0:e.repositoryUrl)!==null&&b!==void 0?b:undefined,branchName:(y=e===null||e===void 0?void 0:e.branchName)!==null&&y!==void 0?y:undefined,commit:(T=e===null||e===void 0?void 0:e.commit)!==null&&T!==void 0?T:undefined,testEnvironment:(_=e===null||e===void 0?void 0:e.testEnvironment)!==null&&_!==void 0?_:undefined};this.ctrfReport={reportFormat:"CTRF",specVersion:"0.0.0",reportId:s.default.randomUUID(),timestamp:(new Date).toISOString(),generatedBy:"playwright-ctrf-json-reporter",results:{tool:{name:"playwright"},summary:{tests:0,passed:0,failed:0,pending:0,skipped:0,other:0,start:0,stop:0},tests:[]}};this.ctrfEnvironment={}}onBegin(e,t){var r,n,i;this.suite=t;this.startTime=Date.now();this.ctrfReport.results.summary.start=this.startTime;if(!o.default.existsSync((r=this.reporterConfigOptions.outputDir)!==null&&r!==void 0?r:this.defaultOutputDir)){o.default.mkdirSync((n=this.reporterConfigOptions.outputDir)!==null&&n!==void 0?n:this.defaultOutputDir,{recursive:true})}this.setEnvironmentDetails(this.reporterConfigOptions);if(this.hasEnvironmentDetails(this.ctrfEnvironment)){this.ctrfReport.results.environment=this.ctrfEnvironment}this.setFilename((i=this.reporterConfigOptions.outputFile)!==null&&i!==void 0?i:this.defaultOutputFile)}onEnd(){this.ctrfReport.results.summary.stop=Date.now();if(this.suite!==undefined){if(this.suite.allTests().length>0){this.processSuite(this.suite);this.ctrfReport.results.summary.suites=this.countSuites(this.suite)}}this.writeReportToFile(this.ctrfReport)}printsToStdio(){return false}processSuite(e){for(const t of e.tests){this.processTest(t)}for(const t of e.suites){this.processSuite(t)}}processTest(e){if(e.results.length===0){return}const t=e.results[e.results.length-1];if(t!==undefined){this.updateCtrfTestResultsFromTestResult(e,t,this.ctrfReport);this.updateSummaryFromTestResult(t,this.ctrfReport)}}setFilename(e){if(e.endsWith(".json")){this.reporterConfigOptions.outputFile=e}else{this.reporterConfigOptions.outputFile=`${e}.json`}}updateCtrfTestResultsFromTestResult(e,t,r){var n,i,o,s,a,u;const l={name:e.title,status:t.status===e.expectedStatus&&t.status!=="skipped"?"passed":this.mapPlaywrightStatusToCtrf(t.status),duration:t.duration};if(this.reporterConfigOptions.minimal===false){l.start=this.updateStart(t.startTime);l.stop=this.calculateStopTime(t.startTime,t.duration);l.message=this.extractFailureDetails(t).message;l.trace=this.extractFailureDetails(t).trace;l.snippet=this.extractFailureDetails(t).snippet;l.rawStatus=t.status;l.tags=(n=e.tags)!==null&&n!==void 0?n:[];l.type=(i=this.reporterConfigOptions.testType)!==null&&i!==void 0?i:"e2e";l.filePath=e.location.file;l.retries=t.retry;l.flaky=t.status==="passed"&&t.retry>0;l.steps=[];if(t.steps.length>0){t.steps.forEach((e=>{this.processStep(l,e)}))}if(this.reporterConfigOptions.screenshot===true){l.screenshot=this.extractScreenshotBase64(t)}l.suite=this.buildSuitePath(e);if(((o=this.extractMetadata(t))===null||o===void 0?void 0:o.name)!==undefined||((s=this.extractMetadata(t))===null||s===void 0?void 0:s.version)!==undefined)l.browser=`${(a=this.extractMetadata(t))===null||a===void 0?void 0:a.name} ${(u=this.extractMetadata(t))===null||u===void 0?void 0:u.version}`;l.attachments=this.filterValidAttachments(t.attachments);l.stdout=t.stdout.map((e=>Buffer.isBuffer(e)?e.toString():String(e)));l.stderr=t.stderr.map((e=>Buffer.isBuffer(e)?e.toString():String(e)));if(this.reporterConfigOptions.annotations!==undefined){l.extra={annotations:e.annotations}}if(e.results.length>1){const t=e.results.slice(0,-1);l.retryAttempts=[];for(const e of t){const t={status:this.mapPlaywrightStatusToCtrf(e.status),duration:e.duration,message:this.extractFailureDetails(e).message,trace:this.extractFailureDetails(e).trace,snippet:this.extractFailureDetails(e).snippet};l.retryAttempts.push(t)}}}r.results.tests.push(l)}updateSummaryFromTestResult(e,t){t.results.summary.tests++;const r=this.mapPlaywrightStatusToCtrf(e.status);if(r in t.results.summary){t.results.summary[r]++}else{t.results.summary.other++}}mapPlaywrightStatusToCtrf(e){switch(e){case"passed":return"passed";case"failed":case"timedOut":case"interrupted":return"failed";case"skipped":return"skipped";case"pending":return"pending";default:return"other"}}setEnvironmentDetails(e){if(e.appName!==undefined){this.ctrfEnvironment.appName=e.appName}if(e.appVersion!==undefined){this.ctrfEnvironment.appVersion=e.appVersion}if(e.osPlatform!==undefined){this.ctrfEnvironment.osPlatform=e.osPlatform}if(e.osRelease!==undefined){this.ctrfEnvironment.osRelease=e.osRelease}if(e.osVersion!==undefined){this.ctrfEnvironment.osVersion=e.osVersion}if(e.buildName!==undefined){this.ctrfEnvironment.buildName=e.buildName}if(e.buildNumber!==undefined){this.ctrfEnvironment.buildNumber=e.buildNumber}if(e.buildUrl!==undefined){this.ctrfEnvironment.buildUrl=e.buildUrl}if(e.repositoryName!==undefined){this.ctrfEnvironment.repositoryName=e.repositoryName}if(e.repositoryUrl!==undefined){this.ctrfEnvironment.repositoryUrl=e.repositoryUrl}if(e.branchName!==undefined){this.ctrfEnvironment.branchName=e.branchName}if(e.commit!==undefined){this.ctrfEnvironment.commit=e.commit}if(e.testEnvironment!==undefined){this.ctrfEnvironment.testEnvironment=e.testEnvironment}}hasEnvironmentDetails(e){return Object.keys(e).length>0}extractMetadata(e){const t=e.attachments.find((e=>e.name==="metadata.json"));if((t===null||t===void 0?void 0:t.body)!==null&&(t===null||t===void 0?void 0:t.body)!==undefined){try{const e=t.body.toString("utf-8");return JSON.parse(e)}catch(e){if(e instanceof Error){console.error(`Error parsing browser metadata: ${e.message}`)}else{console.error("An unknown error occurred in parsing browser metadata")}}}return null}updateStart(e){const t=new Date(e);const r=Math.floor(t.getTime()/1e3);return r}calculateStopTime(e,t){const r=new Date(e);const n=new Date(r.getTime()+t);return Math.floor(n.getTime()/1e3)}buildSuitePath(e){const t=[];let r=e.parent;while(r!==undefined){if(r.title!==""){t.unshift(r.title)}r=r.parent}return t.join(" > ")}extractScreenshotBase64(e){var t;const r=e.attachments.find((e=>e.name==="screenshot"&&(e.contentType==="image/jpeg"||e.contentType==="image/png")));return(t=r===null||r===void 0?void 0:r.body)===null||t===void 0?void 0:t.toString("base64")}extractFailureDetails(e){if((e.status==="failed"||e.status==="timedOut"||e.status==="interrupted")&&e.error!==undefined){const t={};if(e.error.message!==undefined){t.message=e.error.message}if(e.error.stack!==undefined){t.trace=e.error.stack}if(e.error.snippet!==undefined){t.snippet=e.error.snippet}return t}return{}}countSuites(e){let t=0;e.suites.forEach((e=>{t+=this.countSuites(e)}));return t}writeReportToFile(e){var t,r;const n=i.default.join((t=this.reporterConfigOptions.outputDir)!==null&&t!==void 0?t:this.defaultOutputDir,(r=this.reporterConfigOptions.outputFile)!==null&&r!==void 0?r:this.defaultOutputFile);const s=JSON.stringify(e,null,2);try{o.default.writeFileSync(n,s+"\n");console.log(`${this.reporterName}: successfully written ctrf json to %s/%s`,this.reporterConfigOptions.outputDir,this.reporterConfigOptions.outputFile)}catch(e){console.error(`Error writing ctrf json report:, ${String(e)}`)}}processStep(e,t){var r;if(t.category==="test.step"){const n=t.error===undefined?this.mapPlaywrightStatusToCtrf("passed"):this.mapPlaywrightStatusToCtrf("failed");const i={name:t.title,status:n};(r=e.steps)===null||r===void 0?void 0:r.push(i)}const n=t.steps;if(n.length>0){n.forEach((t=>{this.processStep(e,t)}))}}filterValidAttachments(e){return e.filter((e=>e.path!==undefined)).map((e=>{var t;return{name:e.name,contentType:e.contentType,path:(t=e.path)!==null&&t!==void 0?t:""}}))}}t["default"]=GenerateCtrfReport},197:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var i=r(649);Object.defineProperty(t,"default",{enumerable:true,get:function(){return n(i).default}})},406:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.detectCIContext=detectCIContext;function removePrefix(e,t){if(!e){return undefined}return e.startsWith(t)?e.slice(t.length):e}function readEnvironment(){const e=globalThis;return e.process?.env??{}}function buildGithubRepositoryUrl(e){if(!e.GITHUB_SERVER_URL||!e.GITHUB_REPOSITORY){return undefined}return`${e.GITHUB_SERVER_URL}/${e.GITHUB_REPOSITORY}`}function buildGithubBuildUrl(e){if(!e.GITHUB_SERVER_URL||!e.GITHUB_REPOSITORY||!e.GITHUB_RUN_ID){return undefined}return`${e.GITHUB_SERVER_URL}/${e.GITHUB_REPOSITORY}/actions/runs/${e.GITHUB_RUN_ID}`}function detectGitHubBranch(e){if(e.GITHUB_HEAD_REF){return e.GITHUB_HEAD_REF}if(e.GITHUB_REF?.startsWith("refs/heads/")){return e.GITHUB_REF_NAME??removePrefix(e.GITHUB_REF,"refs/heads/")}return undefined}function detectGitHubActionsContext(e){return{branch:detectGitHubBranch(e),commitSha:e.GITHUB_SHA,repositoryUrl:buildGithubRepositoryUrl(e),buildNumber:e.GITHUB_RUN_NUMBER,buildUrl:buildGithubBuildUrl(e)}}function detectGitLabContext(e){return{branch:e.CI_COMMIT_BRANCH||e.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,commitSha:e.CI_COMMIT_SHA,repositoryUrl:e.CI_PROJECT_URL,buildNumber:e.CI_PIPELINE_IID,buildUrl:e.CI_PIPELINE_URL}}function detectAzurePipelinesContext(e){return{branch:removePrefix(e.BUILD_SOURCEBRANCH,"refs/heads/"),commitSha:e.BUILD_SOURCEVERSION,repositoryUrl:e.BUILD_REPOSITORY_URI,buildNumber:e.BUILD_BUILDNUMBER,buildUrl:e.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI&&e.SYSTEM_TEAMPROJECT&&e.BUILD_BUILDID?`${e.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${e.SYSTEM_TEAMPROJECT}/_build/results?buildId=${e.BUILD_BUILDID}`:undefined}}function detectCircleCIContext(e){return{branch:e.CIRCLE_BRANCH,commitSha:e.CIRCLE_SHA1,repositoryUrl:e.CIRCLE_REPOSITORY_URL,buildNumber:e.CIRCLE_BUILD_NUM,buildUrl:e.CIRCLE_BUILD_URL}}function detectJenkinsContext(e){return{branch:removePrefix(e.GIT_BRANCH,"origin/"),commitSha:e.GIT_COMMIT,repositoryUrl:e.GIT_URL,buildNumber:e.BUILD_NUMBER,buildUrl:e.BUILD_URL}}function detectBitbucketContext(e){return{branch:e.BITBUCKET_BRANCH,commitSha:e.BITBUCKET_COMMIT,repositoryUrl:e.BITBUCKET_GIT_HTTP_ORIGIN,buildNumber:e.BITBUCKET_BUILD_NUMBER,buildUrl:e.BITBUCKET_REPO_FULL_NAME&&e.BITBUCKET_BUILD_NUMBER?`https://bitbucket.org/${e.BITBUCKET_REPO_FULL_NAME}/pipelines/results/${e.BITBUCKET_BUILD_NUMBER}`:undefined}}const r=[{isMatch:e=>e.GITHUB_ACTIONS==="true",detect:detectGitHubActionsContext},{isMatch:e=>e.GITLAB_CI==="true",detect:detectGitLabContext},{isMatch:e=>e.TF_BUILD==="True",detect:detectAzurePipelinesContext},{isMatch:e=>e.CIRCLECI==="true",detect:detectCircleCIContext},{isMatch:e=>Boolean(e.JENKINS_URL),detect:detectJenkinsContext},{isMatch:e=>Boolean(e.BITBUCKET_BUILD_NUMBER),detect:detectBitbucketContext}];function detectCIContext(){const e=readEnvironment();for(const t of r){if(t.isMatch(e)){return t.detect(e)}}return{}}},827:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true})},322:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__exportStar||function(e,t){for(var r in e)if(r!=="default"&&!Object.prototype.hasOwnProperty.call(t,r))n(t,e,r)};Object.defineProperty(t,"__esModule",{value:true});t.createTestLocationCollector=t.enrichReportWithJsTestNameSourceSnippets=t.resolveSourceSnippetOptions=t.enrichReportWithSourceSnippets=t.ensureReportId=t.mapAttachmentsToTestResults=t.uploadArtifacts=t.uploadTestRun=t.detectCIContext=void 0;i(r(827),t);var o=r(406);Object.defineProperty(t,"detectCIContext",{enumerable:true,get:function(){return o.detectCIContext}});var s=r(969);Object.defineProperty(t,"uploadTestRun",{enumerable:true,get:function(){return s.uploadTestRun}});Object.defineProperty(t,"uploadArtifacts",{enumerable:true,get:function(){return s.uploadArtifacts}});Object.defineProperty(t,"mapAttachmentsToTestResults",{enumerable:true,get:function(){return s.mapAttachmentsToTestResults}});Object.defineProperty(t,"ensureReportId",{enumerable:true,get:function(){return s.ensureReportId}});var a=r(304);Object.defineProperty(t,"enrichReportWithSourceSnippets",{enumerable:true,get:function(){return a.enrichReportWithSourceSnippets}});Object.defineProperty(t,"resolveSourceSnippetOptions",{enumerable:true,get:function(){return a.resolveSourceSnippetOptions}});var u=r(913);Object.defineProperty(t,"enrichReportWithJsTestNameSourceSnippets",{enumerable:true,get:function(){return u.enrichReportWithJsTestNameSourceSnippets}});var l=r(293);Object.defineProperty(t,"createTestLocationCollector",{enumerable:true,get:function(){return l.createTestLocationCollector}})},913:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.enrichReportWithJsTestNameSourceSnippets=enrichReportWithJsTestNameSourceSnippets;const i=r(455);const o=n(r(760));const s=r(304);const a=3;const u=/\b(describe|it|test)(?:\.(only|skip))?\s*\(\s*(['"`])/g;async function enrichReportWithJsTestNameSourceSnippets(e,t){const r=(0,s.resolveSourceSnippetOptions)(t);const n=new Map;await Promise.all(e.results.tests.map((async e=>{if(e.snippet||!e.filePath){return}const t=o.default.resolve(r.sourceRoot,e.filePath);if(!isInsideSourceRoot(t,r.sourceRoot)){return}const i=await getCachedJsTestCandidates(t,n);if(!i){return}const s=rankCandidatesForTest(e,i).slice(0,a);if(s.length===0){return}e.line??(e.line=s[0].line);e.snippet=formatCandidateSnippet(s,r)})))}function getCachedJsTestCandidates(e,t){let r=t.get(e);if(!r){r=(0,i.readFile)(e,"utf-8").then((e=>scanJsTestCandidates(e))).catch((()=>undefined));t.set(e,r)}return r}function scanJsTestCandidates(e){const t=buildLineOffsets(e);const r=scanJsTestBlocks(e,t);const n=r.filter((e=>e.kind==="describe"));return r.filter((e=>e.kind==="test")).map((e=>{const t=n.filter((t=>t.startIndex<e.startIndex&&t.endIndex>=e.endIndex)).sort(((e,t)=>e.startIndex-t.startIndex)).map((e=>e.title));return{title:e.title,describeTitles:t,fullName:[...t,e.title].join(" ").trim(),line:e.startLine,snippet:e.snippet}}))}function scanJsTestBlocks(e,t){const r=[];u.lastIndex=0;let n;while((n=u.exec(e))!==null){if(isCommentedLine(e,n.index)){continue}const i=readQuotedTitle(e,n.index+n[0].length,n[3]);if(!i){continue}const o=skipWhitespaceAndFindComma(e,i.endIndex+1);if(o==null){continue}const s=n[1]==="describe"?"describe":"test";const a=n.index;const u=findCallbackOpenBrace(e,o+1);if(u==null){continue}const l=findMatchingBrace(e,u);if(l==null){continue}const c=findSnippetEndIndex(e,l);const d=e.slice(a,c).trim();if(!d){continue}r.push({kind:s,title:i.value.trim(),startIndex:a,endIndex:c,startLine:getLineNumber(t,a),snippet:d})}return r}function rankCandidatesForTest(e,t){const r=normalizeWhitespace(e.name);const n=normalizeDescribeChain(e.suite);const i=t.filter((e=>normalizeWhitespace(e.fullName)===r));if(i.length>0){return i}if(n){const e=t.filter((e=>normalizeWhitespace(e.title)===r&&normalizeWhitespace(e.describeTitles.join(" "))===n));if(e.length>0){return e}}const o=t.filter((e=>normalizeWhitespace(e.title)===r));if(o.length>0){return o}return t.filter((e=>{const t=normalizeWhitespace(e.title);if(!r.endsWith(t)){return false}const n=r.slice(0,r.length-t.length).trim();return n.length>0&&normalizeWhitespace(e.describeTitles.join(" "))===n}))}function formatCandidateSnippet(e,t){const r=e.length===1?e[0].snippet:e.map(((e,t)=>`Candidate ${t+1} (line ${e.line})\n${e.snippet}`)).join("\n\n");const n=r.split(/\r?\n/).slice(0,t.maxLines).join("\n").trim();if(n.length<=t.maxChars){return n}return n.slice(0,t.maxChars)}function findCallbackOpenBrace(e,t){for(let r=t;r<e.length;r++){const t=e[r];if(t==="'"||t==='"'||t==="`"){r=skipQuotedString(e,r);continue}if(t==="/"&&e[r+1]==="/"){r=skipLineComment(e,r+2);continue}if(t==="/"&&e[r+1]==="*"){r=skipBlockComment(e,r+2);continue}if(e.startsWith("=>",r)){return findNextBlockBrace(e,r+2)}if(startsWithWord(e,r,"function")){return findNextBlockBrace(e,r+"function".length)}if(t===";"){return undefined}}return undefined}function findNextBlockBrace(e,t){for(let r=t;r<e.length;r++){const t=e[r];if(t==="'"||t==='"'||t==="`"){r=skipQuotedString(e,r);continue}if(t==="{"){return r}if(t==="\n"&&looksLikeLineTerminator(e,r+1)){return undefined}}return undefined}function findMatchingBrace(e,t){let r=0;for(let n=t;n<e.length;n++){const t=e[n];if(t==="'"||t==='"'||t==="`"){n=skipQuotedString(e,n);continue}if(t==="/"&&e[n+1]==="/"){n=skipLineComment(e,n+2);continue}if(t==="/"&&e[n+1]==="*"){n=skipBlockComment(e,n+2);continue}if(t==="{"){r++;continue}if(t==="}"){r--;if(r===0){return n}}}return undefined}function readQuotedTitle(e,t,r){let n="";for(let i=t;i<e.length;i++){const t=e[i];if(t==="\\"){n+=t;if(i+1<e.length){i++;n+=e[i]}continue}if(t===r){return{value:n,endIndex:i}}if(t==="\n"&&r!=="`"){return undefined}n+=t}return undefined}function skipWhitespaceAndFindComma(e,t){for(let r=t;r<e.length;r++){const t=e[r];if(/\s/.test(t)){continue}return t===","?r:undefined}return undefined}function findSnippetEndIndex(e,t){let r=t+1;while(r<e.length){const t=e[r];if(t==="\r"||t==="\n"){return r}r++}return e.length}function skipQuotedString(e,t){const r=e[t];for(let n=t+1;n<e.length;n++){const t=e[n];if(t==="\\"){n++;continue}if(t===r){return n}}return e.length-1}function skipLineComment(e,t){for(let r=t;r<e.length;r++){if(e[r]==="\n"){return r}}return e.length-1}function skipBlockComment(e,t){for(let r=t;r<e.length-1;r++){if(e[r]==="*"&&e[r+1]==="/"){return r+1}}return e.length-1}function looksLikeLineTerminator(e,t){for(let r=t;r<e.length;r++){const t=e[r];if(!/\s/.test(t)){return t!=="."&&t!=="("}}return false}function buildLineOffsets(e){const t=[0];for(let r=0;r<e.length;r++){if(e[r]==="\n"){t.push(r+1)}}return t}function getLineNumber(e,t){let r=0;for(let n=0;n<e.length;n++){if(e[n]>t){break}r=n}return r+1}function isCommentedLine(e,t){const r=e.lastIndexOf("\n",t-1)+1;const n=e.slice(r,t).trimStart();return n.startsWith("//")||n.startsWith("*")}function startsWithWord(e,t,r){if(!e.startsWith(r,t)){return false}const n=t===0?"":e[t-1];const i=e[t+r.length]??"";return!isIdentifierChar(n)&&!isIdentifierChar(i)}function isIdentifierChar(e){return/[A-Za-z0-9_$]/.test(e)}function normalizeWhitespace(e){return(e??"").trim().replace(/\s+/g," ")}function normalizeDescribeChain(e){if(!e){return""}const t=e.split(">").map((e=>e.trim())).filter(Boolean);if(t.length===0){return""}const r=t[0].includes(".");const n=r?t.slice(1):t;return normalizeWhitespace(n.join(" "))}function isInsideSourceRoot(e,t){const r=o.default.relative(t,e);return r.length>0&&!r.startsWith("..")&&!o.default.isAbsolute(r)}},304:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.resolveSourceSnippetOptions=resolveSourceSnippetOptions;t.enrichReportWithSourceSnippets=enrichReportWithSourceSnippets;const i=r(455);const o=n(r(760));const s=2e3;const a=40;function resolveSourceSnippetOptions(e){return{sourceRoot:o.default.resolve(e?.sourceRoot??process.cwd()),maxChars:normalizePositiveInt(e?.maxChars,s),maxLines:normalizePositiveInt(e?.maxLines,a)}}async function enrichReportWithSourceSnippets(e,t){const r=resolveSourceSnippetOptions(t);const n=new Map;await Promise.all(e.results.tests.map((async e=>{if(e.snippet||!e.filePath||!e.line){return}const t=await tryExtractSnippet(e,r,n);if(t){e.snippet=t}})))}async function tryExtractSnippet(e,t,r){const n=o.default.resolve(t.sourceRoot,e.filePath);if(!isInsideSourceRoot(n,t.sourceRoot)){return undefined}const i=await getCachedFileContent(n,r);if(!i){return undefined}return extractEnclosingTestBlock(i,e.line,t)}function getCachedFileContent(e,t){let r=t.get(e);if(!r){r=(0,i.readFile)(e,"utf-8").catch((()=>undefined));t.set(e,r)}return r}function extractEnclosingTestBlock(e,t,r){const n=e.split(/\r?\n/);const i=Math.max(0,Math.min(n.length-1,t-1));const o=findTestStart(n,i);if(o==null){return undefined}const s=[];let a=0;let u=false;for(let e=o;e<n.length&&s.length<r.maxLines;e++){const t=n[e];s.push(t);for(const e of t){if(e==="{"){a++;u=true}else if(e==="}"){a--}}if(u&&a<=0&&isJsTestBlockTerminator(t)){break}}const l=s.join("\n").trim();if(!l){return undefined}return l.length<=r.maxChars?l:l.slice(0,r.maxChars)}function findTestStart(e,t){for(let r=t;r>=0;r--){if(/\b(?:test|it)(?:\.(?:only|skip|fixme|slow))?\s*\(/.test(e[r])){return r}}return undefined}function isJsTestBlockTerminator(e){let t=e.length-1;while(t>=0&&/\s/.test(e[t])){t--}if(t>=0&&e[t]===";"){t--}while(t>=0&&/\s/.test(e[t])){t--}if(t<1||e[t]!==")"){return false}t--;while(t>=0&&/\s/.test(e[t])){t--}return t>=0&&e[t]==="}"}function isInsideSourceRoot(e,t){const r=o.default.relative(t,e);return r.length>0&&!r.startsWith("..")&&!o.default.isAbsolute(r)}function normalizePositiveInt(e,t){return typeof e==="number"&&Number.isInteger(e)&&e>0?e:t}},293:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.createTestLocationCollector=createTestLocationCollector;function createTestLocationCollector(){const e=new Map;return{add(t,r){if(!t||!isValidLocation(r)){return}const n=e.get(t)??[];n.push(r);e.set(t,n)},applyToReport(t){const r=new Map([...e.entries()].map((([e,t])=>[e,[...t]])));for(const e of t.results.tests){const t=r.get(e.name);const n=t?.shift();if(!n){continue}e.filePath??(e.filePath=n.filePath);e.line??(e.line=n.line)}}}}function isValidLocation(e){return Boolean(e.filePath)&&Number.isInteger(e.line)&&e.line>0}},969:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t.ensureReportId=ensureReportId;t.uploadTestRun=uploadTestRun;t.mapAttachmentsToTestResults=mapAttachmentsToTestResults;t.uploadArtifacts=uploadArtifacts;const n=r(406);const i=r(304);const o="https://api.testream.app";function ensureReportId(e){if(typeof e.reportId==="string"&&e.reportId.trim().length>0){return e.reportId}const t=crypto.randomUUID();e.reportId=t;return t}function resolveApiUrl(e){const t=normalizeApiUrl(e);if(t){return t}const r=getEnvApiUrl();if(r){return r}return o}function getEnvApiUrl(){if(typeof process==="undefined"||!process?.env){return undefined}return normalizeApiUrl(process.env.TESTREAM_API_URL)}function normalizeApiUrl(e){if(!e){return undefined}const t=e.trim();if(!t){return undefined}let r=t;while(r.endsWith("/")){r=r.slice(0,-1)}return r}function isReportAlreadyExistsConflict(e){return e.errorCode==="report_already_exists"}function formatUploadError(e){const t=e.detail||e.title||e.rawBody||"Unknown error";const r=e.errorCode?`, code=${e.errorCode}`:"";return`Upload failed (HTTP ${e.statusCode}${r}): ${t}`}async function parseHttpError(e){const t=await e.text();const r=e.headers.get("content-type")||"";if(r.toLowerCase().includes("json")&&t.trim().length>0){try{const r=JSON.parse(t);return{statusCode:e.status,title:r.title,detail:r.detail||r.details||r.error,errorCode:r.errorCode,rawBody:t}}catch{}}return{statusCode:e.status,rawBody:t}}function resolveUploadContext(e){const t=(0,n.detectCIContext)();return{commitSha:e.commitSha??t.commitSha,branch:e.branch??t.branch,repositoryUrl:e.repositoryUrl??t.repositoryUrl,buildName:e.buildName,buildNumber:e.buildNumber??t.buildNumber,buildUrl:e.buildUrl??t.buildUrl,testEnvironment:e.testEnvironment,appName:e.appName,appVersion:e.appVersion,testType:e.testType}}async function uploadTestRun(e){const{report:t,apiKey:r}=e;const n=resolveApiUrl(e.apiUrl);const o=ensureReportId(t);const s=resolveUploadContext(e);await(0,i.enrichReportWithSourceSnippets)(t);const a={report:t,reportId:o,...s};console.log("Uploading test results...");let u;try{u=await fetch(`${n}/api/v1/ingest`,{method:"POST",headers:{"X-API-KEY":r,"Content-Type":"application/json"},body:JSON.stringify(a)})}catch(e){const t=e instanceof Error?e.message:String(e);const r=`Connection failed: ${t}`;console.error(r);return{success:false,reportId:o,error:r}}if(!u.ok){const e=await parseHttpError(u);if(u.status===409&&isReportAlreadyExistsConflict(e)){console.warn("Report already exists (workflow may have been re-run)");return{success:true,reportId:o,summary:{passed:t.results.summary.passed,failed:t.results.summary.failed,skipped:t.results.summary.skipped,total:t.results.summary.tests},alreadyExists:true,statusCode:e.statusCode,errorCode:e.errorCode}}const r=formatUploadError(e);console.error(r);return{success:false,reportId:o,error:r,statusCode:e.statusCode,errorCode:e.errorCode,errorDetail:e.detail||e.rawBody}}const l=await u.json();console.log(`✓ Test results uploaded successfully`);console.log(` Report ID: ${l.reportId}`);console.log(` Test Run ID: ${l.testRunId}`);console.log(` Tests: ${l.summary.passed}/${l.summary.total} passed`);return{success:true,reportId:l.reportId,testRunId:l.testRunId,summary:{passed:l.summary.passed,failed:l.summary.failed,skipped:l.summary.skipped,total:l.summary.total},testResults:l.testResults}}function mapAttachmentsToTestResults(e,t){const r=new Map;for(const e of t){const t=r.get(e.name)??[];t.push(e.id);r.set(e.name,t)}const n=[];for(const t of e){const e=r.get(t.name);const i=e?.shift();if(!t.attachments||t.attachments.length===0){continue}if(!i){console.warn(`Skipping artifact upload: could not match test result for "${t.name}"`);continue}n.push({testResultId:i,attachments:t.attachments})}return n}async function uploadArtifacts(e){const{reportId:t,apiKey:r,testResults:n}=e;const i=resolveApiUrl(e.apiUrl);let o=0;for(const e of n){for(const n of e.attachments){try{const s=await uploadSingleArtifact({testResultId:e.testResultId,attachment:n,reportId:t,apiKey:r,apiUrl:i});if(s)o++}catch(e){const t=e instanceof Error?e.message:String(e);console.error(`Failed to upload artifact ${n.name}: ${t}`)}}}if(o>0){console.log(`✓ Uploaded ${o} artifact(s)`)}return o}async function uploadSingleArtifact(e){const{testResultId:t,attachment:n,reportId:i,apiKey:o,apiUrl:s}=e;const a=await Promise.resolve().then(r.t.bind(r,455,23));const u=await Promise.resolve().then(r.t.bind(r,760,23));const l=u.resolve(n.path);try{await a.access(l)}catch{console.warn(`Artifact not found: ${u.basename(l)}`);return false}let c;let d;const p=u.basename(l);const f=n.contentType||"application/octet-stream";try{c=await a.readFile(l);d=c.byteLength}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`Failed to read file: ${t}`)}try{return await uploadWithPresignedUrl({testResultId:t,reportId:i,apiKey:o,apiUrl:s,attachmentName:n.name,fileName:p,contentType:f,sizeBytes:d,fileBuffer:c})}catch(e){if(!(e instanceof LegacyUploadRequiredError)){throw e}return await uploadWithLegacyEndpoint({testResultId:t,attachmentName:n.name,reportId:i,apiKey:o,apiUrl:s,fileName:p,contentType:f,fileBuffer:c})}}class LegacyUploadRequiredError extends Error{constructor(){super("Legacy upload endpoint required")}}async function uploadWithPresignedUrl(e){const{testResultId:t,reportId:r,apiKey:n,apiUrl:i,attachmentName:o,fileName:s,contentType:a,sizeBytes:u,fileBuffer:l}=e;const c={testResultId:t,ctrfAttachmentName:o,fileName:s,contentType:a,sizeBytes:u};const d=await fetch(`${i}/api/v1/artifacts/${r}/upload-url`,{method:"POST",headers:{"X-API-KEY":n,"Content-Type":"application/json"},body:JSON.stringify(c)});if(shouldFallbackToLegacyUpload(d.status)){throw new LegacyUploadRequiredError}if(!d.ok){const e=await d.text();throw new Error(`Failed to create direct upload URL (HTTP ${d.status}): ${e}`)}const p=await d.json();const f={...p.requiredHeaders};if(!hasHeaderIgnoreCase(f,"Content-Type")){f["Content-Type"]=a}const h=await fetch(p.uploadUrl,{method:"PUT",headers:f,body:l});if(!h.ok){const e=await h.text();throw new Error(`Direct artifact upload failed (HTTP ${h.status}): ${e}`)}const m={testResultId:t,ctrfAttachmentName:o,fileName:s,contentType:a,sizeBytes:u,storageKey:p.storageKey};const g=await fetch(`${i}/api/v1/artifacts/${r}/complete`,{method:"POST",headers:{"X-API-KEY":n,"Content-Type":"application/json"},body:JSON.stringify(m)});if(!g.ok){const e=await g.text();throw new Error(`Failed to finalize artifact upload (HTTP ${g.status}): ${e}`)}return true}async function uploadWithLegacyEndpoint(e){const{testResultId:t,attachmentName:r,reportId:n,apiKey:i,apiUrl:o,fileName:s,contentType:a,fileBuffer:u}=e;const l=new Blob([new Uint8Array(u)],{type:a});const c=new FormData;c.append("testResultId",t);c.append("ctrfAttachmentName",r);c.append("file",l,s);const d=await fetch(`${o}/api/v1/artifacts/${n}`,{method:"POST",headers:{"X-API-KEY":i},body:c});if(!d.ok){const e=await d.text();throw new Error(`Legacy artifact upload failed (HTTP ${d.status}): ${e}`)}return true}function shouldFallbackToLegacyUpload(e){return e===404||e===405||e===501}function hasHeaderIgnoreCase(e,t){const r=t.toLowerCase();return Object.keys(e).some((e=>e.toLowerCase()===r))}},665:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var o=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),o=0;o<r.length;o++)if(r[o]!=="default")n(t,e,r[o]);i(t,e);return t}}();var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.PlaywrightCTRFReporterWithUpload=void 0;const a=o(r(943));const u=o(r(928));const l=r(322);const c=r(10);const d=s(r(197));class PlaywrightCTRFReporterWithUpload{constructor(e){this.testLocations=(0,l.createTestLocationCollector)();if(!e.apiKey){throw new Error("PlaywrightCTRFReporter: apiKey is required")}this.config={uploadEnabled:true,outputFile:"ctrf-report.json",outputDir:"ctrf",failOnUploadError:false,screenshot:true,annotations:false,testType:"e2e",...e};const t=(0,l.detectCIContext)();if(!this.config.branch&&t.branch){this.config.branch=t.branch}if(!this.config.commitSha&&t.commitSha){this.config.commitSha=t.commitSha}if(!this.config.repositoryUrl&&t.repositoryUrl){this.config.repositoryUrl=t.repositoryUrl}if(!this.config.buildNumber&&t.buildNumber){this.config.buildNumber=t.buildNumber}if(!this.config.buildUrl&&t.buildUrl){this.config.buildUrl=t.buildUrl}this.reportPath=u.join(this.config.outputDir,this.config.outputFile);const r={outputFile:this.config.outputFile,outputDir:this.config.outputDir,screenshot:this.config.screenshot,annotations:this.config.annotations,testType:this.config.testType};if(this.config.appName)r.appName=this.config.appName;if(this.config.appVersion)r.appVersion=this.config.appVersion;if(this.config.buildName)r.buildName=this.config.buildName;if(this.config.buildNumber)r.buildNumber=this.config.buildNumber;if(this.config.buildUrl)r.buildUrl=this.config.buildUrl;if(this.config.testEnvironment)r.testEnvironment=this.config.testEnvironment;if(this.config.branch)r.branchName=this.config.branch;if(this.config.commitSha)r.commit=this.config.commitSha;this.ctrfReporter=new d.default(r);this.uploader=this.config.uploadEnabled?new c.ReportUploader(this.config):null}onBegin(e,t){if(this.ctrfReporter.onBegin){this.ctrfReporter.onBegin(e,t)}console.log("");console.log("=".repeat(60));console.log("Playwright Test Manager Reporter");console.log("=".repeat(60));if(this.config.uploadEnabled){if(this.config.branch)console.log(`Branch: ${this.config.branch}`);if(this.config.commitSha)console.log(`Commit: ${this.config.commitSha.substring(0,7)}`);if(this.config.repositoryUrl)console.log(`Repository: ${this.config.repositoryUrl}`)}else{console.log("Upload: Disabled")}console.log(`Report: ${this.reportPath}`);console.log("=".repeat(60));console.log("")}onTestBegin(e,t){if(this.ctrfReporter.onTestBegin){this.ctrfReporter.onTestBegin(e,t)}}onTestEnd(e,t){this.captureTestLocation(e);if(this.ctrfReporter.onTestEnd){this.ctrfReporter.onTestEnd(e,t)}}onError(e){if(this.ctrfReporter.onError){this.ctrfReporter.onError(e)}}onStepBegin(e,t,r){if(this.ctrfReporter.onStepBegin){this.ctrfReporter.onStepBegin(e,t,r)}}onStepEnd(e,t,r){if(this.ctrfReporter.onStepEnd){this.ctrfReporter.onStepEnd(e,t,r)}}async onEnd(e){if(this.ctrfReporter.onEnd){await this.ctrfReporter.onEnd(e)}if(!this.config.uploadEnabled||!this.uploader){console.log("");console.log("CTRF report generated");console.log(` ${this.reportPath}`);return}console.log("");console.log("=".repeat(60));console.log("Uploading Test Results");console.log("=".repeat(60));try{const e=await this.readReport();this.enrichReportWithGitContext(e);this.enrichReportWithTestLocations(e);await this.handleUpload(e)}catch(e){const t=e instanceof Error?e.message:String(e);console.error("");console.error("=".repeat(60));console.error("Upload Failed");console.error("=".repeat(60));console.error(`Error: ${t}`);console.error("");if(this.config.failOnUploadError){throw e}}}async readReport(){const e=await a.readFile(this.reportPath,"utf-8");return JSON.parse(e)}enrichReportWithGitContext(e){e.results.tool.name="playwright";e.generatedBy="@testream/playwright-reporter";e.extra??(e.extra={});if(this.config.branch&&!e.extra.branch)e.extra.branch=this.config.branch;if(this.config.commitSha&&!e.extra.commitSha)e.extra.commitSha=this.config.commitSha}captureTestLocation(e){const t=e.location;if(!t?.file||!t.line){return}this.testLocations.add(e.title,{filePath:t.file,line:t.line})}enrichReportWithTestLocations(e){this.testLocations.applyToReport(e)}async handleUpload(e){if(!this.uploader){return}const t=await this.uploader.uploadReport(e);if(t.success){console.log("=".repeat(60));console.log("Upload Complete");console.log("=".repeat(60));console.log("");return}console.error("Upload completed with errors");if(t.error)console.error(`Error: ${t.error}`);if(t.errorCode)console.error(`Error code: ${t.errorCode}`);console.error("")}}t.PlaywrightCTRFReporterWithUpload=PlaywrightCTRFReporterWithUpload;t["default"]=PlaywrightCTRFReporterWithUpload},10:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t.ReportUploader=void 0;const n=r(322);class ReportUploader{constructor(e){this.config={apiKey:e.apiKey,branch:e.branch,commitSha:e.commitSha,repositoryUrl:e.repositoryUrl,failOnUploadError:e.failOnUploadError??false,buildName:e.buildName,buildNumber:e.buildNumber,buildUrl:e.buildUrl,testEnvironment:e.testEnvironment,appName:e.appName,appVersion:e.appVersion,testType:e.testType}}async uploadReport(e){try{const t=await(0,n.uploadTestRun)({report:e,apiKey:this.config.apiKey,commitSha:this.config.commitSha,branch:this.config.branch,repositoryUrl:this.config.repositoryUrl,buildName:this.config.buildName,buildNumber:this.config.buildNumber,buildUrl:this.config.buildUrl,testEnvironment:this.config.testEnvironment,appName:this.config.appName,appVersion:this.config.appVersion,testType:this.config.testType});if(!t.success){if(this.config.failOnUploadError){throw new Error(t.error||"Upload failed")}return t}let r=0;if(!t.alreadyExists&&t.testRunId&&t.testResults){const i=(0,n.mapAttachmentsToTestResults)(e.results.tests,t.testResults);if(i.length>0){r=await(0,n.uploadArtifacts)({reportId:t.reportId,apiKey:this.config.apiKey,testResults:i})}}return{...t,artifactCount:r}}catch(t){const r=t instanceof Error?t.message:String(t);if(this.config.failOnUploadError){throw new Error(`Failed to upload report: ${r}`)}return{success:false,reportId:(0,n.ensureReportId)(e),error:r}}}}t.ReportUploader=ReportUploader},982:e=>{e.exports=require("crypto")},896:e=>{e.exports=require("fs")},943:e=>{e.exports=require("fs/promises")},455:e=>{e.exports=require("node:fs/promises")},760:e=>{e.exports=require("node:path")},928:e=>{e.exports=require("path")}};var t={};function __nccwpck_require__(r){var n=t[r];if(n!==undefined){return n.exports}var i=t[r]={exports:{}};var o=true;try{e[r].call(i.exports,i,i.exports,__nccwpck_require__);o=false}finally{if(o)delete t[r]}return i.exports}(()=>{var e=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;var t;__nccwpck_require__.t=function(r,n){if(n&1)r=this(r);if(n&8)return r;if(typeof r==="object"&&r){if(n&4&&r.__esModule)return r;if(n&16&&typeof r.then==="function")return r}var i=Object.create(null);__nccwpck_require__.r(i);var o={};t=t||[null,e({}),e([]),e(e)];for(var s=n&2&&r;typeof s=="object"&&!~t.indexOf(s);s=e(s)){Object.getOwnPropertyNames(s).forEach((e=>o[e]=()=>r[e]))}o["default"]=()=>r;__nccwpck_require__.d(i,o);return i}})();(()=>{__nccwpck_require__.d=(e,t)=>{for(var r in t){if(__nccwpck_require__.o(t,r)&&!__nccwpck_require__.o(e,r)){Object.defineProperty(e,r,{enumerable:true,get:t[r]})}}}})();(()=>{__nccwpck_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();(()=>{__nccwpck_require__.r=e=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})}})();if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r={};(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:true});e.PlaywrightCTRFReporterWithUpload=e["default"]=void 0;var t=__nccwpck_require__(665);Object.defineProperty(e,"default",{enumerable:true,get:function(){return t.PlaywrightCTRFReporterWithUpload}});var n=__nccwpck_require__(665);Object.defineProperty(e,"PlaywrightCTRFReporterWithUpload",{enumerable:true,get:function(){return n.PlaywrightCTRFReporterWithUpload}})})();module.exports=r})();
@@ -4,10 +4,11 @@ import { PlaywrightCTRFReporterConfig } from './types';
4
4
  * Playwright Reporter that generates CTRF reports and uploads them to a backend API
5
5
  */
6
6
  export declare class PlaywrightCTRFReporterWithUpload implements Reporter {
7
- private config;
8
- private ctrfReporter;
9
- private uploader;
10
- private reportPath;
7
+ private readonly config;
8
+ private readonly ctrfReporter;
9
+ private readonly uploader;
10
+ private readonly reportPath;
11
+ private readonly testLocations;
11
12
  constructor(config: PlaywrightCTRFReporterConfig);
12
13
  /**
13
14
  * Called once before running tests
@@ -37,6 +38,11 @@ export declare class PlaywrightCTRFReporterWithUpload implements Reporter {
37
38
  * Called after all tests have been run
38
39
  */
39
40
  onEnd(result: FullResult): Promise<void>;
41
+ private readReport;
42
+ private enrichReportWithGitContext;
43
+ private captureTestLocation;
44
+ private enrichReportWithTestLocations;
45
+ private handleUpload;
40
46
  }
41
47
  export default PlaywrightCTRFReporterWithUpload;
42
48
  //# sourceMappingURL=reporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACX,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAMvD;;GAEG;AACH,qBAAa,gCAAiC,YAAW,QAAQ;IAC/D,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,4BAA4B;IAkEhD;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAqB/C;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAMtD;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAMpD;;OAEG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAM5B;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAMjE;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAM/D;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAuE/C;AAED,eAAe,gCAAgC,CAAC"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACX,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAMvD;;GAEG;AACH,qBAAa,gCAAiC,YAAW,QAAQ;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwD;gBAE1E,MAAM,EAAE,4BAA4B;IAgEhD;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAqB/C;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAMtD;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAQpD;;OAEG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAM5B;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAMjE;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAM/D;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAwChC,UAAU;IAKxB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,6BAA6B;YAIvB,YAAY;CAoB3B;AAED,eAAe,gCAAgC,CAAC"}
@@ -4,7 +4,7 @@ import { PlaywrightCTRFReporterConfig } from './types';
4
4
  * Upload CTRF report and artifacts to the backend API
5
5
  */
6
6
  export declare class ReportUploader {
7
- private config;
7
+ private readonly config;
8
8
  constructor(config: PlaywrightCTRFReporterConfig);
9
9
  /**
10
10
  * Upload CTRF report to the backend
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EAKb,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAEvD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAMV;gBAEQ,MAAM,EAAE,4BAA4B;IAiBhD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;CA4D9D"}
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EAKb,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAEvD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAenB;gBAEQ,MAAM,EAAE,4BAA4B;IAiBhD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;CA4D9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testream/playwright-reporter",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Playwright plugin to upload test results to Testream",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",