@testrelic/maestro-analytics 1.4.1-next.145 → 1.4.1-next.153
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/cli.cjs +2 -2
- package/dist/index.cjs +10 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -5418,8 +5418,8 @@ async function orchestrateReport(input) {
|
|
|
5418
5418
|
for (const logFile of logFiles) {
|
|
5419
5419
|
let mtimeDate;
|
|
5420
5420
|
try {
|
|
5421
|
-
const { statSync:
|
|
5422
|
-
mtimeDate =
|
|
5421
|
+
const { statSync: statSync4 } = await import("fs");
|
|
5422
|
+
mtimeDate = statSync4(logFile).mtime;
|
|
5423
5423
|
} catch {
|
|
5424
5424
|
}
|
|
5425
5425
|
const entries = parseLogFile(logFile, mtimeDate);
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';var core=require('@testrelic/core'),fs=require('fs'),path=require('path'),fastXmlParser=require('fast-xml-parser'),yaml=require('yaml'),child_process=require('child_process'),os=require('os'),crypto=require('crypto'),url=require('url'),zlib=require('zlib'),stream=require('stream');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var xt=".testrelic",Ur="testrelic-config.json",zr=".testrelic",Hr=5,$r=new Set(["__proto__","constructor","prototype"]),he=Object.freeze({apiKey:null,endpoint:"https://platform.testrelic.ai/api/v1",uploadStrategy:"batch",timeout:3e4,projectName:null,queueMaxAge:6048e5,queueDirectory:`${xt}/queue`,uploadArtifacts:true,artifactMaxSizeMb:50}),Br={s:1e3,m:60*1e3,h:3600*1e3,d:1440*60*1e3};function ve(e){let t=path.resolve(e);for(let r=0;r<=Hr;r++){let o=path.join(t,xt,Ur);if(fs.existsSync(o))try{if(fs.statSync(o).isFile())return o}catch{}let n=path.join(t,zr);if(fs.existsSync(n))try{if(fs.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.
|
|
2
|
-
`),n}catch{}let s=path.dirname(t);if(s===t)break;t=s;}return null}function xe(e){try{let t=fs.readFileSync(e,"utf-8"),r=JSON.parse(t);return typeof r!="object"||r===null||Array.isArray(r)||!yt(r)?null:r}catch{return null}}function yt(e){for(let t of Object.keys(e)){if($r.has(t))return false;let r=e[t];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!yt(r))return false}return true}function Y(e){let t=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(e);if(t)return process.env[t[1]]??null;let r=/^\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(e);return r?process.env[r[1]]??null:e}function X(e){let t=Object.create(null);for(let r of Object.keys(e)){let o=e[r];typeof o=="string"&&o.startsWith("$")?t[r]=Y(o):typeof o=="object"&&o!==null&&!Array.isArray(o)?t[r]=X(o):t[r]=o;}return t}function be(e){let t=/^(\d+)\s*([smhd])$/.exec(e.trim());if(!t)return null;let r=parseInt(t[1],10),o=t[2],n=Br[o];return !n||r<=0?null:r*n}function ye(e,t){let r=Object.create(null);if(Object.assign(r,he),e){let l=e.cloud;l&&typeof l=="object"&&(typeof l.endpoint=="string"&&(r.endpoint=l.endpoint),typeof l.upload=="string"&&(r.uploadStrategy=l.upload),typeof l.timeout=="number"&&(r.timeout=l.timeout),typeof l.apiKey=="string"&&l.apiKey.length>0&&(r.apiKey=l.apiKey));let c=e["testrelic-repo"]??e.project;c&&typeof c=="object"&&typeof c.name=="string"&&(r.projectName=c.name);let d=e.queue;if(d&&typeof d=="object"){if(typeof d.maxAge=="string"){let p=be(d.maxAge);p!==null&&(r.queueMaxAge=p);}typeof d.directory=="string"&&(r.queueDirectory=d.directory);}}if(t){if(typeof t.apiKey=="string"&&t.apiKey.length>0){let l=t.apiKey.startsWith("$")?Y(t.apiKey):t.apiKey;l&&(r.apiKey=l);}if(typeof t.endpoint=="string"){let l=t.endpoint.startsWith("$")?Y(t.endpoint):t.endpoint;l&&(r.endpoint=l);}if(typeof t.upload=="string"&&(r.uploadStrategy=t.upload),typeof t.timeout=="number"&&(r.timeout=t.timeout),typeof t.projectName=="string"&&(r.projectName=t.projectName),typeof t.queueMaxAge=="string"){let l=be(t.queueMaxAge);l!==null&&(r.queueMaxAge=l);}typeof t.queueDirectory=="string"&&(r.queueDirectory=t.queueDirectory),typeof t.uploadArtifacts=="boolean"&&(r.uploadArtifacts=t.uploadArtifacts),typeof t.artifactMaxSizeMb=="number"&&(r.artifactMaxSizeMb=t.artifactMaxSizeMb);}let o=process.env.TESTRELIC_API_KEY;o&&o.length>0&&(r.apiKey=o);let n=process.env.TESTRELIC_CLOUD_ENDPOINT;n&&core.isValidEndpointUrl(n)&&(r.endpoint=n);let s=process.env.TESTRELIC_UPLOAD_STRATEGY;s&&["batch","realtime","both"].includes(s)&&(r.uploadStrategy=s);let i=process.env.TESTRELIC_CLOUD_TIMEOUT;if(i){let l=parseInt(i,10);!isNaN(l)&&l>=1e3&&l<=12e4&&(r.timeout=l);}let a=Object.freeze(r);return core.isValidCloudConfig(a)?a:he}var qr=["authorization","cookie","set-cookie","x-api-key"],Vr=["password","secret","token","apiKey","api_key"],Jr=1024*1024;function Kr(e){let t=e??{},r=process.env.TESTRELIC_CAPTURE_NETWORK==="1"||process.env.TESTRELIC_CAPTURE_NETWORK?.toLowerCase()==="true";return Object.freeze({enabled:t.enabled??r??false,proxyPort:t.proxyPort??(process.env.TESTRELIC_PROXY_PORT?Number.parseInt(process.env.TESTRELIC_PROXY_PORT,10):8080),proxyHost:t.proxyHost??process.env.TESTRELIC_PROXY_HOST??"127.0.0.1",harPath:t.harPath??process.env.TESTRELIC_HAR_PATH??null,outputDir:t.outputDir??null,skipCertInstall:t.skipCertInstall??false,includeUrls:Object.freeze(t.includeUrls?[...t.includeUrls]:[]),excludeUrls:Object.freeze(t.excludeUrls?[...t.excludeUrls]:[]),redactHeaders:Object.freeze(t.redactHeaders?[...t.redactHeaders]:[...qr]),redactBodyFields:Object.freeze(t.redactBodyFields?[...t.redactBodyFields]:[...Vr]),maxBodyBytes:t.maxBodyBytes??Jr})}var Wr=new Set(["__proto__","constructor","prototype"]);function wt(e){if(typeof e!="object"||e===null)return false;for(let t of Object.keys(e))if(Wr.has(t))return true;return false}function Yr(e){if(typeof e!="object"||e===null||wt(e))return false;let t=e;return !(t.outputPath!==void 0&&typeof t.outputPath!="string"||t.htmlReportPath!==void 0&&typeof t.htmlReportPath!="string"||t.openReport!==void 0&&typeof t.openReport!="boolean"||t.includeScreenshots!==void 0&&typeof t.includeScreenshots!="boolean"||t.includeVideo!==void 0&&typeof t.includeVideo!="boolean"||t.includeAiAnalysis!==void 0&&typeof t.includeAiAnalysis!="boolean"||t.includeLogs!==void 0&&typeof t.includeLogs!="boolean"||t.includeFlowMetadata!==void 0&&typeof t.includeFlowMetadata!="boolean"||t.quiet!==void 0&&typeof t.quiet!="boolean"||t.metadata!==void 0&&t.metadata!==null&&(typeof t.metadata!="object"||wt(t.metadata)))}function Xr(e){if(e!==void 0&&!Yr(e))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid Maestro reporter configuration");let t=Object.create(null),r=e?.outputPath??"./test-results/testrelic-maestro.json";return t.outputPath=r,t.htmlReportPath=e?.htmlReportPath??r.replace(/\.json$/,".html"),t.openReport=e?.openReport??true,t.includeScreenshots=e?.includeScreenshots??true,t.includeVideo=e?.includeVideo??true,t.includeAiAnalysis=e?.includeAiAnalysis??true,t.includeLogs=e?.includeLogs??true,t.includeFlowMetadata=e?.includeFlowMetadata??true,t.flowsDir=e?.flowsDir??null,t.testRunId=e?.testRunId??null,t.metadata=e?.metadata??null,t.quiet=e?.quiet??false,t.reportMode=e?.reportMode??"batch",t.cloud=Qr(e?.cloud??null),t.network=Kr(e?.network),Object.freeze(t)}function Qr(e){let t=ve(process.cwd()),r=t?xe(t):null,o=r?X(r):null,n=ye(o,e??void 0);return n.apiKey?n:null}var q="1.1.0";var to=new fastXmlParser.XMLParser({ignoreAttributes:false,attributeNamePrefix:"@_",allowBooleanAttributes:true,parseAttributeValue:true,trimValues:true});function Q(e){return e==null?[]:Array.isArray(e)?e:[e]}function Ct(e){return !e||typeof e!="object"?[]:Q(e.property).map(o=>({name:String(o["@_name"]??""),value:String(o["@_value"]??"")}))}function ro(e){let t=String(e["@_name"]??"unnamed"),r=String(e["@_classname"]??t),o=Number(e["@_time"]??0),n=e["@_id"]!=null?String(e["@_id"]):null,s=String(e["@_status"]??"").toUpperCase(),i=e.failure,a=e.error,l=e.skipped!==void 0,c="SUCCESS";return i?c="FAILURE":a?c="ERROR":l?c="SKIPPED":s==="FAILURE"||s==="FAILED"?c="FAILURE":s==="ERROR"?c="ERROR":s==="SKIPPED"&&(c="SKIPPED"),{id:n,name:t,classname:r,time:o,status:c,failureMessage:i?String(i["@_message"]??i["#text"]??""):null,failureType:i?String(i["@_type"]??""):null,errorMessage:a?String(a["@_message"]??a["#text"]??""):null,errorType:a?String(a["@_type"]??""):null,properties:Ct(e.properties)}}function kt(e){let t=String(e["@_name"]??"Test Suite"),r=e["@_device"]!=null?String(e["@_device"]):null,o=Number(e["@_tests"]??0),n=Number(e["@_failures"]??0),s=Number(e["@_errors"]??0),i=Number(e["@_skipped"]??0),a=Number(e["@_time"]??0),c=Q(e.testcase).map(ro);return {name:t,device:r,tests:o,failures:n,errors:s,skipped:i,time:a,testCases:c,properties:Ct(e.properties)}}function Rt(e){let t=to.parse(e),r=[];if(t.testsuites){let l=t.testsuites;r=Q(l.testsuite).map(kt);}else t.testsuite&&(r=Q(t.testsuite).map(kt));let o=0,n=0,s=0,i=0,a=0;for(let l of r)o+=l.tests,n+=l.failures,s+=l.errors,i+=l.skipped,a+=l.time;return {testSuites:r,totalTests:o,totalFailures:n,totalErrors:s,totalSkipped:i,totalTime:a}}function we(e){let t=fs.readFileSync(e,"utf-8");return Rt(t)}var lo=new Set(["tapOn","doubleTapOn","longPressOn","inputText","eraseText","pasteText","swipe","scroll","scrollUntilVisible","hideKeyboard","pressKey","setClipboard","copyTextFrom"]),co=new Set(["assertVisible","assertNotVisible","assertTrue","assertScreenshot","assertNoDefectsWithAI","assertWithAI","assertCondition"]),po=new Set(["launchApp","killApp","stopApp","clearState","openLink","back","clearKeychain"]),uo=new Set(["setAirplaneMode","toggleAirplaneMode","setLocation","setOrientation","setPermissions","addMedia","travel"]),fo=new Set(["takeScreenshot","startRecording","stopRecording"]),go=new Set(["runScript","evalScript"]),mo=new Set(["runFlow","repeat","retry","waitForAnimationToEnd","extendedWaitUntil"]),ho=new Set(["assertWithAI","assertNoDefectsWithAI","extractTextWithAI"]),bo=new Set(["inputText","pasteText"]),vo=200,xo=400;function Et(e){return ho.has(e)?"ai":co.has(e)?"assertion":lo.has(e)?"interaction":po.has(e)?"navigation":uo.has(e)?"device":fo.has(e)?"media":go.has(e)?"script":mo.has(e)?"flow_control":"other"}var yo={tapOnElement:"tapOn",assertCondition:"assertVisible",backPress:"back",applyConfiguration:"applyConfiguration",defineVariables:"defineVariables"};function St(e){let t=e.replace(/Command$/,"");return yo[t]??t}var wo=new Set(["metadata","command","commandName","name","status","duration","durationMs","timestamp","time","error","errorMessage","selector","commands","subSteps","children","sequenceNumber"]);function ko(e){for(let t of Object.keys(e)){if(wo.has(t))continue;let r=e[t];if(r&&typeof r=="object"&&!Array.isArray(r))return t}}function Tt(e){if(e.selector&&typeof e.selector=="object"){let t=e.selector;if(typeof t.textRegex=="string")return t.textRegex;if(typeof t.text=="string")return t.text;if(typeof t.id=="string")return `#${t.id}`}if(e.condition&&typeof e.condition=="object"){let t=e.condition,r=t.visible??t.notVisible;if(r){if(typeof r.textRegex=="string")return r.textRegex;if(typeof r.text=="string")return r.text}}if(typeof e.path=="string")return e.path}function At(e,t){return e.length<=t?e:`${e.slice(0,t)}\u2026`}function Co(e){return e.length===0?"":`[REDACTED ${e.length} chars]`}function Mt(e){if(!e||typeof e!="object")return;let t=e;if(typeof t.x=="number"&&typeof t.y=="number")return `${t.x},${t.y}`}function It(e,t){let r={};switch(e){case "inputText":case "pasteText":{let o=t.text??t.value;typeof o=="string"&&(r.text=bo.has(e)?Co(o):o);break}case "swipe":case "scroll":case "scrollUntilVisible":{typeof t.direction=="string"&&(r.direction=t.direction);let o=Mt(t.start??t.startRelative),n=Mt(t.end??t.endRelative);o&&(r.start=o),n&&(r.end=n),typeof t.duration=="number"&&(r.swipeDurationMs=t.duration),typeof t.timeout=="number"&&(r.timeoutMs=t.timeout);break}case "setLocation":{typeof t.latitude=="number"&&(r.latitude=t.latitude),typeof t.longitude=="number"&&(r.longitude=t.longitude);break}case "pressKey":case "back":{typeof t.key=="string"?r.key=t.key:typeof t.code=="string"&&(r.key=t.code);break}case "setOrientation":{typeof t.orientation=="string"&&(r.orientation=t.orientation);break}case "setAirplaneMode":case "toggleAirplaneMode":{(typeof t.value=="string"||typeof t.value=="boolean")&&(r.value=t.value);break}case "setPermissions":{t.permissions&&typeof t.permissions=="object"&&(r.permissions=t.permissions);break}case "addMedia":{Array.isArray(t.mediaPaths)?r.mediaPaths=t.mediaPaths:typeof t.path=="string"&&(r.mediaPaths=[t.path]);break}case "launchApp":case "killApp":case "stopApp":case "clearState":{let o=t.appId??t.packageName??t.bundleId;typeof o=="string"&&(r.appId=o),t.arguments&&(r.arguments=t.arguments);break}case "openLink":{typeof t.url=="string"?r.url=t.url:typeof t.link=="string"&&(r.url=t.link);break}case "runScript":case "evalScript":{typeof t.path=="string"&&(r.path=t.path);let o=t.script??t.scriptString;typeof o=="string"&&(r.script=At(o,vo)),typeof t.sourceDescription=="string"&&(r.sourceDescription=t.sourceDescription);break}case "assertWithAI":case "assertNoDefectsWithAI":case "extractTextWithAI":{let o=t.assertion??t.prompt??t.question;typeof o=="string"&&(r.prompt=At(o,xo));break}case "extendedWaitUntil":case "waitForAnimationToEnd":{typeof t.timeout=="number"&&(r.timeoutMs=t.timeout);break}case "repeat":case "retry":{typeof t.times=="number"&&(r.times=t.times),typeof t.maxRetries=="number"&&(r.maxRetries=t.maxRetries),typeof t.condition=="object"&&t.condition&&(r.condition=t.condition);break}case "runFlow":{typeof t.file=="string"&&(r.file=t.file),typeof t.flowId=="string"&&(r.flowId=t.flowId);break}default:for(let o of ["text","value","url"]){let n=t[o];if(typeof n=="string"||typeof n=="number"||typeof n=="boolean"){r[o]=n;break}}}return Object.keys(r).length>0?r:void 0}function ke(e,t,r){let o=[e.commands,t.commands,t.subSteps,t.children];for(let n of o)if(Array.isArray(n)&&n.length>0)return n.map((s,i)=>Ce(s,i,r));return []}function Ce(e,t,r){let o,n,s,i=[];if(typeof e.command=="object"&&e.command!==null&&!Array.isArray(e.command)){let b=e.command,h=Object.keys(b)[0]??`step-${t}`;o=St(h);let g=b[h]??{};n=Tt(g),s=It(o,g),i=ke(g,e,r);}else {let b=ko(e);if(b){o=St(b);let h=e[b]??{};n=Tt(h),s=It(o,h),i=ke(h,e,r);}else o=e.command??e.commandName??e.name??`step-${t}`,n=e.selector??void 0,i=ke({},e,r);}let a=e.metadata??{},l=Ro(a.status??e.status),c=a.duration??e.duration??e.durationMs??0,d=typeof a.sequenceNumber=="number"?a.sequenceNumber:void 0,p;typeof a.timestamp=="number"?p=new Date(a.timestamp).toISOString():p=e.timestamp??e.time??r;let u=e.error??e.errorMessage??void 0;return {command:o,category:Et(o),status:l,duration:c,timestamp:p,...n?{selector:n}:{},...u?{error:u}:{},...s?{details:s}:{},...d!==void 0?{sequenceNumber:d}:{},...i.length>0?{children:i}:{}}}function Ro(e){if(!e)return "completed";let t=e.toLowerCase();return t==="failed"||t==="error"?"failed":t==="skipped"?"skipped":"completed"}function Ft(e,t){let r=t??new Date().toISOString();try{let o=JSON.parse(e);if(Array.isArray(o))return o.map((n,s)=>Ce(n,s,r));if(typeof o=="object"&&o!==null){let n=o,s=n.commands??n.steps??n.data;if(Array.isArray(s))return s.map((i,a)=>Ce(i,a,r))}return []}catch{return []}}function Re(e,t){try{let r=fs.readFileSync(e,"utf-8");return Ft(r,t)}catch{return []}}function Se(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>path.basename(t).startsWith("commands")&&t.endsWith(".json")).map(t=>path.join(e,t))}catch{return []}}function Eo(e){let t=[];for(let r of e)if(typeof r=="object"&&r!==null){let o=r;if(typeof o.runFlow=="string")t.push(o.runFlow);else if(typeof o.runFlow=="object"&&o.runFlow!==null){let n=o.runFlow;typeof n.file=="string"&&t.push(n.file);}}return t}function Pt(e){if(!e)return [];let t=[],r=Array.isArray(e)?e:[e];for(let o of r)if(typeof o=="string")t.push(o);else if(typeof o=="object"&&o!==null){let n=o;if(typeof n.runFlow=="string")t.push(n.runFlow);else if(typeof n.runFlow=="object"&&n.runFlow!==null){let s=n.runFlow;typeof s.file=="string"&&t.push(s.file);}typeof n.runScript=="string"&&t.push(n.runScript);}return t}function _t(e,t){let r=e.split(/^---\s*$/m,2),o=r[0]??"",n=r[1]??"",s={};try{let v=yaml.parseDocument(o).toJS();typeof v=="object"&&v!==null&&!Array.isArray(v)&&(s=v);}catch{}let i=[];if(n.trim())try{let v=yaml.parseDocument(n).toJS();Array.isArray(v)&&(i=v);}catch{}let a=typeof s.appId=="string"?s.appId:null,l=typeof s.name=="string"?s.name:null,c=[];if(Array.isArray(s.tags))for(let g of s.tags)typeof g=="string"&&c.push(g);let d={};if(typeof s.env=="object"&&s.env!==null&&!Array.isArray(s.env))for(let[g,v]of Object.entries(s.env))d[g]=String(v);let p={};if(typeof s.properties=="object"&&s.properties!==null&&!Array.isArray(s.properties))for(let[g,v]of Object.entries(s.properties))p[g]=String(v);let u=Pt(s.onFlowStart),b=Pt(s.onFlowComplete),h=Eo(i);return {appId:a,name:l,tags:c,env:d,properties:p,onFlowStart:u,onFlowComplete:b,subflowRefs:h,filePath:t}}function Te(e){let t=fs.readFileSync(e,"utf-8");return _t(t,e)}function Ae(e){if(!fs.existsSync(e))return [];let t=[];function r(o){try{let n=fs.readdirSync(o,{withFileTypes:!0});for(let s of n){let i=path.join(o,s.name);if(s.isDirectory())r(i);else if(s.isFile()){let a=path.extname(s.name).toLowerCase();(a===".yaml"||a===".yml")&&t.push(i);}}}catch{}}return r(e),t}var No=/^(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\s+\[?\s*(\w+)\s*\]?\s+(.+)$/,Oo=/^\[?(\d{2}:\d{2}:\d{2}(?:\.\d+)?)\]?\s+\[?\s*(\w+)\s*\]?\s+(.+)$/;function Lt(e){let t=e.toUpperCase();return t==="DEBUG"||t==="TRACE"||t==="VERBOSE"?"DEBUG":t==="INFO"?"INFO":t==="WARN"||t==="WARNING"?"WARN":t==="ERROR"||t==="FATAL"||t==="SEVERE"?"ERROR":"INFO"}function Uo(e,t){let r=/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/.exec(t);if(!r)return new Date().toISOString();let o=Number(r[1]),n=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4].padEnd(3,"0")):0;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),o,n,s,i).toISOString()}function Nt(e,t){let r=[],o=e.split(`
|
|
2
|
+
`),n}catch{}let s=path.dirname(t);if(s===t)break;t=s;}return null}function xe(e){try{let t=fs.readFileSync(e,"utf-8"),r=JSON.parse(t);return typeof r!="object"||r===null||Array.isArray(r)||!yt(r)?null:r}catch{return null}}function yt(e){for(let t of Object.keys(e)){if($r.has(t))return false;let r=e[t];if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&!yt(r))return false}return true}function Y(e){let t=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(e);if(t)return process.env[t[1]]??null;let r=/^\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(e);return r?process.env[r[1]]??null:e}function X(e){let t=Object.create(null);for(let r of Object.keys(e)){let o=e[r];typeof o=="string"&&o.startsWith("$")?t[r]=Y(o):typeof o=="object"&&o!==null&&!Array.isArray(o)?t[r]=X(o):t[r]=o;}return t}function be(e){let t=/^(\d+)\s*([smhd])$/.exec(e.trim());if(!t)return null;let r=parseInt(t[1],10),o=t[2],n=Br[o];return !n||r<=0?null:r*n}function ye(e,t){let r=Object.create(null);if(Object.assign(r,he),e){let l=e.cloud;l&&typeof l=="object"&&(typeof l.endpoint=="string"&&(r.endpoint=l.endpoint),typeof l.upload=="string"&&(r.uploadStrategy=l.upload),typeof l.timeout=="number"&&(r.timeout=l.timeout),typeof l.apiKey=="string"&&l.apiKey.length>0&&(r.apiKey=l.apiKey));let c=e["testrelic-repo"]??e.project;c&&typeof c=="object"&&typeof c.name=="string"&&(r.projectName=c.name);let d=e.queue;if(d&&typeof d=="object"){if(typeof d.maxAge=="string"){let p=be(d.maxAge);p!==null&&(r.queueMaxAge=p);}typeof d.directory=="string"&&(r.queueDirectory=d.directory);}}if(t){if(typeof t.apiKey=="string"&&t.apiKey.length>0){let l=t.apiKey.startsWith("$")?Y(t.apiKey):t.apiKey;l&&(r.apiKey=l);}if(typeof t.endpoint=="string"){let l=t.endpoint.startsWith("$")?Y(t.endpoint):t.endpoint;l&&(r.endpoint=l);}if(typeof t.upload=="string"&&(r.uploadStrategy=t.upload),typeof t.timeout=="number"&&(r.timeout=t.timeout),typeof t.projectName=="string"&&(r.projectName=t.projectName),typeof t.queueMaxAge=="string"){let l=be(t.queueMaxAge);l!==null&&(r.queueMaxAge=l);}typeof t.queueDirectory=="string"&&(r.queueDirectory=t.queueDirectory),typeof t.uploadArtifacts=="boolean"&&(r.uploadArtifacts=t.uploadArtifacts),typeof t.artifactMaxSizeMb=="number"&&(r.artifactMaxSizeMb=t.artifactMaxSizeMb);}let o=process.env.TESTRELIC_API_KEY;o&&o.length>0&&(r.apiKey=o);let n=process.env.TESTRELIC_CLOUD_ENDPOINT;n&&core.isValidEndpointUrl(n)&&(r.endpoint=n);let s=process.env.TESTRELIC_UPLOAD_STRATEGY;s&&["batch","realtime","both"].includes(s)&&(r.uploadStrategy=s);let i=process.env.TESTRELIC_CLOUD_TIMEOUT;if(i){let l=parseInt(i,10);!isNaN(l)&&l>=1e3&&l<=12e4&&(r.timeout=l);}let a=Object.freeze(r);return core.isValidCloudConfig(a)?a:he}var qr=["authorization","cookie","set-cookie","x-api-key"],Vr=["password","secret","token","apiKey","api_key"],Kr=1024*1024;function Jr(e){let t=e??{},r=process.env.TESTRELIC_CAPTURE_NETWORK==="1"||process.env.TESTRELIC_CAPTURE_NETWORK?.toLowerCase()==="true";return Object.freeze({enabled:t.enabled??r??false,proxyPort:t.proxyPort??(process.env.TESTRELIC_PROXY_PORT?Number.parseInt(process.env.TESTRELIC_PROXY_PORT,10):8080),proxyHost:t.proxyHost??process.env.TESTRELIC_PROXY_HOST??"127.0.0.1",harPath:t.harPath??process.env.TESTRELIC_HAR_PATH??null,outputDir:t.outputDir??null,skipCertInstall:t.skipCertInstall??false,includeUrls:Object.freeze(t.includeUrls?[...t.includeUrls]:[]),excludeUrls:Object.freeze(t.excludeUrls?[...t.excludeUrls]:[]),redactHeaders:Object.freeze(t.redactHeaders?[...t.redactHeaders]:[...qr]),redactBodyFields:Object.freeze(t.redactBodyFields?[...t.redactBodyFields]:[...Vr]),maxBodyBytes:t.maxBodyBytes??Kr})}var Wr=new Set(["__proto__","constructor","prototype"]);function wt(e){if(typeof e!="object"||e===null)return false;for(let t of Object.keys(e))if(Wr.has(t))return true;return false}function Yr(e){if(typeof e!="object"||e===null||wt(e))return false;let t=e;return !(t.outputPath!==void 0&&typeof t.outputPath!="string"||t.htmlReportPath!==void 0&&typeof t.htmlReportPath!="string"||t.openReport!==void 0&&typeof t.openReport!="boolean"||t.includeScreenshots!==void 0&&typeof t.includeScreenshots!="boolean"||t.includeVideo!==void 0&&typeof t.includeVideo!="boolean"||t.includeAiAnalysis!==void 0&&typeof t.includeAiAnalysis!="boolean"||t.includeLogs!==void 0&&typeof t.includeLogs!="boolean"||t.includeFlowMetadata!==void 0&&typeof t.includeFlowMetadata!="boolean"||t.quiet!==void 0&&typeof t.quiet!="boolean"||t.metadata!==void 0&&t.metadata!==null&&(typeof t.metadata!="object"||wt(t.metadata)))}function Xr(e){if(e!==void 0&&!Yr(e))throw core.createError(core.ErrorCode.CONFIG_INVALID,"Invalid Maestro reporter configuration");let t=Object.create(null),r=e?.outputPath??"./test-results/testrelic-maestro.json";return t.outputPath=r,t.htmlReportPath=e?.htmlReportPath??r.replace(/\.json$/,".html"),t.openReport=e?.openReport??true,t.includeScreenshots=e?.includeScreenshots??true,t.includeVideo=e?.includeVideo??true,t.includeAiAnalysis=e?.includeAiAnalysis??true,t.includeLogs=e?.includeLogs??true,t.includeFlowMetadata=e?.includeFlowMetadata??true,t.flowsDir=e?.flowsDir??null,t.testRunId=e?.testRunId??null,t.metadata=e?.metadata??null,t.quiet=e?.quiet??false,t.reportMode=e?.reportMode??"batch",t.cloud=Qr(e?.cloud??null),t.network=Jr(e?.network),Object.freeze(t)}function Qr(e){let t=ve(process.cwd()),r=t?xe(t):null,o=r?X(r):null,n=ye(o,e??void 0);return n.apiKey?n:null}var q="1.1.0";var to=new fastXmlParser.XMLParser({ignoreAttributes:false,attributeNamePrefix:"@_",allowBooleanAttributes:true,parseAttributeValue:true,trimValues:true});function Q(e){return e==null?[]:Array.isArray(e)?e:[e]}function Ct(e){return !e||typeof e!="object"?[]:Q(e.property).map(o=>({name:String(o["@_name"]??""),value:String(o["@_value"]??"")}))}function ro(e){let t=String(e["@_name"]??"unnamed"),r=String(e["@_classname"]??t),o=Number(e["@_time"]??0),n=e["@_id"]!=null?String(e["@_id"]):null,s=String(e["@_status"]??"").toUpperCase(),i=e.failure,a=e.error,l=e.skipped!==void 0,c="SUCCESS";return i?c="FAILURE":a?c="ERROR":l?c="SKIPPED":s==="FAILURE"||s==="FAILED"?c="FAILURE":s==="ERROR"?c="ERROR":s==="SKIPPED"&&(c="SKIPPED"),{id:n,name:t,classname:r,time:o,status:c,failureMessage:i?String(i["@_message"]??i["#text"]??""):null,failureType:i?String(i["@_type"]??""):null,errorMessage:a?String(a["@_message"]??a["#text"]??""):null,errorType:a?String(a["@_type"]??""):null,properties:Ct(e.properties)}}function kt(e){let t=String(e["@_name"]??"Test Suite"),r=e["@_device"]!=null?String(e["@_device"]):null,o=Number(e["@_tests"]??0),n=Number(e["@_failures"]??0),s=Number(e["@_errors"]??0),i=Number(e["@_skipped"]??0),a=Number(e["@_time"]??0),c=Q(e.testcase).map(ro);return {name:t,device:r,tests:o,failures:n,errors:s,skipped:i,time:a,testCases:c,properties:Ct(e.properties)}}function Rt(e){let t=to.parse(e),r=[];if(t.testsuites){let l=t.testsuites;r=Q(l.testsuite).map(kt);}else t.testsuite&&(r=Q(t.testsuite).map(kt));let o=0,n=0,s=0,i=0,a=0;for(let l of r)o+=l.tests,n+=l.failures,s+=l.errors,i+=l.skipped,a+=l.time;return {testSuites:r,totalTests:o,totalFailures:n,totalErrors:s,totalSkipped:i,totalTime:a}}function we(e){let t=fs.readFileSync(e,"utf-8");return Rt(t)}var lo=new Set(["tapOn","doubleTapOn","longPressOn","inputText","eraseText","pasteText","swipe","scroll","scrollUntilVisible","hideKeyboard","pressKey","setClipboard","copyTextFrom"]),co=new Set(["assertVisible","assertNotVisible","assertTrue","assertScreenshot","assertNoDefectsWithAI","assertWithAI","assertCondition"]),po=new Set(["launchApp","killApp","stopApp","clearState","openLink","back","clearKeychain"]),uo=new Set(["setAirplaneMode","toggleAirplaneMode","setLocation","setOrientation","setPermissions","addMedia","travel"]),fo=new Set(["takeScreenshot","startRecording","stopRecording"]),go=new Set(["runScript","evalScript"]),mo=new Set(["runFlow","repeat","retry","waitForAnimationToEnd","extendedWaitUntil"]),ho=new Set(["assertWithAI","assertNoDefectsWithAI","extractTextWithAI"]),bo=new Set(["inputText","pasteText"]),vo=200,xo=400;function Et(e){return ho.has(e)?"ai":co.has(e)?"assertion":lo.has(e)?"interaction":po.has(e)?"navigation":uo.has(e)?"device":fo.has(e)?"media":go.has(e)?"script":mo.has(e)?"flow_control":"other"}var yo={tapOnElement:"tapOn",assertCondition:"assertVisible",backPress:"back",applyConfiguration:"applyConfiguration",defineVariables:"defineVariables"};function St(e){let t=e.replace(/Command$/,"");return yo[t]??t}var wo=new Set(["metadata","command","commandName","name","status","duration","durationMs","timestamp","time","error","errorMessage","selector","commands","subSteps","children","sequenceNumber"]);function ko(e){for(let t of Object.keys(e)){if(wo.has(t))continue;let r=e[t];if(r&&typeof r=="object"&&!Array.isArray(r))return t}}function Tt(e){if(e.selector&&typeof e.selector=="object"){let t=e.selector;if(typeof t.textRegex=="string")return t.textRegex;if(typeof t.text=="string")return t.text;if(typeof t.id=="string")return `#${t.id}`}if(e.condition&&typeof e.condition=="object"){let t=e.condition,r=t.visible??t.notVisible;if(r){if(typeof r.textRegex=="string")return r.textRegex;if(typeof r.text=="string")return r.text}}if(typeof e.path=="string")return e.path}function At(e,t){return e.length<=t?e:`${e.slice(0,t)}\u2026`}function Co(e){return e.length===0?"":`[REDACTED ${e.length} chars]`}function Mt(e){if(!e||typeof e!="object")return;let t=e;if(typeof t.x=="number"&&typeof t.y=="number")return `${t.x},${t.y}`}function It(e,t){let r={};switch(e){case "inputText":case "pasteText":{let o=t.text??t.value;typeof o=="string"&&(r.text=bo.has(e)?Co(o):o);break}case "swipe":case "scroll":case "scrollUntilVisible":{typeof t.direction=="string"&&(r.direction=t.direction);let o=Mt(t.start??t.startRelative),n=Mt(t.end??t.endRelative);o&&(r.start=o),n&&(r.end=n),typeof t.duration=="number"&&(r.swipeDurationMs=t.duration),typeof t.timeout=="number"&&(r.timeoutMs=t.timeout);break}case "setLocation":{typeof t.latitude=="number"&&(r.latitude=t.latitude),typeof t.longitude=="number"&&(r.longitude=t.longitude);break}case "pressKey":case "back":{typeof t.key=="string"?r.key=t.key:typeof t.code=="string"&&(r.key=t.code);break}case "setOrientation":{typeof t.orientation=="string"&&(r.orientation=t.orientation);break}case "setAirplaneMode":case "toggleAirplaneMode":{(typeof t.value=="string"||typeof t.value=="boolean")&&(r.value=t.value);break}case "setPermissions":{t.permissions&&typeof t.permissions=="object"&&(r.permissions=t.permissions);break}case "addMedia":{Array.isArray(t.mediaPaths)?r.mediaPaths=t.mediaPaths:typeof t.path=="string"&&(r.mediaPaths=[t.path]);break}case "launchApp":case "killApp":case "stopApp":case "clearState":{let o=t.appId??t.packageName??t.bundleId;typeof o=="string"&&(r.appId=o),t.arguments&&(r.arguments=t.arguments);break}case "openLink":{typeof t.url=="string"?r.url=t.url:typeof t.link=="string"&&(r.url=t.link);break}case "runScript":case "evalScript":{typeof t.path=="string"&&(r.path=t.path);let o=t.script??t.scriptString;typeof o=="string"&&(r.script=At(o,vo)),typeof t.sourceDescription=="string"&&(r.sourceDescription=t.sourceDescription);break}case "assertWithAI":case "assertNoDefectsWithAI":case "extractTextWithAI":{let o=t.assertion??t.prompt??t.question;typeof o=="string"&&(r.prompt=At(o,xo));break}case "extendedWaitUntil":case "waitForAnimationToEnd":{typeof t.timeout=="number"&&(r.timeoutMs=t.timeout);break}case "repeat":case "retry":{typeof t.times=="number"&&(r.times=t.times),typeof t.maxRetries=="number"&&(r.maxRetries=t.maxRetries),typeof t.condition=="object"&&t.condition&&(r.condition=t.condition);break}case "runFlow":{typeof t.file=="string"&&(r.file=t.file),typeof t.flowId=="string"&&(r.flowId=t.flowId);break}default:for(let o of ["text","value","url"]){let n=t[o];if(typeof n=="string"||typeof n=="number"||typeof n=="boolean"){r[o]=n;break}}}return Object.keys(r).length>0?r:void 0}function ke(e,t,r){let o=[e.commands,t.commands,t.subSteps,t.children];for(let n of o)if(Array.isArray(n)&&n.length>0)return n.map((s,i)=>Ce(s,i,r));return []}function Ce(e,t,r){let o,n,s,i=[];if(typeof e.command=="object"&&e.command!==null&&!Array.isArray(e.command)){let b=e.command,h=Object.keys(b)[0]??`step-${t}`;o=St(h);let g=b[h]??{};n=Tt(g),s=It(o,g),i=ke(g,e,r);}else {let b=ko(e);if(b){o=St(b);let h=e[b]??{};n=Tt(h),s=It(o,h),i=ke(h,e,r);}else o=e.command??e.commandName??e.name??`step-${t}`,n=e.selector??void 0,i=ke({},e,r);}let a=e.metadata??{},l=Ro(a.status??e.status),c=a.duration??e.duration??e.durationMs??0,d=typeof a.sequenceNumber=="number"?a.sequenceNumber:void 0,p;typeof a.timestamp=="number"?p=new Date(a.timestamp).toISOString():p=e.timestamp??e.time??r;let u=e.error??e.errorMessage??void 0;return {command:o,category:Et(o),status:l,duration:c,timestamp:p,...n?{selector:n}:{},...u?{error:u}:{},...s?{details:s}:{},...d!==void 0?{sequenceNumber:d}:{},...i.length>0?{children:i}:{}}}function Ro(e){if(!e)return "completed";let t=e.toLowerCase();return t==="failed"||t==="error"?"failed":t==="skipped"?"skipped":"completed"}function Ft(e,t){let r=t??new Date().toISOString();try{let o=JSON.parse(e);if(Array.isArray(o))return o.map((n,s)=>Ce(n,s,r));if(typeof o=="object"&&o!==null){let n=o,s=n.commands??n.steps??n.data;if(Array.isArray(s))return s.map((i,a)=>Ce(i,a,r))}return []}catch{return []}}function Re(e,t){try{let r=fs.readFileSync(e,"utf-8");return Ft(r,t)}catch{return []}}function Se(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>path.basename(t).startsWith("commands")&&t.endsWith(".json")).map(t=>path.join(e,t))}catch{return []}}function Eo(e){let t=[];for(let r of e)if(typeof r=="object"&&r!==null){let o=r;if(typeof o.runFlow=="string")t.push(o.runFlow);else if(typeof o.runFlow=="object"&&o.runFlow!==null){let n=o.runFlow;typeof n.file=="string"&&t.push(n.file);}}return t}function Pt(e){if(!e)return [];let t=[],r=Array.isArray(e)?e:[e];for(let o of r)if(typeof o=="string")t.push(o);else if(typeof o=="object"&&o!==null){let n=o;if(typeof n.runFlow=="string")t.push(n.runFlow);else if(typeof n.runFlow=="object"&&n.runFlow!==null){let s=n.runFlow;typeof s.file=="string"&&t.push(s.file);}typeof n.runScript=="string"&&t.push(n.runScript);}return t}function _t(e,t){let r=e.split(/^---\s*$/m,2),o=r[0]??"",n=r[1]??"",s={};try{let v=yaml.parseDocument(o).toJS();typeof v=="object"&&v!==null&&!Array.isArray(v)&&(s=v);}catch{}let i=[];if(n.trim())try{let v=yaml.parseDocument(n).toJS();Array.isArray(v)&&(i=v);}catch{}let a=typeof s.appId=="string"?s.appId:null,l=typeof s.name=="string"?s.name:null,c=[];if(Array.isArray(s.tags))for(let g of s.tags)typeof g=="string"&&c.push(g);let d={};if(typeof s.env=="object"&&s.env!==null&&!Array.isArray(s.env))for(let[g,v]of Object.entries(s.env))d[g]=String(v);let p={};if(typeof s.properties=="object"&&s.properties!==null&&!Array.isArray(s.properties))for(let[g,v]of Object.entries(s.properties))p[g]=String(v);let u=Pt(s.onFlowStart),b=Pt(s.onFlowComplete),h=Eo(i);return {appId:a,name:l,tags:c,env:d,properties:p,onFlowStart:u,onFlowComplete:b,subflowRefs:h,filePath:t}}function Te(e){let t=fs.readFileSync(e,"utf-8");return _t(t,e)}function Ae(e){if(!fs.existsSync(e))return [];let t=[];function r(o){try{let n=fs.readdirSync(o,{withFileTypes:!0});for(let s of n){let i=path.join(o,s.name);if(s.isDirectory())r(i);else if(s.isFile()){let a=path.extname(s.name).toLowerCase();(a===".yaml"||a===".yml")&&t.push(i);}}}catch{}}return r(e),t}var No=/^(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\s+\[?\s*(\w+)\s*\]?\s+(.+)$/,Oo=/^\[?(\d{2}:\d{2}:\d{2}(?:\.\d+)?)\]?\s+\[?\s*(\w+)\s*\]?\s+(.+)$/;function Lt(e){let t=e.toUpperCase();return t==="DEBUG"||t==="TRACE"||t==="VERBOSE"?"DEBUG":t==="INFO"?"INFO":t==="WARN"||t==="WARNING"?"WARN":t==="ERROR"||t==="FATAL"||t==="SEVERE"?"ERROR":"INFO"}function Uo(e,t){let r=/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/.exec(t);if(!r)return new Date().toISOString();let o=Number(r[1]),n=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4].padEnd(3,"0")):0;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),o,n,s,i).toISOString()}function Nt(e,t){let r=[],o=e.split(`
|
|
3
3
|
`),n=t instanceof Date?t:null,s=typeof t=="string"?t:t instanceof Date?`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`:new Date().toISOString().split("T")[0];for(let i of o){let a=i.trim();if(!a)continue;let l=No.exec(a);if(l){r.push({timestamp:l[1],level:Lt(l[2]),message:l[3],source:null});continue}if(l=Oo.exec(a),l){let c=n?Uo(n,l[1]):`${s}T${l[1]}`;r.push({timestamp:c,level:Lt(l[2]),message:l[3],source:null});continue}if(r.length>0){let c=r[r.length-1];r[r.length-1]={...c,message:c.message+`
|
|
4
|
-
`+a};}}return r}function Me(e,t){try{let r=fs.readFileSync(e,"utf-8");return Nt(r,t)}catch{return []}}function Ie(e){for(let t of e){let r=t.message.toLowerCase();if(r.includes("android")||r.includes("adb")||r.includes("uiautomator")||r.includes("emulator"))return "android";if(r.includes("ios")||r.includes("xcuitest")||r.includes("simulator")||r.includes("xctest"))return "ios";if(r.includes("web driver")||r.includes("chrome")||r.includes("chromium"))return "web"}return "unknown"}function Ee(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>path.basename(t)==="maestro.log"||t.endsWith(".log")).map(t=>path.join(e,t))}catch{return []}}var qo=/(?:defect|issue|bug|error|warning|problem)/i,Vo=/(?:critical|severe|major|blocker)/i,Jo=/(?:warning|moderate|minor)/i,Fe=/(?:cut[\s-]?off|overlap|truncat|misalign|overflow|clip|obscur|hidden\s+text|broken\s+layout)/i,Z=/(?:spelling|typo|misspell|grammar)/i,ee=/(?:i18n|internationali[sz]ation|locali[sz]ation|untranslated|missing\s+translation)/i,Le=/(?:layout|spacing|padding|margin|alignment|centering|position)/i,Ne=/(?:accessib|a11y|contrast|screen\s*reader|alt\s*text|aria)/i;function De(e){return Z.test(e)?"spelling":ee.test(e)?"i18n":Ne.test(e)?"accessibility":Le.test(e)?"layout":"ui"}function Pe(e){return Vo.test(e)?"critical":Jo.test(e)?"warning":"info"}function _e(e){return e.replace(/<[^>]*>/g," ").replace(/\s+/g," ").trim()}function Ko(e){let t=[],r=_e(e),o=/<li[^>]*>([\s\S]*?)<\/li>/gi,n;for(;(n=o.exec(e))!==null;){let s=n[1],i=_e(s);!i||i.length<5||(qo.test(i)||Fe.test(i)||Z.test(i)||ee.test(i))&&t.push({type:De(i),severity:Pe(i),description:i,location:null,screenshot:null});}if(t.length===0){let s=/<p[^>]*>([\s\S]*?)<\/p>/gi;for(;(n=s.exec(e))!==null;){let i=_e(n[1]);!i||i.length<10||(Fe.test(i)||Z.test(i)||ee.test(i)||Le.test(i)||Ne.test(i))&&t.push({type:De(i),severity:Pe(i),description:i,location:null,screenshot:null});}}if(t.length===0&&r.length>20){let s=r.split(/[.!?]+/).filter(i=>i.trim().length>10);for(let i of s){let a=i.trim();(Fe.test(a)||Z.test(a)||ee.test(a)||Le.test(a)||Ne.test(a))&&t.push({type:De(a),severity:Pe(a),description:a,location:null,screenshot:null});}}return t}function Ot(e){let t=Ko(e);return {defects:t,totalDefects:t.length,hasIssues:t.length>0,rawHtml:e}}function Oe(e){try{let t=fs.readFileSync(e,"utf-8");return Ot(t)}catch{return {defects:[],totalDefects:0,hasIssues:false,rawHtml:null}}}function Ue(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>{let r=path.basename(t).toLowerCase();return path.extname(t).toLowerCase()===".html"&&(r.includes("insight")||r.includes("ai")||r.includes("analysis"))}).map(t=>path.join(e,t))}catch{return []}}var en=new Set([".png",".jpg",".jpeg",".webp"]),tn=new Set([".mp4",".webm",".mov"]);function Ut(e){let t=[];if(!fs.existsSync(e))return t;function r(o){try{let n=fs.readdirSync(o,{withFileTypes:!0});for(let s of n){let i=path.join(o,s.name);s.isDirectory()?r(i):s.isFile()&&t.push(i);}}catch{}}return r(e),t}function ze(e,t){let r=[],o=[],n=[],s=[],i=[],a=null,l=[];e&&l.push(...Ut(e)),t&&l.push(...Ut(t));let c=new Set;for(let d of l){if(c.has(d))continue;c.add(d);let p=path.basename(d).toLowerCase(),u=path.extname(d).toLowerCase();if(en.has(u)){r.push(d);continue}if(tn.has(u)){o.push(d);continue}if(p==="maestro.log"||u===".log"&&p.includes("maestro")){n.push(d);continue}if(p.startsWith("commands")&&u===".json"){s.push(d);continue}if(u===".html"&&(p.includes("insight")||p.includes("ai")||p.includes("analysis"))){i.push(d);continue}if(u===".xml"&&(p.includes("report")||p.includes("junit"))){a||(a=d);continue}}return {screenshotPaths:r,videoPaths:o,logPaths:n,commandJsonPaths:s,aiReportPaths:i,junitReportPath:a}}function rn(e){return {screenshots:e.screenshotPaths.length,videos:e.videoPaths.length,logs:e.logPaths.length,commandFiles:e.commandJsonPaths.length,aiReports:e.aiReportPaths.length,junitReport:e.junitReportPath?1:0}}function on(e){switch(e){case "interaction":return "interaction";case "assertion":return "assertion";case "ai":return "ai";case "navigation":return "navigation";case "device":return "device";case "media":return "media";case "script":return "script";case "flow_control":return "flow_control";case "recording":return "media";default:return "other"}}function nn(e){switch(e){case "interaction":return "ui_action";case "assertion":return "assertion";case "ai":return "assertion";case "navigation":return "navigation";case "device":return "custom_step";case "media":return "custom_step";case "script":return "custom_step";case "flow_control":return "custom_step";case "recording":return "custom_step";default:return "custom_step"}}function sn(e){let t=e.details;if(t)switch(e.command){case "inputText":case "pasteText":if(typeof t.text=="string")return `${e.command} \u2192 ${t.text}`;break;case "swipe":case "scroll":case "scrollUntilVisible":if(typeof t.direction=="string")return `${e.command} ${t.direction}`;break;case "setLocation":if(typeof t.latitude=="number"&&typeof t.longitude=="number")return `setLocation ${t.latitude},${t.longitude}`;break;case "pressKey":if(typeof t.key=="string")return `pressKey ${t.key}`;break;case "setOrientation":if(typeof t.orientation=="string")return `setOrientation ${t.orientation}`;break;case "launchApp":case "killApp":case "stopApp":case "clearState":if(typeof t.appId=="string")return `${e.command} ${t.appId}`;break;case "openLink":if(typeof t.url=="string")return `openLink ${t.url}`;break;case "runScript":case "evalScript":if(typeof t.path=="string")return `${e.command} ${t.path}`;if(typeof t.sourceDescription=="string")return `${e.command} ${t.sourceDescription}`;if(typeof t.script=="string")return `${e.command} ${t.script}`;break;case "assertWithAI":case "assertNoDefectsWithAI":case "extractTextWithAI":if(typeof t.prompt=="string")return `${e.command} \u2192 ${t.prompt}`;break;case "retry":if(typeof t.maxRetries=="number")return `retry \xD7 ${t.maxRetries}`;break;case "repeat":if(typeof t.times=="number")return `repeat \xD7 ${t.times}`;break;case "runFlow":if(typeof t.file=="string")return `runFlow ${t.file}`;break}return e.selector?`${e.command} \u2192 ${e.selector}`:e.command}function He(e,t){let r=Date.parse(e.timestamp),o=Number.isFinite(r)&&Number.isFinite(t)?Math.max(0,(r-t)/1e3):null,n=(e.children??[]).map(s=>He(s,t));return {title:sn(e),category:nn(e.category),kind:on(e.category),selector:e.selector??null,status:e.status==="failed"?"failed":"passed",duration:e.duration,timestamp:e.timestamp,videoOffset:o,error:e.error??null,children:n}}function an(e,t){let r=Date.parse(e.timestamp),o=Date.parse(t.timestamp);return Number.isFinite(r)&&Number.isFinite(o)&&r!==o?r-o:0}function ln(e){return {platform:e.platform,platformVersion:null,deviceName:e.deviceId??null,automationName:"maestro",appId:e.appId,appTestMode:e.platform==="web"?"mobile-web":"native",udid:e.deviceId??null}}function cn(e){return e.logEntries.map(t=>({level:t.level==="ERROR"?"error":t.level==="WARN"?"warn":t.level==="DEBUG"?"debug":"info",text:t.message,timestamp:t.timestamp,location:null,source:"driver",tag:t.source??null,pid:null,stackTrace:null}))}function dn(e){return e.aiDefects.map(t=>({type:t.type,severity:t.severity,description:t.description,location:t.location,screenshot:t.screenshot}))}function pn(e,t){let r=Date.parse(e.startedAt),o=[...e.commands].sort((l,c)=>{let d=Date.parse(l.timestamp),p=Date.parse(c.timestamp);if(Number.isFinite(d)&&Number.isFinite(p)&&d!==p)return d-p;let u=l.sequenceNumber??0,b=c.sequenceNumber??0;return u-b}),n=[...e.assertions].sort((l,c)=>{let d=Date.parse(l.timestamp),p=Date.parse(c.timestamp);if(Number.isFinite(d)&&Number.isFinite(p)&&d!==p)return d-p;let u=l.sequenceNumber??0,b=c.sequenceNumber??0;return u-b}),s=[...o.map(l=>He(l,r)),...n.map(l=>He(l,r))];s.sort(an);let i=e.screenshotPaths.length>0||e.videoPath?{screenshot:e.screenshotPaths[0]??void 0,...e.screenshotPaths.length>0?{screenshots:[...e.screenshotPaths]}:{},video:e.videoPath??void 0}:null,a=[...e.tags];return {title:e.flowName,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:0,tags:a,failure:e.failureMessage?{message:e.failureMessage,line:null,code:null,stack:null}:null,testId:`${e.flowFile}::${e.flowName}`,filePath:e.flowFile,suiteName:e.appId??"maestro-suite",testType:"mobile",isFlaky:false,retryStatus:null,expectedStatus:"passed",actualStatus:e.status,artifacts:i,networkRequests:null,apiCalls:t.length>0?[...t]:null,apiAssertions:null,actions:s.length>0?s:null,consoleLogs:e.logEntries.length>0?cn(e):null,device:ln(e),aiDefects:e.aiDefects.length>0?dn(e):null}}function zt(e,t){let r=`${e.flowFile}::${e.flowName}`,o=t?.get(r)??[],n=pn(e,o);return {url:e.appId??"maestro-flow",navigationType:"page_load",visitedAt:e.startedAt,duration:e.duration,specFile:e.flowFile,domContentLoadedAt:null,networkIdleAt:null,networkStats:null,tests:[n]}}function $e(e,t){return e.map(r=>zt(r,t))}var Ht={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0};function un(e){return e===null?"error":e>=200&&e<300?"2xx":e>=300&&e<400?"3xx":e>=400&&e<500?"4xx":e>=500&&e<600?"5xx":"error"}function Be(e,t){if(e.length===0)return null;let r=Math.min(e.length-1,Math.floor(t/100*e.length));return e[r]}function fn(e){if(e.length===0)return {totalApiCalls:0,uniqueApiUrls:0,apiCallsByMethod:{},apiCallsByStatusRange:{...Ht},apiResponseTime:null};let t={},r={...Ht},o=new Set,n=[];for(let i of e)t[i.method]=(t[i.method]??0)+1,r[un(i.responseStatusCode)]+=1,o.add(i.url),Number.isFinite(i.responseTimeMs)&&i.responseTimeMs>0&&n.push(i.responseTimeMs);n.sort((i,a)=>i-a);let s=n.length>0?{p50:Be(n,50)??0,p95:Be(n,95)??0,p99:Be(n,99)??0,avg:n.reduce((i,a)=>i+a,0)/n.length,min:n[0],max:n[n.length-1]}:null;return {totalApiCalls:e.length,uniqueApiUrls:o.size,apiCallsByMethod:t,apiCallsByStatusRange:r,apiResponseTime:s}}function V(e){let t=0,r=0,o=0,n=0,s=0,i=0,a=0,l=0,c=0,d=e.length,p=0,u={},b=new Set,h=[];for(let v of e){b.add(v.url);for(let x of v.tests){switch(t++,x.status){case "passed":r++;break;case "failed":o++;break;case "flaky":n++;break;case "skipped":s++;break;case "timedout":i++;break}if(x.actions)for(let T of x.actions)if(p++,T.category==="assertion")a++,T.status==="passed"?l++:c++;else {let R=T.category;u[R]=(u[R]??0)+1;}x.apiCalls&&x.apiCalls.length>0&&h.push(...x.apiCalls);}}let g=fn(h);return {total:t,passed:r,failed:o,flaky:n,skipped:s,timedout:i,...g,totalAssertions:a,passedAssertions:l,failedAssertions:c,totalNavigations:d,uniqueNavigationUrls:b.size,totalTimelineSteps:e.length,totalActionSteps:p,actionStepsByCategory:u}}var $t=`
|
|
4
|
+
`+a};}}return r}function Me(e,t){try{let r=fs.readFileSync(e,"utf-8");return Nt(r,t)}catch{return []}}function Ie(e){for(let t of e){let r=t.message.toLowerCase();if(r.includes("android")||r.includes("adb")||r.includes("uiautomator")||r.includes("emulator"))return "android";if(r.includes("ios")||r.includes("xcuitest")||r.includes("simulator")||r.includes("xctest"))return "ios";if(r.includes("web driver")||r.includes("chrome")||r.includes("chromium"))return "web"}return "unknown"}function Ee(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>path.basename(t)==="maestro.log"||t.endsWith(".log")).map(t=>path.join(e,t))}catch{return []}}var qo=/(?:defect|issue|bug|error|warning|problem)/i,Vo=/(?:critical|severe|major|blocker)/i,Ko=/(?:warning|moderate|minor)/i,Fe=/(?:cut[\s-]?off|overlap|truncat|misalign|overflow|clip|obscur|hidden\s+text|broken\s+layout)/i,Z=/(?:spelling|typo|misspell|grammar)/i,ee=/(?:i18n|internationali[sz]ation|locali[sz]ation|untranslated|missing\s+translation)/i,Le=/(?:layout|spacing|padding|margin|alignment|centering|position)/i,Ne=/(?:accessib|a11y|contrast|screen\s*reader|alt\s*text|aria)/i;function De(e){return Z.test(e)?"spelling":ee.test(e)?"i18n":Ne.test(e)?"accessibility":Le.test(e)?"layout":"ui"}function Pe(e){return Vo.test(e)?"critical":Ko.test(e)?"warning":"info"}function _e(e){return e.replace(/<[^>]*>/g," ").replace(/\s+/g," ").trim()}function Jo(e){let t=[],r=_e(e),o=/<li[^>]*>([\s\S]*?)<\/li>/gi,n;for(;(n=o.exec(e))!==null;){let s=n[1],i=_e(s);!i||i.length<5||(qo.test(i)||Fe.test(i)||Z.test(i)||ee.test(i))&&t.push({type:De(i),severity:Pe(i),description:i,location:null,screenshot:null});}if(t.length===0){let s=/<p[^>]*>([\s\S]*?)<\/p>/gi;for(;(n=s.exec(e))!==null;){let i=_e(n[1]);!i||i.length<10||(Fe.test(i)||Z.test(i)||ee.test(i)||Le.test(i)||Ne.test(i))&&t.push({type:De(i),severity:Pe(i),description:i,location:null,screenshot:null});}}if(t.length===0&&r.length>20){let s=r.split(/[.!?]+/).filter(i=>i.trim().length>10);for(let i of s){let a=i.trim();(Fe.test(a)||Z.test(a)||ee.test(a)||Le.test(a)||Ne.test(a))&&t.push({type:De(a),severity:Pe(a),description:a,location:null,screenshot:null});}}return t}function Ot(e){let t=Jo(e);return {defects:t,totalDefects:t.length,hasIssues:t.length>0,rawHtml:e}}function Oe(e){try{let t=fs.readFileSync(e,"utf-8");return Ot(t)}catch{return {defects:[],totalDefects:0,hasIssues:false,rawHtml:null}}}function Ue(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>{let r=path.basename(t).toLowerCase();return path.extname(t).toLowerCase()===".html"&&(r.includes("insight")||r.includes("ai")||r.includes("analysis"))}).map(t=>path.join(e,t))}catch{return []}}var en=new Set([".png",".jpg",".jpeg",".webp"]),tn=new Set([".mp4",".webm",".mov"]);function Ut(e){let t=[];if(!fs.existsSync(e))return t;function r(o){try{let n=fs.readdirSync(o,{withFileTypes:!0});for(let s of n){let i=path.join(o,s.name);s.isDirectory()?r(i):s.isFile()&&t.push(i);}}catch{}}return r(e),t}function ze(e,t){let r=[],o=[],n=[],s=[],i=[],a=null,l=[];e&&l.push(...Ut(e)),t&&l.push(...Ut(t));let c=new Set;for(let d of l){if(c.has(d))continue;c.add(d);let p=path.basename(d).toLowerCase(),u=path.extname(d).toLowerCase();if(en.has(u)){r.push(d);continue}if(tn.has(u)){o.push(d);continue}if(p==="maestro.log"||u===".log"&&p.includes("maestro")){n.push(d);continue}if(p.startsWith("commands")&&u===".json"){s.push(d);continue}if(u===".html"&&(p.includes("insight")||p.includes("ai")||p.includes("analysis"))){i.push(d);continue}if(u===".xml"&&(p.includes("report")||p.includes("junit"))){a||(a=d);continue}}return {screenshotPaths:r,videoPaths:o,logPaths:n,commandJsonPaths:s,aiReportPaths:i,junitReportPath:a}}function rn(e){return {screenshots:e.screenshotPaths.length,videos:e.videoPaths.length,logs:e.logPaths.length,commandFiles:e.commandJsonPaths.length,aiReports:e.aiReportPaths.length,junitReport:e.junitReportPath?1:0}}function on(e){switch(e){case "interaction":return "interaction";case "assertion":return "assertion";case "ai":return "ai";case "navigation":return "navigation";case "device":return "device";case "media":return "media";case "script":return "script";case "flow_control":return "flow_control";case "recording":return "media";default:return "other"}}function nn(e){switch(e){case "interaction":return "ui_action";case "assertion":return "assertion";case "ai":return "assertion";case "navigation":return "navigation";case "device":return "custom_step";case "media":return "custom_step";case "script":return "custom_step";case "flow_control":return "custom_step";case "recording":return "custom_step";default:return "custom_step"}}function sn(e){let t=e.details;if(t)switch(e.command){case "inputText":case "pasteText":if(typeof t.text=="string")return `${e.command} \u2192 ${t.text}`;break;case "swipe":case "scroll":case "scrollUntilVisible":if(typeof t.direction=="string")return `${e.command} ${t.direction}`;break;case "setLocation":if(typeof t.latitude=="number"&&typeof t.longitude=="number")return `setLocation ${t.latitude},${t.longitude}`;break;case "pressKey":if(typeof t.key=="string")return `pressKey ${t.key}`;break;case "setOrientation":if(typeof t.orientation=="string")return `setOrientation ${t.orientation}`;break;case "launchApp":case "killApp":case "stopApp":case "clearState":if(typeof t.appId=="string")return `${e.command} ${t.appId}`;break;case "openLink":if(typeof t.url=="string")return `openLink ${t.url}`;break;case "runScript":case "evalScript":if(typeof t.path=="string")return `${e.command} ${t.path}`;if(typeof t.sourceDescription=="string")return `${e.command} ${t.sourceDescription}`;if(typeof t.script=="string")return `${e.command} ${t.script}`;break;case "assertWithAI":case "assertNoDefectsWithAI":case "extractTextWithAI":if(typeof t.prompt=="string")return `${e.command} \u2192 ${t.prompt}`;break;case "retry":if(typeof t.maxRetries=="number")return `retry \xD7 ${t.maxRetries}`;break;case "repeat":if(typeof t.times=="number")return `repeat \xD7 ${t.times}`;break;case "runFlow":if(typeof t.file=="string")return `runFlow ${t.file}`;break}return e.selector?`${e.command} \u2192 ${e.selector}`:e.command}function He(e,t){let r=Date.parse(e.timestamp),o=Number.isFinite(r)&&Number.isFinite(t)?Math.max(0,(r-t)/1e3):null,n=(e.children??[]).map(s=>He(s,t));return {title:sn(e),category:nn(e.category),kind:on(e.category),selector:e.selector??null,status:e.status==="failed"?"failed":"passed",duration:e.duration,timestamp:e.timestamp,videoOffset:o,error:e.error??null,children:n}}function an(e,t){let r=Date.parse(e.timestamp),o=Date.parse(t.timestamp);return Number.isFinite(r)&&Number.isFinite(o)&&r!==o?r-o:0}function ln(e){return {platform:e.platform,platformVersion:null,deviceName:e.deviceId??null,automationName:"maestro",appId:e.appId,appTestMode:e.platform==="web"?"mobile-web":"native",udid:e.deviceId??null}}function cn(e){return e.logEntries.map(t=>({level:t.level==="ERROR"?"error":t.level==="WARN"?"warn":t.level==="DEBUG"?"debug":"info",text:t.message,timestamp:t.timestamp,location:null,source:"driver",tag:t.source??null,pid:null,stackTrace:null}))}function dn(e){return e.aiDefects.map(t=>({type:t.type,severity:t.severity,description:t.description,location:t.location,screenshot:t.screenshot}))}function pn(e,t){let r=Date.parse(e.startedAt),o=[...e.commands].sort((l,c)=>{let d=Date.parse(l.timestamp),p=Date.parse(c.timestamp);if(Number.isFinite(d)&&Number.isFinite(p)&&d!==p)return d-p;let u=l.sequenceNumber??0,b=c.sequenceNumber??0;return u-b}),n=[...e.assertions].sort((l,c)=>{let d=Date.parse(l.timestamp),p=Date.parse(c.timestamp);if(Number.isFinite(d)&&Number.isFinite(p)&&d!==p)return d-p;let u=l.sequenceNumber??0,b=c.sequenceNumber??0;return u-b}),s=[...o.map(l=>He(l,r)),...n.map(l=>He(l,r))];s.sort(an);let i=e.screenshotPaths.length>0||e.videoPath?{screenshot:e.screenshotPaths[0]??void 0,...e.screenshotPaths.length>0?{screenshots:[...e.screenshotPaths]}:{},video:e.videoPath??void 0}:null,a=[...e.tags];return {title:e.flowName,status:e.status,duration:e.duration,startedAt:e.startedAt,completedAt:e.completedAt,retryCount:0,tags:a,failure:e.failureMessage?{message:e.failureMessage,line:null,code:null,stack:null}:null,testId:`${e.flowFile}::${e.flowName}`,filePath:e.flowFile,suiteName:e.appId??"maestro-suite",testType:"mobile",isFlaky:false,retryStatus:null,expectedStatus:"passed",actualStatus:e.status,artifacts:i,networkRequests:null,apiCalls:t.length>0?[...t]:null,apiAssertions:null,actions:s.length>0?s:null,consoleLogs:e.logEntries.length>0?cn(e):null,device:ln(e),aiDefects:e.aiDefects.length>0?dn(e):null}}function zt(e,t){let r=`${e.flowFile}::${e.flowName}`,o=t?.get(r)??[],n=pn(e,o);return {url:e.appId??"maestro-flow",navigationType:"page_load",visitedAt:e.startedAt,duration:e.duration,specFile:e.flowFile,domContentLoadedAt:null,networkIdleAt:null,networkStats:null,tests:[n]}}function $e(e,t){return e.map(r=>zt(r,t))}var Ht={"2xx":0,"3xx":0,"4xx":0,"5xx":0,error:0};function un(e){return e===null?"error":e>=200&&e<300?"2xx":e>=300&&e<400?"3xx":e>=400&&e<500?"4xx":e>=500&&e<600?"5xx":"error"}function Be(e,t){if(e.length===0)return null;let r=Math.min(e.length-1,Math.floor(t/100*e.length));return e[r]}function fn(e){if(e.length===0)return {totalApiCalls:0,uniqueApiUrls:0,apiCallsByMethod:{},apiCallsByStatusRange:{...Ht},apiResponseTime:null};let t={},r={...Ht},o=new Set,n=[];for(let i of e)t[i.method]=(t[i.method]??0)+1,r[un(i.responseStatusCode)]+=1,o.add(i.url),Number.isFinite(i.responseTimeMs)&&i.responseTimeMs>0&&n.push(i.responseTimeMs);n.sort((i,a)=>i-a);let s=n.length>0?{p50:Be(n,50)??0,p95:Be(n,95)??0,p99:Be(n,99)??0,avg:n.reduce((i,a)=>i+a,0)/n.length,min:n[0],max:n[n.length-1]}:null;return {totalApiCalls:e.length,uniqueApiUrls:o.size,apiCallsByMethod:t,apiCallsByStatusRange:r,apiResponseTime:s}}function V(e){let t=0,r=0,o=0,n=0,s=0,i=0,a=0,l=0,c=0,d=e.length,p=0,u={},b=new Set,h=[];for(let v of e){b.add(v.url);for(let x of v.tests){switch(t++,x.status){case "passed":r++;break;case "failed":o++;break;case "flaky":n++;break;case "skipped":s++;break;case "timedout":i++;break}if(x.actions)for(let T of x.actions)if(p++,T.category==="assertion")a++,T.status==="passed"?l++:c++;else {let R=T.category;u[R]=(u[R]??0)+1;}x.apiCalls&&x.apiCalls.length>0&&h.push(...x.apiCalls);}}let g=fn(h);return {total:t,passed:r,failed:o,flaky:n,skipped:s,timedout:i,...g,totalAssertions:a,passedAssertions:l,failedAssertions:c,totalNavigations:d,uniqueNavigationUrls:b.size,totalTimelineSteps:e.length,totalActionSteps:p,actionStepsByCategory:u}}var $t=`
|
|
5
5
|
/* \u2500\u2500 Theme Variables (verbatim from Appium) \u2500\u2500 */
|
|
6
6
|
:root,[data-theme="dark"]{
|
|
7
7
|
--bg:#0f1117;--bg-1:#161b22;--bg-2:#1c2128;--bg-3:#21262d;--bg-code:#13111c;
|
|
@@ -875,7 +875,7 @@ function getCmdBadge(cat){
|
|
|
875
875
|
var pair=m[cat]||['CMD','cmd-badge-cmd'];
|
|
876
876
|
return '<span class="cmd-badge '+pair[1]+'">'+pair[0]+'</span>';
|
|
877
877
|
}
|
|
878
|
-
`;var
|
|
878
|
+
`;var Kt=`
|
|
879
879
|
function renderAssertionsTab(flow){
|
|
880
880
|
var actions=flow.test.actions||[];
|
|
881
881
|
var asserts=actions.filter(function(a){return a.category==='assertion'});
|
|
@@ -906,7 +906,7 @@ function renderAssertionsTab(flow){
|
|
|
906
906
|
h+='</tbody></table>';
|
|
907
907
|
return h;
|
|
908
908
|
}
|
|
909
|
-
`;var
|
|
909
|
+
`;var Jt=`
|
|
910
910
|
function renderAiDefectsTab(){
|
|
911
911
|
if(aiDefects.length===0)return '<div class="ai-empty">\\u2714 No AI defects detected.</div>';
|
|
912
912
|
var h='<div style="font-size:12px;color:var(--fg-1);margin-bottom:16px">'+aiDefects.length+' defect'+(aiDefects.length>1?'s':'')+' found by Maestro AI analysis</div>';
|
|
@@ -1729,8 +1729,8 @@ document.addEventListener('keydown',function(e){
|
|
|
1729
1729
|
${Gt}
|
|
1730
1730
|
${qt}
|
|
1731
1731
|
${Vt}
|
|
1732
|
-
${Jt}
|
|
1733
1732
|
${Kt}
|
|
1733
|
+
${Jt}
|
|
1734
1734
|
${Wt}
|
|
1735
1735
|
${Yt}
|
|
1736
1736
|
|
|
@@ -1835,10 +1835,10 @@ document.addEventListener('keydown',function(e){
|
|
|
1835
1835
|
Set --skip-cert-install to silence this hint.`),{teardown:async()=>{await tr(["shell","settings","put","global","http_proxy",":0"],t);}})}async function Ln(e){return new Promise(t=>{let r=child_process.spawn("xcrun",e,{stdio:["ignore","pipe","pipe"]}),o="",n="";r.stdout?.on("data",s=>{o+=s.toString();}),r.stderr?.on("data",s=>{n+=s.toString();}),r.on("error",()=>t({code:127,stdout:o,stderr:n||"xcrun not on PATH"})),r.on("close",s=>t({code:s??1,stdout:o,stderr:n}));})}async function Nn(e){let{proxyHost:t,proxyPort:r,quiet:o,skipCertInstall:n}=e;if(process.platform!=="darwin")return E(o,"\u26A0 TestRelic: iOS simulator capture requires macOS; the host is not Darwin. Skipping setup."),U(o,"ios",t,r),H;if(!or("xcrun"))return E(o,"\u26A0 TestRelic: `xcrun` not on PATH; skipping automatic iOS simulator setup."),U(o,"ios",t,r),H;if(!n){let s=path.join(process.env.HOME??"",".mitmproxy","mitmproxy-ca-cert.pem");if(fs.existsSync(s)){let i=e.deviceId??"booted",a=await Ln(["simctl","keychain",i,"add-root-cert",s]);a.code===0?E(o,`\u2139 TestRelic: installed mitmproxy CA on iOS simulator (${i}).`):(E(o,`\u26A0 TestRelic: failed to add-root-cert via simctl: ${a.stderr.trim()}`),U(o,"ios",t,r));}else E(o,`\u26A0 TestRelic: mitmproxy CA not found at ${s}. Run mitmdump once to generate it,
|
|
1836
1836
|
then re-run with --capture-network. Falling back to manual instructions:`),U(o,"ios",t,r);}return E(o,`\u2139 TestRelic: in the iOS simulator, configure Wi-Fi \u2192 (i) \u2192 Manual proxy:
|
|
1837
1837
|
Server: ${t} Port: ${r}
|
|
1838
|
-
(We do not set host-wide \`networksetup\` proxy automatically; see docs.)`),H}async function nr(e){switch(e.platform){case "android":return _n(e);case "ios":return Nn(e);case "web":return E(e.quiet,"\u2139 TestRelic: --capture-network ignored for Maestro web flows (browser already handles HTTP)."),H;default:return E(e.quiet,"\u26A0 TestRelic: target platform unknown; printing manual proxy setup instructions:"),U(e.quiet,"android",e.proxyHost,e.proxyPort),U(e.quiet,"ios",e.proxyHost,e.proxyPort),H}}function $n(){let e=crypto.randomBytes(8).toString("hex");return path.join(os.tmpdir(),`testrelic-maestro-${e}`)}function ir(e,t){let r=[];e.platform&&r.push("--platform",e.platform),e.device&&r.push("--device",e.device),r.push("test");let o=path.join(t,"report.xml"),n=path.join(t,"artifacts"),s=path.join(t,"debug");if(r.push("--format","junit"),r.push("--output",o),r.push("--test-output-dir",n),r.push("--debug-output",s),e.analyze&&r.push("--analyze"),e.includeTags&&r.push("--include-tags",e.includeTags),e.excludeTags&&r.push("--exclude-tags",e.excludeTags),e.shards&&e.shards>1&&r.push("--shards",String(e.shards)),e.config&&r.push("--config",e.config),e.env)for(let[i,a]of Object.entries(e.env))r.push("-e",`${i}=${a}`);return e.maestroArgs&&r.push(...e.maestroArgs),r.push(...e.flowPaths),r}function Bn(e){switch((e??"").toLowerCase()){case "android":return "android";case "ios":return "ios";case "web":return "web";default:return "unknown"}}function jn(e,t,r,o,n,s,i){return new Promise(a=>{let l=[],c=[],d=child_process.spawn("maestro",e,{stdio:["inherit","pipe","pipe"]});d.stdout.on("data",p=>{l.push(p),s||process.stdout.write(p);}),d.stderr.on("data",p=>{c.push(p),s||process.stderr.write(p);}),d.on("close",async p=>{try{await i();}catch{}a({exitCode:p??1,junitPath:t,testOutputDir:r,debugOutputDir:o,stdout:Buffer.concat(l).toString("utf-8"),stderr:Buffer.concat(c).toString("utf-8"),networkJsonlDir:n});}),d.on("error",async p=>{try{await i();}catch{}a({exitCode:127,junitPath:t,testOutputDir:r,debugOutputDir:o,stdout:"",stderr:`Failed to start maestro CLI: ${p.message}`,networkJsonlDir:n});});})}async function Gn(e,t={}){let r=e.outputDir?path.resolve(e.outputDir):$n();fs.mkdirSync(path.join(r,"artifacts"),{recursive:true}),fs.mkdirSync(path.join(r,"debug"),{recursive:true});let o=ir(e,r),n=path.join(r,"report.xml"),s=path.join(r,"artifacts"),i=path.join(r,"debug"),a=null,l=null,c=t.network;if(c?.enabled){let u=path.join(r,"network");a=await er({config:c,outputDir:u,verbose:!e.quiet}),a&&(l=await nr({platform:Bn(e.platform),deviceId:e.device,proxyHost:a.host,proxyPort:a.port,skipCertInstall:c.skipCertInstall,quiet:e.quiet}));}let d=a?.outputDir??null,p=async()=>{if(a&&await new Promise(u=>setTimeout(u,500)),l)try{await l.teardown();}catch{}if(a)try{await a.stop();}catch{}};return jn(o,n,s,i,d,e.quiet,p)}var cr="[REDACTED]";function ar(e,t){if(!e)return null;let r=new Set(t.map(n=>n.toLowerCase())),o={};for(let[n,s]of Object.entries(e))o[n]=r.has(n.toLowerCase())?cr:s;return o}function Je(e,t){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(o=>Je(o,t));let r={};for(let[o,n]of Object.entries(e))r[o]=t.has(o)?cr:Je(n,t);return r}function lr(e,t){if(!e||t.length===0)return e;try{let r=JSON.parse(e),o=Je(r,new Set(t));return JSON.stringify(o)}catch{return e}}function Ke(e,t,r){return {...e,requestHeaders:ar(e.requestHeaders,t),responseHeaders:ar(e.responseHeaders,t),requestBody:lr(e.requestBody,r),responseBody:e.isBinary?e.responseBody:lr(e.responseBody,r)}}function We(e,t,r){let o=n=>typeof n=="string"?e.includes(n):n.test(e);return r.some(o)?false:t.length===0?true:t.some(o)}function Jn(e){let t=e.trim();if(!t)return null;try{let r=JSON.parse(t);return typeof r.url!="string"||typeof r.method!="string"?null:{id:r.id??`api-call-${Date.now()}`,timestamp:r.timestamp??new Date().toISOString(),method:r.method,url:r.url,requestHeaders:r.requestHeaders??null,requestBody:r.requestBody??null,responseStatusCode:r.responseStatusCode??null,responseStatusText:r.responseStatusText??null,responseHeaders:r.responseHeaders??null,responseBody:r.responseBody??null,responseTimeMs:typeof r.responseTimeMs=="number"?r.responseTimeMs:0,isBinary:r.isBinary??!1,error:r.error??null}}catch{return null}}function Kn(e,t){let r=[];for(let o of e.split(/\r?\n/)){let n=Jn(o);n&&We(n.url,t.includeUrls,t.excludeUrls)&&r.push(Ke(n,t.redactHeaders,t.redactBodyFields));}return r}function Wn(e,t){try{return Kn(fs.readFileSync(e,"utf-8"),t)}catch{return []}}function Yn(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>t.endsWith(".jsonl")).map(t=>path.join(e,t))}catch{return []}}function dr(e){if(!e||e.length===0)return null;let t={};for(let r of e)typeof r.name=="string"&&typeof r.value=="string"&&(t[r.name]=r.value);return Object.keys(t).length>0?t:null}function Xn(e){return e?typeof e.text=="string"?e.text:Array.isArray(e.params)?e.params.map(t=>`${encodeURIComponent(t.name)}=${encodeURIComponent(t.value??"")}`).join("&"):null:null}function Qn(e){return e?/^(image|audio|video|application\/(octet-stream|pdf|zip|protobuf))/.test(e):false}function Zn(e,t){let r=e.request,o=e.response;if(!r?.method||!r.url)return null;let n=o?.content,s=Qn(n?.mimeType);return {id:`har-call-${t}`,timestamp:e.startedDateTime??new Date().toISOString(),method:r.method,url:r.url,requestHeaders:dr(r.headers),requestBody:Xn(r.postData),responseStatusCode:typeof o?.status=="number"&&o.status>0?o.status:null,responseStatusText:o?.statusText??null,responseHeaders:dr(o?.headers),responseBody:n?.text??null,responseTimeMs:typeof e.time=="number"?e.time:0,isBinary:s,error:null}}function es(e,t){let r;try{r=JSON.parse(e);}catch{return []}let o=r.log?.entries??[],n=[];return o.forEach((s,i)=>{let a=Zn(s,i);a&&We(a.url,t.includeUrls,t.excludeUrls)&&n.push(Ke(a,t.redactHeaders,t.redactBodyFields));}),n}function ts(e,t){try{return es(fs.readFileSync(e,"utf-8"),t)}catch{return []}}function rs(e,t){let r=new Map;for(let n of t)r.set(n.testId,[]);if(e.length===0||t.length===0)return r;let o=t.map(n=>({testId:n.testId,startMs:Date.parse(n.startedAt),endMs:Date.parse(n.completedAt)}));for(let n of e){let s=Date.parse(n.timestamp);if(!Number.isFinite(s))continue;let i=o.find(l=>Number.isFinite(l.startMs)&&Number.isFinite(l.endMs)&&s>=l.startMs&&s<=l.endMs);if(i){r.get(i.testId).push(n);continue}let a=null;for(let l of o){if(!Number.isFinite(l.startMs)||!Number.isFinite(l.endMs))continue;let c=s<l.startMs?l.startMs-s:s-l.endMs;(!a||c<a.dist)&&(a={testId:l.testId,dist:c});}a&&r.get(a.testId).push(n);}return r}function fr(e,t,r){if(!t.enabled&&!t.harPath)return new Map;let o=[];if(e)for(let n of Yn(e))o.push(...Wn(n,t));return t.harPath&&fs.existsSync(t.harPath)&&o.push(...ts(t.harPath,t)),o.length===0?new Map:rs(o,r)}function gr(e){return e.map((t,r)=>({...t,id:`api-call-${r}`}))}var ss=new Set(["localhost","127.0.0.1","0.0.0.0"]);function Ye(e){let t=new URL(e);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&ss.has(t.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${t.protocol}//${t.hostname}`)}var is=3e3;async function te(e){let t=new AbortController,r=setTimeout(()=>t.abort(),is);try{return (await fetch(`${e}/health`,{method:"GET",signal:t.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function hr(e){return new Promise(t=>setTimeout(t,e))}async function mr(e){try{let r=(await e.json()).error;if(r&&typeof r.message=="string")return r.message}catch{}return `HTTP ${e.status}`}async function re(e,t,r){let o=new AbortController,n=setTimeout(()=>o.abort(),r);try{let s=await fetch(`${e}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:t}),signal:o.signal});if(s.ok){let a=await s.json();return {accessToken:a.accessToken,refreshToken:a.refreshToken,expiresIn:a.expiresIn,orgId:a.orgId,orgName:a.orgName,userId:a.userId,userName:a.userName}}if(s.status===429){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:5e3;if(!isNaN(l)&&l>0){await hr(l);let c=await fetch(`${e}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:t}),signal:o.signal});if(c.ok){let d=await c.json();return {accessToken:d.accessToken,refreshToken:d.refreshToken,expiresIn:d.expiresIn,orgId:d.orgId,orgName:d.orgName,userId:d.userId,userName:d.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return s.status===400?{code:"validation_error",message:await mr(s),statusCode:400}:s.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:s.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await mr(s),statusCode:s.status}}catch(s){return s instanceof DOMException&&s.name==="AbortError"?{code:"timeout",message:"Token exchange timed out.",statusCode:null}:{code:"network_error",message:"Failed to reach cloud for token exchange.",statusCode:null}}finally{clearTimeout(n);}}function oe(e){return "code"in e&&typeof e.code=="string"&&["invalid_key","expired_key","validation_error","rate_limited","server_error","network_error","timeout"].includes(e.code)}async function Xe(e,t,r){let o=new AbortController,n=setTimeout(()=>o.abort(),r);try{let s=await fetch(`${e}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:t}),signal:o.signal});if(s.status===429){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:5e3;!isNaN(l)&&l>0&&(await hr(l),s=await fetch(`${e}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:t}),signal:o.signal}));}if(!s.ok)return null;let i=await s.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn}}catch{return null}finally{clearTimeout(n);}}async function Qe(e,t,r,o,n,s){let i=new AbortController,a=setTimeout(()=>i.abort(),n);try{let l={gitId:r,displayName:o};s&&(l.branch=s);let c=await fetch(`${e}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(l),signal:i.signal});if(!c.ok)return null;let d=await c.json();return {repoId:d.repoId,displayName:d.displayName}}catch{return null}finally{clearTimeout(a);}}var ps=5e3;function z(e,t){try{return child_process.execSync(e,{cwd:t,timeout:ps,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Ze(e){let t=z("git rev-parse --abbrev-ref HEAD",e),r=z("git rev-parse --short HEAD",e),o=z("git log -1 --pretty=%s",e),n=z("git log -1 --format=%an",e)??z("git config user.name",e),s=us(e),i=s?B(s):null;return {branch:t,commitSha:r,commitMessage:o,commitAuthor:n,remoteUrl:i}}function us(e){let t=z("git remote get-url origin",e);if(t)return t;let r=z("git remote",e);if(!r)return null;let o=r.split(`
|
|
1838
|
+
(We do not set host-wide \`networksetup\` proxy automatically; see docs.)`),H}async function nr(e){switch(e.platform){case "android":return _n(e);case "ios":return Nn(e);case "web":return E(e.quiet,"\u2139 TestRelic: --capture-network ignored for Maestro web flows (browser already handles HTTP)."),H;default:return E(e.quiet,"\u26A0 TestRelic: target platform unknown; printing manual proxy setup instructions:"),U(e.quiet,"android",e.proxyHost,e.proxyPort),U(e.quiet,"ios",e.proxyHost,e.proxyPort),H}}function $n(){let e=crypto.randomBytes(8).toString("hex");return path.join(os.tmpdir(),`testrelic-maestro-${e}`)}function ir(e,t){let r=[];e.platform&&r.push("--platform",e.platform),e.device&&r.push("--device",e.device),r.push("test");let o=path.join(t,"report.xml"),n=path.join(t,"artifacts"),s=path.join(t,"debug");if(r.push("--format","junit"),r.push("--output",o),r.push("--test-output-dir",n),r.push("--debug-output",s),e.analyze&&r.push("--analyze"),e.includeTags&&r.push("--include-tags",e.includeTags),e.excludeTags&&r.push("--exclude-tags",e.excludeTags),e.shards&&e.shards>1&&r.push("--shards",String(e.shards)),e.config&&r.push("--config",e.config),e.env)for(let[i,a]of Object.entries(e.env))r.push("-e",`${i}=${a}`);return e.maestroArgs&&r.push(...e.maestroArgs),r.push(...e.flowPaths),r}function Bn(e){switch((e??"").toLowerCase()){case "android":return "android";case "ios":return "ios";case "web":return "web";default:return "unknown"}}function jn(e,t,r,o,n,s,i){return new Promise(a=>{let l=[],c=[],d=child_process.spawn("maestro",e,{stdio:["inherit","pipe","pipe"]});d.stdout.on("data",p=>{l.push(p),s||process.stdout.write(p);}),d.stderr.on("data",p=>{c.push(p),s||process.stderr.write(p);}),d.on("close",async p=>{try{await i();}catch{}a({exitCode:p??1,junitPath:t,testOutputDir:r,debugOutputDir:o,stdout:Buffer.concat(l).toString("utf-8"),stderr:Buffer.concat(c).toString("utf-8"),networkJsonlDir:n});}),d.on("error",async p=>{try{await i();}catch{}a({exitCode:127,junitPath:t,testOutputDir:r,debugOutputDir:o,stdout:"",stderr:`Failed to start maestro CLI: ${p.message}`,networkJsonlDir:n});});})}async function Gn(e,t={}){let r=e.outputDir?path.resolve(e.outputDir):$n();fs.mkdirSync(path.join(r,"artifacts"),{recursive:true}),fs.mkdirSync(path.join(r,"debug"),{recursive:true});let o=ir(e,r),n=path.join(r,"report.xml"),s=path.join(r,"artifacts"),i=path.join(r,"debug"),a=null,l=null,c=t.network;if(c?.enabled){let u=path.join(r,"network");a=await er({config:c,outputDir:u,verbose:!e.quiet}),a&&(l=await nr({platform:Bn(e.platform),deviceId:e.device,proxyHost:a.host,proxyPort:a.port,skipCertInstall:c.skipCertInstall,quiet:e.quiet}));}let d=a?.outputDir??null,p=async()=>{if(a&&await new Promise(u=>setTimeout(u,500)),l)try{await l.teardown();}catch{}if(a)try{await a.stop();}catch{}};return jn(o,n,s,i,d,e.quiet,p)}var cr="[REDACTED]";function ar(e,t){if(!e)return null;let r=new Set(t.map(n=>n.toLowerCase())),o={};for(let[n,s]of Object.entries(e))o[n]=r.has(n.toLowerCase())?cr:s;return o}function Ke(e,t){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(o=>Ke(o,t));let r={};for(let[o,n]of Object.entries(e))r[o]=t.has(o)?cr:Ke(n,t);return r}function lr(e,t){if(!e||t.length===0)return e;try{let r=JSON.parse(e),o=Ke(r,new Set(t));return JSON.stringify(o)}catch{return e}}function Je(e,t,r){return {...e,requestHeaders:ar(e.requestHeaders,t),responseHeaders:ar(e.responseHeaders,t),requestBody:lr(e.requestBody,r),responseBody:e.isBinary?e.responseBody:lr(e.responseBody,r)}}function We(e,t,r){let o=n=>typeof n=="string"?e.includes(n):n.test(e);return r.some(o)?false:t.length===0?true:t.some(o)}function Kn(e){let t=e.trim();if(!t)return null;try{let r=JSON.parse(t);return typeof r.url!="string"||typeof r.method!="string"?null:{id:r.id??`api-call-${Date.now()}`,timestamp:r.timestamp??new Date().toISOString(),method:r.method,url:r.url,requestHeaders:r.requestHeaders??null,requestBody:r.requestBody??null,responseStatusCode:r.responseStatusCode??null,responseStatusText:r.responseStatusText??null,responseHeaders:r.responseHeaders??null,responseBody:r.responseBody??null,responseTimeMs:typeof r.responseTimeMs=="number"?r.responseTimeMs:0,isBinary:r.isBinary??!1,error:r.error??null}}catch{return null}}function Jn(e,t){let r=[];for(let o of e.split(/\r?\n/)){let n=Kn(o);n&&We(n.url,t.includeUrls,t.excludeUrls)&&r.push(Je(n,t.redactHeaders,t.redactBodyFields));}return r}function Wn(e,t){try{return Jn(fs.readFileSync(e,"utf-8"),t)}catch{return []}}function Yn(e){if(!fs.existsSync(e))return [];try{return fs.readdirSync(e,{recursive:!0}).map(String).filter(t=>t.endsWith(".jsonl")).map(t=>path.join(e,t))}catch{return []}}function dr(e){if(!e||e.length===0)return null;let t={};for(let r of e)typeof r.name=="string"&&typeof r.value=="string"&&(t[r.name]=r.value);return Object.keys(t).length>0?t:null}function Xn(e){return e?typeof e.text=="string"?e.text:Array.isArray(e.params)?e.params.map(t=>`${encodeURIComponent(t.name)}=${encodeURIComponent(t.value??"")}`).join("&"):null:null}function Qn(e){return e?/^(image|audio|video|application\/(octet-stream|pdf|zip|protobuf))/.test(e):false}function Zn(e,t){let r=e.request,o=e.response;if(!r?.method||!r.url)return null;let n=o?.content,s=Qn(n?.mimeType);return {id:`har-call-${t}`,timestamp:e.startedDateTime??new Date().toISOString(),method:r.method,url:r.url,requestHeaders:dr(r.headers),requestBody:Xn(r.postData),responseStatusCode:typeof o?.status=="number"&&o.status>0?o.status:null,responseStatusText:o?.statusText??null,responseHeaders:dr(o?.headers),responseBody:n?.text??null,responseTimeMs:typeof e.time=="number"?e.time:0,isBinary:s,error:null}}function es(e,t){let r;try{r=JSON.parse(e);}catch{return []}let o=r.log?.entries??[],n=[];return o.forEach((s,i)=>{let a=Zn(s,i);a&&We(a.url,t.includeUrls,t.excludeUrls)&&n.push(Je(a,t.redactHeaders,t.redactBodyFields));}),n}function ts(e,t){try{return es(fs.readFileSync(e,"utf-8"),t)}catch{return []}}function rs(e,t){let r=new Map;for(let n of t)r.set(n.testId,[]);if(e.length===0||t.length===0)return r;let o=t.map(n=>({testId:n.testId,startMs:Date.parse(n.startedAt),endMs:Date.parse(n.completedAt)}));for(let n of e){let s=Date.parse(n.timestamp);if(!Number.isFinite(s))continue;let i=o.find(l=>Number.isFinite(l.startMs)&&Number.isFinite(l.endMs)&&s>=l.startMs&&s<=l.endMs);if(i){r.get(i.testId).push(n);continue}let a=null;for(let l of o){if(!Number.isFinite(l.startMs)||!Number.isFinite(l.endMs))continue;let c=s<l.startMs?l.startMs-s:s-l.endMs;(!a||c<a.dist)&&(a={testId:l.testId,dist:c});}a&&r.get(a.testId).push(n);}return r}function fr(e,t,r){if(!t.enabled&&!t.harPath)return new Map;let o=[];if(e)for(let n of Yn(e))o.push(...Wn(n,t));return t.harPath&&fs.existsSync(t.harPath)&&o.push(...ts(t.harPath,t)),o.length===0?new Map:rs(o,r)}function gr(e){return e.map((t,r)=>({...t,id:`api-call-${r}`}))}var ss=new Set(["localhost","127.0.0.1","0.0.0.0"]);function Ye(e){let t=new URL(e);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&ss.has(t.hostname)))throw core.createError(core.ErrorCode.CLOUD_CONFIG_INVALID,`HTTPS is required for cloud communication. Got: ${t.protocol}//${t.hostname}`)}var is=3e3;async function te(e){let t=new AbortController,r=setTimeout(()=>t.abort(),is);try{return (await fetch(`${e}/health`,{method:"GET",signal:t.signal})).ok}catch{return false}finally{clearTimeout(r);}}async function hr(e){return new Promise(t=>setTimeout(t,e))}async function mr(e){try{let r=(await e.json()).error;if(r&&typeof r.message=="string")return r.message}catch{}return `HTTP ${e.status}`}async function re(e,t,r){let o=new AbortController,n=setTimeout(()=>o.abort(),r);try{let s=await fetch(`${e}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:t}),signal:o.signal});if(s.ok){let a=await s.json();return {accessToken:a.accessToken,refreshToken:a.refreshToken,expiresIn:a.expiresIn,orgId:a.orgId,orgName:a.orgName,userId:a.userId,userName:a.userName}}if(s.status===429){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:5e3;if(!isNaN(l)&&l>0){await hr(l);let c=await fetch(`${e}/sdk/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:t}),signal:o.signal});if(c.ok){let d=await c.json();return {accessToken:d.accessToken,refreshToken:d.refreshToken,expiresIn:d.expiresIn,orgId:d.orgId,orgName:d.orgName,userId:d.userId,userName:d.userName}}}return {code:"rate_limited",message:"Rate limited during token exchange.",statusCode:429}}return s.status===400?{code:"validation_error",message:await mr(s),statusCode:400}:s.status===401?{code:"invalid_key",message:"API key is invalid or has been revoked.",statusCode:401}:s.status===403?{code:"expired_key",message:"API key has expired.",statusCode:403}:{code:"server_error",message:await mr(s),statusCode:s.status}}catch(s){return s instanceof DOMException&&s.name==="AbortError"?{code:"timeout",message:"Token exchange timed out.",statusCode:null}:{code:"network_error",message:"Failed to reach cloud for token exchange.",statusCode:null}}finally{clearTimeout(n);}}function oe(e){return "code"in e&&typeof e.code=="string"&&["invalid_key","expired_key","validation_error","rate_limited","server_error","network_error","timeout"].includes(e.code)}async function Xe(e,t,r){let o=new AbortController,n=setTimeout(()=>o.abort(),r);try{let s=await fetch(`${e}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:t}),signal:o.signal});if(s.status===429){let a=s.headers.get("Retry-After"),l=a?parseInt(a,10)*1e3:5e3;!isNaN(l)&&l>0&&(await hr(l),s=await fetch(`${e}/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:t}),signal:o.signal}));}if(!s.ok)return null;let i=await s.json();return {accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn}}catch{return null}finally{clearTimeout(n);}}async function Qe(e,t,r,o,n,s){let i=new AbortController,a=setTimeout(()=>i.abort(),n);try{let l={gitId:r,displayName:o};s&&(l.branch=s);let c=await fetch(`${e}/repos/resolve`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(l),signal:i.signal});if(!c.ok)return null;let d=await c.json();return {repoId:d.repoId,displayName:d.displayName}}catch{return null}finally{clearTimeout(a);}}var ps=5e3;function z(e,t){try{return child_process.execSync(e,{cwd:t,timeout:ps,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}}function Ze(e){let t=z("git rev-parse --abbrev-ref HEAD",e),r=z("git rev-parse --short HEAD",e),o=z("git log -1 --pretty=%s",e),n=z("git log -1 --format=%an",e)??z("git config user.name",e),s=us(e),i=s?B(s):null;return {branch:t,commitSha:r,commitMessage:o,commitAuthor:n,remoteUrl:i}}function us(e){let t=z("git remote get-url origin",e);if(t)return t;let r=z("git remote",e);if(!r)return null;let o=r.split(`
|
|
1839
1839
|
`)[0]?.trim();return o?z(`git remote get-url ${o}`,e):null}function B(e){let t=e.trim();return t=t.replace(/^[a-z+]+:\/\//,""),t=t.replace(/^[^@]+@/,""),t=t.replace(/:(?!\d)/,"/"),t=t.replace(/\.git$/,""),t=t.replace(/\/+$/,""),t=t.replace(/^[^@/]+@/,""),t.toLowerCase()}function et(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function br(e){try{let t=fs.readFileSync(path.join(e,"package.json"),"utf-8"),r=JSON.parse(t);return typeof r.name=="string"&&r.name.length>0?r.name:null}catch{return null}}function j(e){let t=br(e);return t||`local/${path.basename(e)}`}var vs="1.0.0",vr=10;function se(e,t,r,o,n,s,i,a){try{fs.mkdirSync(e,{recursive:!0});let l=Date.now(),c=`${l}-${t}-${r}.json`,d=path.join(e,c),p={version:vs,queuedAt:new Date(l).toISOString(),reason:o,retryCount:0,targetEndpoint:n,method:s,payload:i,headers:a},u=d+".tmp";fs.writeFileSync(u,JSON.stringify(p,null,2),"utf-8"),fs.renameSync(u,d);}catch(l){l.code==="ENOSPC"?process.stderr.write(`\u26A0 TestRelic: Disk full \u2014 unable to queue upload data.
|
|
1840
1840
|
`):process.stderr.write(`\u26A0 TestRelic: Unable to queue upload data.
|
|
1841
|
-
`);}}async function rt(e,t,r){let o;try{o=fs.readdirSync(e).filter(s=>s.endsWith(".json")&&!s.endsWith(".tmp")).sort();}catch{return}if(o.length===0)return;let n=[];for(let s=0;s<o.length;s+=vr)n.push(o.slice(s,s+vr));for(let s of n)for(let i of s){let a=path.join(e,i);try{if(!fs.statSync(a).isFile())continue;let c=fs.readFileSync(a,"utf-8"),d=JSON.parse(c);if(!core.isValidQueueEntry(d)){fs.unlinkSync(a);continue}let p=d;if((await fetch(p.targetEndpoint,{method:p.method,headers:{...p.headers,Authorization:`Bearer ${r}`},body:JSON.stringify(p.payload)})).ok)fs.unlinkSync(a);else return}catch{return}}}function ot(e,t){try{let r=fs.readdirSync(e).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")),o=Date.now();for(let n of r){let s=path.join(e,n);try{let i=fs.readFileSync(s,"utf-8"),l=JSON.parse(i).queuedAt;if(typeof l=="string"){let c=new Date(l).getTime();o-c>t&&fs.unlinkSync(s);}}catch{try{fs.unlinkSync(s);}catch{}}}}catch{}}var Ss=3e5,Ts=864e5,As=6e4,wr=3e4,kr="https://platform.testrelic.ai/settings/api-keys";function Cr(e){return new Promise(t=>{let r=setTimeout(t,e);typeof r?.unref=="function"&&r.unref();})}var
|
|
1841
|
+
`);}}async function rt(e,t,r){let o;try{o=fs.readdirSync(e).filter(s=>s.endsWith(".json")&&!s.endsWith(".tmp")).sort();}catch{return}if(o.length===0)return;let n=[];for(let s=0;s<o.length;s+=vr)n.push(o.slice(s,s+vr));for(let s of n)for(let i of s){let a=path.join(e,i);try{if(!fs.statSync(a).isFile())continue;let c=fs.readFileSync(a,"utf-8"),d=JSON.parse(c);if(!core.isValidQueueEntry(d)){fs.unlinkSync(a);continue}let p=d;if((await fetch(p.targetEndpoint,{method:p.method,headers:{...p.headers,Authorization:`Bearer ${r}`},body:JSON.stringify(p.payload)})).ok)fs.unlinkSync(a);else return}catch{return}}}function ot(e,t){try{let r=fs.readdirSync(e).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")),o=Date.now();for(let n of r){let s=path.join(e,n);try{let i=fs.readFileSync(s,"utf-8"),l=JSON.parse(i).queuedAt;if(typeof l=="string"){let c=new Date(l).getTime();o-c>t&&fs.unlinkSync(s);}}catch{try{fs.unlinkSync(s);}catch{}}}}catch{}}var Ss=3e5,Ts=864e5,As=6e4,wr=3e4,kr="https://platform.testrelic.ai/settings/api-keys";function Cr(e){return new Promise(t=>{let r=setTimeout(t,e);typeof r?.unref=="function"&&r.unref();})}var J=class{constructor(t){this.gitMetadata=null;this.repoId=null;this.failureReason=null;this.flushPromise=null;this.healthCheckTimer=null;this.config=t,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.
|
|
1842
1842
|
`);return}try{if(Ye(this.config.endpoint),this.gitMetadata=Ze(),!await te(this.config.endpoint)){this.setLocalMode("cloud_unreachable"),process.stderr.write(`\u26A0 TestRelic: Cloud unreachable. Switching to local mode.
|
|
1843
1843
|
`);return}let r=await re(this.config.endpoint,this.config.apiKey,this.config.timeout);if(oe(r)){this.handleAuthError(r.code,r.statusCode);return}let o=r;this.authState={mode:"cloud",accessToken:o.accessToken,refreshToken:o.refreshToken,expiresAt:Date.now()+o.expiresIn*1e3,orgId:o.orgId,orgName:o.orgName,userId:o.userId,userName:o.userName},process.stderr.write(`\u2713 TestRelic: Connected to cloud (${o.orgName} / ${o.userName})
|
|
1844
1844
|
`),await this.resolveRepoId(),this.config.queueDirectory&&(ot(this.config.queueDirectory,this.config.queueMaxAge),this.startBackgroundFlush()),this.startHealthCheck();}catch(t){this.setLocalMode("unexpected_error"),process.stderr.write(`\u26A0 TestRelic: Unexpected error during cloud initialization. ${t instanceof Error?t.message:String(t)}
|
|
@@ -1850,11 +1850,11 @@ document.addEventListener('keydown',function(e){
|
|
|
1850
1850
|
`);break;case "rate_limited":this.setLocalMode("rate_limited"),process.stderr.write(`\u26A0 TestRelic: Rate limited during authentication. Running in local mode.
|
|
1851
1851
|
`);break;default:this.setLocalMode(`auth_error_${r??"unknown"}`),process.stderr.write(`\u26A0 TestRelic: Cloud authentication failed. Running in local mode.
|
|
1852
1852
|
`);break}}async resolveRepoId(){if(!this.config||!this.authState.accessToken)return;let t=this.gitMetadata?.remoteUrl?B(this.gitMetadata.remoteUrl):null,r=t?et(t):this.config.projectName??j(process.cwd()),o=t??this.config.projectName??j(process.cwd()),n=this.readRepoCache(o);if(n){this.repoId=n.repoId;return}try{let s=await Qe(this.config.endpoint,this.authState.accessToken,o,r,this.config.timeout,this.gitMetadata?.branch);s&&(this.repoId=s.repoId,this.writeRepoCache(o,s.repoId,s.displayName));}catch{}}readRepoCache(t){if(!this.config)return null;let r=path.join(this.config.queueDirectory,"..","cache","repo.json");try{if(!fs.existsSync(r))return null;let o=fs.readFileSync(r,"utf-8"),n=JSON.parse(o);if(n.gitId!==t||Date.now()-n.resolvedAt>Ts)return null;let s=this.hashApiKey();return s&&n.apiKeyHash!==s?null:n}catch{return null}}writeRepoCache(t,r,o){if(!this.config)return;let n=path.join(this.config.queueDirectory,"..","cache"),s=path.join(n,"repo.json");try{fs.mkdirSync(n,{recursive:!0});let i={repoId:r,gitId:t,displayName:o,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},a=s+".tmp";fs.writeFileSync(a,JSON.stringify(i,null,2),"utf-8"),fs.renameSync(a,s);}catch{}}hashApiKey(){return this.config?.apiKey?crypto.createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let t=this.authState.accessToken,r=this.config.queueDirectory,o=this.config.endpoint;this.flushPromise=Promise.race([rt(r,o,t),Cr(wr)]).catch(()=>{});}startHealthCheck(){if(!this.config)return;let t=this.config.endpoint;this.healthCheckTimer=setInterval(async()=>{if(!this.isCloudMode()&&!(!this.failureReason||!["cloud_unreachable","auth_timeout","network_error"].includes(this.failureReason)))try{if(!await te(t))return;if(this.config?.apiKey){let o=await re(this.config.endpoint,this.config.apiKey,this.config.timeout);if(!oe(o)){let n=o;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.
|
|
1853
|
-
`),this.startBackgroundFlush();}}}catch{}},As),typeof this.healthCheckTimer?.unref=="function"&&this.healthCheckTimer.unref();}};var Is=1048576,ie=[1e3,3e3,9e3],ae=3;function ce(e,t,r,o,n){let s=o?.provider&&o.provider!=="unknown"?o.provider:"local";return {runId:e.testRunId,repoGitId:t,startedAt:e.startedAt,summary:e.summary,timeline:e.timeline,environment:s,testFramework:"maestro",testType:"mobile",...n&&n.length>0?{tests:n}:{},...r?.branch?{branch:r.branch}:{},...r?.commitSha?{commit:r.commitSha}:{},...r?.commitMessage?{commitMessage:r.commitMessage}:{},...r?.commitAuthor?{commitAuthor:r.commitAuthor}:{},...e.completedAt?{finishedAt:e.completedAt}:{},...e.totalDuration?{duration:e.totalDuration}:{},...o?.provider?{ciProvider:o.provider}:{},...o?.runUrl?{ciRunUrl:o.runUrl}:{}}}async function le(e){return new Promise(t=>setTimeout(t,e))}async function Rr(e,t,r){for(let o=0;o<ae;o++)try{let n=await fetch(e,t);if(n.ok)return n;if(n.status===401&&r&&o===0){let s=await r();if(s){let i={...t,headers:{...t.headers,Authorization:`Bearer ${s}`}},a=await fetch(e,i);if(a.ok)return a}return null}if(n.status===429&&o<ae-1){let s=n.headers.get("Retry-After"),i=s?parseInt(s,10)*1e3:ie[o];!isNaN(i)&&i>0?await le(i):await le(ie[o]);continue}if(n.status>=500&&o<ae-1){await le(ie[o]);continue}return n}catch{if(o<ae-1){await le(ie[o]);continue}return null}return null}function Es(e){let t=JSON.stringify(e),r={"Content-Type":"application/json"};if(Buffer.byteLength(t,"utf-8")>Is){let o=zlib.gzipSync(Buffer.from(t,"utf-8"));return r["Content-Encoding"]="gzip",{body:o,headers:r}}return {body:t,headers:r}}async function st(e,t,r,o){let n=`${e}/runs`,{body:s,headers:i}=Es(r);i.Authorization=`Bearer ${t}`;let a=await Rr(n,{method:"POST",headers:i,body:s},o);return a?.ok?{success:true,statusCode:a.status,error:null}:a?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:a?`Upload failed with status ${a.status}`:"Upload failed after retries",statusCode:a?.status??null,payload:r,targetEndpoint:n,method:"POST"}}function Fs(e){let t={};for(let[r,o]of Object.entries(e))o!=null&&(t[r]=o);return t}async function Ds(e,t,r){let o=`${e}/runs/init`;try{let n=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(Fs(r))});return n.ok?{runId:(await n.json()).runId}:null}catch{return null}}async function Ps(e,t,r,o){let n=`${e}/runs/${r}/finalize`;return (await Rr(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(o)}))?.ok??false}var Us=5,de=[1e3,3e3,9e3],G=3,zs={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".mov":"video/quicktime",".zip":"application/zip"},it=0,at=[];async function Hs(){it>=Us&&await new Promise(e=>at.push(e)),it++;}function $s(){it--,at.length>0&&at.shift()();}async function pe(e){return new Promise(t=>setTimeout(t,e))}function Bs(e){let t=e.substring(e.lastIndexOf(".")).toLowerCase();return zs[t]??"application/octet-stream"}function js(e){try{return fs.statSync(e).size}catch{return 0}}async function Gs(e,t,r,o,n){let s=`${e}/artifacts/upload-url`,i=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:n,type:r.type,sizeBytes:o});for(let a=0;a<G;a++)try{let l=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:i});if(l.ok)return await l.json();if(l.status>=500&&a<G-1){await pe(de[a]);continue}return null}catch{if(a<G-1){await pe(de[a]);continue}return null}return null}async function qs(e,t,r,o){for(let n=0;n<G;n++)try{let s=fs.createReadStream(t),i=stream.Readable.toWeb(s),a=await fetch(e,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(o)},body:i,duplex:"half"});if(a.ok)return !0;if(a.status>=500&&n<G-1){await pe(de[n]);continue}return !1}catch{if(n<G-1){await pe(de[n]);continue}return false}return false}async function Vs(e,t,r){try{return (await fetch(`${e}/artifacts/confirm`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function Sr(e,t,r,o){let n=js(r.filePath);if(n===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(n>o*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let s=Bs(r.filePath);await Hs();try{let i=await Gs(e,t,r,n,s);if(!i)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await qs(i.uploadUrl,r.filePath,s,n))return {success:!1,storageKey:i.storageKey,artifactId:i.artifactId,error:"presigned_put_failed"};let l=await Vs(e,t,i.artifactId);return {success:l,storageKey:i.storageKey,artifactId:i.artifactId,error:l?null:"confirm_failed"}}finally{$s();}}async function lt(e,t,r,o){let n=new Map,s=r.map(async i=>{let a=await Sr(e,t,i,o);n.set(i.filePath,a);});return await Promise.allSettled(s),n}function
|
|
1853
|
+
`),this.startBackgroundFlush();}}}catch{}},As),typeof this.healthCheckTimer?.unref=="function"&&this.healthCheckTimer.unref();}};var Is=1048576,ie=[1e3,3e3,9e3],ae=3;function ce(e,t,r,o,n){let s=o?.provider&&o.provider!=="unknown"?o.provider:"local";return {runId:e.testRunId,repoGitId:t,startedAt:e.startedAt,summary:e.summary,timeline:e.timeline,environment:s,testFramework:"maestro",testType:"mobile",...n&&n.length>0?{tests:n}:{},...r?.branch?{branch:r.branch}:{},...r?.commitSha?{commit:r.commitSha}:{},...r?.commitMessage?{commitMessage:r.commitMessage}:{},...r?.commitAuthor?{commitAuthor:r.commitAuthor}:{},...e.completedAt?{finishedAt:e.completedAt}:{},...e.totalDuration?{duration:e.totalDuration}:{},...o?.provider?{ciProvider:o.provider}:{},...o?.runUrl?{ciRunUrl:o.runUrl}:{}}}async function le(e){return new Promise(t=>setTimeout(t,e))}async function Rr(e,t,r){for(let o=0;o<ae;o++)try{let n=await fetch(e,t);if(n.ok)return n;if(n.status===401&&r&&o===0){let s=await r();if(s){let i={...t,headers:{...t.headers,Authorization:`Bearer ${s}`}},a=await fetch(e,i);if(a.ok)return a}return null}if(n.status===429&&o<ae-1){let s=n.headers.get("Retry-After"),i=s?parseInt(s,10)*1e3:ie[o];!isNaN(i)&&i>0?await le(i):await le(ie[o]);continue}if(n.status>=500&&o<ae-1){await le(ie[o]);continue}return n}catch{if(o<ae-1){await le(ie[o]);continue}return null}return null}function Es(e){let t=JSON.stringify(e),r={"Content-Type":"application/json"};if(Buffer.byteLength(t,"utf-8")>Is){let o=zlib.gzipSync(Buffer.from(t,"utf-8"));return r["Content-Encoding"]="gzip",{body:o,headers:r}}return {body:t,headers:r}}async function st(e,t,r,o){let n=`${e}/runs`,{body:s,headers:i}=Es(r);i.Authorization=`Bearer ${t}`;let a=await Rr(n,{method:"POST",headers:i,body:s},o);return a?.ok?{success:true,statusCode:a.status,error:null}:a?.status===409?{success:true,statusCode:409,error:null}:{success:false,reason:a?`Upload failed with status ${a.status}`:"Upload failed after retries",statusCode:a?.status??null,payload:r,targetEndpoint:n,method:"POST"}}function Fs(e){let t={};for(let[r,o]of Object.entries(e))o!=null&&(t[r]=o);return t}async function Ds(e,t,r){let o=`${e}/runs/init`;try{let n=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(Fs(r))});return n.ok?{runId:(await n.json()).runId}:null}catch{return null}}async function Ps(e,t,r,o){let n=`${e}/runs/${r}/finalize`;return (await Rr(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(o)}))?.ok??false}var Us=5,de=[1e3,3e3,9e3],G=3,zs={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".webm":"video/webm",".mp4":"video/mp4",".mov":"video/quicktime",".zip":"application/zip"},it=0,at=[];async function Hs(){it>=Us&&await new Promise(e=>at.push(e)),it++;}function $s(){it--,at.length>0&&at.shift()();}async function pe(e){return new Promise(t=>setTimeout(t,e))}function Bs(e){let t=e.substring(e.lastIndexOf(".")).toLowerCase();return zs[t]??"application/octet-stream"}function js(e){try{return fs.statSync(e).size}catch{return 0}}async function Gs(e,t,r,o,n){let s=`${e}/artifacts/upload-url`,i=JSON.stringify({runId:r.runId,testId:r.testId,fileName:path.basename(r.filePath),contentType:n,type:r.type,sizeBytes:o});for(let a=0;a<G;a++)try{let l=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:i});if(l.ok)return await l.json();if(l.status>=500&&a<G-1){await pe(de[a]);continue}return null}catch{if(a<G-1){await pe(de[a]);continue}return null}return null}async function qs(e,t,r,o){for(let n=0;n<G;n++)try{let s=fs.createReadStream(t),i=stream.Readable.toWeb(s),a=await fetch(e,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(o)},body:i,duplex:"half"});if(a.ok)return !0;if(a.status>=500&&n<G-1){await pe(de[n]);continue}return !1}catch{if(n<G-1){await pe(de[n]);continue}return false}return false}async function Vs(e,t,r){try{return (await fetch(`${e}/artifacts/confirm`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({artifactId:r})})).ok}catch{return false}}async function Sr(e,t,r,o){let n=js(r.filePath);if(n===0)return {success:false,storageKey:null,artifactId:null,error:"file_not_found_or_empty"};if(n>o*1024*1024)return {success:false,storageKey:null,artifactId:null,error:"file_too_large"};let s=Bs(r.filePath);await Hs();try{let i=await Gs(e,t,r,n,s);if(!i)return {success:!1,storageKey:null,artifactId:null,error:"upload_url_request_failed"};if(!await qs(i.uploadUrl,r.filePath,s,n))return {success:!1,storageKey:i.storageKey,artifactId:i.artifactId,error:"presigned_put_failed"};let l=await Vs(e,t,i.artifactId);return {success:l,storageKey:i.storageKey,artifactId:i.artifactId,error:l?null:"confirm_failed"}}finally{$s();}}async function lt(e,t,r,o){let n=new Map,s=r.map(async i=>{let a=await Sr(e,t,i,o);n.set(i.filePath,a);});return await Promise.allSettled(s),n}function Ks(e){return e.GITHUB_ACTIONS!=="true"?null:{provider:"github-actions",buildId:e.GITHUB_RUN_ID??null,commitSha:e.GITHUB_SHA??null,branch:e.GITHUB_REF_NAME??null,runUrl:e.GITHUB_SERVER_URL&&e.GITHUB_REPOSITORY&&e.GITHUB_RUN_ID?`${e.GITHUB_SERVER_URL}/${e.GITHUB_REPOSITORY}/actions/runs/${e.GITHUB_RUN_ID}`:null}}function Js(e){return e.GITLAB_CI!=="true"?null:{provider:"gitlab-ci",buildId:e.CI_PIPELINE_ID??null,commitSha:e.CI_COMMIT_SHA??null,branch:e.CI_COMMIT_BRANCH??e.CI_COMMIT_REF_NAME??null,runUrl:e.CI_PIPELINE_URL??null}}function Ws(e){if(!e.JENKINS_URL)return null;let t=e.GIT_BRANCH??null;return t?.startsWith("origin/")&&(t=t.slice(7)),{provider:"jenkins",buildId:e.BUILD_ID??null,commitSha:e.GIT_COMMIT??null,branch:t,runUrl:e.BUILD_URL??null}}function Ys(e){return e.CIRCLECI!=="true"?null:{provider:"circleci",buildId:e.CIRCLE_BUILD_NUM??null,commitSha:e.CIRCLE_SHA1??null,branch:e.CIRCLE_BRANCH??null,runUrl:e.CIRCLE_BUILD_URL??null}}function Xs(e){if(!e.BITBUCKET_PIPELINE_UUID)return null;let t=e.BITBUCKET_WORKSPACE&&e.BITBUCKET_REPO_SLUG&&e.BITBUCKET_PIPELINE_UUID?`https://bitbucket.org/${e.BITBUCKET_WORKSPACE}/${e.BITBUCKET_REPO_SLUG}/pipelines/results/${e.BITBUCKET_PIPELINE_UUID}`:null;return {provider:"bitbucket-pipelines",buildId:e.BITBUCKET_BUILD_NUMBER??null,commitSha:e.BITBUCKET_COMMIT??null,branch:e.BITBUCKET_BRANCH??null,runUrl:t}}var Qs=[Ks,Js,Ws,Ys,Xs];function ue(e){let t=e??process.env;for(let r of Qs){let o=r(t);if(o)return o}return null}function Zs(e){let t=[];for(let r of e){let o=r,n=o.tests;if(!Array.isArray(n)||n.length===0){t.push(r);continue}for(let s of n){t.push({timestamp:s.startedAt,title:s.title,category:"test",navigationType:o.navigationType,url:o.url,visitedAt:o.visitedAt,duration:s.duration,status:s.status,test_status:s.status,test_id:s.testId,test_title:s.title,specfile:s.filePath,suiteName:s.suiteName,type:"test",...s.failure?{error:s.failure.message,errorMessage:s.failure.message}:{}});for(let i of s.actions??[])t.push({timestamp:i.timestamp,title:i.title,category:i.category,status:i.status,test_status:s.status,duration:i.duration,error:i.error,test_id:s.testId,test_title:s.title,specfile:s.filePath,url:o.url,type:i.category==="assertion"?"assert":"action"});}}return t}function Tr(e){let r=e.getGitMetadata()?.remoteUrl;return r?B(r):e.getConfig()?.projectName??j(process.cwd())}async function ct(e,t,r,o,n,s,i,a,l,c,d){try{let p=d?.length??0,u=(a?.length??0)+(l?.length??0)+p>0;if(e.isCloudMode()&&u&&await e.ensureValidToken()){let h=e.getEndpoint(),g=e.getAccessToken(),v=t?.artifactMaxSizeMb??50,x=[];for(let R of a??[])x.push({filePath:R,runId:r,testId:"maestro-suite",type:"screenshot"});let T=new Set;for(let R of d??[])x.push({filePath:R.path,runId:r,testId:R.testId,type:"video"}),T.add(R.path);for(let R of l??[])T.has(R)||x.push({filePath:R,runId:r,testId:"maestro-suite",type:"video"});if(x.length>0){let R=await lt(h,g,x,v),L=Array.from(R.entries()),M=L.filter(([,m])=>m.success).length,f=L.filter(([,m])=>!m.success);if(M>0){let m=x.filter(k=>k.type==="video").length,y=d?.length??0,w=x.filter(k=>k.type==="screenshot").length,S=[];if(w>0&&S.push(`${w} screenshot(s)`),m>0){let k=y>0?` (${y} per-flow)`:"";S.push(`${m} video(s)${k}`);}process.stderr.write(`\u2713 TestRelic: Uploaded ${M} artifact(s) [${S.join(", ")}] to cloud storage.
|
|
1854
1854
|
`);}if(f.length>0){process.stderr.write(`\u26A0 TestRelic: ${f.length} artifact(s) failed to upload:
|
|
1855
1855
|
`);for(let[m,y]of f){let w=x.find(k=>k.filePath===m),S=w?`[${w.type}] ${m}`:m;process.stderr.write(` \u2717 ${S} \u2014 reason: ${y.error??"unknown"}
|
|
1856
1856
|
`);}}}}if(e.isCloudMode())if(await e.ensureValidToken()){let h=e.getGitMetadata(),g=ue(),v=Tr(e),x=Zs(o.timeline),T={...o,timeline:x},R=ce(T,v,h,g,c),L=await st(e.getEndpoint(),e.getAccessToken(),R,async()=>await e.ensureValidToken()?e.getAccessToken():null);if(L.success)process.stderr.write(`\u2713 TestRelic: Cloud upload succeeded \u2192 ${e.getEndpoint()}/runs/${r}
|
|
1857
1857
|
`);else {let M=L,f=t?.queueDirectory??".testrelic/queue";se(f,r,"batch",M.reason,M.targetEndpoint,M.method,M.payload,{"Content-Type":"application/json"}),process.stderr.write(`\u26A0 TestRelic: Cloud upload failed, queued for retry.
|
|
1858
|
-
`);}}else {let h=t?.queueDirectory??".testrelic/queue",g=e.getGitMetadata(),v=ue(),x=Tr(e),T=ce(o,x,g,v);se(h,r,"batch",e.getFailureReason()??"token_invalid",`${e.getEndpoint()}/runs`,"POST",T,{"Content-Type":"application/json"});}await e.dispose();}catch{try{await e.dispose();}catch{}}}function Mr(e,t,r){if(t.length===0)return null;let o=path.basename(e,path.extname(e)).toLowerCase(),n=t.find(a=>path.basename(a,path.extname(a)).toLowerCase()===o);if(n)return n;let s=t.find(a=>path.basename(a).toLowerCase().includes(o));if(s)return s;let i=t.find(a=>{let l=path.basename(a,path.extname(a)).toLowerCase();return l.length>=3&&(o.startsWith(l)||o.includes(l))});if(i)return i;if(r){let a=path.basename(r,path.extname(r)).toLowerCase(),l=t.find(d=>path.basename(d,path.extname(d)).toLowerCase()===a);if(l)return l;let c=t.find(d=>path.basename(d).toLowerCase().includes(a));if(c)return c}return null}function ni(e,t){if(t.length===0)return [];let r=path.basename(e,path.extname(e)).toLowerCase(),o=t.filter(n=>{let s=path.basename(n).toLowerCase(),i=path.basename(n,path.extname(n)).toLowerCase();return s.startsWith(r)||s.includes(r)?true:i.length>=3&&(r.startsWith(i)||r.includes(i))});return o.length>0?o:t.slice()}function si(e){for(let t of e)if(t.command==="startRecording"){let r=t.metadata,o=r?.path??r?.recording??r?.fileName;if(typeof o=="string")return o;if(typeof t.selector=="string")return t.selector}return null}function Ir(e){return path.basename(e).replace(/^commands[-_]?/i,"").replace(/\.json$/i,"").replace(/^\(/,"").replace(/\)$/,"").toLowerCase()}function ii(e){let t=new Map;for(let[r,o]of e){let n=Ir(r),s=si(o);s&&n&&t.set(n,s);}return t}function ai(e,t){let r=path.basename(t,path.extname(t)).toLowerCase();if(!r||e.size===0)return {commands:[],matchedAnyFile:false};let o=n=>Ir(n);for(let[n,s]of e)if(o(n)===r)return {commands:s,matchedAnyFile:true};for(let[n,s]of e){let i=o(n);if(i.length>=3&&i.includes(r))return {commands:s,matchedAnyFile:true}}for(let[n,s]of e){let i=o(n);if(i.length>=3&&r.includes(i))return {commands:s,matchedAnyFile:true}}return {commands:[],matchedAnyFile:false}}function li(e){switch(e){case "android":return "Android";case "ios":return "iOS";case "web":return "Web";default:return}}function ci(e,t,r){let o=e.logEntries.length>0?e.logEntries.map(n=>({level:n.level.toLowerCase(),message:n.message,timestamp:n.timestamp,source:n.source})):void 0;return {testId:`${e.flowFile}::${e.flowName}`,title:e.flowName,status:e.status,duration:e.duration,suiteName:e.appId??"maestro-suite",filePath:e.flowFile,testType:"mobile",isFlaky:false,startedAt:e.startedAt,completedAt:e.completedAt,tags:e.tags,failure:e.failureMessage?{message:e.failureMessage}:null,retry:0,retryCount:0,retryStatus:null,source:"maestro",platform:e.platform!=="unknown"?e.platform:void 0,os:li(e.platform),deviceName:e.deviceId,...o?{consoleLogs:o}:{},...t&&t.length>0?{apiCalls:t}:{},...r&&r.length>0?{actions:r}:{}}}function di(e,t,r){if(e.length===0)return [];let o=Date.parse(t),n=Date.parse(r);return Number.isNaN(o)||Number.isNaN(n)?e.slice():e.filter(s=>{let i=Date.parse(s.timestamp);return Number.isNaN(i)?true:i>=o&&i<=n})}async function pi(e){let{config:t}=e,r=new Date().toISOString(),o=t.testRunId??crypto.randomUUID(),n=ze(e.testOutputDir,e.debugOutputDir),s=e.junitPath??n.junitReportPath,i=e.debugOutputDir?Ee(e.debugOutputDir):n.logPaths,a=[];for(let f of i){let m;try{let{statSync:w}=await import('fs');m=w(f).mtime;}catch{}let y=Me(f,m);y.length>0&&a.push(...y);}let l=e.platform??"unknown";if(l==="unknown"&&a.length>0){let f=Ie(a);f!=="unknown"&&(l=f);}let c=new Map;if(e.flowsDir&&fs.existsSync(e.flowsDir)){let f=Ae(e.flowsDir);for(let m of f){let y=Te(m),w=y.name??m;c.set(w,y);}}let d=new Map,p=e.testOutputDir?Se(e.testOutputDir):n.commandJsonPaths;for(let f of p)d.set(f,Re(f));let u=[],b=e.testOutputDir?Ue(e.testOutputDir):n.aiReportPaths;for(let f of b){let m=Oe(f);u.push(...m.defects);}let h=ii(d),g=[];if(s&&fs.existsSync(s)){let f=we(s),m=Array.from(d.values()).flat(),y=m.filter(S=>S.category==="assertion"),w=m.filter(S=>S.category!=="assertion");for(let S of f.testSuites)for(let k of S.testCases){let C=k.name,I=c.get(C),N=k.status==="SUCCESS"?"passed":k.status==="SKIPPED"?"skipped":"failed",F=k.time*1e3,_=k.classname||C,W=path.basename(_,path.extname(_)).toLowerCase(),Fr=h.get(W)??null,{commands:dt,matchedAnyFile:pt}=ai(d,_),ut=pt?dt.filter($=>$.category!=="assertion"):w,ft=pt?dt.filter($=>$.category==="assertion"):y,gt=[...ut,...ft].reduce(($,Dr)=>{let me=Date.parse(Dr.timestamp);return Number.isFinite(me)&&me<$?me:$},Number.POSITIVE_INFINITY),ge=Number.isFinite(gt)?new Date(gt).toISOString():r,mt=new Date(new Date(ge).getTime()+F).toISOString();g.push({flowName:C,flowFile:_,appId:I?.appId??null,platform:l,deviceId:e.device,status:N,duration:F,startedAt:ge,completedAt:mt,tags:I?.tags??[],properties:I?.properties??{},commands:ut,assertions:ft,screenshotPaths:ni(_,n.screenshotPaths),videoPath:Mr(_,n.videoPaths,Fr),aiDefects:u,logEntries:di(a,ge,mt),failureMessage:k.failureMessage??k.errorMessage??null,failureType:k.failureType??k.errorType??null,subflowRefs:I?.subflowRefs??[],metadata:I??null});}}if(g.length===0&&c.size>0)for(let[,f]of c)g.push({flowName:f.name??f.filePath,flowFile:f.filePath,appId:f.appId,platform:l,deviceId:e.device,status:"passed",duration:0,startedAt:r,completedAt:r,tags:f.tags,properties:f.properties,commands:[],assertions:[],screenshotPaths:[],videoPath:null,aiDefects:[],logEntries:a.slice(),failureMessage:null,failureType:null,subflowRefs:f.subflowRefs,metadata:f});let v=(()=>{if(!t.network?.enabled&&!t.network?.harPath)return;let f=g.map(w=>({testId:`${w.flowFile}::${w.flowName}`,startedAt:w.startedAt,completedAt:w.completedAt})),m=fr(e.networkJsonlDir??null,t.network,f);if(m.size===0)return;let y=new Map;for(let[w,S]of m)y.set(w,gr(S));return y})(),x=$e(g,v),T=V(x),R=new Date().toISOString(),L=Date.now()-new Date(r).getTime(),M={schemaVersion:q,testRunId:o,startedAt:r,completedAt:R,totalDuration:L,summary:T,ci:null,metadata:t.metadata??null,timeline:x,shardRunIds:null};if(fs.mkdirSync(path.dirname(path.resolve(t.outputPath)),{recursive:true}),fs.writeFileSync(path.resolve(t.outputPath),JSON.stringify(M,null,2),"utf-8"),Ge(M,u,n.screenshotPaths,path.resolve(t.htmlReportPath)),qe(T,t.outputPath,t.htmlReportPath,t.quiet,u),t.openReport&&Ve(path.resolve(t.htmlReportPath)),t.cloud){let f=new
|
|
1859
|
-
`);}let i=V(r),a=o?new Date(o).getTime():Date.now(),l=n?new Date(n).getTime():Date.now();return {schemaVersion:q,testRunId:s||`maestro-merged-${Date.now()}`,startedAt:o||new Date().toISOString(),completedAt:n||new Date().toISOString(),totalDuration:l-a,summary:i,ci:null,metadata:null,timeline:t,shardRunIds:null}}function xi(e,t){if(!fs.existsSync(e))throw new Error(`Directory does not exist: ${e}`);let r=fs.readdirSync(e).filter(n=>path.extname(n)===".json"&&n.includes("testrelic")).map(n=>path.join(e,n)),o=Er(r);return fs.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),o}exports.CloudClient=
|
|
1858
|
+
`);}}else {let h=t?.queueDirectory??".testrelic/queue",g=e.getGitMetadata(),v=ue(),x=Tr(e),T=ce(o,x,g,v);se(h,r,"batch",e.getFailureReason()??"token_invalid",`${e.getEndpoint()}/runs`,"POST",T,{"Content-Type":"application/json"});}await e.dispose();}catch{try{await e.dispose();}catch{}}}function Mr(e,t,r){if(t.length===0)return null;let o=path.basename(e,path.extname(e)).toLowerCase(),n=t.find(a=>path.basename(a,path.extname(a)).toLowerCase()===o);if(n)return n;let s=t.find(a=>path.basename(a).toLowerCase().includes(o));if(s)return s;let i=t.find(a=>{let l=path.basename(a,path.extname(a)).toLowerCase();return l.length>=3&&(o.startsWith(l)||o.includes(l))});if(i)return i;if(r){let a=path.basename(r,path.extname(r)).toLowerCase(),l=t.find(d=>path.basename(d,path.extname(d)).toLowerCase()===a);if(l)return l;let c=t.find(d=>path.basename(d).toLowerCase().includes(a));if(c)return c}return null}function ni(e,t){if(t.length===0)return [];let r=path.basename(e,path.extname(e)).toLowerCase(),o=t.filter(n=>{let s=path.basename(n).toLowerCase(),i=path.basename(n,path.extname(n)).toLowerCase();return s.startsWith(r)||s.includes(r)?true:i.length>=3&&(r.startsWith(i)||r.includes(i))});return o.length>0?o:t.slice()}function si(e){for(let t of e)if(t.command==="startRecording"){let r=t.metadata,o=r?.path??r?.recording??r?.fileName;if(typeof o=="string")return o;if(typeof t.selector=="string")return t.selector}return null}function Ir(e){return path.basename(e).replace(/^commands[-_]?/i,"").replace(/\.json$/i,"").replace(/^\(/,"").replace(/\)$/,"").toLowerCase()}function ii(e){let t=new Map;for(let[r,o]of e){let n=Ir(r),s=si(o);s&&n&&t.set(n,s);}return t}function ai(e,t){let r=path.basename(t,path.extname(t)).toLowerCase();if(!r||e.size===0)return {commands:[],matchedAnyFile:false};let o=n=>Ir(n);for(let[n,s]of e)if(o(n)===r)return {commands:s,matchedAnyFile:true};for(let[n,s]of e){let i=o(n);if(i.length>=3&&i.includes(r))return {commands:s,matchedAnyFile:true}}for(let[n,s]of e){let i=o(n);if(i.length>=3&&r.includes(i))return {commands:s,matchedAnyFile:true}}return {commands:[],matchedAnyFile:false}}function li(e){switch(e){case "android":return "Android";case "ios":return "iOS";case "web":return "Web";default:return}}function ci(e,t,r){let o=e.logEntries.length>0?e.logEntries.map(n=>({level:n.level.toLowerCase(),message:n.message,timestamp:n.timestamp,source:n.source})):void 0;return {testId:`${e.flowFile}::${e.flowName}`,title:e.flowName,status:e.status,duration:e.duration,suiteName:e.appId??"maestro-suite",filePath:e.flowFile,testType:"mobile",isFlaky:false,startedAt:e.startedAt,completedAt:e.completedAt,tags:e.tags,failure:e.failureMessage?{message:e.failureMessage}:null,retry:0,retryCount:0,retryStatus:null,source:"maestro",platform:e.platform!=="unknown"?e.platform:void 0,os:li(e.platform),deviceName:e.deviceId,...o?{consoleLogs:o}:{},...t&&t.length>0?{apiCalls:t}:{},...r&&r.length>0?{actions:r}:{}}}function di(e,t,r){if(e.length===0)return [];let o=Date.parse(t),n=Date.parse(r);return Number.isNaN(o)||Number.isNaN(n)?e.slice():e.filter(s=>{let i=Date.parse(s.timestamp);return Number.isNaN(i)?true:i>=o&&i<=n})}async function pi(e){let{config:t}=e,r=new Date().toISOString(),o=t.testRunId??crypto.randomUUID(),n=ze(e.testOutputDir,e.debugOutputDir),s=e.junitPath??n.junitReportPath,i=e.debugOutputDir?Ee(e.debugOutputDir):n.logPaths,a=[];for(let f of i){let m;try{let{statSync:w}=await import('fs');m=w(f).mtime;}catch{}let y=Me(f,m);y.length>0&&a.push(...y);}let l=e.platform??"unknown";if(l==="unknown"&&a.length>0){let f=Ie(a);f!=="unknown"&&(l=f);}let c=new Map;if(e.flowsDir&&fs.existsSync(e.flowsDir)){let f=Ae(e.flowsDir);for(let m of f){let y=Te(m),w=y.name??m;c.set(w,y);}}let d=new Map,p=e.testOutputDir?Se(e.testOutputDir):n.commandJsonPaths;for(let f of p)d.set(f,Re(f));let u=[],b=e.testOutputDir?Ue(e.testOutputDir):n.aiReportPaths;for(let f of b){let m=Oe(f);u.push(...m.defects);}let h=ii(d),g=[];if(s&&fs.existsSync(s)){let f=we(s),m=Array.from(d.values()).flat(),y=m.filter(S=>S.category==="assertion"),w=m.filter(S=>S.category!=="assertion");for(let S of f.testSuites)for(let k of S.testCases){let C=k.name,I=c.get(C),N=k.status==="SUCCESS"?"passed":k.status==="SKIPPED"?"skipped":"failed",F=k.time*1e3,_=k.classname||C,W=path.basename(_,path.extname(_)).toLowerCase(),Fr=h.get(W)??null,{commands:dt,matchedAnyFile:pt}=ai(d,_),ut=pt?dt.filter($=>$.category!=="assertion"):w,ft=pt?dt.filter($=>$.category==="assertion"):y,gt=[...ut,...ft].reduce(($,Dr)=>{let me=Date.parse(Dr.timestamp);return Number.isFinite(me)&&me<$?me:$},Number.POSITIVE_INFINITY),ge=Number.isFinite(gt)?new Date(gt).toISOString():r,mt=new Date(new Date(ge).getTime()+F).toISOString();g.push({flowName:C,flowFile:_,appId:I?.appId??null,platform:l,deviceId:e.device,status:N,duration:F,startedAt:ge,completedAt:mt,tags:I?.tags??[],properties:I?.properties??{},commands:ut,assertions:ft,screenshotPaths:ni(_,n.screenshotPaths),videoPath:Mr(_,n.videoPaths,Fr),aiDefects:u,logEntries:di(a,ge,mt),failureMessage:k.failureMessage??k.errorMessage??null,failureType:k.failureType??k.errorType??null,subflowRefs:I?.subflowRefs??[],metadata:I??null});}}if(g.length===0&&c.size>0)for(let[,f]of c)g.push({flowName:f.name??f.filePath,flowFile:f.filePath,appId:f.appId,platform:l,deviceId:e.device,status:"passed",duration:0,startedAt:r,completedAt:r,tags:f.tags,properties:f.properties,commands:[],assertions:[],screenshotPaths:[],videoPath:null,aiDefects:[],logEntries:a.slice(),failureMessage:null,failureType:null,subflowRefs:f.subflowRefs,metadata:f});let v=(()=>{if(!t.network?.enabled&&!t.network?.harPath)return;let f=g.map(w=>({testId:`${w.flowFile}::${w.flowName}`,startedAt:w.startedAt,completedAt:w.completedAt})),m=fr(e.networkJsonlDir??null,t.network,f);if(m.size===0)return;let y=new Map;for(let[w,S]of m)y.set(w,gr(S));return y})(),x=$e(g,v),T=V(x),R=new Date().toISOString(),L=Date.now()-new Date(r).getTime(),M={schemaVersion:q,testRunId:o,startedAt:r,completedAt:R,totalDuration:L,summary:T,ci:null,metadata:t.metadata??null,timeline:x,shardRunIds:null};if(fs.mkdirSync(path.dirname(path.resolve(t.outputPath)),{recursive:true}),fs.writeFileSync(path.resolve(t.outputPath),JSON.stringify(M,null,2),"utf-8"),Ge(M,u,n.screenshotPaths,path.resolve(t.htmlReportPath)),qe(T,t.outputPath,t.htmlReportPath,t.quiet,u),t.openReport&&Ve(path.resolve(t.htmlReportPath)),t.cloud){let f=new J(t.cloud);await f.initialize();let m=t.includeVideo?n.videoPaths:[],y=[];if(m.length>0){for(let C of g){let I=path.basename(C.flowFile,path.extname(C.flowFile)).toLowerCase(),N=h.get(I)??null,F=Mr(C.flowFile,m,N);if(F){let _=`${C.flowFile}::${C.flowName}`;y.some(W=>W.path===F&&W.testId===_)||y.push({path:F,testId:_});}}if(m.length===1){let C=m[0];for(let I of g){let N=`${I.flowFile}::${I.flowName}`;y.some(F=>F.testId===N)||y.push({path:C,testId:N});}}}let w=new Set(y.map(C=>C.path)),S=m.filter(C=>!w.has(C)),k=g.map((C,I)=>{let N=`${C.flowFile}::${C.flowName}`,F=x[I]?.tests?.[0];return ci(C,v?.get(N),F?.actions??null)});await ct(f,t.cloud,o,M,R,L,T,t.includeScreenshots?n.screenshotPaths:[],S,k,y);}return {report:M,flowResults:g,aiDefects:u,artifacts:n}}function vi(e){return "tests"in e&&"visitedAt"in e}function Er(e){let t=[],r=[],o="",n="",s="";for(let c of e)try{let d=fs.readFileSync(c,"utf-8"),p=JSON.parse(d);s||(s=p.testRunId),(!o||p.startedAt<o)&&(o=p.startedAt),(!n||p.completedAt&&p.completedAt>n)&&(n=p.completedAt);for(let u of p.timeline)t.push(u),vi(u)&&r.push(u);}catch{process.stderr.write(`\u26A0 TestRelic: Unable to read report file: ${c}
|
|
1859
|
+
`);}let i=V(r),a=o?new Date(o).getTime():Date.now(),l=n?new Date(n).getTime():Date.now();return {schemaVersion:q,testRunId:s||`maestro-merged-${Date.now()}`,startedAt:o||new Date().toISOString(),completedAt:n||new Date().toISOString(),totalDuration:l-a,summary:i,ci:null,metadata:null,timeline:t,shardRunIds:null}}function xi(e,t){if(!fs.existsSync(e))throw new Error(`Directory does not exist: ${e}`);let r=fs.readdirSync(e).filter(n=>path.extname(n)===".json"&&n.includes("testrelic")).map(n=>path.join(e,n)),o=Er(r);return fs.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),o}exports.CloudClient=J;exports.DEFAULT_CLOUD_CONFIG=he;exports.SCHEMA_VERSION=q;exports.buildMaestroArgs=ir;exports.buildSummary=V;exports.buildTimeline=$e;exports.buildTimelineEntry=zt;exports.buildUploadPayload=ce;exports.categorizeCommand=Et;exports.cleanupExpiredQueue=ot;exports.collectArtifacts=ze;exports.collectGitMetadata=Ze;exports.deriveNonGitProjectId=j;exports.deriveRepoDisplayName=et;exports.detectCI=ue;exports.detectPlatformFromLogs=Ie;exports.discoverAiReports=Ue;exports.discoverCommandFiles=Se;exports.discoverConfigFile=ve;exports.discoverFlowFiles=Ae;exports.discoverLogFiles=Ee;exports.enforceHttps=Ye;exports.exchangeToken=re;exports.finalizeAndUpload=ct;exports.finalizeRun=Ps;exports.flushQueue=rt;exports.generateHtmlReport=Ge;exports.getArtifactStats=rn;exports.healthCheck=te;exports.initRealtimeRun=Ds;exports.isAuthError=oe;exports.mergeCloudConfig=ye;exports.mergeReports=Er;exports.mergeReportsFromDirectory=xi;exports.normalizeGitRemoteUrl=B;exports.openInBrowser=Ve;exports.orchestrateReport=pi;exports.parseAiReportFile=Oe;exports.parseAiReportHtml=Ot;exports.parseCommandsFile=Re;exports.parseCommandsJson=Ft;exports.parseConfigFile=xe;exports.parseDuration=be;exports.parseFlowFile=Te;exports.parseFlowYaml=_t;exports.parseJUnitFile=we;exports.parseJUnitXml=Rt;exports.parseLogContent=Nt;exports.parseLogFile=Me;exports.printConsoleSummary=qe;exports.readPackageJsonName=br;exports.refreshAccessToken=Xe;exports.renderHtmlDocument=je;exports.resolveConfig=Xr;exports.resolveEnvVar=Y;exports.resolveEnvVars=X;exports.resolveRepo=Qe;exports.runMaestro=Gn;exports.uploadArtifact=Sr;exports.uploadArtifacts=lt;exports.uploadBatchRun=st;exports.writeToQueue=se;//# sourceMappingURL=index.cjs.map
|
|
1860
1860
|
//# sourceMappingURL=index.cjs.map
|