@testrelic/maestro-analytics 1.4.1 → 1.4.2
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/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {isValidEndpointUrl,isValidCloudConfig,createError,ErrorCode,isValidQueueEntry}from'@testrelic/core';import {existsSync,statSync,readFileSync,readdirSync,mkdirSync,writeFileSync,renameSync,unlinkSync,createReadStream}from'fs';import {resolve,join,dirname,basename,extname}from'path';import {XMLParser}from'fast-xml-parser';import {parseDocument}from'yaml';import {execFile,spawn,execSync,spawnSync}from'child_process';import {tmpdir}from'os';import {createHash,randomUUID,randomBytes}from'crypto';import {fileURLToPath}from'url';import {gzipSync}from'zlib';import {Readable}from'stream';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=resolve(e);for(let r=0;r<=Hr;r++){let o=join(t,xt,Ur);if(existsSync(o))try{if(statSync(o).isFile())return o}catch{}let n=join(t,zr);if(existsSync(n))try{if(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=dirname(t);if(s===t)break;t=s;}return null}function xe(e){try{let t=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&&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 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 createError(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 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=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=readFileSync(e,"utf-8");return Ft(r,t)}catch{return []}}function Se(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>basename(t).startsWith("commands")&&t.endsWith(".json")).map(t=>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=parseDocument(o).toJS();typeof v=="object"&&v!==null&&!Array.isArray(v)&&(s=v);}catch{}let i=[];if(n.trim())try{let v=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=readFileSync(e,"utf-8");return _t(t,e)}function Ae(e){if(!existsSync(e))return [];let t=[];function r(o){try{let n=readdirSync(o,{withFileTypes:!0});for(let s of n){let i=join(o,s.name);if(s.isDirectory())r(i);else if(s.isFile()){let a=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=dirname(t);if(s===t)break;t=s;}return null}function xe(e){try{let t=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&&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 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 createError(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 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=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=readFileSync(e,"utf-8");return Ft(r,t)}catch{return []}}function Se(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>basename(t).startsWith("commands")&&t.endsWith(".json")).map(t=>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=parseDocument(o).toJS();typeof v=="object"&&v!==null&&!Array.isArray(v)&&(s=v);}catch{}let i=[];if(n.trim())try{let v=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=readFileSync(e,"utf-8");return _t(t,e)}function Ae(e){if(!existsSync(e))return [];let t=[];function r(o){try{let n=readdirSync(o,{withFileTypes:!0});for(let s of n){let i=join(o,s.name);if(s.isDirectory())r(i);else if(s.isFile()){let a=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=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(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>basename(t)==="maestro.log"||t.endsWith(".log")).map(t=>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=readFileSync(e,"utf-8");return Ot(t)}catch{return {defects:[],totalDefects:0,hasIssues:false,rawHtml:null}}}function Ue(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>{let r=basename(t).toLowerCase();return extname(t).toLowerCase()===".html"&&(r.includes("insight")||r.includes("ai")||r.includes("analysis"))}).map(t=>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(!existsSync(e))return t;function r(o){try{let n=readdirSync(o,{withFileTypes:!0});for(let s of n){let i=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=basename(d).toLowerCase(),u=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=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(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>basename(t)==="maestro.log"||t.endsWith(".log")).map(t=>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=readFileSync(e,"utf-8");return Ot(t)}catch{return {defects:[],totalDefects:0,hasIssues:false,rawHtml:null}}}function Ue(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>{let r=basename(t).toLowerCase();return extname(t).toLowerCase()===".html"&&(r.includes("insight")||r.includes("ai")||r.includes("analysis"))}).map(t=>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(!existsSync(e))return t;function r(o){try{let n=readdirSync(o,{withFileTypes:!0});for(let s of n){let i=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=basename(d).toLowerCase(),u=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=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=join(process.env.HOME??"",".mitmproxy","mitmproxy-ca-cert.pem");if(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=randomBytes(8).toString("hex");return join(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=join(t,"report.xml"),n=join(t,"artifacts"),s=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=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?resolve(e.outputDir):$n();mkdirSync(join(r,"artifacts"),{recursive:true}),mkdirSync(join(r,"debug"),{recursive:true});let o=ir(e,r),n=join(r,"report.xml"),s=join(r,"artifacts"),i=join(r,"debug"),a=null,l=null,c=t.network;if(c?.enabled){let u=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(readFileSync(e,"utf-8"),t)}catch{return []}}function Yn(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>t.endsWith(".jsonl")).map(t=>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(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&&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 createError(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 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=randomBytes(8).toString("hex");return join(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=join(t,"report.xml"),n=join(t,"artifacts"),s=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=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?resolve(e.outputDir):$n();mkdirSync(join(r,"artifacts"),{recursive:true}),mkdirSync(join(r,"debug"),{recursive:true});let o=ir(e,r),n=join(r,"report.xml"),s=join(r,"artifacts"),i=join(r,"debug"),a=null,l=null,c=t.network;if(c?.enabled){let u=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(readFileSync(e,"utf-8"),t)}catch{return []}}function Yn(e){if(!existsSync(e))return [];try{return readdirSync(e,{recursive:!0}).map(String).filter(t=>t.endsWith(".jsonl")).map(t=>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(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&&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 createError(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 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=readFileSync(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/${basename(e)}`}var vs="1.0.0",vr=10;function se(e,t,r,o,n,s,i,a){try{mkdirSync(e,{recursive:!0});let l=Date.now(),c=`${l}-${t}-${r}.json`,d=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";writeFileSync(u,JSON.stringify(p,null,2),"utf-8"),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=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=join(e,i);try{if(!statSync(a).isFile())continue;let c=readFileSync(a,"utf-8"),d=JSON.parse(c);if(!isValidQueueEntry(d)){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)unlinkSync(a);else return}catch{return}}}function ot(e,t){try{let r=readdirSync(e).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")),o=Date.now();for(let n of r){let s=join(e,n);try{let i=readFileSync(s,"utf-8"),l=JSON.parse(i).queuedAt;if(typeof l=="string"){let c=new Date(l).getTime();o-c>t&&unlinkSync(s);}}catch{try{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=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=join(e,i);try{if(!statSync(a).isFile())continue;let c=readFileSync(a,"utf-8"),d=JSON.parse(c);if(!isValidQueueEntry(d)){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)unlinkSync(a);else return}catch{return}}}function ot(e,t){try{let r=readdirSync(e).filter(n=>n.endsWith(".json")&&!n.endsWith(".tmp")),o=Date.now();for(let n of r){let s=join(e,n);try{let i=readFileSync(s,"utf-8"),l=JSON.parse(i).queuedAt;if(typeof l=="string"){let c=new Date(l).getTime();o-c>t&&unlinkSync(s);}}catch{try{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=join(this.config.queueDirectory,"..","cache","repo.json");try{if(!existsSync(r))return null;let o=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=join(this.config.queueDirectory,"..","cache"),s=join(n,"repo.json");try{mkdirSync(n,{recursive:!0});let i={repoId:r,gitId:t,displayName:o,resolvedAt:Date.now(),apiKeyHash:this.hashApiKey()??""},a=s+".tmp";writeFileSync(a,JSON.stringify(i,null,2),"utf-8"),renameSync(a,s);}catch{}}hashApiKey(){return this.config?.apiKey?createHash("sha256").update(this.config.apiKey).digest("hex").substring(0,16):null}startBackgroundFlush(){if(!this.config||!this.authState.accessToken)return;let 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=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 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: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=createReadStream(t),i=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=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 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: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=createReadStream(t),i=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=basename(e,extname(e)).toLowerCase(),n=t.find(a=>basename(a,extname(a)).toLowerCase()===o);if(n)return n;let s=t.find(a=>basename(a).toLowerCase().includes(o));if(s)return s;let i=t.find(a=>{let l=basename(a,extname(a)).toLowerCase();return l.length>=3&&(o.startsWith(l)||o.includes(l))});if(i)return i;if(r){let a=basename(r,extname(r)).toLowerCase(),l=t.find(d=>basename(d,extname(d)).toLowerCase()===a);if(l)return l;let c=t.find(d=>basename(d).toLowerCase().includes(a));if(c)return c}return null}function ni(e,t){if(t.length===0)return [];let r=basename(e,extname(e)).toLowerCase(),o=t.filter(n=>{let s=basename(n).toLowerCase(),i=basename(n,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 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=basename(t,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??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&&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&&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=basename(_,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(mkdirSync(dirname(resolve(t.outputPath)),{recursive:true}),writeFileSync(resolve(t.outputPath),JSON.stringify(M,null,2),"utf-8"),Ge(M,u,n.screenshotPaths,resolve(t.htmlReportPath)),qe(T,t.outputPath,t.htmlReportPath,t.quiet,u),t.openReport&&Ve(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(!existsSync(e))throw new Error(`Directory does not exist: ${e}`);let r=readdirSync(e).filter(n=>extname(n)===".json"&&n.includes("testrelic")).map(n=>join(e,n)),o=Er(r);return writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),o}export{
|
|
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=basename(e,extname(e)).toLowerCase(),n=t.find(a=>basename(a,extname(a)).toLowerCase()===o);if(n)return n;let s=t.find(a=>basename(a).toLowerCase().includes(o));if(s)return s;let i=t.find(a=>{let l=basename(a,extname(a)).toLowerCase();return l.length>=3&&(o.startsWith(l)||o.includes(l))});if(i)return i;if(r){let a=basename(r,extname(r)).toLowerCase(),l=t.find(d=>basename(d,extname(d)).toLowerCase()===a);if(l)return l;let c=t.find(d=>basename(d).toLowerCase().includes(a));if(c)return c}return null}function ni(e,t){if(t.length===0)return [];let r=basename(e,extname(e)).toLowerCase(),o=t.filter(n=>{let s=basename(n).toLowerCase(),i=basename(n,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 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=basename(t,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??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&&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&&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=basename(_,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(mkdirSync(dirname(resolve(t.outputPath)),{recursive:true}),writeFileSync(resolve(t.outputPath),JSON.stringify(M,null,2),"utf-8"),Ge(M,u,n.screenshotPaths,resolve(t.htmlReportPath)),qe(T,t.outputPath,t.htmlReportPath,t.quiet,u),t.openReport&&Ve(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=basename(C.flowFile,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=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(!existsSync(e))throw new Error(`Directory does not exist: ${e}`);let r=readdirSync(e).filter(n=>extname(n)===".json"&&n.includes("testrelic")).map(n=>join(e,n)),o=Er(r);return writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),o}export{J as CloudClient,he as DEFAULT_CLOUD_CONFIG,q as SCHEMA_VERSION,ir as buildMaestroArgs,V as buildSummary,$e as buildTimeline,zt as buildTimelineEntry,ce as buildUploadPayload,Et as categorizeCommand,ot as cleanupExpiredQueue,ze as collectArtifacts,Ze as collectGitMetadata,j as deriveNonGitProjectId,et as deriveRepoDisplayName,ue as detectCI,Ie as detectPlatformFromLogs,Ue as discoverAiReports,Se as discoverCommandFiles,ve as discoverConfigFile,Ae as discoverFlowFiles,Ee as discoverLogFiles,Ye as enforceHttps,re as exchangeToken,ct as finalizeAndUpload,Ps as finalizeRun,rt as flushQueue,Ge as generateHtmlReport,rn as getArtifactStats,te as healthCheck,Ds as initRealtimeRun,oe as isAuthError,ye as mergeCloudConfig,Er as mergeReports,xi as mergeReportsFromDirectory,B as normalizeGitRemoteUrl,Ve as openInBrowser,pi as orchestrateReport,Oe as parseAiReportFile,Ot as parseAiReportHtml,Re as parseCommandsFile,Ft as parseCommandsJson,xe as parseConfigFile,be as parseDuration,Te as parseFlowFile,_t as parseFlowYaml,we as parseJUnitFile,Rt as parseJUnitXml,Nt as parseLogContent,Me as parseLogFile,qe as printConsoleSummary,br as readPackageJsonName,Xe as refreshAccessToken,je as renderHtmlDocument,Xr as resolveConfig,Y as resolveEnvVar,X as resolveEnvVars,Qe as resolveRepo,Gn as runMaestro,Sr as uploadArtifact,lt as uploadArtifacts,st as uploadBatchRun,se as writeToQueue};//# sourceMappingURL=index.js.map
|
|
1860
1860
|
//# sourceMappingURL=index.js.map
|