@currents/cmd 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/dist/bin/index.js +41 -40
- package/dist/index.js +8 -9
- package/dist/services/upload/discovery/jest/reporter.js +1 -1
- package/dist/skills/currents-cli/SKILL.md +3 -2
- package/docs/ci-setup.md +2 -2
- package/package.json +14 -34
package/dist/bin/index.js
CHANGED
|
@@ -1,72 +1,73 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
"use strict";var
|
|
3
|
-
`)),
|
|
2
|
+
"use strict";var xu=Object.create;var Yr=Object.defineProperty;var Su=Object.getOwnPropertyDescriptor;var Au=Object.getOwnPropertyNames;var bu=Object.getPrototypeOf,Pu=Object.prototype.hasOwnProperty;var Uu=(t,e)=>{for(var r in e)Yr(t,r,{get:e[r],enumerable:!0})},Du=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Au(e))!Pu.call(t,o)&&o!==r&&Yr(t,o,{get:()=>e[o],enumerable:!(n=Su(e,o))||n.enumerable});return t};var g=(t,e,r)=>(r=t!=null?xu(bu(t)):{},Du(e||!t||!t.__esModule?Yr(r,"default",{value:t,enumerable:!0}):r,t));var wt={name:"@currents/cmd",version:"3.0.0",main:"./dist/index.js",author:{name:"Currents Software Inc",email:"hello@currents.dev"},license:"MIT",repository:{type:"git",url:"https://github.com/currents-dev/currents-reporter"},description:"Currents CLI tools",engines:{node:">=22.13"},scripts:{test:"vitest",rm:"rimraf dist",lint:'TIMING=1 eslint "**/*.ts*"',types:"tsc --noEmit",build:"tsup-node --minify --dts",dev:"tsup-node --watch --dts",release:"release-it","publish:npm":"npm run rm && npm run build && ./publish.js"},devDependencies:{"@jest/reporters":"^30.5.2","@jest/types":"^30.4.1","@release-it/conventional-changelog":"^12.0.0","release-it":"^21.0.2","@types/debug":"^4.1.12","@types/fs-extra":"^11.0.4","@types/lodash":"^4.17.16","@types/node":"^25.5.0","@types/semver":"^7.5.8","@types/xml2js":"^0.4.14","@types/yauzl":"3.4.0","@types/yazl":"3.3.1","fs-extra":"^11.3.4",jest:"^30.4.2","jest-cli":"^30.4.2","jest-config":"^30.4.2",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.11"},dependencies:{"@commander-js/extra-typings":"^14.0.0","@currents/commit-info":"3.0.0","@currents/rules":"0.1.0",commander:"^14.0.0",debug:"^4.4.0",dotenv:"17.4.2",lodash:"^4.18.1","proxy-from-env":"2.1.0",semver:"^7.8.5",tinyglobby:"^0.2.17",undici:"7.30.1",xml2js:"^0.6.2",yauzl:"3.4.0",yazl:"3.3.1"},bin:{currents:"./dist/bin/index.js","currents-cli":"./dist/bin/index.js"},files:["dist","docs","!**/*.map","!**/*/*.map"],keywords:["cloud test dashboard","test reporter","test results","currents","currents dashboard","ci"],exports:{".":{import:"./dist/index.js",require:"./dist/index.js",types:"./dist/index.d.ts"},"./discovery/jest":{import:"./dist/services/upload/discovery/jest/reporter.js",require:"./dist/services/upload/discovery/jest/reporter.js",types:"./dist/services/upload/discovery/jest/reporter.d.ts"},"./package.json":"./package.json"},"release-it":{npm:{publish:!1},github:{release:!0,releaseName:"${npm.name} v${version}"},plugins:{"@release-it/conventional-changelog":{preset:{name:"conventionalcommits"},header:"# Changelog",ignoreVersion:!0,infile:"./CHANGELOG.md"}},git:{commitMessage:"chore: release ${npm.name} v${version}",tagName:"${npm.name}-v${version}"}}};function Io(t=process.versions.node){let[e,r=0]=Wr(wt.engines.node.replace(">=","")),[n,o]=Wr(t);if(n>e||n===e&&o>=r)return;let s=Wr(wt.version)[0]-1;throw new Error(`${wt.name} requires Node.js ${e}.${r} or later. This is Node.js ${t}. Upgrade Node.js, or use ${wt.name}@${s} with older Node.js versions.`)}function Wr(t){return t.replace(/^v/,"").split(".").map(Number)}try{Io()}catch(t){console.error(t.message),process.exit(1)}var bP=require("dotenv/config");var wu=require("@commander-js/extra-typings");var Bt=wt.version;var Jn=require("@commander-js/extra-typings");var vu=[];function zr(t){vu.push(t)}var V=g(require("util"));var Qr=require("debug"),Lu=g(require("fs")),d=(0,Qr.debug)("currents"),Bu=null;function To(){Qr.debug.enable("currents,currents:*")}function Co(t){Bu=t}var yo=[],Ro=[];var k=(...t)=>(...e)=>{let r=e.join(" ");return r?t.reduceRight((n,o)=>(0,V.styleText)(o,n),r):""},Ue=(...t)=>{let e=V.default.format(...t);zr(e),console.log(e)},wo=(...t)=>{let e=V.default.format(...t);zr(e),console.error(e)},C=Ue,I=(...t)=>{let e=V.default.format(...t);return Ro.push(e),d("WARNING: ",e),Ue(k("bgYellow","black")(" WARNING "),e)},_t=(...t)=>{let e=V.default.format(..._o(t));return d("WARNING: ",V.default.format(...t)),Ue(k("bgYellow","black")(" WARNING "),e)},De=(...t)=>wo(k("bgYellow","black")(" WARNING "),V.default.format(...t)),Ne=(...t)=>Ue(k("green","bold")(V.default.format(...t))),T=(...t)=>{let e=V.default.format(..._o(t));return yo.push(e),d("ERROR: ",V.default.format(...t)),wo(k("bgRed","white")(" ERROR "),e)};var _o=t=>t.map(e=>e instanceof Error?e.message:e),ve=(t=2)=>console.log(Array(t).fill("").join(`
|
|
3
|
+
`)),th=k("cyan"),eh=k("blueBright"),rh=k("red"),nh=k("yellow"),oh=k("green"),sh=k("gray"),ih=k("white"),ah=k("black"),ch=k("magenta"),b=k("dim"),ph=k("bold");var Oo=80,Xr=" ",ku=" ";function Mu(t){let e=t.match(/"[^"]*"|'[^']*'|\S+/g)??[],r=[];for(let n of e){let o=r[r.length-1];o?.startsWith("-")&&!o.includes(" ")&&!n.startsWith("-")?r[r.length-1]=`${o} ${n}`:r.push(n)}return r}function $u(t){if(t.includes(`
|
|
4
4
|
`))return t.split(`
|
|
5
|
-
`).map(n=>
|
|
5
|
+
`).map(n=>Xr+n);let e=[],r=Xr;for(let n of Mu(t)){let o=r.trim()==="";!o&&r.length+1+n.length+2>Oo?(e.push(`${r} \\`),r=ku+n):r=o?r+n:`${r} ${n}`}return[...e,r]}function ju(t){let e=`${Xr}# `,r=[],n=e;for(let o of t.split(" "))n!==e&&n.length+1+o.length>Oo?(r.push(n),n=e+o):n=n===e?n+o:`${n} ${o}`;return[...r,n].map(o=>b(o))}function y(t){return`
|
|
6
6
|
Examples:
|
|
7
|
-
${t.map(r=>[...
|
|
7
|
+
${t.map(r=>[...ju(r.comment),...r.commands.flatMap($u)].join(`
|
|
8
8
|
`)).join(`
|
|
9
9
|
|
|
10
10
|
`)}
|
|
11
|
-
`}var Nr=f(require("lodash")),Vp=["apiKey","recordKey","key"];function oo(t,e){return Nr.default.isPlainObject(t)?Nr.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":oo(r,e)):t}function E(t){return oo(t,Vp)}var tt=class extends Error{};var Y=f(require("fs-extra")),Tt=require("path"),so=require("uuid");async function yt(t){try{return await Y.default.readJson(t)}catch(e){throw C("Error while reading JSON file: %s",t,e),C}}async function Rt(t,e){try{return await Y.default.writeFile(t,e,"utf8"),t}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function wt(t,e){try{try{return await Y.default.access(t),t}catch{return await Y.default.writeFile(t,e,"utf8"),t}}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function io(t,e){if(e){await Y.default.ensureDir(t);return}let r=(0,Tt.dirname)(t);await Y.default.ensureDir(r)}function Yp(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,so.v4)();return`${t}-${e}`}async function ao(t,e){let r=Yp(),n=(0,Tt.join)(t,e,r);return _t(n)}async function _t(t){try{return await Y.default.ensureDir(t),p("Folder created",t),t}catch(e){throw C(`Failed to create folder at ${t}:`,e),e}}async function Ce(t,e){try{return await Y.default.ensureDir((0,Tt.dirname)(e)),await Y.default.copy(t,e),p("File copied from %s to %s",t,e),e}catch(r){throw C(`Failed to copy file from ${t} to ${e}:`,r),r}}function Te(t,e){let r=e;for(;!Y.default.existsSync((0,Tt.join)(r,t));){let n=(0,Tt.dirname)(r);if(n===r)return;r=n}return r}var co=f(require("crypto"));function W(t){return co.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var ye={};Lp(ye,{getNanoid:()=>Lr,userFacingNanoid:()=>Br});var vr=require("nanoid"),po="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Lr=(t=16)=>(0,vr.customAlphabet)(po,t)(),Br=(0,vr.customAlphabet)(po,12);function Fr(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}function Nt(t){return Fr(t).replace(/[?#].*$/,"")}function Wp(t){return Object.entries(t??{}).reduce((e,[r,n])=>n===void 0?e:{...e,[r]:n},{})}function uo(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function P(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function Re(t,e){return t[e].cli}function we(t,e){return t[e].name}function U(t,e,r,n){let o=Wp(r);return e.forEach(s=>{if(!o[s]){let i=s,a=P(t,i);throw C(`${we(t,i)} is required: pass ${S(Re(t,i))}${a?` or set ${S(a)}`:""}`),new tt("Missing required config variable")}}),typeof n=="function"&&n(o),o}var O={apiKey:{name:"API key",env:"CURRENTS_API_KEY",cli:"--api-key"},recordKey:{name:"Record key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},ciBuildId:{name:"CI build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},tag:{name:"Tag",cli:"--tag"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};var{apiKey:qp,debug:zp,ciBuildId:Qp,projectId:Xp,tag:Zp}=O,_e={apiKey:qp,debug:zp,ciBuildId:Qp,projectId:Xp,tag:Zp,branch:{name:"Branch",cli:"--branch"},output:{name:"Output file",env:"CURRENTS_OUTPUT",cli:"--output"}};var td=p.extend("config"),ed=["apiKey","projectId"],rd=t=>{let{ciBuildId:e,tag:r,branch:n}=t;if(!([e,r,n].filter(Boolean).length===1||r&&n&&!e))throw C("Pass --ci-build-id, or --branch, --tag or both"),new tt("Missing or invalid parameters")},Mr=null;function mo(t){Mr=U(_e,ed,t,rd),td("Resolved config: %o",E(Mr))}function Oe(){return Mr}var Yo=require("fs/promises");function vt({apiKey:t,recordKey:e}){return e?{"x-currents-key":e}:t?{Authorization:`Bearer ${t}`}:{}}var Po=f(require("lodash"));var yo=f(require("axios")),Ro=f(require("axios-retry")),Kr=f(require("lodash"));var lo=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",Qt=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",fo=()=>3e4;var xe=require("axios"),kr=f(require("pretty-ms"));var ho=p.extend("http"),go=[3*1e3,15*1e3,30*1e3],Io=60*1e3;function Pe(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let n=Number(r);if(Number.isFinite(n))return Math.max(0,n*1e3);let o=Date.parse(String(r));return Number.isNaN(o)?void 0:Math.max(0,o-e)}var Ae=(t,e)=>{let r=go[Math.min(t,go.length)-1],n=Pe(e);return n===void 0?r:Math.min(Math.max(n,r),Io)},jr=t=>(ho("isRetriableError: %o",{message:t.message,code:"code"in t?t.code:void 0,status:"response"in t?t.response?.status:void 0,headers:"response"in t?t.response?.headers:void 0,data:"response"in t?t.response?.data:void 0,isAxiosError:(0,xe.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,xe.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),nd=["get","head","options","put","delete"],Eo=t=>{if(!(0,xe.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=Pe(t);return r===void 0||r<=Io}return nd.includes(t.config?.method?.toLowerCase()??"get")?jr(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},Se=()=>3;function Co(t,e,r){ho("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,kr.default)(Ae(t,e)??0),t,Se()),I("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,kr.default)(Ae(t,e)??0),t,Se())}var $r=p.extend("http");var Gr={api:null,restApi:null};function od(t){let e=t==="api"?lo():Qt();$r("client base url: %s",e);let r=yo.default.create({baseURL:e,timeout:fo(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(n=>{let o=n["axios-retry"]?.retryCount??0;n.headers.set({"x-cmd-version":bt}),n.headers.get("Content-Type")||n.headers.set("Content-Type","application/json");let s={...Kr.default.pick(n,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(n.data)?"buffer":n.data,params:n.params};return o?$r("network request retry: %o",To({...s,baseURL:e,isRetry:!0})):$r("network request: %o",To(s)),n}),(0,Ro.default)(r,{retries:Se(),retryCondition:t==="restApi"?Eo:jr,retryDelay:(n,o)=>Ae(n,o),shouldResetTimeout:!0,onRetry:Co}),r}function Lt(t){return Gr[t]===null&&(Gr[t]=od(t)),Gr[t]}function To(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":sd(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function sd(t){if(t?.results?.raw)return E({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return E(JSON.parse(t))}catch{return t}return Kr.default.isPlainObject(t)?E(t):t}var Oo=require("axios"),xo=f(require("lodash")),F=require("ts-pattern");function Ao(t){(0,F.match)(t).when(Oo.isAxiosError,id).otherwise(()=>{I("Unexpected error while sending network request: %s",t)})}function id(t){return(0,F.match)(t).with({code:"ECONNABORTED"},()=>{I("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{I("Network connection aborted")}).with({code:"ECONNRESET"},()=>{I("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{I("Network connection timeout")}).with({response:F.P.not(F.P.nullish)},e=>{ad(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{I(`[currents] Unexpected network error: %s
|
|
12
|
-
%O`,t.message,{method:
|
|
13
|
-
%o`,r)
|
|
14
|
-
%O`,t.message,{method:t.
|
|
15
|
-
%O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var wo={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function _o(t,e){return xo.default.isString(t)?e?.length===0?[t]:[t,`
|
|
11
|
+
`}var Zr=g(require("lodash")),Hu=["apiKey","recordKey","key"];function xo(t,e){return Zr.default.isPlainObject(t)?Zr.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":xo(r,e)):t}function E(t){return xo(t,Hu)}var Q=class extends Error{};var tn=require("crypto"),So=require("fs"),q=g(require("fs/promises")),Ao=require("os"),gt=require("path");function Le(t){let e=0,r=[];return async n=>{e<t?e++:await new Promise(o=>r.push(o));try{return await n()}finally{let o=r.shift();o?o():e--}}}var ct=Le(32);async function pt(t){let e=await q.default.readFile(t,"utf8");try{return JSON.parse(e.replace(/^\uFEFF/,""))}catch(r){throw r.message=`${t}: ${r.message}`,r}}function P(t){return q.default.access(t).then(()=>!0,()=>!1)}async function Ot(t){try{return await pt(t)}catch(e){throw T("Error while reading JSON file: %s",t,e),T}}async function xt(t,e){try{return await q.default.writeFile(t,e,"utf8"),t}catch(r){throw T(`Error writing file at ${t}:`,r),r}}async function St(t,e){try{try{return await q.default.access(t),t}catch{return await q.default.writeFile(t,e,"utf8"),t}}catch(r){throw T(`Error writing file at ${t}:`,r),r}}async function bo(t,e){if(e){await q.default.mkdir(t,{recursive:!0});return}let r=(0,gt.dirname)(t);await q.default.mkdir(r,{recursive:!0})}async function Be(t=""){let e=(0,gt.join)((0,Ao.tmpdir)(),`currents-${(0,tn.randomUUID)()}${t}`);return await q.default.writeFile(e,"",{flag:"wx",mode:384}),e}function Gu(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,tn.randomUUID)();return`${t}-${e}`}async function Po(t,e){let r=Gu(),n=(0,gt.join)(t,e,r);return At(n)}async function At(t){try{return await q.default.mkdir(t,{recursive:!0}),d("Folder created",t),t}catch(e){throw T(`Failed to create folder at ${t}:`,e),e}}async function Fe(t,e){try{return await q.default.mkdir((0,gt.dirname)(e),{recursive:!0}),await q.default.cp(t,e,{recursive:!0,verbatimSymlinks:!0}),d("File copied from %s to %s",t,e),e}catch(r){throw T(`Failed to copy file from ${t} to ${e}:`,r),r}}function ke(t,e){let r=e;for(;!(0,So.existsSync)((0,gt.join)(r,t));){let n=(0,gt.dirname)(r);if(n===r)return;r=n}return r}var Uo=g(require("crypto"));function X(t){return Uo.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var $e={};Uu($e,{getNanoid:()=>Me,userFacingNanoid:()=>en});var No=require("crypto"),Do="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Me=(t=16)=>Array.from({length:t},()=>Do[(0,No.randomInt)(Do.length)]).join(""),en=()=>Me(12);function rn(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}function Ft(t){return rn(t).replace(/[?#].*$/,"")}function Ku(t){return Object.entries(t??{}).reduce((e,[r,n])=>n===void 0?e:{...e,[r]:n},{})}function vo(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function U(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function je(t,e){return t[e].cli}function He(t,e){return t[e].name}function D(t,e,r,n){let o=Ku(r);return e.forEach(s=>{if(!o[s]){let i=s,a=U(t,i);throw T(`${He(t,i)} is required: pass ${b(je(t,i))}${a?` or set ${b(a)}`:""}`),new Q("Missing required config variable")}}),typeof n=="function"&&n(o),o}var x={apiKey:{name:"API key",env:"CURRENTS_API_KEY",cli:"--api-key"},recordKey:{name:"Record key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},ciBuildId:{name:"CI build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},tag:{name:"Tag",cli:"--tag"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};var{apiKey:Ju,debug:Vu,ciBuildId:qu,projectId:Yu,tag:Wu}=x,Ge={apiKey:Ju,debug:Vu,ciBuildId:qu,projectId:Yu,tag:Wu,branch:{name:"Branch",cli:"--branch"},output:{name:"Output file",env:"CURRENTS_OUTPUT",cli:"--output"}};var zu=d.extend("config"),Qu=["apiKey","projectId"],Xu=t=>{let{ciBuildId:e,tag:r,branch:n}=t;if(!([e,r,n].filter(Boolean).length===1||r&&n&&!e))throw T("Pass --ci-build-id, or --branch, --tag or both"),new Q("Missing or invalid parameters")},nn=null;function Lo(t){nn=D(Ge,Qu,t,Xu),zu("Resolved config: %o",E(nn))}function Ke(){return nn}var Ls=require("fs/promises");function kt({apiKey:t,recordKey:e}){return e?{"x-currents-key":e}:t?{Authorization:`Bearer ${t}`}:{}}var ds=require("timers/promises"),ln=g(require("lodash"));var Bo=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",ie=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",Fo=()=>3e4;var ts=require("http"),pn=require("stream"),ae=require("util"),$t=g(require("zlib")),es=require("undici");var Mt=require("undici");var Yo=require("proxy-from-env");var Zu=new Set(["localhost","0.0.0.0"]),$o=t=>{let e=t.length;for(;e&&t.charCodeAt(e-1)===46;)e--;return e===t.length?t:t.slice(0,e)},jo=t=>{let e=t.split(".");return e.length!==4||e[0]!=="127"?!1:e.every(r=>/^\d+$/.test(r)&&Number(r)>=0&&Number(r)<=255)},on=t=>{if(/^0[xX][0-9a-fA-F]+$/.test(t)){let e=parseInt(t.slice(2),16);return Number.isFinite(e)?e:null}if(t.length>1&&/^0[0-7]+$/.test(t)){let e=parseInt(t,8);return Number.isFinite(e)?e:null}if(t.length>1&&/^0[0-9]+$/.test(t))return null;if(/^[0-9]+$/.test(t)){let e=parseInt(t,10);return Number.isFinite(e)?e:null}return null},Ho=t=>{if(typeof t!="string"||!t||t.indexOf(":")!==-1)return t;let e=t;if(e.charAt(0)==="["&&e.charAt(e.length-1)==="]"&&(e=e.slice(1,-1)),e=$o(e),!/^[0-9.xXa-fA-F]+$/.test(e))return t;let r=e.split(".");if(r.some(l=>l===""))return t;if(r.length===4){let l=r.map(on);return l.some(m=>m===null||m<0||m>255)?t:l.join(".")}if(r.length>4||r.length===1)return t;let n=r.slice(0,-1),o=r[r.length-1],s=4-n.length,i=on(o);if(i===null)return t;let a=(1<<8*s)-1;if(i<0||i>a)return t;let u=new Array(s).fill(0);for(let l=s-1,m=i;l>=0;l--,m>>=8)u[l]=m&255;let p=n.map(on);return p.some(l=>l===null||l<0||l>255)?t:[...p,...u].join(".")},sn=t=>/^0{1,4}$/.test(t),td=t=>{if(t==="::")return!0;let e=t.indexOf("::");if(e!==-1){if(e!==t.lastIndexOf("::"))return!1;let n=t.slice(0,e),o=t.slice(e+2),s=n?n.split(":"):[],i=o?o.split(":"):[];return s.length+i.length<8&&s.every(sn)&&i.every(sn)}let r=t.split(":");return r.length===8&&r.every(sn)},ed=t=>{if(t==="::1")return!0;let e=t.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);if(e)return jo(e[1]);let r=t.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);if(r){let o=parseInt(r[1],16);return o>=32512&&o<=32767}let n=t.split(":");if(n.length===8){for(let o=0;o<7;o++)if(!/^0+$/.test(n[o]))return!1;return/^0*1$/.test(n[7])}return!1},ko=t=>t?Zu.has(t)||jo(t)||td(t)?!0:ed(t):!1,rd={http:80,https:443,ws:80,wss:443,ftp:21},nd=t=>{let e=t,r=0;if(e.charAt(0)==="["){let s=e.indexOf("]");if(s!==-1){let i=e.slice(1,s),a=e.slice(s+1);return a.charAt(0)===":"&&/^\d+$/.test(a.slice(1))&&(r=Number.parseInt(a.slice(1),10)),[i,r]}}let n=e.indexOf(":"),o=e.lastIndexOf(":");return n!==-1&&n===o&&/^\d+$/.test(e.slice(o+1))&&(r=Number.parseInt(e.slice(o+1),10),e=e.slice(0,o)),[e,r]},od=/^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:(\d+\.\d+\.\d+\.\d+)$/i,sd=/^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i,Go=t=>{if(typeof t!="string"||t.indexOf(":")===-1)return t;let e=t.match(od);if(e)return e[1];let r=t.match(sd);if(r){let n=parseInt(r[1],16),o=parseInt(r[2],16);return`${n>>8}.${n&255}.${o>>8}.${o&255}`}return t},id=/^(?:0|[1-9]\d{0,2})$/,Ko=t=>{let e=t.split(".");return e.length===4&&e.every(r=>id.test(r)&&Number(r)<=255)?e.map(Number):null},ad=/^[0-9a-f]{1,4}$/i,cd=t=>{let e=t.split("::");if(e.length>2)return null;let r=e[0]?e[0].split(":"):[];if(e.length===2){let n=e[1]?e[1].split(":"):[],o=8-r.length-n.length;if(o<1)return null;r.push(...new Array(o).fill("0"),...n)}return r.length!==8||r.some(n=>!ad.test(n))?null:r.flatMap(n=>{let o=Number.parseInt(n,16);return[o>>8&255,o&255]})},Jo=t=>typeof t!="string"||!t?null:t.indexOf(":")!==-1?cd(t):Ko(t),Mo=t=>{if(!t)return t;t.charAt(0)==="["&&t.charAt(t.length-1)==="]"&&(t=t.slice(1,-1));let e=$o(t),r=Ho(e);return r!==e?r:Go(e)},pd=t=>{let e=t,r=e.charAt(0)==="[",n=e.charAt(e.length-1)==="]",o=e.includes("[")||e.includes("]");if(r||n){if(!r||!n||(e=e.slice(1,-1),e.indexOf(":")===-1||e.includes("[")||e.includes("]")))return null}else if(o)return null;if(!e||e.charAt(e.length-1)===".")return null;let s=e.indexOf(":")!==-1;if(s)try{e=new URL(`http://[${e}]/`).hostname.slice(1,-1)}catch{return null}else if(e=Ho(e),!Ko(e))return null;return{normalized:Go(e),wasIPv6:s}},ud=/^(.+)\/(0|[1-9]\d{0,2})$/,dd=t=>{if(t.indexOf("/")===-1)return;let e=ud.exec(t);if(!e)return null;let r=Number(e[2]),n=pd(e[1]);if(!n)return null;let{normalized:o,wasIPv6:s}=n;if(s&&o.indexOf(":")===-1){if(r<96)return null;r-=96}let i=Jo(o);return!i||r>i.length*8?null:{bytes:i,prefix:r}},md=(t,e,r)=>{let n=r>>3;for(let s=0;s<n;s++)if(t[s]!==e[s])return!1;let o=r&7;if(o){let s=255<<8-o&255;if((t[n]&s)!==(e[n]&s))return!1}return!0};function Vo(t,e){let r;try{r=new URL(t)}catch{return!1}let n=e.toLowerCase();if(!n)return!1;if(n==="*")return!0;let o=Number.parseInt(r.port,10)||rd[r.protocol.split(":",1)[0]]||0,s=Mo(r.hostname.toLowerCase()),i=Jo(s);return n.split(/[\s,]+/).some(a=>{if(!a)return!1;if(a==="*")return!0;let u=dd(a);if(u!==void 0)return u!==null&&!!i&&i.length===u.bytes.length&&md(i,u.bytes,u.prefix);let[p,l]=nd(a);return p=Mo(p),!p||l&&l!==o?!1:(p.charAt(0)==="*"&&(p=p.slice(1)),p.charAt(0)==="."?s.endsWith(p):s===p||ko(s)&&ko(p))})}var ld=d.extend("http");function fd(t){return process.env[t.toLowerCase()]||process.env[t.toUpperCase()]||""}function gd(t){let e=(0,Yo.getProxyForUrl)(t);return!e||Vo(t,fd("no_proxy"))?"":e}var an={headersTimeout:0,bodyTimeout:0},hd=new Mt.Agent({...an,connect:{timeout:0}}),qo=new Map;function Ed(t){let e=qo.get(t);if(e)return e;let{username:r,password:n}=new URL(t);return e=new Mt.ProxyAgent({uri:t,token:r||n?`Basic ${Buffer.from(`${decodeURIComponent(r)}:${decodeURIComponent(n)}`).toString("base64")}`:void 0,proxyTunnel:!1,proxyTls:{timeout:0},...an,factory:(o,s)=>new Mt.Pool(o,{...s,...an})}),qo.set(t,e),e}function Wo(t){let e=gd(t);return e?(ld("Using HTTP proxy %s for %s",Ft(e),Ft(t)),Ed(e)):hd}var H=class extends Error{constructor(r,n,o,s){super(r);this.code=n;this.config=o;this.response=s;this.name="HttpError"}get status(){return this.response?.status}};function L(t){return t instanceof H}var Id=21,Td=/^(?:(?:proxy-)?authorization|cookie)$/i;async function bt(t){let e={method:t.method.toLowerCase(),url:t.url,data:t.body},{res:r,method:n}=await Cd(t,e),o=await xd(r,n,t.responseType??"json",e);if(o.status<200||o.status>=300)throw new H(`Request failed with status code ${o.status}`,o.status<500?"ERR_BAD_REQUEST":"ERR_BAD_RESPONSE",e,o);return o}async function Cd(t,e){let r=t.timeout??0,n=new AbortController,o=yd(t,n.signal,r),s,i=new Promise((a,u)=>{r<=0||(s=setTimeout(()=>{u(new H(`timeout of ${r}ms exceeded`,"ETIMEDOUT",e)),n.abort(),o.then(({res:p})=>p.body.destroy(),()=>{})},r))});try{return await Promise.race([o,i])}catch(a){throw a instanceof H?a:Sd(a,e)}finally{clearTimeout(s)}}async function yd(t,e,r){let{url:n,body:o}=t,s=t.method.toUpperCase(),i=Rd(t.headers??{},o);for(let a=0;;a++){let u=await(0,es.request)(n,{method:s,headers:i,body:o,signal:e,bodyTimeout:r,dispatcher:Wo(n),reset:!1}),p=u.headers.location;if(u.statusCode<300||u.statusCode>=400||typeof p!="string"||o instanceof pn.Readable)return{res:u,method:s};if(await u.body.dump(),a>=Id)throw Object.assign(new Error("Maximum number of redirects exceeded"),{code:"ERR_FR_TOO_MANY_REDIRECTS"});((u.statusCode===301||u.statusCode===302)&&s==="POST"||u.statusCode===303&&!/^(?:GET|HEAD)$/.test(s))&&(s="GET",o=void 0,i=zo(i,/^content-/i));let l=new URL(n),m=new URL(p,l);(m.protocol!==l.protocol&&m.protocol!=="https:"||m.host!==l.host&&!m.host.endsWith(`.${l.host}`))&&(i=zo(i,Td)),n=m.href}}function Rd(t,e){let r={accept:"application/json, text/plain, */*","user-agent":"axios/1.20.0","accept-encoding":"gzip, compress, deflate, br"};e&&!(e instanceof pn.Readable)&&(r["content-length"]=String(Buffer.byteLength(e)));for(let[n,o]of Object.entries(t))r[n.toLowerCase()]=o;return r}function zo(t,e){return Object.fromEntries(Object.entries(t).filter(([r])=>!e.test(r)))}var Qo=(0,ae.promisify)($t.default.unzip),wd=(0,ae.promisify)($t.default.inflateRaw),_d=(0,ae.promisify)($t.default.brotliDecompress),cn=typeof $t.default.zstdDecompress=="function"?(0,ae.promisify)($t.default.zstdDecompress):void 0,Xo=t=>["gzip","x-gzip","compress","x-compress","deflate","br"].includes(t)||t==="zstd"&&cn!==void 0;function Od(t,e){return e==="br"?_d(t):e==="zstd"&&cn?cn(t):e==="deflate"?Qo(t).catch(()=>wd(t)):Qo(t)}async function xd(t,e,r,n){let o={...t.headers},s=String(o["content-encoding"]??"").toLowerCase();s&&Xo(s)&&delete o["content-encoding"];let i={status:t.statusCode,statusText:t.statusText,headers:o};if(e==="HEAD"||t.statusCode===204||t.statusCode===304)return delete o["content-encoding"],await t.body.dump(),{...i,data:Zo(Buffer.alloc(0),r)};let a;try{a=Buffer.from(await t.body.arrayBuffer())}catch{throw new H("stream has been aborted","ERR_BAD_RESPONSE",n,{...i,data:void 0})}if(s&&Xo(s)&&a.length>0)try{a=await Od(a,s)}catch(u){let p=u;throw new H(p.message,p.code,n,{...i,data:void 0})}return{...i,data:Zo(a,r)}}function Zo(t,e){if(e==="buffer")return t;let r=t.toString("utf8").replace(/^\uFEFF/,"");if(e==="text"||!r)return r;try{return JSON.parse(r)}catch{return r}}function Sd(t,e){let r=t,n=Ad(r);if(n)return new H(`Request failed with status code ${n}`,n<500?"ERR_BAD_REQUEST":"ERR_BAD_RESPONSE",e,{status:n,statusText:ts.STATUS_CODES[n]??"",headers:{},data:""});if(r.code==="UND_ERR_SOCKET")return new H("socket hang up","ECONNRESET",e);let o=!r.message&&r.errors?r.errors.map(s=>s.message).join("; "):r.message;return new H(o,r.code,e)}function Ad(t){let e=t.message?.match(/^Proxy response \((\d{3})\) !== 200 when HTTP Tunneling$/)??t.message?.match(/^Proxy Authentication Required \((407)\)$/);return e?Number(e[1]):void 0}function rs(t){return["UND_ERR_INVALID_ARG","UND_ERR_NOT_SUPPORTED","UND_ERR_REQ_CONTENT_LENGTH_MISMATCH"].includes(t.code??"")}var ss=d.extend("http"),ns=[3*1e3,15*1e3,30*1e3],is=60*1e3;function qe(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let n=Number(r);if(Number.isFinite(n))return Math.max(0,n*1e3);let o=Date.parse(String(r));return Number.isNaN(o)?void 0:Math.max(0,o-e)}var Je=(t,e)=>{let r=ns[Math.min(t,ns.length)-1],n=qe(e);return n===void 0?r:Math.min(Math.max(n,r),is)},un=t=>(ss("isRetriableError: %o",{message:t.message,code:"code"in t?t.code:void 0,status:"response"in t?t.response?.status:void 0,headers:"response"in t?t.response?.headers:void 0,data:"response"in t?t.response?.data:void 0,isHttpError:L(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:L(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),bd=["get","head","options","put","delete"],as=t=>{if(!L(t))return!1;let e=t.response?.status;if(e===429){let r=qe(t);return r===void 0||r<=is}return bd.includes(t.config?.method?.toLowerCase()??"get")?un(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},Ve=()=>3;function os(t){let e=[],r=Math.trunc(t/36e5),n=Math.trunc(t/6e4)%60;if(r&&e.push(`${r}h`),n&&e.push(`${n}m`),t<1e3){let o=t>=1?Math.round(t):Math.ceil(t);o&&e.push(`${o}ms`)}else{let o=Math.floor(t/1e3%60*10+1e-7)/10;o&&e.push(`${o}s`)}return e.join(" ")||"0ms"}function cs(t,e,r){ss("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,os(Je(t,e)??0),t,Ve()),I("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,os(Je(t,e)??0),t,Ve())}var mn=d.extend("http");var dn={api:null,restApi:null};function Pd(t){let e=t==="api"?Bo():ie();mn("client base url: %s",e);let r=Ve(),n=t==="restApi"?as:un;return{async request(o){let s={"content-type":"application/json",...ln.default.mapKeys(o.headers??{},(u,p)=>p.toLowerCase()),"x-cmd-version":Bt},i=Ud(o.data),a=Dd(e,o.url,o.params);for(let u=0;;u++){vd(e,o,s,u>0);try{return await bt({method:o.method,url:a,headers:s,body:i,timeout:Fo(),responseType:o.responseType})}catch(p){if(p instanceof H&&(p.config.url=o.url),!(u<r&&n(p)))throw p;cs(u+1,p,o),await(0,ds.setTimeout)(Je(u+1,p))}}}}}function jt(t){return dn[t]===null&&(dn[t]=Pd(t)),dn[t]}function Ud(t){if(t!==void 0)return typeof t=="string"||Buffer.isBuffer(t)?t:JSON.stringify(t)}function Dd(t,e,r){let n=new URL(`${t.replace(/\/?\/$/,"")}/${e.replace(/^\/+/,"")}`),o=r instanceof URLSearchParams?r.toString():r?Nd(r):"";return o?`${n.origin}${n.pathname}${n.search}${n.search?"&":"?"}${o}`:n.href}function Nd(t){let e=[];for(let[r,n]of Object.entries(t))if(n!=null)if(Array.isArray(n))for(let o of n)o!=null&&e.push([`${r.trim()}[]`,String(o)]);else e.push([r.trim(),String(n)]);return e.map(([r,n])=>`${ps(r)}=${ps(n)}`).join("&")}function ps(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function vd(t,e,r,n){let o={method:e.method.toLowerCase(),baseURL:t,url:e.url,headers:r,data:Buffer.isBuffer(e.data)?"buffer":e.data,params:e.params,isRetry:n};mn(n?"network request retry: %o":"network request: %o",us(o))}function us(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":Ld(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,authorization:"Bearer ***","x-currents-key":"***"}}}function Ld(t){if(t?.results?.raw)return E({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return E(JSON.parse(t))}catch{return t}return ln.default.isPlainObject(t)?E(t):t}var Ht=g(require("lodash"));function gs(t){if(!L(t)){I("Unexpected error while sending network request: %s",t);return}switch(t.code){case"ECONNABORTED":case"ECONNREFUSED":I("Network connection aborted");return;case"ECONNRESET":I("Network connection reset");return;case"ETIMEDOUT":I("Network connection timeout");return}if(t.response){Bd(t,t.response.status,t.response.data);return}I(`[currents] Unexpected network error: %s
|
|
12
|
+
%O`,t.message,{method:void 0,url:void 0,status:void 0,payload:void 0})}function Bd(t,e,r){let{method:n,url:o}=t.config;switch(e){case 401:I(`[currents] ${n} ${o} - 401 Unauthorized Request from cloud service`);return;case 400:I(`[currents] ${n} ${o} - 400 Bad Request from cloud service:
|
|
13
|
+
%o`,r);return;case 404:I(`[currents] ${n} ${o} - 404 Not Found from cloud service`);return;case 429:I(`[currents] ${n} ${o} - 429 Too Many Requests from cloud service`);return;case 422:Fd(t,r);return;default:hs(t)}}function hs(t){I(`[currents] Unexpected network response: %s
|
|
14
|
+
%O`,t.message,{method:t.config.method,url:t.config.url,status:t.response?.status})}var ms=t=>Array.isArray(t)&&t.every(Ht.default.isString);function Fd(t,e){let{code:r,message:n,errors:o}=e??{};if(r===ls.MISSING_SUITE&&Ht.default.isString(n)&&ms(o)){ve(1),T(...fs(n,o));return}if(r===ls.RUN_EXPIRED&&Ht.default.isString(n)){I(n);return}if(Ht.default.isString(n)&&ms(o)){ve(1),I(...fs(n,o)),ve(1);return}hs(t)}var ls={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function fs(t,e){return Ht.default.isString(t)?e?.length===0?[t]:[t,`
|
|
16
15
|
${(e??[]).map(r=>` - ${r}`).join(`
|
|
17
16
|
`)}
|
|
18
|
-
`]:["Unexpected network error"]}var
|
|
17
|
+
`]:["Unexpected network error"]}var Es=d.extend("http");async function Y(t,e,r=jt){try{let n=await r(t).request(e);return Es("network response: %o",{...n,url:e.url,method:e.method.toLowerCase()}),n}catch(n){let o=n;throw Es("network error: %o",{code:o.code,message:o.message,url:o.config?.url,method:o.config?.method,status:o.response?.status,headers:o.response?.headers,data:o.response?.data}),gs(o),o}}var Gt=d.extend("api");async function Is(t){try{return Gt("Request params: %o",E(t)),Y("api",{url:"cache/upload",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Gt("Failed to create cache:",e),e}}async function Ts(t){try{return Gt("Request params: %o",E(t)),Y("api",{url:"cache/v2/download",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Gt("Failed to retrieve cache:",e),e}}async function Cs(t){try{return Gt("Request params: %o",E(t)),Y("api",{url:"cache/meta",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Gt("Failed to retrieve reference cache meta:",e),e}}var kd=d.extend("api");async function ys(t){return kd("Cancel params: %o",E(t)),(await Y("api",{url:"v1/runs/cancel",method:"POST",data:t})).data}var ws=require("util"),_s=require("zlib");var Rs=d.extend("api"),Md=(0,ws.promisify)(_s.gzip);async function Os(t){try{Rs("Run params: %o",E(t));let e=await $d(JSON.stringify(t));return Y("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw Rs("Failed to create the run:",e),e}}async function $d(t){try{return await Md(t)}catch(e){throw T("Failed to compress run payload:",e),e}}var xs=d.extend("api");async function Ss(t,e){try{return xs("Run params: %o",e),Y("restApi",{url:"v1/runs/find",params:e,method:"GET",headers:{"Content-Type":"application/json",...kt({apiKey:t})}}).then(r=>r.data)}catch(r){throw xs("Failed to obtain run data:",r),r}}function As(t,e){return jt("restApi").request({...e,headers:{...kt({apiKey:t}),...e.headers},responseType:"text"})}var jd=d.extend("api");async function bs(t,e){try{return await Y("api",{url:`rules/project/${encodeURIComponent(t)}`,method:"GET",headers:{"x-currents-key":e}}).then(r=>r.data.rules)}catch(r){throw jd("Failed to get the project actions:",r),r}}var Ps=d.extend("api");function Hd(t){if(!L(t)||!t.response)return t;let e=t.response.data,r=[`${t.response.status}`];e?.code&&r.push(e.code);let n=e?.error??t.message,o=qe(t),s=o?` Retry in ${Math.ceil(o/1e3)} seconds.`:"",i=Gd(e?.candidates);return new Error(`${r.join(" ")}: ${n}${s}${i}`)}function Gd(t){return!Array.isArray(t)||t.length===0?"":`
|
|
19
18
|
Matches:
|
|
20
19
|
${t.map(({spec:r,title:n,instanceId:o,testId:s,runId:i,ciBuildId:a})=>i?` - run ${i} (CI build ID ${a})`:` - ${[r,n].filter(Boolean).join(" > ")} (instance ${o}${s?`, test ${s}`:""})`).join(`
|
|
21
|
-
`)}`}async function
|
|
22
|
-
`)}var Hs=require("axios"),rn=f(require("path"));var M=require("@commander-js/extra-typings");var Wo=require("@commander-js/extra-typings");function De(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}function qo(t){for(let e of t.options){let r=e.attributeName();if(!e.envVar||!e.isBoolean()||t.getOptionValueSource(r)!=="env")continue;let n=uo(process.env[e.envVar]);t.setOptionValueWithSource(r,n??e.defaultValue,n===void 0?"default":"env")}}function hd(t,e){if(!Array.isArray(t))return String(t)===e;let r=n=>n.map(o=>o.trim()).filter(Boolean).join(",");return r(t.map(String))===r(e.split(","))}function zo(t){for(let e of t.options){let r=e.attributeName(),n=e.envVar?process.env[e.envVar]:void 0,o=t.getOptionValue(r);!n||e.isBoolean()||t.getOptionValueSource(r)!=="cli"||hd(o,n)||he(`${e.long} and ${e.envVar} are set to different values; using ${e.long}`)}}function Mt(){console.log=(...t)=>console.error(...t)}async function R(t,e){try{e.debug&&Qn(),await t(e),process.exit(0)}catch(r){C(r.message);let n=r instanceof Wo.CommanderError?r.exitCode:1;process.exit(n)}}function Zt(t){return new Promise((e,r)=>process.stdout.write(t,n=>n?r(n):e()))}var Qo="Without it the ID comes from the CI job: on GitHub Actions the repository, the run ID and --matrix-index; on GitLab the pipeline ID and the job name; on other CI the variables that identify the pipeline and the job, and --matrix-index. When no CI job is detected the ID is random, so pass --id",Xo=new M.Option("--id <id>",`the ID to save the files under. ${Qo}`),Zo=new M.Option("--id <id>",`the ID the files were saved under. ${Qo}`),ts=new M.Option("--path <path>",'comma-separated paths or glob patterns of the files to save, inside the current folder; quote globs, e.g. "dist/**/*". At most 50 MB zipped').argParser(De),te=(e=>(e.lastRun="last-run",e))(te||{}),es=new M.Option("--preset <preset-name>",'"last-run" saves the Playwright .last-run.json files of --pw-output-dir, to rerun only the failed tests').choices(Object.values(te)),rs=new M.Option("--preset <preset-name>",'"last-run" restores the saved .last-run.json files and writes the Playwright options for the rerun to --preset-output').choices(Object.values(te)),ns=new M.Option("--output-dir <folder>","the folder to restore the files to; by default the current folder"),os=new M.Option("--pw-output-dir <folder>","the Playwright output folder that holds .last-run.json").default("test-results"),ee=".currents_env",ss=new M.Option("--preset-output <path>",'the file the "last-run" preset writes, relative to the current folder. On GitHub Actions and CircleCI it holds options for "playwright test"; on GitLab the shell variables EXTRA_PW_FLAGS, EXTRA_PWCP_FLAGS and RUN_ATTEMPT, to source. Nothing is written on other CI').default(ee),Jr=new M.Option("--matrix-index <number>","the index of this job among parallel jobs, from 1; each job has its own cache. Pass it when the CI does not tell the jobs apart, as in a GitHub Actions matrix").default(1).argParser(is),Vr=new M.Option("--matrix-total <number>","GitHub Actions only: the number of jobs in the matrix, for the shards that the last-run preset writes").default(1).argParser(is);function is(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new M.InvalidArgumentError("A positive integer is expected.");return e}var as=new M.Option("--continue","exit with 0 when the cache is not found").default(!1),cs=new M.Option("--continue","exit with 0 when no files are found, and save the cache without files").default(!1);var Id={recordKey:O.recordKey,debug:O.debug},Ed={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output folder",cli:"--pw-output-dir"},presetOutput:{name:"Preset output path",cli:"--preset-output"},path:{name:"Paths to cache",cli:"--path"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue when upload path missing",cli:"--continue"}},Cd={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Output folder",cli:"--output-dir"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue on cache miss",cli:"--continue"}},Yr={...Id,...Ed,...Cd};var ps=p.extend("config"),ds=["recordKey"],Ot;function us(t){Ot={type:"SET_COMMAND_CONFIG",values:U(Yr,ds,t)},ps("Resolved config: %o",{...Ot,values:E(Ot.values)})}function ms(t){Ot={type:"GET_COMMAND_CONFIG",values:U(Yr,ds,t)},ps("Resolved config: %o",{...Ot,values:E(Ot.values)})}function mt(){return Ot}function ls(t){return{recordKey:t.key,id:t.id,preset:t.preset,outputDir:t.outputDir,presetOutput:t.presetOutput,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}function fs(t){return{recordKey:t.key,id:t.id,preset:t.preset,pwOutputDir:t.pwOutputDir,path:t.path,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}var w=require("lodash");var Ue=p.extend("ci"),Td=(t,e)=>(0,w.set)(t,(0,w.camelCase)(e),process.env[e]),b=t=>(0,w.transform)(t,Td,{}),yd=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Rd=()=>(0,w.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),wd=()=>process.env.bamboo_buildNumber,_d=()=>(0,w.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),Od=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),xd=()=>!!(process.env.BUILD_ID&&process.env.PROJECT_ID&&process.env.PROJECT_NUMBER||process.env.GCP_PROJECT||process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT),Ad=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Sd={appveyor:"APPVEYOR",azure:yd,awsCodeBuild:Rd,bamboo:wd,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:_d,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Od,goCD:"GO_JOB_NAME",jenkins:Ad,googleCloud:xd,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Pd(){let{env:t}=process;return(0,w.findKey)(Sd,e=>{if((0,w.isString)(e))return t[e];if((0,w.isFunction)(e))return e()})}var gs=()=>({appveyor:b(["APPVEYOR_JOB_ID","APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER","APPVEYOR_BUILD_VERSION","APPVEYOR_PULL_REQUEST_NUMBER","APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"]),azure:b(["AGENT_BUILDDIRECTORY","AGENT_ID","AGENT_JOBNAME","AGENT_JOBSTATUS","AGENT_MACHINENAME","AGENT_NAME","AGENT_OS","AGENT_OSARCHITECTURE","BUILD_BUILDID","BUILD_BUILDNUMBER","BUILD_BUILDURI","BUILD_CONTAINERID","BUILD_CRONSCHEDULE_DISPLAYNAME","BUILD_DEFINITIONNAME","BUILD_DEFINITIONVERSION","BUILD_QUEUEDBY","BUILD_QUEUEDBYID","BUILD_REASON","BUILD_REPOSITORY_ID","BUILD_REPOSITORY_NAME","BUILD_REPOSITORY_PROVIDER","BUILD_REPOSITORY_URI","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILD_SOURCEBRANCH","BUILD_SOURCEBRANCHNAME","BUILD_SOURCESDIRECTORY","BUILD_SOURCEVERSION","BUILD_SOURCEVERSIONAUTHOR","BUILD_SOURCEVERSIONMESSAGE","BUILD_STAGINGDIRECTORY","BUILD_TRIGGEREDBY_BUILDID","BUILD_TRIGGEREDBY_BUILDNUMBER","BUILD_TRIGGEREDBY_DEFINITIONID","BUILD_TRIGGEREDBY_DEFINITIONNAME","BUILD_TRIGGEREDBY_PROJECTID","COMMON_TESTRESULTSDIRECTORY","PIPELINE_WORKSPACE","SYSTEM_COLLECTIONID","SYSTEM_COLLECTIONURI","SYSTEM_DEFAULTWORKINGDIRECTORY","SYSTEM_DEFINITIONID","SYSTEM_HOSTTYPE","SYSTEM_JOBATTEMPT","SYSTEM_JOBDISPLAYNAME","SYSTEM_JOBID","SYSTEM_JOBNAME","SYSTEM_PHASEATTEMPT","SYSTEM_PHASEDISPLAYNAME","SYSTEM_PHASENAME","SYSTEM_PLANID","SYSTEM_PULLREQUEST_ISFORK","SYSTEM_PULLREQUEST_PULLREQUESTID","SYSTEM_PULLREQUEST_PULLREQUESTNUMBER","SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI","SYSTEM_PULLREQUEST_SOURCEBRANCH","SYSTEM_PULLREQUEST_SOURCECOMMITID","SYSTEM_PULLREQUEST_TARGETBRANCH","SYSTEM_PULLREQUEST_TARGETBRANCHNAME","SYSTEM_STAGEATTEMPT","SYSTEM_STAGEDISPLAYNAME","SYSTEM_STAGENAME","SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","SYSTEM_TEAMPROJECT","SYSTEM_TEAMPROJECTID","SYSTEM_TIMELINEID"]),awsCodeBuild:b(["AWS_DEFAULT_REGION","AWS_REGION","CODEBUILD_BATCH_BUILD_IDENTIFIER","CODEBUILD_BUILD_ARN","CODEBUILD_BUILD_ID","CODEBUILD_BUILD_IMAGE","CODEBUILD_BUILD_NUMBER","CODEBUILD_BUILD_SUCCEEDING","CODEBUILD_BUILD_URL","CODEBUILD_INITIATOR","CODEBUILD_PROJECT_ARN","CODEBUILD_PUBLIC_BUILD_URL","CODEBUILD_RESOLVED_SOURCE_VERSION","CODEBUILD_SOURCE_REPO_URL","CODEBUILD_SOURCE_VERSION","CODEBUILD_SRC_DIR","CODEBUILD_START_TIME","CODEBUILD_WEBHOOK_ACTOR_ACCOUNT_ID","CODEBUILD_WEBHOOK_BASE_REF","CODEBUILD_WEBHOOK_EVENT","CODEBUILD_WEBHOOK_HEAD_REF","CODEBUILD_WEBHOOK_MERGE_COMMIT","CODEBUILD_WEBHOOK_PREV_COMMIT","CODEBUILD_WEBHOOK_TRIGGER","CODEBUILD_WEBHOOK_LABEL","CODEBUILD_WEBHOOK_RUN_ID","CODEBUILD_WEBHOOK_JOB_ID","CODEBUILD_WEBHOOK_WORKFLOW_NAME","CODEBUILD_RUNNER_OWNER","CODEBUILD_RUNNER_REPO","CODEBUILD_RUNNER_REPO_DOMAIN","CODEBUILD_RUNNER_WITH_BUILDSPEC"]),bamboo:b(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:b(["CI","BITBUCKET_WORKSPACE","BITBUCKET_REPO_SLUG","BITBUCKET_REPO_UUID","BITBUCKET_REPO_FULL_NAME","BITBUCKET_REPO_IS_PRIVATE","BITBUCKET_REPO_OWNER","BITBUCKET_REPO_OWNER_UUID","BITBUCKET_PROJECT_KEY","BITBUCKET_PROJECT_UUID","BITBUCKET_BUILD_NUMBER","BITBUCKET_PIPELINE_UUID","BITBUCKET_STEP_UUID","BITBUCKET_STEP_RUN_NUMBER","BITBUCKET_STEP_TRIGGERER_UUID","BITBUCKET_PARALLEL_STEP","BITBUCKET_PARALLEL_STEP_COUNT","BITBUCKET_CLONE_DIR","BITBUCKET_COMMIT","BITBUCKET_BRANCH","BITBUCKET_TAG","BITBUCKET_BOOKMARK","BITBUCKET_GIT_HTTP_ORIGIN","BITBUCKET_GIT_SSH_ORIGIN","BITBUCKET_PR_ID","BITBUCKET_PR_DESTINATION_BRANCH","BITBUCKET_PR_DESTINATION_COMMIT","BITBUCKET_DEPLOYMENT_ENVIRONMENT","BITBUCKET_DEPLOYMENT_ENVIRONMENT_UUID","BITBUCKET_EXIT_CODE"]),buildkite:b(["BUILDKITE_ORGANIZATION_SLUG","BUILDKITE_PIPELINE_ID","BUILDKITE_PIPELINE_NAME","BUILDKITE_PIPELINE_SLUG","BUILDKITE_PIPELINE_DEFAULT_BRANCH","BUILDKITE_REPO","BUILDKITE_SOURCE","BUILDKITE_BRANCH","BUILDKITE_TAG","BUILDKITE_COMMIT","BUILDKITE_MESSAGE","BUILDKITE_BUILD_AUTHOR","BUILDKITE_BUILD_AUTHOR_EMAIL","BUILDKITE_JOB_ID","BUILDKITE_BUILD_ID","BUILDKITE_BUILD_URL","BUILDKITE_BUILD_NUMBER","BUILDKITE_LABEL","BUILDKITE_COMMAND","BUILDKITE_STEP_ID","BUILDKITE_STEP_KEY","BUILDKITE_PARALLEL_JOB","BUILDKITE_PARALLEL_JOB_COUNT","BUILDKITE_RETRY_COUNT","BUILDKITE_COMPUTE_TYPE","BUILDKITE_CLUSTER_NAME","BUILDKITE_PULL_REQUEST","BUILDKITE_PULL_REQUEST_REPO","BUILDKITE_PULL_REQUEST_BASE_BRANCH","BUILDKITE_PULL_REQUEST_DRAFT","BUILDKITE_PULL_REQUEST_LABELS","BUILDKITE_MERGE_QUEUE_BASE_BRANCH","BUILDKITE_MERGE_QUEUE_BASE_COMMIT","BUILDKITE_REBUILT_FROM_BUILD_ID","BUILDKITE_REBUILT_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_ID","BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG"]),circle:b(["CI","CIRCLECI","CIRCLE_BRANCH","CIRCLE_BUILD_NUM","CIRCLE_BUILD_URL","CIRCLE_PREVIOUS_BUILD_NUM","CIRCLE_JOB","CIRCLE_WORKFLOW_ID","CIRCLE_WORKFLOW_JOB_ID","CIRCLE_WORKFLOW_WORKSPACE_ID","CIRCLE_PIPELINE_ID","CIRCLE_ORGANIZATION_ID","CIRCLE_PROJECT_ID","CIRCLE_PROJECT_REPONAME","CIRCLE_PROJECT_USERNAME","CIRCLE_REPOSITORY_URL","CIRCLE_WORKING_DIRECTORY","CIRCLE_SHA1","CIRCLE_TAG","CIRCLE_USERNAME","CIRCLE_NODE_INDEX","CIRCLE_NODE_TOTAL","CIRCLE_PR_NUMBER","CIRCLE_PR_REPONAME","CIRCLE_PR_USERNAME","CIRCLE_PULL_REQUEST","CIRCLE_PULL_REQUESTS","CI_PULL_REQUEST"]),concourse:b(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:b(["CF_BUILD_ID","CF_BUILD_URL","CF_CURRENT_ATTEMPT","CF_STEP_NAME","CF_PIPELINE_NAME","CF_PIPELINE_TRIGGER_ID","CF_PULL_REQUEST_ID","CF_PULL_REQUEST_IS_FORK","CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_TARGET"]),drone:b(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:b(["CI","GITHUB_ACTIONS","GITHUB_WORKFLOW","GITHUB_WORKFLOW_REF","GITHUB_WORKFLOW_SHA","GITHUB_ACTION","GITHUB_ACTION_PATH","GITHUB_ACTION_REPOSITORY","GITHUB_JOB","GITHUB_EVENT_NAME","GITHUB_EVENT_PATH","GITHUB_RUN_ID","GITHUB_RUN_NUMBER","GITHUB_RUN_ATTEMPT","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REPOSITORY_OWNER","GITHUB_REPOSITORY_OWNER_ID","GITHUB_REF","GITHUB_REF_NAME","GITHUB_REF_TYPE","GITHUB_REF_PROTECTED","GITHUB_BASE_REF","GITHUB_HEAD_REF","GITHUB_SHA","GITHUB_ACTOR","GITHUB_ACTOR_ID","GITHUB_TRIGGERING_ACTOR","GITHUB_SERVER_URL","GITHUB_API_URL","GITHUB_GRAPHQL_URL","GITHUB_WORKSPACE","GITHUB_RETENTION_DAYS","RUNNER_OS","RUNNER_ARCH","RUNNER_NAME","RUNNER_ENVIRONMENT","RUNNER_DEBUG"]),gitlab:b(["CI_PIPELINE_ID","CI_PIPELINE_URL","CI_BUILD_ID","CI_JOB_ID","CI_JOB_URL","CI_JOB_NAME","CI_NODE_INDEX","CI_NODE_TOTAL","GITLAB_HOST","CI_PROJECT_ID","CI_PROJECT_URL","CI_REPOSITORY_URL","CI_ENVIRONMENT_URL","CI_DEFAULT_BRANCH","RUN_ATTEMPT","CI_MERGE_REQUEST_IID","CI_MERGE_REQUEST_PROJECT_URL","CI_MERGE_REQUEST_TITLE","CI_MERGE_REQUEST_SOURCE_BRANCH_NAME","CI_MERGE_REQUEST_TARGET_BRANCH_NAME","CI_OPEN_MERGE_REQUESTS"]),goCD:b(["GO_SERVER_URL","GO_ENVIRONMENT_NAME","GO_PIPELINE_NAME","GO_PIPELINE_COUNTER","GO_PIPELINE_LABEL","GO_STAGE_NAME","GO_STAGE_COUNTER","GO_JOB_NAME","GO_TRIGGER_USER","GO_REVISION","GO_TO_REVISION","GO_FROM_REVISION","GO_MATERIAL_HAS_CHANGED"]),googleCloud:b(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:b(["BRANCH_NAME","BUILD_DISPLAY_NAME","BUILD_ID","BUILD_NUMBER","BUILD_TAG","BUILD_URL","CHANGE_AUTHOR","CHANGE_AUTHOR_DISPLAY_NAME","CHANGE_AUTHOR_EMAIL","CHANGE_BRANCH","CHANGE_FORK","CHANGE_ID","CHANGE_TARGET","CHANGE_TITLE","CHANGE_URL","CI","EXECUTOR_NUMBER","JAVA_HOME","JENKINS_HOME","JENKINS_URL","JOB_BASE_NAME","JOB_NAME","JOB_URL","NODE_LABELS","NODE_NAME","RUN_ARTIFACTS_DISPLAY_URL","RUN_CHANGES_DISPLAY_URL","TAG_NAME","WORKSPACE","WORKSPACE_TMP","GIT_AUTHOR_EMAIL","GIT_AUTHOR_NAME","GIT_BRANCH","GIT_COMMIT","GIT_COMMITTER_EMAIL","GIT_COMMITTER_NAME","GIT_LOCAL_BRANCH","GIT_PREVIOUS_COMMIT","GIT_PREVIOUS_SUCCESSFUL_COMMIT","GIT_URL","ghprbActualCommit","ghprbGhRepository","ghprbPullId","ghprbPullLink","ghprbSourceBranch","ghprbTargetBranch","ghprbTriggerAuthorLogin"]),semaphore:b(["SEMAPHORE_BRANCH_ID","SEMAPHORE_BUILD_NUMBER","SEMAPHORE_CURRENT_JOB","SEMAPHORE_CURRENT_THREAD","SEMAPHORE_EXECUTABLE_UUID","SEMAPHORE_GIT_BRANCH","SEMAPHORE_GIT_DIR","SEMAPHORE_GIT_REF","SEMAPHORE_GIT_REF_TYPE","SEMAPHORE_GIT_REPO_SLUG","SEMAPHORE_GIT_SHA","SEMAPHORE_GIT_URL","SEMAPHORE_JOB_COUNT","SEMAPHORE_JOB_ID","SEMAPHORE_JOB_NAME","SEMAPHORE_JOB_UUID","SEMAPHORE_PIPELINE_ID","SEMAPHORE_PLATFORM","SEMAPHORE_PROJECT_DIR","SEMAPHORE_PROJECT_HASH_ID","SEMAPHORE_PROJECT_ID","SEMAPHORE_PROJECT_NAME","SEMAPHORE_PROJECT_UUID","SEMAPHORE_REPO_SLUG","SEMAPHORE_TRIGGER_SOURCE","SEMAPHORE_WORKFLOW_ID","PULL_REQUEST_NUMBER"]),teamcity:null,travis:b(["TRAVIS_JOB_ID","TRAVIS_BUILD_ID","TRAVIS_BUILD_WEB_URL","TRAVIS_REPO_SLUG","TRAVIS_JOB_NUMBER","TRAVIS_EVENT_TYPE","TRAVIS_COMMIT_RANGE","TRAVIS_BUILD_NUMBER","TRAVIS_PULL_REQUEST","TRAVIS_PULL_REQUEST_BRANCH","TRAVIS_PULL_REQUEST_SHA"]),netlify:b(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Dd=t=>{let e=hs();return e?(0,w.chain)(t()).get(e).value():{}};function Ud(){return(0,w.chain)(gs()).omitBy(w.isNull).keys().value()}function bd(t){return t&&Ud().includes(t)}function hs(){let t=Pd();return Ue("detected CI provider name: %s",t),t||null}function Nd(){let t=Dd(gs);return(0,w.mapValues)(t,e=>(0,w.isString)(e)?Fr(e):e)}function st(t){let e=Nd(),r=hs(),n=vd(t,r);return Ue("detected CI provider: %s",r),Ue("detected CI params: %O",e),Ue("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function vd(t,e){return t?{source:"user",value:t}:bd(e)?{source:"server",value:null}:{source:"random",value:`auto:${Br()}`}}var Is=f(require("archiver")),Es=f(require("fs-extra")),Wr=f(require("path")),Cs=f(require("unzipper"));var Ld=50*1024*1024;async function Ts(t,e=Ld){return new Promise((r,n)=>{let o=(0,Is.default)("zip",{zlib:{level:9}}),s=[],i=0;o.on("data",d=>{s.push(d),i+=d.length,i>e&&n(new Error(`Zip size exceeded the limit of ${e} bytes`))}),o.on("warning",d=>{d.code==="ENOENT"?I(d):n(d)}),o.on("error",d=>n(d)),o.on("end",()=>{let d=Buffer.concat(s);r(d)});let a=async d=>{let l=process.cwd(),m=Wr.default.normalize(d),h=Wr.default.relative(l,m),g=await Es.default.stat(d);g.isDirectory()?o.directory(d,h):o.file(d,{name:h,stats:g})};(async d=>{for(let l of d)await a(l);await o.finalize()})(t).catch(n)})}async function ys(t,e){return Cs.default.Open.buffer(t).then(r=>r.extract({path:e,concurrency:3}))}var Rs=require("lodash");var Bd={githubActions:[],gitlab:[],appveyor:["APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER"],azure:["SYSTEM_COLLECTIONID","BUILD_BUILDID"],awsCodeBuild:["CODEBUILD_BUILD_ID"],bamboo:["bamboo_buildKey","bamboo_buildNumber"],bitbucket:["BITBUCKET_PIPELINE_UUID"],buildkite:["BUILDKITE_BUILD_ID"],circle:["CIRCLE_WORKFLOW_WORKSPACE_ID"],concourse:["BUILD_ID"],codeFresh:["CF_BUILD_ID"],drone:["DRONE_BUILD_LINK"],goCD:["GO_PIPELINE_NAME","GO_PIPELINE_COUNTER"],googleCloud:["BUILD_ID"],jenkins:["JOB_NAME","BUILD_NUMBER"],semaphore:["SEMAPHORE_PIPELINE_ID"],travis:["TRAVIS_JOB_ID"],netlify:["BUILD_ID"]};function Fd({provider:t,params:e}){let r=t?Bd[t]:null;return!r||!e?!1:r.every(n=>!!e[(0,Rs.camelCase)(n)])}function be(t,e){e||Fd(t)||he("No CI job detected: without --id the cache ID is random, so cache get does not find what cache set saved. Pass --id to save and restore the same cache.")}var As=f(require("async-retry")),Ss=f(require("fs")),Ps=require("stream"),re=require("axios");var ws=f(require("axios")),_s=require("https-proxy-agent"),Os=f(require("proxy-from-env"));var Md=p.extend("axios");function qr(t={}){let e=ws.default.create(t);return e.interceptors.request.use(r=>{let n={...r},o=e.getUri(r),s=Os.default.getProxyForUrl(o);return s&&(Md("Using HTTP proxy %s for %s",Nt(s),Nt(o)),n.proxy=!1,n.httpsAgent=kd(s)),n}),e}var Ne=null;function kd(t){return Ne||(Ne=new _s.HttpsProxyAgent(t),Ne)}var ne=p.extend("upload"),ve=5;async function zr(t,e,r){return ne("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),vs(t.buffer,t.uploadUrl,e,r,t.headers,Us(Buffer.byteLength(t.buffer)))}var jd=256*1024,$d=120*1e3;async function Ds(t){return ne("Uploading file %s",t.name,{bytes:t.sizeBytes}),vs(()=>t.sizeBytes>0?Ss.default.createReadStream(t.path,{end:t.sizeBytes-1}):Ps.Readable.from([]),t.uploadUrl,t.contentType,void 0,{...t.headers??{"Content-Type":t.contentType},"Content-Length":String(t.sizeBytes)},Us(t.sizeBytes))}function Us(t){return $d+Math.ceil(t/jd)*1e3}async function Gd(t,e,r,n,o,s){return qr().request({method:"put",url:e,timeout:s,data:typeof t=="function"?t():t,...typeof t=="function"&&{maxRedirects:0},onUploadProgress:n,headers:o??{"Content-Disposition":"inline","Content-Type":r}})}async function Qr(t,e){try{let r=await qr().get(t,{responseType:"arraybuffer",onDownloadProgress:e});return Buffer.isBuffer(r.data)?r.data:Buffer.from(r.data)}catch(r){throw(0,re.isAxiosError)(r)&&ne("Failed to download %s: %s",Nt(t),r.message),r}}var Kd=["RequestTimeout","OperationAborted","SlowDown"];function bs(t){if(t)return t.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi,e=>Nt(e)).slice(0,200)}function Ns(t){let e=(0,re.isAxiosError)(t)?t.response?.data:void 0,r=typeof e=="string"?e:"";return{code:r.match(/<Code>([^<]*)<\/Code>/)?.[1],message:bs(r.match(/<Message>([^<]*)<\/Message>/)?.[1])}}function Hd(t){let e=(0,re.isAxiosError)(t)?t.response?.status:void 0;if(e===void 0||e<400||e>=500||e===408||e===429)return!1;let{code:r}=Ns(t);return!(r&&Kd.includes(r))}function Jd(t){if(!(0,re.isAxiosError)(t)||!t.response)return t instanceof Error?t:new Error(String(t));let{code:e,message:r}=Ns(t),n=[bs(e),r].filter(Boolean).join(": ");return new Error(`storage answered ${t.response.status}${n?` ${n}`:""}`)}async function vs(...t){try{await Vd(t)}catch(e){throw Jd(e)}}async function Vd(t){await(0,As.default)(async e=>{try{await Gd(...t)}catch(r){if(Hd(r)){e(r);return}throw r}},{retries:ve,onRetry:(e,r)=>{if(ne("Upload failed %d out of %d attempts: %s",r,ve,e.message),r===ve){C(`Cannot upload after ${r} times: ${e.message}`);return}I(`Upload failed ${r} out of ${ve} attempts: ${e.message}`)}})}var Xr=t=>({total:e,loaded:r})=>{ne("Uploading %s: %d / %d",t,xs(r),xs(e??0))};function xs(t){return t/1e3/1e3}var en=f(require("lodash"));var it=f(require("path")),tn=f(require("globby"));var Ls=require("lodash");function Zr({config:t,cacheId:e,orgId:r,path:n,ci:o,cacheKey:s,metaCacheKey:i}){let a={id:e,orgId:r,config:(0,Ls.omit)(t,"recordKey"),path:n,ci:o,createdAt:new Date().toISOString(),cacheKey:s,metaCacheKey:i};return Buffer.from(JSON.stringify(a))}function Bs(t,e){t instanceof Error?Ct("%s. %s.",e,t.message):Ct("%s. %s.",e,"Unknown error")}var Fs=async t=>{let e=it.default.resolve(t??"./test-results"),r=[it.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),it.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return tn.sync(r)},Ms=async(t=[])=>{let e=Yd(t);return e.length===0?[]:tn.sync(e.map(r=>r.replace(/\\/g,"/")))};function Yd(t){let e=process.cwd();return t.filter(r=>{let n=it.default.relative(e,it.default.resolve(r));return n===".."||n.startsWith(`..${it.default.sep}`)||it.default.isAbsolute(n)?(Bs(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function Le(t){return t?t.path.some(e=>it.default.basename(e)===".last-run.json"):!1}async function ks(t,e){switch(e.provider){case"githubActions":await Gs(t,e);break;case"gitlab":await $s(t,e);break;case"circle":await Ks(t,e);break;default:break}}async function js(t,e,r){switch(e.provider){case"githubActions":await Gs(t,e,r);break;case"gitlab":await $s(t,e,r);break;case"circle":await Ks(t,e,r);break;default:break}}async function $s(t,e,r=null){let n=e.params,o=r?.ci.params,i=(o?kt(o.runAttempt,0):0)+1,a=kt(n.ciNodeIndex,1),u=kt(n.ciNodeTotal,1),d=Le(r),l=i>1&&d,m=l?"--last-failed":"",h="";u>1&&(h=l?"--shard=1/1":`--shard=${a}/${u}`);let g=[m,h].filter(Boolean).join(" ");await Rt(t.presetOutput??ee,`EXTRA_PW_FLAGS="${g}"
|
|
20
|
+
`)}`}async function Us(t,e){try{return(await jt("restApi").request({...e,headers:kt(t)})).data.data}catch(r){throw Hd(r)}}function ce(t,e,r){return Us(e,{method:"POST",url:t,data:r})}function Ds(t,e){return Ps("Create session params: %o",e),ce("v1/sessions",t,e)}function Ns(t,e,r,n){return Ps("Create attachments: %o",{owner:e,target:r,attachments:n}),"sessionId"in e?ce(`v1/sessions/${encodeURIComponent(e.sessionId)}/attachments`,t,{attachments:n}):"runId"in e?ce(`v1/runs/${encodeURIComponent(e.runId)}/attachments`,t,{...r,attachments:n}):ce("v1/runs/attachments",t,{...e,...r,attachments:n})}function fn(t,e){return ce("v1/share",t,e)}function vs(t,e){return Us(t,{method:"GET",url:`v1/instances/${encodeURIComponent(e)}`})}async function gn(){try{let t=Ke();if(!t)throw new Error("Config is missing!");let e=t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId,pwLastRun:t.pwLastRun}:{projectId:t.projectId,branch:t.branch,tag:t.tag,pwLastRun:t.pwLastRun},r=await Ss(t.apiKey,e);if(t.pwLastRun&&!r.data.pwLastRun)throw new Error("The API answered without the status and failed tests of the run (pwLastRun). Nothing was written.");await Kd(t.pwLastRun?r.data.pwLastRun:r.data,t)}catch(t){throw d("Failed to get run data"),t}}async function Kd(t,e){let r=JSON.stringify(t,null,2);e.output?(await bo(e.output),await(0,Ls.writeFile)(e.output,r,"utf-8"),C(`Successfully written to ${e.output}`)):process.stdout.write(r+`
|
|
21
|
+
`)}var Sn=g(require("path"));var $=require("@commander-js/extra-typings");var Bs=require("@commander-js/extra-typings");function Ye(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}function Fs(t){for(let e of t.options){let r=e.attributeName();if(!e.envVar||!e.isBoolean()||t.getOptionValueSource(r)!=="env")continue;let n=vo(process.env[e.envVar]);t.setOptionValueWithSource(r,n??e.defaultValue,n===void 0?"default":"env")}}function Jd(t,e){if(!Array.isArray(t))return String(t)===e;let r=n=>n.map(o=>o.trim()).filter(Boolean).join(",");return r(t.map(String))===r(e.split(","))}function ks(t){for(let e of t.options){let r=e.attributeName(),n=e.envVar?process.env[e.envVar]:void 0,o=t.getOptionValue(r);!n||e.isBoolean()||t.getOptionValueSource(r)!=="cli"||Jd(o,n)||De(`${e.long} and ${e.envVar} are set to different values; using ${e.long}`)}}function Jt(){console.log=(...t)=>console.error(...t)}async function R(t,e){try{e.debug&&To(),await t(e),process.exit(0)}catch(r){T(r.message);let n=r instanceof Bs.CommanderError?r.exitCode:1;process.exit(n)}}function pe(t){return new Promise((e,r)=>process.stdout.write(t,n=>n?r(n):e()))}var Ms="Without it the ID comes from the CI job: on GitHub Actions the repository, the run ID and --matrix-index; on GitLab the pipeline ID and the job name; on other CI the variables that identify the pipeline and the job, and --matrix-index. When no CI job is detected the ID is random, so pass --id",$s=new $.Option("--id <id>",`the ID to save the files under. ${Ms}`),js=new $.Option("--id <id>",`the ID the files were saved under. ${Ms}`),Hs=new $.Option("--path <path>",'comma-separated paths or glob patterns of the files to save, inside the current folder; quote globs, e.g. "dist/**/*". At most 50 MB zipped').argParser(Ye),ue=(e=>(e.lastRun="last-run",e))(ue||{}),Gs=new $.Option("--preset <preset-name>",'"last-run" saves the Playwright .last-run.json files of --pw-output-dir, to rerun only the failed tests').choices(Object.values(ue)),Ks=new $.Option("--preset <preset-name>",'"last-run" restores the saved .last-run.json files and writes the Playwright options for the rerun to --preset-output').choices(Object.values(ue)),Js=new $.Option("--output-dir <folder>","the folder to restore the files to; by default the current folder"),Vs=new $.Option("--pw-output-dir <folder>","the Playwright output folder that holds .last-run.json").default("test-results"),de=".currents_env",qs=new $.Option("--preset-output <path>",'the file the "last-run" preset writes, relative to the current folder. On GitHub Actions and CircleCI it holds options for "playwright test"; on GitLab the shell variables EXTRA_PW_FLAGS, EXTRA_PWCP_FLAGS and RUN_ATTEMPT, to source. Nothing is written on other CI').default(de),hn=new $.Option("--matrix-index <number>","the index of this job among parallel jobs, from 1; each job has its own cache. Pass it when the CI does not tell the jobs apart, as in a GitHub Actions matrix").default(1).argParser(Ys),En=new $.Option("--matrix-total <number>","GitHub Actions only: the number of jobs in the matrix, for the shards that the last-run preset writes").default(1).argParser(Ys);function Ys(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new $.InvalidArgumentError("A positive integer is expected.");return e}var Ws=new $.Option("--continue","exit with 0 when the cache is not found").default(!1),zs=new $.Option("--continue","exit with 0 when no files are found, and save the cache without files").default(!1);var Vd={recordKey:x.recordKey,debug:x.debug},qd={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output folder",cli:"--pw-output-dir"},presetOutput:{name:"Preset output path",cli:"--preset-output"},path:{name:"Paths to cache",cli:"--path"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue when upload path missing",cli:"--continue"}},Yd={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Output folder",cli:"--output-dir"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue on cache miss",cli:"--continue"}},In={...Vd,...qd,...Yd};var Qs=d.extend("config"),Xs=["recordKey"],Pt;function Zs(t){Pt={type:"SET_COMMAND_CONFIG",values:D(In,Xs,t)},Qs("Resolved config: %o",{...Pt,values:E(Pt.values)})}function ti(t){Pt={type:"GET_COMMAND_CONFIG",values:D(In,Xs,t)},Qs("Resolved config: %o",{...Pt,values:E(Pt.values)})}function ht(){return Pt}function ei(t){return{recordKey:t.key,id:t.id,preset:t.preset,outputDir:t.outputDir,presetOutput:t.presetOutput,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}function ri(t){return{recordKey:t.key,id:t.id,preset:t.preset,pwOutputDir:t.pwOutputDir,path:t.path,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}var w=require("lodash");var We=d.extend("ci"),Wd=(t,e)=>(0,w.set)(t,(0,w.camelCase)(e),process.env[e]),v=t=>(0,w.transform)(t,Wd,{}),zd=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Qd=()=>(0,w.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Xd=()=>process.env.bamboo_buildNumber,Zd=()=>(0,w.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),tm=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),em=()=>!!(process.env.BUILD_ID&&process.env.PROJECT_ID&&process.env.PROJECT_NUMBER||process.env.GCP_PROJECT||process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT),rm=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,nm={appveyor:"APPVEYOR",azure:zd,awsCodeBuild:Qd,bamboo:Xd,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Zd,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:tm,goCD:"GO_JOB_NAME",jenkins:rm,googleCloud:em,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function om(){let{env:t}=process;return(0,w.findKey)(nm,e=>{if((0,w.isString)(e))return t[e];if((0,w.isFunction)(e))return e()})}var ni=()=>({appveyor:v(["APPVEYOR_JOB_ID","APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER","APPVEYOR_BUILD_VERSION","APPVEYOR_PULL_REQUEST_NUMBER","APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"]),azure:v(["AGENT_BUILDDIRECTORY","AGENT_ID","AGENT_JOBNAME","AGENT_JOBSTATUS","AGENT_MACHINENAME","AGENT_NAME","AGENT_OS","AGENT_OSARCHITECTURE","BUILD_BUILDID","BUILD_BUILDNUMBER","BUILD_BUILDURI","BUILD_CONTAINERID","BUILD_CRONSCHEDULE_DISPLAYNAME","BUILD_DEFINITIONNAME","BUILD_DEFINITIONVERSION","BUILD_QUEUEDBY","BUILD_QUEUEDBYID","BUILD_REASON","BUILD_REPOSITORY_ID","BUILD_REPOSITORY_NAME","BUILD_REPOSITORY_PROVIDER","BUILD_REPOSITORY_URI","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILD_SOURCEBRANCH","BUILD_SOURCEBRANCHNAME","BUILD_SOURCESDIRECTORY","BUILD_SOURCEVERSION","BUILD_SOURCEVERSIONAUTHOR","BUILD_SOURCEVERSIONMESSAGE","BUILD_STAGINGDIRECTORY","BUILD_TRIGGEREDBY_BUILDID","BUILD_TRIGGEREDBY_BUILDNUMBER","BUILD_TRIGGEREDBY_DEFINITIONID","BUILD_TRIGGEREDBY_DEFINITIONNAME","BUILD_TRIGGEREDBY_PROJECTID","COMMON_TESTRESULTSDIRECTORY","PIPELINE_WORKSPACE","SYSTEM_COLLECTIONID","SYSTEM_COLLECTIONURI","SYSTEM_DEFAULTWORKINGDIRECTORY","SYSTEM_DEFINITIONID","SYSTEM_HOSTTYPE","SYSTEM_JOBATTEMPT","SYSTEM_JOBDISPLAYNAME","SYSTEM_JOBID","SYSTEM_JOBNAME","SYSTEM_PHASEATTEMPT","SYSTEM_PHASEDISPLAYNAME","SYSTEM_PHASENAME","SYSTEM_PLANID","SYSTEM_PULLREQUEST_ISFORK","SYSTEM_PULLREQUEST_PULLREQUESTID","SYSTEM_PULLREQUEST_PULLREQUESTNUMBER","SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI","SYSTEM_PULLREQUEST_SOURCEBRANCH","SYSTEM_PULLREQUEST_SOURCECOMMITID","SYSTEM_PULLREQUEST_TARGETBRANCH","SYSTEM_PULLREQUEST_TARGETBRANCHNAME","SYSTEM_STAGEATTEMPT","SYSTEM_STAGEDISPLAYNAME","SYSTEM_STAGENAME","SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","SYSTEM_TEAMPROJECT","SYSTEM_TEAMPROJECTID","SYSTEM_TIMELINEID"]),awsCodeBuild:v(["AWS_DEFAULT_REGION","AWS_REGION","CODEBUILD_BATCH_BUILD_IDENTIFIER","CODEBUILD_BUILD_ARN","CODEBUILD_BUILD_ID","CODEBUILD_BUILD_IMAGE","CODEBUILD_BUILD_NUMBER","CODEBUILD_BUILD_SUCCEEDING","CODEBUILD_BUILD_URL","CODEBUILD_INITIATOR","CODEBUILD_PROJECT_ARN","CODEBUILD_PUBLIC_BUILD_URL","CODEBUILD_RESOLVED_SOURCE_VERSION","CODEBUILD_SOURCE_REPO_URL","CODEBUILD_SOURCE_VERSION","CODEBUILD_SRC_DIR","CODEBUILD_START_TIME","CODEBUILD_WEBHOOK_ACTOR_ACCOUNT_ID","CODEBUILD_WEBHOOK_BASE_REF","CODEBUILD_WEBHOOK_EVENT","CODEBUILD_WEBHOOK_HEAD_REF","CODEBUILD_WEBHOOK_MERGE_COMMIT","CODEBUILD_WEBHOOK_PREV_COMMIT","CODEBUILD_WEBHOOK_TRIGGER","CODEBUILD_WEBHOOK_LABEL","CODEBUILD_WEBHOOK_RUN_ID","CODEBUILD_WEBHOOK_JOB_ID","CODEBUILD_WEBHOOK_WORKFLOW_NAME","CODEBUILD_RUNNER_OWNER","CODEBUILD_RUNNER_REPO","CODEBUILD_RUNNER_REPO_DOMAIN","CODEBUILD_RUNNER_WITH_BUILDSPEC"]),bamboo:v(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:v(["CI","BITBUCKET_WORKSPACE","BITBUCKET_REPO_SLUG","BITBUCKET_REPO_UUID","BITBUCKET_REPO_FULL_NAME","BITBUCKET_REPO_IS_PRIVATE","BITBUCKET_REPO_OWNER","BITBUCKET_REPO_OWNER_UUID","BITBUCKET_PROJECT_KEY","BITBUCKET_PROJECT_UUID","BITBUCKET_BUILD_NUMBER","BITBUCKET_PIPELINE_UUID","BITBUCKET_STEP_UUID","BITBUCKET_STEP_RUN_NUMBER","BITBUCKET_STEP_TRIGGERER_UUID","BITBUCKET_PARALLEL_STEP","BITBUCKET_PARALLEL_STEP_COUNT","BITBUCKET_CLONE_DIR","BITBUCKET_COMMIT","BITBUCKET_BRANCH","BITBUCKET_TAG","BITBUCKET_BOOKMARK","BITBUCKET_GIT_HTTP_ORIGIN","BITBUCKET_GIT_SSH_ORIGIN","BITBUCKET_PR_ID","BITBUCKET_PR_DESTINATION_BRANCH","BITBUCKET_PR_DESTINATION_COMMIT","BITBUCKET_DEPLOYMENT_ENVIRONMENT","BITBUCKET_DEPLOYMENT_ENVIRONMENT_UUID","BITBUCKET_EXIT_CODE"]),buildkite:v(["BUILDKITE_ORGANIZATION_SLUG","BUILDKITE_PIPELINE_ID","BUILDKITE_PIPELINE_NAME","BUILDKITE_PIPELINE_SLUG","BUILDKITE_PIPELINE_DEFAULT_BRANCH","BUILDKITE_REPO","BUILDKITE_SOURCE","BUILDKITE_BRANCH","BUILDKITE_TAG","BUILDKITE_COMMIT","BUILDKITE_MESSAGE","BUILDKITE_BUILD_AUTHOR","BUILDKITE_BUILD_AUTHOR_EMAIL","BUILDKITE_JOB_ID","BUILDKITE_BUILD_ID","BUILDKITE_BUILD_URL","BUILDKITE_BUILD_NUMBER","BUILDKITE_LABEL","BUILDKITE_COMMAND","BUILDKITE_STEP_ID","BUILDKITE_STEP_KEY","BUILDKITE_PARALLEL_JOB","BUILDKITE_PARALLEL_JOB_COUNT","BUILDKITE_RETRY_COUNT","BUILDKITE_COMPUTE_TYPE","BUILDKITE_CLUSTER_NAME","BUILDKITE_PULL_REQUEST","BUILDKITE_PULL_REQUEST_REPO","BUILDKITE_PULL_REQUEST_BASE_BRANCH","BUILDKITE_PULL_REQUEST_DRAFT","BUILDKITE_PULL_REQUEST_LABELS","BUILDKITE_MERGE_QUEUE_BASE_BRANCH","BUILDKITE_MERGE_QUEUE_BASE_COMMIT","BUILDKITE_REBUILT_FROM_BUILD_ID","BUILDKITE_REBUILT_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_ID","BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG"]),circle:v(["CI","CIRCLECI","CIRCLE_BRANCH","CIRCLE_BUILD_NUM","CIRCLE_BUILD_URL","CIRCLE_PREVIOUS_BUILD_NUM","CIRCLE_JOB","CIRCLE_WORKFLOW_ID","CIRCLE_WORKFLOW_JOB_ID","CIRCLE_WORKFLOW_WORKSPACE_ID","CIRCLE_PIPELINE_ID","CIRCLE_ORGANIZATION_ID","CIRCLE_PROJECT_ID","CIRCLE_PROJECT_REPONAME","CIRCLE_PROJECT_USERNAME","CIRCLE_REPOSITORY_URL","CIRCLE_WORKING_DIRECTORY","CIRCLE_SHA1","CIRCLE_TAG","CIRCLE_USERNAME","CIRCLE_NODE_INDEX","CIRCLE_NODE_TOTAL","CIRCLE_PR_NUMBER","CIRCLE_PR_REPONAME","CIRCLE_PR_USERNAME","CIRCLE_PULL_REQUEST","CIRCLE_PULL_REQUESTS","CI_PULL_REQUEST"]),concourse:v(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:v(["CF_BUILD_ID","CF_BUILD_URL","CF_CURRENT_ATTEMPT","CF_STEP_NAME","CF_PIPELINE_NAME","CF_PIPELINE_TRIGGER_ID","CF_PULL_REQUEST_ID","CF_PULL_REQUEST_IS_FORK","CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_TARGET"]),drone:v(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:v(["CI","GITHUB_ACTIONS","GITHUB_WORKFLOW","GITHUB_WORKFLOW_REF","GITHUB_WORKFLOW_SHA","GITHUB_ACTION","GITHUB_ACTION_PATH","GITHUB_ACTION_REPOSITORY","GITHUB_JOB","GITHUB_EVENT_NAME","GITHUB_EVENT_PATH","GITHUB_RUN_ID","GITHUB_RUN_NUMBER","GITHUB_RUN_ATTEMPT","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REPOSITORY_OWNER","GITHUB_REPOSITORY_OWNER_ID","GITHUB_REF","GITHUB_REF_NAME","GITHUB_REF_TYPE","GITHUB_REF_PROTECTED","GITHUB_BASE_REF","GITHUB_HEAD_REF","GITHUB_SHA","GITHUB_ACTOR","GITHUB_ACTOR_ID","GITHUB_TRIGGERING_ACTOR","GITHUB_SERVER_URL","GITHUB_API_URL","GITHUB_GRAPHQL_URL","GITHUB_WORKSPACE","GITHUB_RETENTION_DAYS","RUNNER_OS","RUNNER_ARCH","RUNNER_NAME","RUNNER_ENVIRONMENT","RUNNER_DEBUG"]),gitlab:v(["CI_PIPELINE_ID","CI_PIPELINE_URL","CI_BUILD_ID","CI_JOB_ID","CI_JOB_URL","CI_JOB_NAME","CI_NODE_INDEX","CI_NODE_TOTAL","GITLAB_HOST","CI_PROJECT_ID","CI_PROJECT_URL","CI_REPOSITORY_URL","CI_ENVIRONMENT_URL","CI_DEFAULT_BRANCH","RUN_ATTEMPT","CI_MERGE_REQUEST_IID","CI_MERGE_REQUEST_PROJECT_URL","CI_MERGE_REQUEST_TITLE","CI_MERGE_REQUEST_SOURCE_BRANCH_NAME","CI_MERGE_REQUEST_TARGET_BRANCH_NAME","CI_OPEN_MERGE_REQUESTS"]),goCD:v(["GO_SERVER_URL","GO_ENVIRONMENT_NAME","GO_PIPELINE_NAME","GO_PIPELINE_COUNTER","GO_PIPELINE_LABEL","GO_STAGE_NAME","GO_STAGE_COUNTER","GO_JOB_NAME","GO_TRIGGER_USER","GO_REVISION","GO_TO_REVISION","GO_FROM_REVISION","GO_MATERIAL_HAS_CHANGED"]),googleCloud:v(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:v(["BRANCH_NAME","BUILD_DISPLAY_NAME","BUILD_ID","BUILD_NUMBER","BUILD_TAG","BUILD_URL","CHANGE_AUTHOR","CHANGE_AUTHOR_DISPLAY_NAME","CHANGE_AUTHOR_EMAIL","CHANGE_BRANCH","CHANGE_FORK","CHANGE_ID","CHANGE_TARGET","CHANGE_TITLE","CHANGE_URL","CI","EXECUTOR_NUMBER","JAVA_HOME","JENKINS_HOME","JENKINS_URL","JOB_BASE_NAME","JOB_NAME","JOB_URL","NODE_LABELS","NODE_NAME","RUN_ARTIFACTS_DISPLAY_URL","RUN_CHANGES_DISPLAY_URL","TAG_NAME","WORKSPACE","WORKSPACE_TMP","GIT_AUTHOR_EMAIL","GIT_AUTHOR_NAME","GIT_BRANCH","GIT_COMMIT","GIT_COMMITTER_EMAIL","GIT_COMMITTER_NAME","GIT_LOCAL_BRANCH","GIT_PREVIOUS_COMMIT","GIT_PREVIOUS_SUCCESSFUL_COMMIT","GIT_URL","ghprbActualCommit","ghprbGhRepository","ghprbPullId","ghprbPullLink","ghprbSourceBranch","ghprbTargetBranch","ghprbTriggerAuthorLogin"]),semaphore:v(["SEMAPHORE_BRANCH_ID","SEMAPHORE_BUILD_NUMBER","SEMAPHORE_CURRENT_JOB","SEMAPHORE_CURRENT_THREAD","SEMAPHORE_EXECUTABLE_UUID","SEMAPHORE_GIT_BRANCH","SEMAPHORE_GIT_DIR","SEMAPHORE_GIT_REF","SEMAPHORE_GIT_REF_TYPE","SEMAPHORE_GIT_REPO_SLUG","SEMAPHORE_GIT_SHA","SEMAPHORE_GIT_URL","SEMAPHORE_JOB_COUNT","SEMAPHORE_JOB_ID","SEMAPHORE_JOB_NAME","SEMAPHORE_JOB_UUID","SEMAPHORE_PIPELINE_ID","SEMAPHORE_PLATFORM","SEMAPHORE_PROJECT_DIR","SEMAPHORE_PROJECT_HASH_ID","SEMAPHORE_PROJECT_ID","SEMAPHORE_PROJECT_NAME","SEMAPHORE_PROJECT_UUID","SEMAPHORE_REPO_SLUG","SEMAPHORE_TRIGGER_SOURCE","SEMAPHORE_WORKFLOW_ID","PULL_REQUEST_NUMBER"]),teamcity:null,travis:v(["TRAVIS_JOB_ID","TRAVIS_BUILD_ID","TRAVIS_BUILD_WEB_URL","TRAVIS_REPO_SLUG","TRAVIS_JOB_NUMBER","TRAVIS_EVENT_TYPE","TRAVIS_COMMIT_RANGE","TRAVIS_BUILD_NUMBER","TRAVIS_PULL_REQUEST","TRAVIS_PULL_REQUEST_BRANCH","TRAVIS_PULL_REQUEST_SHA"]),netlify:v(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),sm=t=>{let e=oi();return e?(0,w.chain)(t()).get(e).value():{}};function im(){return(0,w.chain)(ni()).omitBy(w.isNull).keys().value()}function am(t){return t&&im().includes(t)}function oi(){let t=om();return We("detected CI provider name: %s",t),t||null}function cm(){let t=sm(ni);return(0,w.mapValues)(t,e=>(0,w.isString)(e)?rn(e):e)}function ut(t){let e=cm(),r=oi(),n=pm(t,r);return We("detected CI provider: %s",r),We("detected CI params: %O",e),We("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function pm(t,e){return t?{source:"user",value:t}:am(e)?{source:"server",value:null}:{source:"random",value:`auto:${en()}`}}var yn=g(require("path")),pi=g(require("yazl"));var Vt=g(require("fs")),me=g(require("path")),si=require("stream/promises"),ze=require("util"),Tn=g(require("yauzl")),um=(0,ze.promisify)(Tn.default.open),dm=(0,ze.promisify)(Tn.default.fromBuffer);async function le(t,e,r){let n=r.split(me.default.sep).join("/").replace(/^(\.\.\/|\/)+/,"");if(!(await Vt.default.promises.stat(e)).isDirectory()){t.addFile(e,n);return}n&&t.addEmptyDirectory(n);for(let s of await Vt.default.promises.readdir(e))await le(t,me.default.join(e,s),n?`${n}/${s}`:s)}function Qe(t){let e=t.outputStream;return t.on("error",r=>e.destroy(r)),t.end(),e}function ii(t,e){return new Promise((r,n)=>{t.on("error",n),t.on("end",()=>r()),t.on("entry",o=>{Promise.resolve(e(o)).then(()=>t.readEntry()).catch(s=>{t.close(),n(s)})}),t.readEntry()})}function ai(t){let e={lazyEntries:!0};return typeof t=="string"?um(t,e):dm(t,e)}async function ci(t){let e=await ai(t),r=[];return await ii(e,n=>{r.push(n.fileName)}),r}async function Cn(t,e){let r=await ai(t),n=(0,ze.promisify)(r.openReadStream.bind(r));await ii(r,async o=>{let s=me.default.join(e,o.fileName);if(o.fileName.endsWith("/")){await Vt.default.promises.mkdir(s,{recursive:!0});return}await Vt.default.promises.mkdir(me.default.dirname(s),{recursive:!0}),await(0,si.pipeline)(await n(o),Vt.default.createWriteStream(s))})}var mm=50*1024*1024;async function ui(t,e=mm){let r=new pi.default.ZipFile;for(let i of t)await le(r,i,yn.default.relative(process.cwd(),yn.default.normalize(i)));let n=[],o=0,s=Qe(r);for await(let i of s){if(o+=i.length,o>e)throw s.destroy(),new Error(`Zip size exceeded the limit of ${e} bytes`);n.push(i)}return Buffer.concat(n)}var di=require("lodash");var lm={githubActions:[],gitlab:[],appveyor:["APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER"],azure:["SYSTEM_COLLECTIONID","BUILD_BUILDID"],awsCodeBuild:["CODEBUILD_BUILD_ID"],bamboo:["bamboo_buildKey","bamboo_buildNumber"],bitbucket:["BITBUCKET_PIPELINE_UUID"],buildkite:["BUILDKITE_BUILD_ID"],circle:["CIRCLE_WORKFLOW_WORKSPACE_ID"],concourse:["BUILD_ID"],codeFresh:["CF_BUILD_ID"],drone:["DRONE_BUILD_LINK"],goCD:["GO_PIPELINE_NAME","GO_PIPELINE_COUNTER"],googleCloud:["BUILD_ID"],jenkins:["JOB_NAME","BUILD_NUMBER"],semaphore:["SEMAPHORE_PIPELINE_ID"],travis:["TRAVIS_JOB_ID"],netlify:["BUILD_ID"]};function fm({provider:t,params:e}){let r=t?lm[t]:null;return!r||!e?!1:r.every(n=>!!e[(0,di.camelCase)(n)])}function Xe(t,e){e||fm(t)||De("No CI job detected: without --id the cache ID is random, so cache get does not find what cache set saved. Pass --id to save and restore the same cache.")}var li=g(require("fs")),fi=require("stream"),gi=require("timers/promises");var ge=d.extend("upload"),fe=5;async function Rn(t,e,r){return ge("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),Ci(t.buffer,t.uploadUrl,e,r,t.headers,Ei(Buffer.byteLength(t.buffer)))}var gm=256*1024,hm=120*1e3;async function hi(t){return ge("Uploading file %s",t.name,{bytes:t.sizeBytes}),Ci(()=>t.sizeBytes>0?li.default.createReadStream(t.path,{end:t.sizeBytes-1}):fi.Readable.from([]),t.uploadUrl,t.contentType,void 0,{...t.headers??{"Content-Type":t.contentType},"Content-Length":String(t.sizeBytes)},Ei(t.sizeBytes))}function Ei(t){return hm+Math.ceil(t/gm)*1e3}async function Em(t,e,r,n,o,s){let i=typeof t=="function"?t():t;await bt({method:"PUT",url:e,timeout:s,body:i,headers:o??{"Content-Disposition":"inline","Content-Type":r}}),Buffer.isBuffer(i)&&n?.({loaded:i.length,total:i.length})}async function wn(t){try{return(await bt({method:"GET",url:t,responseType:"buffer"})).data}catch(e){throw L(e)&&ge("Failed to download %s: %s",Ft(t),e.message),e}}var Im=["RequestTimeout","OperationAborted","SlowDown"];function Ii(t){if(t)return t.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi,e=>Ft(e)).slice(0,200)}function Ti(t){let e=L(t)?t.response?.data:void 0,r=typeof e=="string"?e:"";return{code:r.match(/<Code>([^<]*)<\/Code>/)?.[1],message:Ii(r.match(/<Message>([^<]*)<\/Message>/)?.[1])}}function Tm(t){let e=L(t)?t.response?.status:void 0;if(e===void 0||e<400||e>=500||e===408||e===429)return!1;let{code:r}=Ti(t);return!(r&&Im.includes(r))}function Cm(t){if(!L(t)||!t.response)return t instanceof Error?t:new Error(String(t));let{code:e,message:r}=Ti(t),n=[Ii(e),r].filter(Boolean).join(": ");return new Error(`storage answered ${t.response.status}${n?` ${n}`:""}`)}async function Ci(...t){try{await wm(t)}catch(e){throw Cm(e)}}function ym(){return Array.from({length:fe},(t,e)=>Math.round((Math.random()+1)*1e3*2**e)).sort((t,e)=>t-e)}function Rm(t){let e=new Map,r=t[0],n=0;for(let o of t){let s=(e.get(o.message)??0)+1;e.set(o.message,s),s>=n&&(r=o,n=s)}return r}async function wm(t){let e=ym(),r=[];for(let n=1;;n++)try{return await Em(...t)}catch(o){if(Tm(o))throw o;if(r.push(o),n>fe)throw Rm(r);_m(o,n),await(0,gi.setTimeout)(e[n-1])}}function _m(t,e){if(ge("Upload failed %d out of %d attempts: %s",e,fe,t.message),e===fe){T(`Cannot upload after ${e} times: ${t.message}`);return}I(`Upload failed ${e} out of ${fe} attempts: ${t.message}`)}var _n=t=>({total:e,loaded:r})=>{ge("Uploading %s: %d / %d",t,mi(r),mi(e??0))};function mi(t){return t/1e3/1e3}var xn=g(require("lodash"));var dt=g(require("path"));var Ri=require("path"),wi=require("tinyglobby");function he(t){let e=t.map(xm),r=e.filter(o=>o.startsWith("!")).map(o=>o.slice(1)),n=e.filter(o=>!o.startsWith("!")).flatMap(o=>(0,wi.globSync)(o,{absolute:(0,Ri.isAbsolute)(o),ignore:r}).sort());return[...new Set(n)]}var Om=/(?<!\\)\{(-?\d+)\.\.(-?\d+)(?:\.\.(-?\d+))?\}/g,yi=1e3;function xm(t){return t.replace(Om,(e,r,n,o)=>{let s=Sm(r,n,o);return s.length===1?s[0]:`{${s.join(",")}}`})}function Sm(t,e,r="1"){let n=Number(t),o=Number(e),s=Math.abs(Number(r))||1,i=Math.floor(Math.abs(o-n)/s)+1;if(i>yi){let l=[t,e,...r==="1"?[]:[r]].join("..");throw new Error(`{${l}} expands to more than ${yi} values`)}let a=n<=o?1:-1,p=[t,e].some(l=>/^-?0\d/.test(l))?Math.max(t.length,e.length):0;return Array.from({length:i},(l,m)=>{let h=n+m*a*s,f=h<0?"-":"";return f+String(Math.abs(h)).padStart(p-f.length,"0")})}var _i=require("lodash");function On({config:t,cacheId:e,orgId:r,path:n,ci:o,cacheKey:s,metaCacheKey:i}){let a={id:e,orgId:r,config:(0,_i.omit)(t,"recordKey"),path:n,ci:o,createdAt:new Date().toISOString(),cacheKey:s,metaCacheKey:i};return Buffer.from(JSON.stringify(a))}function Oi(t,e){t instanceof Error?_t("%s. %s.",e,t.message):_t("%s. %s.",e,"Unknown error")}var xi=async t=>{let e=dt.default.resolve(t??"./test-results"),r=[dt.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),dt.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return he(r)},Si=async(t=[])=>{let e=Am(t);return e.length===0?[]:he(e.map(r=>r.replace(/\\/g,"/")))};function Am(t){let e=process.cwd();return t.filter(r=>{let n=dt.default.relative(e,dt.default.resolve(r));return n===".."||n.startsWith(`..${dt.default.sep}`)||dt.default.isAbsolute(n)?(Oi(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function Ze(t){return t?t.path.some(e=>dt.default.basename(e)===".last-run.json"):!1}async function Ai(t,e){switch(e.provider){case"githubActions":await Ui(t,e);break;case"gitlab":await Pi(t,e);break;case"circle":await Di(t,e);break;default:break}}async function bi(t,e,r){switch(e.provider){case"githubActions":await Ui(t,e,r);break;case"gitlab":await Pi(t,e,r);break;case"circle":await Di(t,e,r);break;default:break}}async function Pi(t,e,r=null){let n=e.params,o=r?.ci.params,i=(o?qt(o.runAttempt,0):0)+1,a=qt(n.ciNodeIndex,1),u=qt(n.ciNodeTotal,1),p=Ze(r),l=i>1&&p,m=l?"--last-failed":"",h="";u>1&&(h=l?"--shard=1/1":`--shard=${a}/${u}`);let f=[m,h].filter(Boolean).join(" ");await xt(t.presetOutput??de,`EXTRA_PW_FLAGS="${f}"
|
|
23
22
|
EXTRA_PWCP_FLAGS="${m}"
|
|
24
23
|
RUN_ATTEMPT=${i}
|
|
25
|
-
`)}async function
|
|
26
|
-
`+t.map(e=>`${
|
|
27
|
-
`))}var{recordKey:tu,projectId:eu,ciBuildId:ru,debug:nu}=O,et={recordKey:tu,projectId:eu,ciBuildId:ru,runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:nu};var ou=p.extend("config"),su=["recordKey","projectId"];function iu(t){if(!(t.runId||t.ciBuildId))throw C(`${we(et,"runId")} or ${we(et,"ciBuildId")} is required: pass ${S(Re(et,"runId"))} or ${S(Re(et,"ciBuildId"))}, or set ${S(P(et,"runId"))} or ${S(P(et,"ciBuildId"))}`),new tt("Missing required config variable")}var sn=null;function Ys(t){sn=U(et,su,t,iu),ou("Resolved config: %o",E(sn))}function Be(){return sn}async function an(){let t=Be();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await No({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?T('Run "%s" (%s) is cancelled',r.data.runId,e):T('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw p("Failed to cancel the run"),r}}var Ws=require("@currents/commit-info"),qs=require("lodash");var au=p.extend("git"),cu=async()=>{let t=await(0,Ws.commitInfo)();return au("commit: %O",t),{branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData??null}},oe=(0,qs.memoize)(cu);var zs=f(require("getos")),Qs=require("lodash"),q=require("os"),Xs=require("util"),pu=async()=>{if((0,q.platform)()==="linux")try{let t=await(0,Xs.promisify)(zs.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,q.release)()}catch{return(0,q.release)()}return(0,q.release)()},du=async()=>{let t=await pu();return{osName:(0,q.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,q.freemem)(),total:(0,q.totalmem)()}}},Zs=(0,Qs.memoize)(du);var na=f(require("axios")),hn=f(require("fs-extra")),We=f(require("path")),oa=f(require("semver"));var{debug:uu,ciBuildId:mu,recordKey:lu,projectId:fu,machineId:gu}=O,z={debug:uu,ciBuildId:mu,recordKey:lu,projectId:fu,machineId:gu,tag:{...O.tag,env:"CURRENTS_TAG"},disableTitleTags:{name:"Disable title tags",env:"CURRENTS_DISABLE_TITLE_TAGS",cli:"--disable-title-tags"},removeTitleTags:{name:"Remove title tags",env:"CURRENTS_REMOVE_TITLE_TAGS",cli:"--remove-title-tags"},environment:{name:"Environment",env:"CURRENTS_ENVIRONMENT",cli:"--environment"},failOnFailures:{name:"Fail on failures",env:"CURRENTS_FAIL_ON_FAILURES",cli:"--fail-on-failures"},reportDir:{name:"Report folder",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};var hu=p.extend("config"),Iu=["projectId","recordKey"],cn=null;function ti(t){cn=U(z,Iu,t),hu("Resolved Currents config: %o",E(cn))}function Fe(){return cn}function ei(t){return{ciBuildId:t.ciBuildId,projectId:t.projectId,recordKey:t.key,tag:t.tag,removeTitleTags:t.removeTitleTags,disableTitleTags:t.disableTitleTags,debug:t.debug,machineId:t.machineId,environment:t.environment,reportDir:t.reportDir,failOnFailures:t.failOnFailures}}var L=require("@currents/rules");var Me=p.extend("actions"),Eu=512;async function oi(t,e){try{let r=await $o(t,e);if(!Array.isArray(r))throw new Error("The project actions are not a list");return Me("Fetched %d project actions",r.length),r}catch(r){return I("Failed to fetch the project actions, uploading without them"),Me("Failed to fetch the project actions: %o",r),[]}}function si({actions:t,instances:e,fullTestSuite:r,gitInfo:n,runTags:o,disableTitleTags:s=!1,group:i}){let a={skipped:0,quarantined:0,tagged:0};if(t.length===0)return a;let u=new L.RulesEvalBase(t,Me);for(let d of e){let l=i??d.groupId;for(let m of d.results.tests){let h=s?[]:pi(r,{groupId:l,spec:d.spec,testId:m.testId})?.test.tags??[],g=u.getMatchedRules(Cu({groupId:l,spec:d.spec,test:m,gitInfo:n,tags:[...h,...o]}));if(g.length===0)continue;Me("Test %s matched actions: %j",m.testId,g);let _=Tu(m,g);_.length>0&&(yu(r,{groupId:l,spec:d.spec,testId:m.testId,tags:_}),a.tagged++);let k=ri(g,L.ACTION_TYPE.SKIP),Ut=ri(g,L.ACTION_TYPE.QUARANTINE);k?(ni(m,k,L.ACTION_ANNOTATIONS.SKIP_POST),a.skipped++):Ut&&m.state==="failed"&&(ni(m,Ut,L.ACTION_ANNOTATIONS.QUARANTINE_POST),a.quarantined++)}}return a}function ii(t){t.skipped+t.quarantined+t.tagged!==0&&T("[currents] Actions: %d tests skipped, %d quarantined, %d tagged",t.skipped,t.quarantined,t.tagged)}function Cu({groupId:t,spec:e,test:r,gitInfo:n,tags:o}){return{title:r.title[r.title.length-1],titlePath:[e,...r.title],file:e,project:t,testId:r.testId,tag:Array.from(new Set([...r.tags??[],...o])),gitInfo:n&&{branch:n.branch,authorName:n.authorName,authorEmail:n.authorEmail,remoteOrigin:n.remoteOrigin,message:n.message},errors:r.attempts.flatMap(s=>s.errors).filter(s=>!!s.message).map(s=>({message:s.message}))}}function ri(t,e){return t.find(r=>r.action.some(n=>n.op===e))}function Tu(t,e){let r=[];for(let n of e)for(let o of n.action){if(o.op!==L.ACTION_TYPE.TAG)continue;let s=(0,L.normalizeTagMatcherValue)(o.details?.tags??[]);s.length!==0&&(ai(t,L.ACTION_ANNOTATIONS.TAG,ci({action:n,type:L.ACTION_TYPE.TAG,testId:t.testId,extraDetails:{tags:s}})),r.push(...(0,L.normalizeTagMatcherValue)(s,{removeAtPrefix:!0})))}return r.length>0&&(t.tags=Array.from(new Set([...t.tags??[],...r]))),r}function ni(t,e,r){let n=t.state;ai(t,r,ci({action:e,type:r===L.ACTION_ANNOTATIONS.SKIP_POST?L.ACTION_TYPE.SKIP:L.ACTION_TYPE.QUARANTINE,testId:t.testId,extraDetails:{status:n}})),t.state="pending"}function ai(t,e,r){t.annotations=[...t.annotations??[],{type:e,description:JSON.stringify(r),source:"test"}]}function ci({action:t,type:e,testId:r,extraDetails:n}){return{rule:{v:t.v,id:t._id,name:t.name.slice(0,Eu),type:e,extraDetails:n,appliedAt:Date.now()},testInfo:{testId:r,status:n.status}}}function pi(t,{groupId:e,spec:r,testId:n}){let o=t.find(i=>i.name===e),s=o?.tests.find(i=>i.spec===r&&i.testId===n);return o&&s?{project:o,test:s}:null}function yu(t,{groupId:e,spec:r,testId:n,tags:o}){let s=pi(t,{groupId:e,spec:r,testId:n});if(!s)return;let{project:i,test:a}=s;a.tags=Array.from(new Set([...a.tags,...o])),i.tags=Array.from(new Set([...i.tags,...o]))}var mn=f(require("fs-extra")),at=require("path");var di=f(require("path")),pn={".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".jpeg":{type:"screenshot",contentType:"image/jpeg"},".webp":{type:"screenshot",contentType:"image/webp"},".gif":{type:"screenshot",contentType:"image/gif"},".mp4":{type:"video",contentType:"video/mp4"},".webm":{type:"video",contentType:"video/webm"},".svg":{type:"attachment",contentType:"image/svg+xml"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".yml":{type:"attachment",contentType:"text/plain"},".yaml":{type:"attachment",contentType:"text/plain"},".md":{type:"attachment",contentType:"text/markdown"},".html":{type:"attachment",contentType:"text/html"},".csv":{type:"attachment",contentType:"text/csv"},".json":{type:"attachment",contentType:"application/json"},".pdf":{type:"attachment",contentType:"application/pdf"},".gz":{type:"attachment",contentType:"application/gzip"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}},dn=t=>pn[di.default.extname(t).toLowerCase()];var ui=f(require("fs-extra")),mi=require("path"),un=p.extend("detox"),Ru="detox.json";function li(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function fi(t){let e=(0,mi.join)(t,Ru);try{let r=await ui.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){un("Unexpected Detox manifest contents at %s",e);return}return un("Detox manifest: %o",r),r}catch{un("No Detox manifest at %s",e);return}}var ke=require("path"),wu=p.extend("detox"),gi=255,_u=/[/\\?<>:*|"$\u0000-\u001f]/g,hi=4;function Ii(t){return Ou(t)??xu(t)}function Ou({rootDir:t,fullName:e,status:r,invocations:n}){try{let o=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(o),i=new s({rootDir:t});return(0,ke.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:n}))}catch(o){wu("Detox path builder is not available: %o",o);return}}function xu({rootDir:t,fullName:e,status:r,invocations:n}){let o=Su(r),s=n>1?` (${n})`:"",i=e.slice(-gi+o.length+s.length),a=`${o}${i}${s}`.replace(_u,"_");return(0,ke.join)(t,Au(a,gi))}function Au(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Su(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var Ci=f(require("fs-extra")),Ti=require("path"),Ei=p.extend("detox"),je="detox.trace.json",Pu="ws-client-invocation";async function yi(t){let e=(0,Ti.join)(t,je),r=new Map,n;try{n=await Ci.default.readJson(e)}catch{return Ei("No Detox trace at %s",e),r}if(!Array.isArray(n))return Ei("Unexpected Detox trace contents at %s",e),r;let o=Du(n);return bu(n).forEach(({pid:i,ts:a,step:u})=>{o.filter(l=>l.pid===i&&a>=l.startTs&&a<=l.endTs).sort((l,m)=>l.startTs-m.startTs).pop()?.steps.push(u)}),o.forEach(({fullName:i,invocations:a,steps:u})=>{let d=r.get(i)??[];d.push({fullName:i,invocations:a,steps:u.sort((l,m)=>+new Date(l.startTime)-+new Date(m.startTime))}),r.set(i,d)}),r}function Du(t){let e=new Map,r=[];t.forEach(o=>{let s=`${o.pid}:${o.tid}`,i=e.get(s)??[];if(e.set(s,i),o.ph==="B"){i.push(Uu(o));return}if(o.ph==="E"){let a=i.pop();a&&r.push({...a,endTs:Number(o.ts)})}});let n=[...e.values()].flatMap(o=>o.filter(s=>s!==void 0));return[...r,...n]}function Uu(t){let e=t.args?.fullName;if(!(t.args?.context!=="test"||typeof e!="string"))return{fullName:e,invocations:Number(t.args?.invocations??1),pid:Number(t.pid),startTs:Number(t.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function bu(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(Pu))return;let o=`${n.pid}:${n.tid}`,s=e.get(o)??[];if(n.ph==="B"){s.push({name:n.name??"action",cat:n.cat,ts:Number(n.ts)}),e.set(o,s);return}if(n.ph==="E"){let i=s.pop();if(!i)return;r.push({pid:Number(n.pid),ts:i.ts,step:{title:i.name,category:"detox",startTime:new Date(i.ts/1e3).toISOString(),duration:Math.round((Number(n.ts)-i.ts)/1e3),steps:[]}})}}),r}var se=p.extend("detox"),Ri="artifacts",Nu=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],vu=t=>{let e=(0,at.extname)(t);return Nu.includes(e)?pn[e]:void 0};async function wi({instances:t,reportDir:e,manifest:r}){let n=Bu(r),o=await yi(r.artifactsRootDir),s=await _t((0,at.join)(e,Ri)),i={artifacts:0,steps:0};for(let a of t)for(let u of a.results.tests){let d=n.get(u.testId);if(!d){se("No Detox manifest entry for %s",u.testId);continue}await Fu({test:u,manifestTest:d,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(d.fullName)??[],result:i})}return i.artifacts+=await Lu({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function Lu({instances:t,rootDir:e,artifactsDir:r}){if(!await mn.default.pathExists((0,at.join)(e,je)))return 0;let[n]=await _i(e,[je],r),o=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return o.forEach(s=>{s.artifacts=[...s.artifacts??[],n]}),o.length}function Bu(t){let e=new Map;return t.tests.forEach(r=>{e.set(r.fullName,[...e.get(r.fullName)??[],r.testId])}),new Map(t.tests.filter(r=>{let n=e.get(r.fullName)?.length===1;return n||se("Ambiguous Detox test name, skipping: %s",r.fullName),n}).map(r=>[r.testId,r]))}async function Fu({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let i=[...t.attempts].sort((d,l)=>d.attempt-l.attempt),a=li(e.attempts),u=1;for(let[d,l]of a.entries()){let m=i[d];if(!m){se("No reported attempt %d of %s",d,e.fullName);continue}let h=await Mu({fullName:e.fullName,status:l.status,rootDir:r,artifactsDir:n,fromInvocation:u});h&&(u=h.invocation+1,m.artifacts=[...m.artifacts??[],...h.artifacts],s.artifacts+=h.artifacts.length);let g=ju(o,d,h?.invocation);g.length&&(m.steps=[...m.steps??[],...g],s.steps+=g.length)}}async function Mu({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+hi;s++){let i=Ii({rootDir:r,fullName:t,status:e,invocations:s}),a=await ku(i);if(a)return{invocation:s,artifacts:await _i(i,a,n)}}se("No Detox artifacts for %s [%s]",t,e)}async function ku(t){try{return(await mn.default.readdir(t)).sort()}catch{return}}async function _i(t,e,r){let n=[];for(let o of e){let s=vu(o);if(!s){se("Skipping unsupported Detox artifact %s",o);continue}let i=(0,at.join)(t,o),a=`${W(i)}${(0,at.extname)(o)}`;await Ce(i,(0,at.join)(r,a)),n.push({...s,path:(0,at.join)(Ri,a),name:o})}return n}function ju(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,i)=>s.invocations-i.invocations)[e])?.steps??[]}var lt=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var Gu=f(require("crypto"));var Oi=f(require("fs-extra")),$u=f(require("path"));async function $e(t){let e=await Oi.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}function xi(){return"root"}function Ai(t){let e=(t.join(" ").match(/@(\S+)/g)??[]).filter(Boolean).map(r=>r);return Array.from(new Set([...e].map(r=>r.trim()).map(r=>r.replace("@",""))))}var Ku=/^[0-9a-f]{32}$/;function Si(t){let e=[];for(let r of t){let n=e.find(o=>o.name===r.groupId);n||(n={name:r.groupId,tags:[],tests:[]},e.push(n)),n.tests.push(...Di(r))}return e.length===1&&Ku.test(e[0].name)&&(e[0].name=xi()),e}function Pi(t,e,r){let n=[];for(let{projectId:o,spec:s}of e){let i=r.find(u=>u.spec===s&&u.groupId===o)??(t.length===1?r.find(u=>u.spec===s):void 0);if(!i){n.push(s);continue}let a=t.length===1?t[0]:t.find(u=>u.name===o);a||(a={name:o,tags:[],tests:[]},t.push(a)),a.tests.push(...Di(i))}return n}function Di(t){return t.results.tests.map(e=>({spec:t.spec,testId:e.testId,title:e.title,tags:e.tags??Ai(e.title)}))}var Ji=f(require("fs-extra")),Vi=f(require("tmp"));var Ki=require("lodash");function Ui(t){let e=[];for(let[r,n]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof n=="boolean"?n&&e.push(`--${r}`):Array.isArray(n)?n.forEach(o=>{e.push(`--${r}=${o}`)}):e.push(`--${r}=${n}`));return e.join(" ")}var bi=require("lodash"),Hu=["bail","clearCache","collectCoverage","collectCoverageFrom","color","colors","config","coverage","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","debug","detectLeaks","detectOpenHandles","errorOnDeprecated","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","notify","notifyMode","openHandlesTimeout","outputFile","reporters","runner","shard","showConfig","showSeed","silent","testFailureExitCode","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function Ni(t){return(0,bi.omit)(t,...Hu)}var $i=f(require("fs")),Je=require("lodash"),fn=f(require("path"));var ln=f(require("fs")),Ge=require("module"),Ke=f(require("path")),vi=f(require("semver")),Ju=">=29.5.0";function Vu(){let t=(0,Ge.createRequire)(Ke.default.join(process.cwd(),"package.json"));if(Yu(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,Ge.createRequire)(t.resolve("jest")).resolve("jest-cli")}catch{}try{return t.resolve("jest-cli")}catch{throw new Error(`Jest discovery needs the "jest" package, and it is not installed in ${process.cwd()}. Run the command from the folder of the project that ran the tests, or install Jest 29.5 or later: npm install --save-dev jest`)}}function Yu(t){for(let e of t.resolve.paths("jest")??[]){if(ln.default.existsSync(Ke.default.join(e,"jest","package.json")))return"jest";if(ln.default.existsSync(Ke.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function Li(){let t=(0,Ge.createRequire)(Vu()),{version:e}=t("jest-cli/package.json");if(!vi.default.satisfies(e,Ju,{includePrerelease:!0}))throw new Error(`Jest discovery needs Jest 29.5 or later, and ${process.cwd()} has Jest ${e}. Update Jest: npm install --save-dev jest@latest`);return t}function Bi(){return Li()("jest-cli")}function Fi(){return Li()("jest-config")}function He(t,e){return(...r)=>new Promise((n,o)=>{let s=0,i=()=>{s++;try{let a=t(...r);n(a)}catch(a){if(s>=e.length)o(a);else{let u=e[s-1];setTimeout(i,u)}}};i()})}var Mi=p.extend("jest-discovery");function ki(t){return["testEnvironment","globalSetup","globalTeardown"].some(e=>String(t[e]??"").includes("detox"))}function ji(t){return{...(0,Je.omit)(t,["globalSetup","globalTeardown","testEnvironmentOptions"]),testEnvironment:"node"}}async function Gi(t,e){let r=e.detox;try{let{readInitialOptions:n}=Fi(),{config:o,configPath:s}=await n(t);r||=[o,...o.projects??[]].some(h=>typeof h!="string"&&ki(h));let i=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],a=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],u=h=>e.detox||ki(h),d=(0,Je.omit)(o,i);if(u(d)&&(d=ji(d)),d.projects&&(d.projects=d.projects.map(h=>{if(typeof h=="string")return h;let g=(0,Je.omit)(h,a);return u(g)?ji(g):g})),d.rootDir&&Object.keys(d).length===1)return null;let l=fn.default.resolve(s?fn.default.dirname(s):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),m=`module.exports=${JSON.stringify(d,null,2)}`;return Mi("configFileContent: %O",m),$i.default.writeFileSync(l,m),await He($e,[200,200,200,200,200,1e3])(l),l}catch(n){if(Mi("error %o",n),r)throw new Error(`Failed to recreate the Jest config for discovery: ${n.message}`);return C("Failed to recreate the config file"),null}}async function Hi(t,e){let r="!!##ThisPatternWillNotMatchAnyTestName##!!",n=t.options,o=Ni(n),s=Ui(o),i=n.config,a=await Gi(i,e);return{cliArgs:[s,"--testNamePattern",r,"--reporters",require.resolve("@currents/cmd/discovery/jest"),"--shard=1/1","--testFailureExitCode=0",a?`--config=${a}`:"",...t.args].filter(d=>!(0,Ki.isEmpty)(d)),configFilePath:a}}var Wu=p.extend("jest-discovery");async function Yi(t,e){console.time(S("@currents/jest:fullTestSuite-ready"));let{run:r}=Bi(),{cliArgs:n,configFilePath:o}=await Hi(t,e);try{let s=Vi.default.fileSync({postfix:".json"});return Wu("running scanner: %o",n),process.env.CURRENTS_DISCOVERY_PATH=s.name,await r(n.concat(["--openHandlesTimeout=0"])),await He($e,Array.from({length:300},()=>100))(s.name),console.timeEnd(S("@currents/jest:fullTestSuite-ready")),await yt(s.name)}catch(s){return C("Failed to obtain the jest full test suite:",s),{fullTestSuite:[],specsWithoutResults:[]}}finally{o&&Ji.default.unlinkSync(o)}}var Wi=p.extend("jest-discovery"),Ve=class extends lt{constructor(r,n){super(r);this.instances=n}async getFullTestSuite(){if(!this.config.frameworkConfig?.shard)return Wi("Not a sharded run, listing the tests of the results"),Si(this.instances);let{fullTestSuite:r,specsWithoutResults:n}=await Yi(this.config.cliArgs,{detox:this.config.frameworkConfig.originFramework==="detox"});if(n.length===0)return r;for(let{spec:s,message:i}of n)I("Discovery could not load %s: %s",s,qu(i));let o=Pi(r,n,this.instances);return I("The tests of these files are listed from the results of the shard that ran them. Currents can show the run as finished before the other shards upload."),Wi("Files that did not run on this shard: %o",o),r.filter(s=>s.tests.length>0)}};function qu(t){return t.split(`
|
|
28
|
-
`).map(e=>e.trim()).find(e=>e&&!e.startsWith("\u25CF"))??""}var
|
|
29
|
-
`))}async function
|
|
30
|
-
`)}function
|
|
31
|
-
`}catch{return r}}async function
|
|
24
|
+
`)}async function Ui(t,e,r=null){let{matrixIndex:n,matrixTotal:o}=t,s=e.params,i=qt(s.githubRunAttempt,1),a=Ze(r),u=i>1&&a,p=u?"--last-failed":"",l="";o>1&&(l=u?"--shard=1/1":`--shard=${n}/${o}`);let m=[p,l].filter(Boolean).join(" "),h=t.presetOutput??de;await xt(h,m),d('Dumped PW config: "%s" for GHA to %s',m,h)}async function Di(t,e,r=null){let n=e.params,o=r?.ci.params,s=o?.circleWorkflowId,i=o?.circleWorkflowWorkspaceId,a=qt(n.circleNodeIndex,0),u=qt(n.circleNodeTotal,1),p=i==n.circleWorkflowWorkspaceId&&s!==n.circleWorkflowId,l=Ze(r),m=p&&l,h=m?"--last-failed":"",f="";u>1&&(f=m?"--shard=1/1":`--shard=${a+1}/${u}`);let O=[h,f].filter(Boolean).join(" "),j=t.presetOutput??de;await xt(j,O),d('Dumped PW config: "%s" for Circle to %s',O,j)}var qt=(t,e)=>{let r=xn.default.toNumber(t);return xn.default.isNaN(r)?e:r};async function An(){let t=ht();if(t.type!=="GET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:n,matrixIndex:o,matrixTotal:s,continue:i}=t.values,a=t.values.outputDir,u=ut();Xe(u,r),n==="last-run"&&await Ai(t.values,u);let{cacheId:p,refMetaReadUrl:l}=await Cs({recordKey:e,ci:u,id:r,config:{matrixIndex:o,matrixTotal:s}});try{let m=await Um(l),{readUrl:h}=await Ts({recordKey:e,cacheKey:m.cacheKey}),f=await bm({readUrl:h,outputDir:a});n==="last-run"&&await bi(t.values,u,m),C(b("- restoring cache to"),f),Ne("Cache restored. Cache ID: %s",p)}catch(m){if(L(m)&&(m.response?.status===403||m.response?.status===404)){let h=`Cache with ID "${p}" not found`;if(i){_t(h);return}throw new Error(h)}throw m}}async function bm({readUrl:t,outputDir:e}){let r=await wn(t),n=Pm(e);return await Cn(r,n),d("Cache downloaded",{readUrl:t,destination:n}),n}function Pm(t){let e=t??process.cwd();return Sn.default.isAbsolute(e)?e:Sn.default.resolve(process.cwd(),e)}async function Um(t){let e=await wn(t),r=JSON.parse(e.toString("utf-8"));return d("Meta file downloaded: %O",r),r}var vi=require("lodash");async function bn(){let t=ht();if(t.type!=="SET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:n,pwOutputDir:o,matrixIndex:s,matrixTotal:i,continue:a}=t.values,u=await Si(t.values.path),p=t.values.path||[],l=ut();if(Xe(l,r),n==="last-run"&&(p.push(o),u.push(...await xi(o))),u.length===0){let j=`No files available to upload: ${p.filter(Boolean).join(",")}`;if(!a)throw new Error(j);_t(j)}let m=await Is({recordKey:e,ci:l,id:r,config:{matrixIndex:s,matrixTotal:i}});d("Cache upload url created",{result:m});let h=Nm(l),f=u.length>0?await ui(u):null,O=[];f&&O.push(Dm({archive:f,cacheId:m.cacheId,uploadUrl:m.uploadUrl}).then(()=>{vm(u),d("Cache archive uploaded",{uploadUrl:m.uploadUrl})})),O.push(Ni({meta:On({cacheId:m.cacheId,config:t.values,ci:h,orgId:m.orgId,path:u}),cacheId:m.cacheId,uploadUrl:m.metaUploadUrl}).then(()=>d("Meta uploaded",{uploadUrl:m.metaUploadUrl})),Ni({meta:On({cacheId:m.cacheId,config:t.values,ci:h,orgId:m.orgId,path:u,cacheKey:m.cacheKey,metaCacheKey:m.metaCacheKey}),cacheId:m.cacheId,uploadUrl:m.refMetaUploadUrl}).then(()=>d("Ref meta uploaded",{uploadUrl:m.refMetaUploadUrl}))),await Promise.all(O),Ne("Cache uploaded. Cache ID: %s",m.cacheId)}async function Dm({archive:t,cacheId:e,uploadUrl:r}){try{let n="application/zip";await Rn({buffer:t,contentType:n,name:e,uploadUrl:r},n,_n(e)),d("Cache archive uploaded",{cacheId:e})}catch(n){throw d("Failed to upload cache archive",n),n}}async function Ni({meta:t,cacheId:e,uploadUrl:r}){try{let n=`${e}_meta`,o="application/json";await Rn({buffer:t,contentType:o,name:n,uploadUrl:r},o,_n(n)),d("Cache meta uploaded",{cacheId:e})}catch(n){throw d("Failed to upload cache meta",n),n}}function Nm(t){return t.ciBuildId.source==="server"||t.ciBuildId.source==="random"?(0,vi.omit)(t,"ciBuildId"):t}function vm(t){C(`Cache upload paths:
|
|
25
|
+
`+t.map(e=>`${b("- uploading")} ${e}`).join(`
|
|
26
|
+
`))}var{recordKey:Lm,projectId:Bm,ciBuildId:Fm,debug:km}=x,nt={recordKey:Lm,projectId:Bm,ciBuildId:Fm,runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:km};var Mm=d.extend("config"),$m=["recordKey","projectId"];function jm(t){if(!(t.runId||t.ciBuildId))throw T(`${He(nt,"runId")} or ${He(nt,"ciBuildId")} is required: pass ${b(je(nt,"runId"))} or ${b(je(nt,"ciBuildId"))}, or set ${b(U(nt,"runId"))} or ${b(U(nt,"ciBuildId"))}`),new Q("Missing required config variable")}var Pn=null;function Li(t){Pn=D(nt,$m,t,jm),Mm("Resolved config: %o",E(Pn))}function tr(){return Pn}async function Un(){let t=tr();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await ys({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?C('Run "%s" (%s) is cancelled',r.data.runId,e):C('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw d("Failed to cancel the run"),r}}var Bi=require("@currents/commit-info"),Fi=require("lodash");var Hm=d.extend("git"),Gm=async()=>{let t=await(0,Bi.commitInfo)();return Hm("commit: %O",t),{branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData??null}},Ee=(0,Fi.memoize)(Gm);var ji=require("child_process"),Nn=g(require("fs/promises")),Hi=require("lodash"),Z=require("os"),Gi=g(require("path")),Km=[["/etc/fedora-release",["Fedora"]],["/etc/redhat-release",["RHEL","RHAS","Red Hat Linux","Scientific Linux","ScientificSL","ScientificCERNSLC","ScientificFermiLTS","ScientificSLF","CentOS"]],["/etc/redhat_version",["RHEL","RHAS","Red Hat Linux","Scientific Linux","ScientificSL","ScientificCERNSLC","ScientificFermiLTS","ScientificSLF"]],["/etc/SuSE-release",["SUSE Linux"]],["/etc/lsb-release",["Ubuntu","Chakra","IYCC","Linux Mint","elementary OS","Arch Linux","Manjaro Linux","KDE neon","Zorin"]],["/etc/debian_version",["Debian"]],["/etc/debian_release",["Debian"]],["/etc/arch-release",["Arch Linux"]],["/etc/NIXOS",["NixOS"]],["/etc/annvix-release",["Annvix"]],["/etc/arklinux-release",["Arklinux"]],["/etc/aurox-release",["Aurox Linux"]],["/etc/blackcat-release",["BlackCat"]],["/etc/cobalt-release",["Cobalt"]],["/etc/conectiva-release",["Conectiva"]],["/etc/eos-version",["FreeEOS"]],["/etc/gentoo-release",["Gentoo Linux"]],["/etc/hlfs-release",["HLFS"]],["/etc/hlfs_version",["HFLS"]],["/etc/immunix-release",["Immunix"]],["/knoppix_version",["Knoppix"]],["/etc/lfs-release",["Linux-From-Scratch"]],["/etc/lfs_version",["Linux-From-Scratch"]],["/etc/linuxppc-release",["Linux-PPC"]],["/etc/mageia-release",["Mageia"]],["/etc/mandriva-release",["Mandriva Linux","Mandrake Linux"]],["/etc/mandakelinux-release",["Mandriva Linux","Mandrake Linux"]],["/etc/mandrake-release",["Mandrake","Mandriva Linux","Mandrake Linux"]],["/etc/mklinux-release",["MkLinux"]],["/etc/nld-release",["Novell Linux Desktop"]],["/etc/pld-release",["PLD Linux"]],["/etc/rubix-version",["Rubix"]],["/etc/slackware-version",["Slackware"]],["/etc/slackware-release",["Slackware"]],["/etc/e-smith-release",["SME Server"]],["/etc/release",["Solaris SPARC"]],["/etc/sun-release",["Sun JDS"]],["/etc/novell-release",["SUSE Linux"]],["/etc/sles-release",["SUSE Linux ES9"]],["/etc/synoinfo.conf",["Synology"]],["/etc/tinysofa-release",["Tiny Sofa"]],["/etc/trustix-release",["Trustix"]],["/etc/trustix-version",["Trustix"]],["/etc/turbolinux-release",["TurboLinux"]],["/etc/ultrapenguin-release",["UltraPenguin"]],["/etc/UnitedLinux-release",["UnitedLinux"]],["/etc/va-release",["VA-Linux/RH-VALE"]],["/etc/yellowdog-release",["Yellow Dog"]],["/etc/alpine-release",["Alpine Linux"]],["/etc/system-release",["Amazon Linux"]],["/etc/os-release",["Raspbian"]]],Yt=/distrib_release=(.*)/,ki=/release ([^ ]+)/,Mi=/(.*)/,Jm={alpine:Mi,amazon:/release (.*)/,arch:Yt,centos:ki,debian:Mi,fedora:/release (..)/,kde:Yt,manjaro:Yt,mint:Yt,raspbian:/VERSION_ID="(.*)"/,red:ki,suse:/VERSION = (.*)\n/,ubuntu:Yt,zorin:Yt};function $i(t){return t.split(" ").map(e=>e.toLowerCase()).find(e=>e!=="linux")}function Dn(t,e){let r=Jm[t];return r?e.match(r)?.[1]:void 0}function Vm(){return new Promise((t,e)=>(0,ji.execFile)("lsb_release",["-a"],(r,n)=>r?e(r):t(n)))}async function qm(t){try{return(await Vm()).match(/Release:\t(.*)/)?.[1]}catch{return Dn("debian",t)}}async function Ym(t){for(let[e,r]of Km){let n=Gi.default.join(t,e);if((await Nn.default.stat(n).catch(()=>null))?.isFile())return{filePath:n,candidates:r}}return null}async function Wm(t="/"){let e=await Ym(t);if(!e)return;let r=await Nn.default.readFile(e.filePath,"utf8"),[n]=e.candidates,o;if(e.candidates.length===1){let s=$i(n);o=s==="debian"?await qm(r):Dn(s,r)}else{let s=r.toLowerCase();for(let i of e.candidates){let a=$i(i);s.includes(a)&&(n=i,o=Dn(a,s)??o)}}return o===void 0?void 0:`${n} - ${o}`}var zm=async()=>{if((0,Z.platform)()==="linux")try{return await Wm()??(0,Z.release)()}catch{return(0,Z.release)()}return(0,Z.release)()},Qm=async()=>{let t=await zm();return{osName:(0,Z.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,Z.freemem)(),total:(0,Z.totalmem)()}}},Ki=(0,Hi.memoize)(Qm);var Ja=g(require("fs/promises")),mr=g(require("path")),Va=g(require("semver"));var{debug:Xm,ciBuildId:Zm,recordKey:tl,projectId:el,machineId:rl}=x,tt={debug:Xm,ciBuildId:Zm,recordKey:tl,projectId:el,machineId:rl,tag:{...x.tag,env:"CURRENTS_TAG"},disableTitleTags:{name:"Disable title tags",env:"CURRENTS_DISABLE_TITLE_TAGS",cli:"--disable-title-tags"},removeTitleTags:{name:"Remove title tags",env:"CURRENTS_REMOVE_TITLE_TAGS",cli:"--remove-title-tags"},environment:{name:"Environment",env:"CURRENTS_ENVIRONMENT",cli:"--environment"},failOnFailures:{name:"Fail on failures",env:"CURRENTS_FAIL_ON_FAILURES",cli:"--fail-on-failures"},reportDir:{name:"Report folder",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};var nl=d.extend("config"),ol=["projectId","recordKey"],vn=null;function Ji(t){vn=D(tt,ol,t),nl("Resolved Currents config: %o",E(vn))}function er(){return vn}function Vi(t){return{ciBuildId:t.ciBuildId,projectId:t.projectId,recordKey:t.key,tag:t.tag,removeTitleTags:t.removeTitleTags,disableTitleTags:t.disableTitleTags,debug:t.debug,machineId:t.machineId,environment:t.environment,reportDir:t.reportDir,failOnFailures:t.failOnFailures}}var B=require("@currents/rules");var rr=d.extend("actions"),sl=512;async function Wi(t,e){try{let r=await bs(t,e);if(!Array.isArray(r))throw new Error("The project actions are not a list");return rr("Fetched %d project actions",r.length),r}catch(r){return I("Failed to fetch the project actions, uploading without them"),rr("Failed to fetch the project actions: %o",r),[]}}function zi({actions:t,instances:e,fullTestSuite:r,gitInfo:n,runTags:o,disableTitleTags:s=!1,group:i}){let a={skipped:0,quarantined:0,tagged:0};if(t.length===0)return a;let u=new B.RulesEvalBase(t,rr);for(let p of e){let l=i??p.groupId;for(let m of p.results.tests){let h=s?[]:ta(r,{groupId:l,spec:p.spec,testId:m.testId})?.test.tags??[],f=u.getMatchedRules(il({groupId:l,spec:p.spec,test:m,gitInfo:n,tags:[...h,...o]}));if(f.length===0)continue;rr("Test %s matched actions: %j",m.testId,f);let O=al(m,f);O.length>0&&(cl(r,{groupId:l,spec:p.spec,testId:m.testId,tags:O}),a.tagged++);let j=qi(f,B.ACTION_TYPE.SKIP),Lt=qi(f,B.ACTION_TYPE.QUARANTINE);j?(Yi(m,j,B.ACTION_ANNOTATIONS.SKIP_POST),a.skipped++):Lt&&m.state==="failed"&&(Yi(m,Lt,B.ACTION_ANNOTATIONS.QUARANTINE_POST),a.quarantined++)}}return a}function Qi(t){t.skipped+t.quarantined+t.tagged!==0&&C("[currents] Actions: %d tests skipped, %d quarantined, %d tagged",t.skipped,t.quarantined,t.tagged)}function il({groupId:t,spec:e,test:r,gitInfo:n,tags:o}){return{title:r.title[r.title.length-1],titlePath:[e,...r.title],file:e,project:t,testId:r.testId,tag:Array.from(new Set([...r.tags??[],...o])),gitInfo:n&&{branch:n.branch,authorName:n.authorName,authorEmail:n.authorEmail,remoteOrigin:n.remoteOrigin,message:n.message},errors:r.attempts.flatMap(s=>s.errors).filter(s=>!!s.message).map(s=>({message:s.message}))}}function qi(t,e){return t.find(r=>r.action.some(n=>n.op===e))}function al(t,e){let r=[];for(let n of e)for(let o of n.action){if(o.op!==B.ACTION_TYPE.TAG)continue;let s=(0,B.normalizeTagMatcherValue)(o.details?.tags??[]);s.length!==0&&(Xi(t,B.ACTION_ANNOTATIONS.TAG,Zi({action:n,type:B.ACTION_TYPE.TAG,testId:t.testId,extraDetails:{tags:s}})),r.push(...(0,B.normalizeTagMatcherValue)(s,{removeAtPrefix:!0})))}return r.length>0&&(t.tags=Array.from(new Set([...t.tags??[],...r]))),r}function Yi(t,e,r){let n=t.state;Xi(t,r,Zi({action:e,type:r===B.ACTION_ANNOTATIONS.SKIP_POST?B.ACTION_TYPE.SKIP:B.ACTION_TYPE.QUARANTINE,testId:t.testId,extraDetails:{status:n}})),t.state="pending"}function Xi(t,e,r){t.annotations=[...t.annotations??[],{type:e,description:JSON.stringify(r),source:"test"}]}function Zi({action:t,type:e,testId:r,extraDetails:n}){return{rule:{v:t.v,id:t._id,name:t.name.slice(0,sl),type:e,extraDetails:n,appliedAt:Date.now()},testInfo:{testId:r,status:n.status}}}function ta(t,{groupId:e,spec:r,testId:n}){let o=t.find(i=>i.name===e),s=o?.tests.find(i=>i.spec===r&&i.testId===n);return o&&s?{project:o,test:s}:null}function cl(t,{groupId:e,spec:r,testId:n,tags:o}){let s=ta(t,{groupId:e,spec:r,testId:n});s&&(s.test.tags=Array.from(new Set([...s.test.tags,...o])))}var da=g(require("fs/promises")),mt=require("path");var ea=g(require("path")),Ln={".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".jpeg":{type:"screenshot",contentType:"image/jpeg"},".webp":{type:"screenshot",contentType:"image/webp"},".gif":{type:"screenshot",contentType:"image/gif"},".mp4":{type:"video",contentType:"video/mp4"},".webm":{type:"video",contentType:"video/webm"},".svg":{type:"attachment",contentType:"image/svg+xml"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".yml":{type:"attachment",contentType:"text/plain"},".yaml":{type:"attachment",contentType:"text/plain"},".md":{type:"attachment",contentType:"text/markdown"},".html":{type:"attachment",contentType:"text/html"},".csv":{type:"attachment",contentType:"text/csv"},".json":{type:"attachment",contentType:"application/json"},".pdf":{type:"attachment",contentType:"application/pdf"},".gz":{type:"attachment",contentType:"application/gzip"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}},Bn=t=>Ln[ea.default.extname(t).toLowerCase()];var ra=require("path"),Fn=d.extend("detox"),pl="detox.json";function na(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function oa(t){let e=(0,ra.join)(t,pl);try{let r=await pt(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){Fn("Unexpected Detox manifest contents at %s",e);return}return Fn("Detox manifest: %o",r),r}catch{Fn("No Detox manifest at %s",e);return}}var nr=require("path"),ul=d.extend("detox"),sa=255,dl=/[/\\?<>:*|"$\u0000-\u001f]/g,ia=4;function aa(t){return ml(t)??ll(t)}function ml({rootDir:t,fullName:e,status:r,invocations:n}){try{let o=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(o),i=new s({rootDir:t});return(0,nr.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:n}))}catch(o){ul("Detox path builder is not available: %o",o);return}}function ll({rootDir:t,fullName:e,status:r,invocations:n}){let o=gl(r),s=n>1?` (${n})`:"",i=e.slice(-sa+o.length+s.length),a=`${o}${i}${s}`.replace(dl,"_");return(0,nr.join)(t,fl(a,sa))}function fl(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function gl(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var pa=require("path"),ca=d.extend("detox"),or="detox.trace.json",hl="ws-client-invocation";async function ua(t){let e=(0,pa.join)(t,or),r=new Map,n;try{n=await pt(e)}catch{return ca("No Detox trace at %s",e),r}if(!Array.isArray(n))return ca("Unexpected Detox trace contents at %s",e),r;let o=El(n);return Tl(n).forEach(({pid:i,ts:a,step:u})=>{o.filter(l=>l.pid===i&&a>=l.startTs&&a<=l.endTs).sort((l,m)=>l.startTs-m.startTs).pop()?.steps.push(u)}),o.forEach(({fullName:i,invocations:a,steps:u})=>{let p=r.get(i)??[];p.push({fullName:i,invocations:a,steps:u.sort((l,m)=>+new Date(l.startTime)-+new Date(m.startTime))}),r.set(i,p)}),r}function El(t){let e=new Map,r=[];t.forEach(o=>{let s=`${o.pid}:${o.tid}`,i=e.get(s)??[];if(e.set(s,i),o.ph==="B"){i.push(Il(o));return}if(o.ph==="E"){let a=i.pop();a&&r.push({...a,endTs:Number(o.ts)})}});let n=[...e.values()].flatMap(o=>o.filter(s=>s!==void 0));return[...r,...n]}function Il(t){let e=t.args?.fullName;if(!(t.args?.context!=="test"||typeof e!="string"))return{fullName:e,invocations:Number(t.args?.invocations??1),pid:Number(t.pid),startTs:Number(t.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function Tl(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(hl))return;let o=`${n.pid}:${n.tid}`,s=e.get(o)??[];if(n.ph==="B"){s.push({name:n.name??"action",cat:n.cat,ts:Number(n.ts)}),e.set(o,s);return}if(n.ph==="E"){let i=s.pop();if(!i)return;r.push({pid:Number(n.pid),ts:i.ts,step:{title:i.name,category:"detox",startTime:new Date(i.ts/1e3).toISOString(),duration:Math.round((Number(n.ts)-i.ts)/1e3),steps:[]}})}}),r}var Ie=d.extend("detox"),ma="artifacts",Cl=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],yl=t=>{let e=(0,mt.extname)(t);return Cl.includes(e)?Ln[e]:void 0};async function la({instances:t,reportDir:e,manifest:r}){let n=wl(r),o=await ua(r.artifactsRootDir),s=await At((0,mt.join)(e,ma)),i={artifacts:0,steps:0};for(let a of t)for(let u of a.results.tests){let p=n.get(u.testId);if(!p){Ie("No Detox manifest entry for %s",u.testId);continue}await _l({test:u,manifestTest:p,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(p.fullName)??[],result:i})}return i.artifacts+=await Rl({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function Rl({instances:t,rootDir:e,artifactsDir:r}){if(!await P((0,mt.join)(e,or)))return 0;let[n]=await fa(e,[or],r),o=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return o.forEach(s=>{s.artifacts=[...s.artifacts??[],n]}),o.length}function wl(t){let e=new Map;return t.tests.forEach(r=>{e.set(r.fullName,[...e.get(r.fullName)??[],r.testId])}),new Map(t.tests.filter(r=>{let n=e.get(r.fullName)?.length===1;return n||Ie("Ambiguous Detox test name, skipping: %s",r.fullName),n}).map(r=>[r.testId,r]))}async function _l({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let i=[...t.attempts].sort((p,l)=>p.attempt-l.attempt),a=na(e.attempts),u=1;for(let[p,l]of a.entries()){let m=i[p];if(!m){Ie("No reported attempt %d of %s",p,e.fullName);continue}let h=await Ol({fullName:e.fullName,status:l.status,rootDir:r,artifactsDir:n,fromInvocation:u});h&&(u=h.invocation+1,m.artifacts=[...m.artifacts??[],...h.artifacts],s.artifacts+=h.artifacts.length);let f=Sl(o,p,h?.invocation);f.length&&(m.steps=[...m.steps??[],...f],s.steps+=f.length)}}async function Ol({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+ia;s++){let i=aa({rootDir:r,fullName:t,status:e,invocations:s}),a=await xl(i);if(a)return{invocation:s,artifacts:await fa(i,a,n)}}Ie("No Detox artifacts for %s [%s]",t,e)}async function xl(t){try{return(await da.default.readdir(t)).sort()}catch{return}}async function fa(t,e,r){let n=[];for(let o of e){let s=yl(o);if(!s){Ie("Skipping unsupported Detox artifact %s",o);continue}let i=(0,mt.join)(t,o),a=`${X(i)}${(0,mt.extname)(o)}`;await Fe(i,(0,mt.join)(r,a)),n.push({...s,path:(0,mt.join)(ma,a),name:o})}return n}function Sl(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,i)=>s.invocations-i.invocations)[e])?.steps??[]}var Et=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var bl=g(require("crypto"));var Al=g(require("path"));async function sr(t){let e=await P(t);if(!e)throw new Error("File does not exist");return e}function ga(){return"root"}function ha(t){let e=(t.join(" ").match(/@(\S+)/g)??[]).filter(Boolean).map(r=>r);return Array.from(new Set([...e].map(r=>r.trim()).map(r=>r.replace("@",""))))}var Pl=/^[0-9a-f]{32}$/;function Ea(t){let e=[];for(let r of t){let n=e.find(o=>o.name===r.groupId);n||(n={name:r.groupId,tags:[],tests:[]},e.push(n)),n.tests.push(...Ta(r))}return e.length===1&&Pl.test(e[0].name)&&(e[0].name=ga()),e}function Ia(t,e,r){let n=[];for(let{projectId:o,spec:s}of e){let i=r.find(u=>u.spec===s&&u.groupId===o)??(t.length===1?r.find(u=>u.spec===s):void 0);if(!i){n.push(s);continue}let a=t.length===1?t[0]:t.find(u=>u.name===o);a||(a={name:o,tags:[],tests:[]},t.push(a)),a.tests.push(...Ta(i))}return n}function Ta(t){return t.results.tests.map(e=>({spec:t.spec,testId:e.testId,title:e.title,tags:e.tags??ha(e.title)}))}var va=g(require("fs"));var Da=require("lodash");function Ca(t){let e=[];for(let[r,n]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof n=="boolean"?n&&e.push(`--${r}`):Array.isArray(n)?n.forEach(o=>{e.push(`--${r}=${o}`)}):e.push(`--${r}=${n}`));return e.join(" ")}var ya=require("lodash"),Ul=["bail","clearCache","collectCoverage","collectCoverageFrom","color","colors","config","coverage","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","debug","detectLeaks","detectOpenHandles","errorOnDeprecated","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","notify","notifyMode","openHandlesTimeout","outputFile","reporters","runner","shard","showConfig","showSeed","silent","testFailureExitCode","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function Ra(t){return(0,ya.omit)(t,...Ul)}var Pa=g(require("fs")),pr=require("lodash"),Mn=g(require("path"));var kn=g(require("fs")),ir=require("module"),ar=g(require("path")),wa=g(require("semver")),Dl=">=29.5.0";function Nl(){let t=(0,ir.createRequire)(ar.default.join(process.cwd(),"package.json"));if(vl(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,ir.createRequire)(t.resolve("jest")).resolve("jest-cli")}catch{}try{return t.resolve("jest-cli")}catch{throw new Error(`Jest discovery needs the "jest" package, and it is not installed in ${process.cwd()}. Run the command from the folder of the project that ran the tests, or install Jest 29.5 or later: npm install --save-dev jest`)}}function vl(t){for(let e of t.resolve.paths("jest")??[]){if(kn.default.existsSync(ar.default.join(e,"jest","package.json")))return"jest";if(kn.default.existsSync(ar.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function _a(){let t=(0,ir.createRequire)(Nl()),{version:e}=t("jest-cli/package.json");if(!wa.default.satisfies(e,Dl,{includePrerelease:!0}))throw new Error(`Jest discovery needs Jest 29.5 or later, and ${process.cwd()} has Jest ${e}. Update Jest: npm install --save-dev jest@latest`);return t}function Oa(){return _a()("jest-cli")}function xa(){return _a()("jest-config")}function cr(t,e){return(...r)=>new Promise((n,o)=>{let s=0,i=()=>{s++;try{let a=t(...r);n(a)}catch(a){if(s>=e.length)o(a);else{let u=e[s-1];setTimeout(i,u)}}};i()})}var Sa=d.extend("jest-discovery");function Aa(t){return["testEnvironment","globalSetup","globalTeardown"].some(e=>String(t[e]??"").includes("detox"))}function ba(t){return{...(0,pr.omit)(t,["globalSetup","globalTeardown","testEnvironmentOptions"]),testEnvironment:"node"}}async function Ua(t,e){let r=e.detox;try{let{readInitialOptions:n}=xa(),{config:o,configPath:s}=await n(t);r||=[o,...o.projects??[]].some(h=>typeof h!="string"&&Aa(h));let i=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],a=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],u=h=>e.detox||Aa(h),p=(0,pr.omit)(o,i);if(u(p)&&(p=ba(p)),p.projects&&(p.projects=p.projects.map(h=>{if(typeof h=="string")return h;let f=(0,pr.omit)(h,a);return u(f)?ba(f):f})),p.rootDir&&Object.keys(p).length===1)return null;let l=Mn.default.resolve(s?Mn.default.dirname(s):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),m=`module.exports=${JSON.stringify(p,null,2)}`;return Sa("configFileContent: %O",m),Pa.default.writeFileSync(l,m),await cr(sr,[200,200,200,200,200,1e3])(l),l}catch(n){if(Sa("error %o",n),r)throw new Error(`Failed to recreate the Jest config for discovery: ${n.message}`);return T("Failed to recreate the config file"),null}}async function Na(t,e){let r="!!##ThisPatternWillNotMatchAnyTestName##!!",n=t.options,o=Ra(n),s=Ca(o),i=n.config,a=await Ua(i,e);return{cliArgs:[s,"--testNamePattern",r,"--reporters",require.resolve("@currents/cmd/discovery/jest"),"--shard=1/1","--testFailureExitCode=0",a?`--config=${a}`:"",...t.args].filter(p=>!(0,Da.isEmpty)(p)),configFilePath:a}}var Ll=d.extend("jest-discovery");async function La(t,e){console.time(b("@currents/jest:fullTestSuite-ready"));let{run:r}=Oa(),{cliArgs:n,configFilePath:o}=await Na(t,e);try{let s=await Be(".json");return Ll("running scanner: %o",n),process.env.CURRENTS_DISCOVERY_PATH=s,await r(n.concat(["--openHandlesTimeout=0"])),await cr(sr,Array.from({length:300},()=>100))(s),console.timeEnd(b("@currents/jest:fullTestSuite-ready")),await Ot(s)}catch(s){return T("Failed to obtain the jest full test suite:",s),{fullTestSuite:[],specsWithoutResults:[]}}finally{o&&va.default.unlinkSync(o)}}var Ba=d.extend("jest-discovery"),ur=class extends Et{constructor(r,n){super(r);this.instances=n}async getFullTestSuite(){if(!this.config.frameworkConfig?.shard)return Ba("Not a sharded run, listing the tests of the results"),Ea(this.instances);let{fullTestSuite:r,specsWithoutResults:n}=await La(this.config.cliArgs,{detox:this.config.frameworkConfig.originFramework==="detox"});if(n.length===0)return r;for(let{spec:s,message:i}of n)I("Discovery could not load %s: %s",s,Bl(i));let o=Ia(r,n,this.instances);return I("The tests of these files are listed from the results of the shard that ran them. Currents can show the run as finished before the other shards upload."),Ba("Files that did not run on this shard: %o",o),r.filter(s=>s.tests.length>0)}};function Bl(t){return t.split(`
|
|
27
|
+
`).map(e=>e.trim()).find(e=>e&&!e.startsWith("\u25CF"))??""}var ka=g(require("fs"));var Fa=g(require("path"));function It(t){return Fa.default.join(t,"fullTestSuite.json")}var Fl=d.extend("junit-discovery");async function Ma(t){console.time(b("@currents/junit:fullTestSuite-ready"));try{Fl("running scanner: %o",t);let e=It(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=ka.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return T("Failed to obtain the junit full test suite:",e),[]}}var dr=class extends Et{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return Ma(this.reportDir)}};function $a(t,e,r){switch(t.framework){case"jest":return new ur(t,r);case"junit":return new dr(t,e);default:return new Et(t)}}var Te=g(require("fs/promises")),lt=g(require("path"));async function ja(t){let e=await kl(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??lt.default.join(e,"config.json")}}async function kl(t){if(t){if(!await P(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,lt.join)(process.cwd(),".currents"),r=await P(e)?await Ml(e):null;if(!r)throw new Error(`No reports found: there is no report folder in "${e}". Run the tests with a Currents reporter first, or pass --report-dir with the folder of the reports.`);return r}async function Ml(t){let e=await Te.default.readdir(t),r=null;for(let n of e){let o=lt.default.join(t,n),s=await Te.default.stat(o);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:n,birthtime:s.birthtime})}return r?(0,lt.resolve)(t,r.name):null}async function $n(t){try{return await P(t)}catch{return T("Error checking if path exists:",T),!1}}async function Ha(t){let e=lt.default.join(t,"instances");return $l(e)}async function $l(t){let e=await Te.default.readdir(t),r=[];for(let n of e){let o=lt.default.join(t,n);(await Te.default.stat(o)).isFile()&&r.push(o)}return r}var jl=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Ga=(t,e=1048576)=>{let r=[],n=[],o=0;for(let s of t){let i=jl(s);o+i>e&&(r.push(n),n=[],o=0),n.push(s),o+=i}return n.length>0&&r.push(n),r};var Hl=3e4,Gl=Le(64);async function jn(){let t=er();if(!t)throw new Error("Currents config is missing!");let e=await ja(t);Co(Yl(e.reportDir)),d("Reporter options: %o",e),C("Report directory: %s",e.reportDir);let r=await Ot(e.configFilePath);d("Report config: %o",r);let n=await Ha(e.reportDir);d("Found %d instance results in the reportDir: %s",n.length,e.reportDir);let o=ql(e.reportDir),s=await $n(o),i=It(e.reportDir),a=null;if(s){let S=await Ot(o);I("Marker file detected. The report was already uploaded: %o",{runUrl:S.response.runUrl,isoDate:S.isoDate})}let u=[];for(let S of n)u.push(await Ot(S));if(a=await Wl(i),a)d("Full test suite file detected: %s",i);else{let rt=await $a(r,e.reportDir,u).getFullTestSuite();if(!qa(rt)||Ya(rt))throw new Error("Failed to discover the full test suite!");a=rt,await xt(i,JSON.stringify(a))}t.environment&&(a=a.map(S=>({...S,environment:S.environment??t.environment})));let p=a.length===1?a[0].name:null,l={currents:t},m={type:r.framework,version:r.frameworkVersion,clientVersion:Bt,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},h=$e.userFacingNanoid(),f=ut(t.ciBuildId),O={};for(let S of u)O[S.groupId]||(O[S.groupId]=[]),O[S.groupId].push(S);let j=await oa(e.reportDir);if(j){let S=await la({instances:Object.values(O).flat(),reportDir:e.reportDir,manifest:j});C("[currents] Attached %d Detox artifacts and %d steps",S.artifacts,S.steps)}let Lt=await Wi(t.projectId,t.recordKey);Qi(zi({actions:Lt,instances:Object.values(O).flat(),fullTestSuite:a,gitInfo:await Ee(),runTags:t.tag??[],disableTitleTags:t.disableTitleTags,group:p}));let Pe=new Map;Object.values(O).forEach(S=>{S.forEach(rt=>{rt.artifacts?.forEach(z=>{z&&Pe.set(z.path,z.contentType)}),rt.results.tests.forEach(z=>{z.artifacts?.forEach(J=>{J&&Pe.set(J.path,J.contentType)}),z.attempts.forEach(J=>{J.artifacts?.forEach(Rt=>{Rt&&Pe.set(Rt.path,Rt.contentType)})})})})});for await(let S of Object.keys(O)){let rt=O[S],z=S;p&&(d("Default group found: %s, overwriting the group in the results",p),z=p,rt=rt.map(J=>({...J,groupId:p})));try{let J=Ga(rt),Rt=await Ka({ci:f,group:z,instances:[],fullTestSuite:a,config:l,machineId:h,framework:m});for(let Vr=0;Vr<J.length;Vr++){let qr=await Ka({ci:f,group:z,instances:J[Vr],fullTestSuite:[],config:l,machineId:h,framework:m});qr.artifactUploadUrls&&qr.artifactUploadUrls.length>0&&await zl(qr.artifactUploadUrls,e.reportDir,Pe)}d("Api response: %o",Rt),C("[%s] Run created: %s",z,Rt.runUrl);let Ou={response:Rt,isoDate:new Date().toISOString()};await xt(o,JSON.stringify(Ou)),d("Marker file %s: %s",s?"overwritten":"created",o)}catch(J){throw d("Failed to upload the results to the dashboard"),J}}t.failOnFailures&&Jl(u)}var Kl=10;function Jl(t){let e=t.flatMap(o=>o.results.tests.filter(s=>s.state==="failed").map(s=>`${o.spec}: ${Vl(s.title,o.spec)}`));if(e.length===0)return;let r=e.slice(0,Kl),n=e.length-r.length;throw new Error([`${e.length} ${e.length===1?"test":"tests"} failed (--fail-on-failures):`,...r.map(o=>` - ${o}`),...n>0?[` and ${n} more`]:[]].join(`
|
|
28
|
+
`))}function Vl(t,e){return(t[0]===e?t.slice(1):t).join(" > ")}async function Ka({ci:t,group:e,instances:r,fullTestSuite:n,config:o,machineId:s,framework:i}){let a=await Ee(),u=await Ki(),p={browserName:"node",browserVersion:Va.default.coerce(process.version)?.version},{currents:l}=o,h={platform:{...p,...u},ci:t,commit:a,group:e,fullTestSuite:n,config:o,projectId:l.projectId,recordKey:l.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:l.tag??[],machineId:l.machineId??s,framework:i,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return d("Creating run: %o",E(h)),Os(h)}function ql(t){return mr.default.join(t,"upload.marker.json")}function Yl(t){return mr.default.join(t,`.debug-${new Date().toISOString()}.log`)}async function Wl(t){if(!await $n(t))return null;try{let e=await Ot(t);return!qa(e)||Ya(e)?(I("Ignoring %s, it is not a list of projects and tests",t),null):e}catch(e){return I("Ignoring %s, it is not valid JSON: %s",t,e),null}}function qa(t){return Array.isArray(t)&&t.every(e=>typeof e?.name=="string"&&Array.isArray(e.tests)&&e.tests.every(r=>typeof r?.spec=="string"&&typeof r.testId=="string"&&Array.isArray(r.title)&&r.title.every(n=>typeof n=="string")))}function Ya(t){return t.length===0||t.some(e=>e.tests.length===0)}async function zl(t,e,r){d("Uploading %d artifacts",t.length),await Promise.all(t.map(n=>{let o=mr.default.join(e,n.path),s=r.get(n.path)||"application/octet-stream";return Gl(()=>Ql(o,s,n.uploadUrl))}))}var Ql=async(t,e,r)=>{try{if(!await P(t)){I("Artifact file not found: %s",t);return}let n=await Ja.default.readFile(t);await bt({method:"PUT",url:r,body:n,headers:{"Content-Type":e},timeout:Hl})}catch(n){d("Failed to upload artifact %s: %o",t,n)}};var Xl=d.extend("cli");async function Wa(t,e){await R(async r=>{r.output||Jt(),e.getOptionValueSource("ciBuildId")==="env"&&(r.branch||r.tag)&&(r={...r,ciBuildId:void 0}),Lo(r);let o=Ke();Xl("Config: %o",E(o)),await gn()},t)}var ot=require("@commander-js/extra-typings");var Xa=g(require("fs/promises"));var Zl=d.extend("api");function tf(t){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(t))throw new Error(`Pass a path such as /v1/runs/<run-id>, not a URL. The CLI sends requests to ${ie()}`);let e=t.replace(/^\/+/,""),r=n=>/^(\.|%2e){1,2}$/i.test(n);if(e.split(/[?#]/)[0].split("/").some(r))throw new Error(`The path cannot hold "." or ".." segments: ${t}`);return/^v1(\/|\?|$)/.test(e)?e:`v1/${e}`}function ef(t){let e=Object.create(null);for(let[r,n]of t)if(r.endsWith("[]")){let o=r.slice(0,-2);e[o]=[...Array.isArray(e[o])?e[o]:[],n]}else e[r]=n;return e}function rf(t){let e=new URLSearchParams;for(let[r,n]of t)e.append(r,String(n));return e}async function nf(t){let e=t==="-"?await new Promise((r,n)=>{let o="";process.stdin.setEncoding("utf8"),process.stdin.on("data",s=>o+=s),process.stdin.on("end",()=>r(o)),process.stdin.on("error",n)}):await Xa.default.readFile(t,"utf8");try{return JSON.parse(e)}catch(r){throw new Error(`--input ${t} is not valid JSON: ${r.message}`)}}async function of(t,e){let r=[...e.field??[],...e.rawField??[]],n=e.input!==void 0,o=e.method??(n||r.length>0?"POST":"GET"),s=n||o==="GET"||o==="HEAD";return{method:o,url:tf(t),params:s&&r.length>0?rf(r):void 0,data:n?JSON.stringify(await nf(e.input)):!s&&r.length>0?JSON.stringify(ef(r)):void 0,headers:Object.fromEntries(e.header??[])}}function za(t){let e=Object.entries(t.headers).map(([r,n])=>`${r}: ${Array.isArray(n)?n.join(", "):n}`);return[`HTTP/1.1 ${t.status} ${t.statusText}`,...e,"",""].join(`
|
|
29
|
+
`)}function Qa(t,e){let r=t.data??"",n=String(t.headers["content-type"]??"").toLowerCase().includes("json");if(!e||!n||!r)return r;try{return JSON.stringify(JSON.parse(r),null,2)+`
|
|
30
|
+
`}catch{return r}}async function Za(t,e){let{apiKey:r}=D(x,["apiKey"],e),n=s=>s?.map(([i])=>i);Zl("Options: %o",E({...e,field:n(e.field),rawField:n(e.rawField),header:n(e.header)}));let o=await of(t,e);try{let s=await As(r,o);e.include&&process.stdout.write(za(s)),process.stdout.write(Qa(s,!!process.stdout.isTTY))}catch(s){if(!L(s))throw s;let i=s.response;if(!i&&rs(s))throw new Error(`The request was not sent: ${s.message}`);if(!i)throw new Error(`Could not reach the REST API at ${ie()}: ${s.message}`);e.include&&process.stderr.write(za(i));let a=Qa(i,!!process.stderr.isTTY);throw a&&process.stderr.write(a.endsWith(`
|
|
32
31
|
`)?a:`${a}
|
|
33
|
-
`),new Error(`${o.method} ${o.url.split("?")[0]} failed: the REST API answered ${i.status} ${i.statusText}`)}}var
|
|
32
|
+
`),new Error(`${o.method} ${o.url.split("?")[0]} failed: the REST API answered ${i.status} ${i.statusText}`)}}var tc=["GET","POST","PUT","PATCH","DELETE","HEAD"];function Hn(t,e){let r=t.indexOf(e),n=r<0?"":t.slice(0,r).trim();if(!n)throw new ot.InvalidArgumentError(`Expected key${e}value.`);let o=t.slice(r+1);return[n,e===":"?o.trim():o]}function sf(t){if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(/^-?\d+(\.\d+)?$/.test(t)){let e=Number(t);if(t.includes(".")?Number.isFinite(e):Number.isSafeInteger(e))return e}return t}var af=(t,e=[])=>{let[r,n]=Hn(t,"=");return[...e,[r,sf(n)]]},cf=(t,e=[])=>[...e,Hn(t,"=")],pf=(t,e=[])=>[...e,Hn(t,":")],ec=new ot.Option("-X, --method <method>","the HTTP method; GET by default, POST when --field, --raw-field or --input is given").argParser(t=>{let e=t.toUpperCase();if(!tc.includes(e))throw new ot.InvalidArgumentError(`Use one of ${tc.join(", ")}.`);return e}),rc=new ot.Option("-f, --field <key=value>","a request parameter; repeat for more. Sent in the query string of a GET and in the JSON body otherwise. true, false, null and numbers are sent as JSON values; in a JSON body, key[]=value adds the value to an array").argParser(af),nc=new ot.Option("-F, --raw-field <key=value>","like --field, but the value is always a string").argParser(cf),oc=new ot.Option("--input <file>",'send the JSON in this file as the body, or the JSON from stdin with "-"; fields then go to the query string'),sc=new ot.Option("-H, --header <key:value>","an HTTP header to send; repeat for more").argParser(pf),ic=new ot.Option("-i, --include","print the HTTP status line and the response headers before the body");async function ac(t,e){await R(async r=>{Jt(),await Za(t,r)},e)}var Ut=require("@commander-js/extra-typings");var Gn="(required)",G=(t=Gn)=>new Ut.Option("-k, --key <record-key>",`the record key from the Currents dashboard ${t}`).env(x.recordKey.env),st=(t=Gn)=>new Ut.Option("--api-key <api-key>",`an API key from the Currents dashboard ${t}`).env(x.apiKey.env),it=()=>new Ut.Option("-p, --project-id <id>",`the project ID from the Currents dashboard ${Gn}`).env(x.projectId.env),Wt=t=>new Ut.Option("--ci-build-id <id>",`the CI build ID the run was recorded with${t}`).env(x.ciBuildId.env),zt=t=>new Ut.Option("-t, --tag <tag>",`${t}; comma-separated or repeated`).argParser(Ye),N=()=>new Ut.Option("--debug","print debug logs; keys are hidden in them").env(x.debug.env).default(!1);var lr=require("@commander-js/extra-typings");var cc=new lr.Option("-o, --output <path>","write the JSON to this file instead of stdout").env(U(Ge,"output")),pc=Wt("; cannot be combined with --branch or --tag. The environment variable is ignored when --branch or --tag is set"),uc=zt("find the last run with these tags"),dc=new lr.Option("-b, --branch <branch>","find the last run of this git branch"),mc=new lr.Option("--pw-last-run","print only the status and the failed tests of the run, in the format of Playwright's .last-run.json");var fr="get",Kn="run",Vn=t=>[{comment:"Get the data of the run recorded under a CI build ID",commands:[`${t} ${Kn} ${fr} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id>`]},{comment:"Get the data of the last run of a branch with the tags tagA and tagB",commands:[`${t} ${Kn} ${fr} --api-key <api-key> --project-id <project-id> --branch <branch> --tag tagA,tagB`]},{comment:'Save the failed tests of a run where Playwright reads them, for "playwright test --last-failed"',commands:[`${t} ${Kn} ${fr} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id> --pw-last-run --output test-results/.last-run.json`]}],uf=t=>[{comment:"Get a run, with the API key in CURRENTS_API_KEY",commands:[`${t} api /v1/runs/<run-id>`]},{comment:"List the failed runs of the main branch of a project",commands:[`${t} api /v1/projects/<project-id>/runs -X GET -f "branches[]=main" -f status=FAILED -f limit=20`]},{comment:"Cancel a run",commands:[`${t} api /v1/runs/<run-id>/cancel -X PUT`]},{comment:"Create a webhook from the JSON in webhook.json",commands:[`${t} api /v1/webhooks -X POST -F projectId=<project-id> --input webhook.json`]}],lc=t=>new Jn.Command().name("api").summary("Make an authenticated request to the Currents REST API").description(`Make an authenticated request to the Currents REST API and print the response body. The path is a REST API route, such as /v1/runs/<run-id>; v1/runs/<run-id> and runs/<run-id> are the same route. A response that is not 2xx prints its body on stderr and exits with 1.
|
|
34
33
|
|
|
35
|
-
The REST API routes: https://docs.currents.dev/resources/api/api-resources`).usage("<path> [options]").argument("<path>","the REST API route, such as /v1/runs/<run-id>").enablePositionalOptions().helpCommand(!1).addOption(
|
|
36
|
-
run: npx ${t} ${
|
|
37
|
-
`)}),r};var
|
|
38
|
-
`).map(r=>r.trim());return e.find(r=>/^\w*Error\b/.test(r))??e[0]}function
|
|
39
|
-
`),r=e.match(/^(\w*Error): (.*)$/);return{message:r?r[2]:e,value:r?.[1],stack:t}}function
|
|
40
|
-
`),u=0,
|
|
41
|
-
`).join("")}async function
|
|
42
|
-
${
|
|
34
|
+
The REST API routes: https://docs.currents.dev/resources/api/api-resources`).usage("<path> [options]").argument("<path>","the REST API route, such as /v1/runs/<run-id>").enablePositionalOptions().helpCommand(!1).addOption(st()).addOption(ec).addOption(rc).addOption(nc).addOption(oc).addOption(sc).addOption(ic).addOption(N()).addHelpText("after",y(uf(t))).showHelpAfterError("(add --help for additional information)").addCommand(qn(t).name("get-run"),{hidden:!0}).action((r,n,o)=>r==="help"?o.help():ac(r,n)),qn=t=>new Jn.Command().name(fr).summary("Get the data of a run from the Currents API").description("Get the data of a run from the Currents API and print it as JSON, or write it to --output. Find the run by --ci-build-id, or the last run by --branch, --tag or both").addHelpText("after",y(Vn(t))).allowUnknownOption().addOption(st()).addOption(N()).addOption(pc).addOption(it()).addOption(dc).addOption(uc).addOption(cc).addOption(mc).action(Wa);var gr=require("@commander-js/extra-typings");var df=d.extend("cli");async function fc(t){await R(async e=>{ti(ei(e));let r=ht();df("Config: %o",E(r.values)),await An()},t)}var mf=d.extend("cli");async function gc(t){await R(async e=>{Zs(ri(e));let r=ht();mf("Config: %o",E(r.values)),await bn()},t)}var Qt="cache",hr=t=>[{comment:"Save files to the cache under an ID",commands:[`${t} ${Qt} set --key <record-key> --id <id> --path <path-1,path-2,...path-n>`]},{comment:"Save Playwright's .last-run.json to the cache",commands:[`${t} ${Qt} set --key <record-key> --preset last-run`]}],Er=t=>[{comment:"Restore the files saved in the cache under an ID",commands:[`${t} ${Qt} get --key <record-key> --id <id>`]},{comment:"Restore Playwright's .last-run.json from the cache, to rerun only the failed tests",commands:[`${t} ${Qt} get --key <record-key> --preset last-run`]},{comment:"Restore Playwright's .last-run.json to another folder",commands:[`${t} ${Qt} get --key <record-key> --preset last-run --output-dir <output-dir>`]}],hc=t=>new gr.Command().command(Qt).summary("Save files to the Currents cache and restore them").description("Save files to the Currents cache and restore them, e.g. in another CI job").addHelpText("after",y([...hr(t),...Er(t)])).showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(lf(t)).addCommand(ff(t)),lf=t=>new gr.Command().name("set").description("Save files to the cache").addHelpText("after",y(hr(t))).allowUnknownOption().addOption(G()).addOption($s).addOption(Gs).addOption(Hs).addOption(N()).addOption(Vs).addOption(hn).addOption(En).addOption(zs).action(gc),ff=t=>new gr.Command().name("get").description("Restore files from the cache").addHelpText("after",y(Er(t))).allowUnknownOption().addOption(G()).addOption(js).addOption(Ks).addOption(Js).addOption(qs).addOption(N()).addOption(hn).addOption(En).addOption(Ws).action(fc);var yc=require("@commander-js/extra-typings");var gf=d.extend("cli");async function Ec(t){await R(async({key:e,...r})=>{Li({...r,recordKey:e});let n=tr();gf("Config: %o",E(n??{})),await Un()},t)}var Ic=require("@commander-js/extra-typings");var Tc=Wt(" (required unless --run-id is set)"),Cc=new Ic.Option("--run-id <id>","the ID of the run to cancel, as printed when the run was created; wins over --ci-build-id").env(U(nt,"runId"));var Xt="cancel",Ir="run",Ce=t=>[{comment:"Cancel the run recorded under a CI build ID",commands:[`${t} ${Ir} ${Xt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Cancel a run by its ID, as printed when the run was created",commands:[`${t} ${Ir} ${Xt} --key <record-key> --project-id <id> --run-id <run-id>`]},{comment:"Cancel the run when a GitHub Actions workflow is cancelled (workflow step). It reads CURRENTS_RECORD_KEY, CURRENTS_PROJECT_ID and CURRENTS_CI_BUILD_ID from the environment",commands:[`- if: \${{ cancelled() }}
|
|
35
|
+
run: npx ${t} ${Ir} ${Xt}`]}],Tr=(t,{deprecated:e=!1}={})=>{let r=new yc.Command().name(Xt).summary("Cancel a run in progress").description("Cancel a run in progress, e.g. when the CI job it belongs to is cancelled").addHelpText("after",y(Ce(t))).allowUnknownOption().addOption(G()).addOption(it()).addOption(Tc).addOption(Cc).addOption(N()).action(Ec);return e&&r.hook("preAction",()=>{process.stderr.write(`'${t} ${Xt}' is deprecated and will be removed in a future version. Use '${t} ${Ir} ${Xt}'.
|
|
36
|
+
`)}),r};var Vc=require("@commander-js/extra-typings");var Tt=require("@commander-js/extra-typings");var ye=(r=>(r.junit="junit",r.cypressJson="cypress-json",r))(ye||{}),Cr=t=>new Tt.Option("--input-format <format>",["the format of the reports to convert",t].filter(Boolean).join(" ")).choices(Object.values(ye)),yr=t=>new Tt.Option("--input-file <patterns>",`comma-separated glob patterns of the report files, e.g. "reports/*.xml,other.xml"; quote them so that the shell does not expand them ${t}`).argParser(hf),Rr=new Tt.Option("-o, --output-dir <folder>","the folder to save the converted reports to; it must be empty, not exist, or hold only the reports being converted"),Re=(s=>(s.cypress="cypress",s.postman="postman",s.node="node",s.vitest="vitest",s.wdio="wdio",s))(Re||{}),wr=t=>new Tt.Option("--framework <framework>",`the test framework that wrote the reports ${t}`).choices(Object.values(Re)),_r=new Tt.Option("--framework-version <version>","the version of the test framework that wrote the reports");function hf(t){let e=t.split(",").map(n=>n.trim()),r=he(e);if(r.length===0)throw new Tt.InvalidArgumentError("No files found with the provided patterns");return r}var Rc={debug:x.debug,inputFormat:{name:"Input format",cli:"--input-format"},inputFiles:{name:"Input file",cli:"--input-file"},outputDir:{name:"Output folder",cli:"--output-dir"},framework:{name:"Framework",cli:"--framework"},frameworkVersion:{name:"Framework version",cli:"--framework-version"}};var Ef=d.extend("config"),If=["inputFormat","inputFiles","framework"],Yn=null;function wc(t){Yn=D(Rc,If,{...t,framework:t?.framework??(t?.inputFormat==="cypress-json"?"cypress":void 0)}),Ef("Resolved config: %o",Yn)}function Or(){return Yn}function _c(t){return{inputFiles:t.inputFile,inputFormat:t.inputFormat,outputDir:t.outputDir,framework:t.framework,frameworkVersion:t.frameworkVersion,debug:t.debug}}var Hc=g(require("fs/promises")),F=require("path");var bc=require("lodash"),Pc=g(require("crypto"));var et=require("path"),Sr=async(t,e,r,n)=>{if(t)for(let o of t)try{let s=(0,et.resolve)(n,o.path),i=(0,et.relative)(n,s);if(i.startsWith("..")||(0,et.isAbsolute)(i)){d("Skipping artifact outside workspace: %s (resolved: %s)",o.path,s);continue}let a=`${X(e+o.path)}.${(0,et.extname)(o.path).slice(1)||"bin"}`;await Fe(s,(0,et.join)(r,a)),o.path=(0,et.join)("artifacts",a)}catch(s){d("Failed to copy artifact %s: %o",o.path,s)}};function xc(t){let e=Ac(t.properties?.property??t.property);return xr(e,"currents.artifact.instance.","spec")}function Sc(t){let e=Ac(t.properties?.property),r=xr(e,"currents.artifact.test.","test"),n=new Map;Tf(e).forEach((i,a)=>{n.has(a)||n.set(a,[]),n.get(a).push(...i)});let s=xr(e,"currents.artifact.attempt.","attempt");return s.length>0&&(n.has(0)||n.set(0,[]),n.get(0).push(...s)),{testArtifacts:r,attemptArtifacts:n}}function Tf(t){let e=new Map,r=/^currents\.artifact\.attempt\.(\d+)\.(.+)$/,n=new Map;for(let o of t){let s=o.value??o._;if(!o.name||!s)continue;let i=o.name.match(r);if(!i)continue;let[,a,u]=i,p=parseInt(a,10);n.has(p)||n.set(p,[]),n.get(p).push({name:`currents.artifact.attempt.${u}`,value:s})}for(let[o,s]of n.entries()){let i=xr(s,"currents.artifact.attempt.","attempt");i.length>0&&e.set(o,i)}return e}function xr(t,e,r){let n=[],o={};for(let s of t){let i=s.value??s._;if(!s.name||!i||!s.name.startsWith(e))continue;let a=s.name.slice(e.length);/^\d+\./.test(a)||["path","type","contentType","name"].includes(a)&&(o[a]&&(Oc(o)&&n.push({...o,level:r}),o={}),o[a]=i)}return Oc(o)&&n.push({...o,level:r}),n}function Oc(t){return!!(t.path&&t.type&&t.contentType)}function Ac(t){return t?Array.isArray(t)?t:[t]:[]}function Uc(t,e,r,n){let o=at(t.failure),s=o.length>0,i=e?.timestamp??"",a="skipped"in t,u=a?"pending":s?"failed":"passed",{testArtifacts:p,attemptArtifacts:l}=Sc(t);return{_t:Pr(i),testId:Ar(we(t.name,n).join(", "),n),title:we(t.name,n),state:u,isFlaky:Cf(),expectedStatus:"passed",timeout:yf(),location:Rf(e?.file??""),retries:wf(o),artifacts:p,attempts:_f(t,o,Xn(i),r,l,a)}}function Ar(t,e){let r=`${t}${e}`;return Pc.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function br(t,e){let r=t.slice(0,-1).join(" "),n=t[t.length-1];return Ar([r,n].filter(Boolean).join(", "),e)}function Pr(t){return Dc(t)?new Date(t).getTime():new Date().getTime()}function Xn(t){return Dc(t)?new Date(t).toISOString():new Date().toISOString()}function Dc(t){let e=new Date(t);return!isNaN(e.getTime())}function we(t,e){return[e,t].filter(Boolean)}function Cf(){return!1}function yf(){return 0}function Rf(t){return{column:1,file:t,line:1}}function wf(t){let e=0;return t.forEach(r=>{typeof r!="string"&&e++}),e}function _f(t,e,r,n,o,s){let i=t.time?Ur(t.time):0,a=Array.from(o.values()).flat();return s?[{_s:"pending",attempt:0,startTime:r,steps:[],duration:i,status:"skipped",stdout:Wn(t?.["system-out"]),stderr:zn(t?.["system-err"]),artifacts:a,errors:[],error:void 0}]:e.length===0?[{_s:"passed",attempt:0,startTime:r,steps:[],duration:i,status:"passed",stdout:Wn(t?.["system-out"]),stderr:zn(t?.["system-err"]),artifacts:a,errors:[],error:void 0}]:e.reduce((u,p,l)=>{if(p!=="true"&&p!=="false"){let m=Of(p);u.push({_s:"failed",attempt:l,startTime:xf(n,r),steps:[],duration:i,status:"failed",stdout:Wn(t?.["system-out"]),stderr:zn(t?.["system-err"]),artifacts:o.get(l),errors:m,error:m[0]})}return u},[])}function Wn(t){return t?[t]:[]}function zn(t){return t?[t]:[]}function Of(t){return t==="true"||t==="false"?[]:[typeof t=="string"?{message:t}:{message:t.message,stack:t._,value:t.type}]}function xf(t,e){let r=Pr(e)+t;return new Date(r).toISOString()}function at(t){return t?Array.isArray(t)?t:[t]:[]}function Sf(t){return Math.round(t*1e3)}function Ur(t){let e=parseFloat(t);return isNaN(e)?0:Sf(e)}function Dr(t,e,r){let n=(0,bc.isNumber)(r)&&r>0,o=!!t.id&&Qn(e,"id",t.id);if(t.file){let s=Qn(e,"file",t.file);return s&&!o?`${t.file} - ${t.id}`:s&&n?`${t.file} - ${r}`:t.file}if(t.name){let s=Qn(e,"name",t.name);return s&&!o?`${t.name} - ${t.id}`:s&&n?`${t.name} - ${r}`:t.name}return t.id?o&&n?`${t.id} - ${r}`:t.id:n?`unknown - ${r}`:"unknown"}function Qn(t,e,r){return t.filter(o=>o[e]===r).length>1}function Nc(t){let e=[];return t.forEach(r=>{let n=at(r.testsuites?.testsuite),o={name:r.testsuites?.name??"No name",tags:[],tests:[]};n?.forEach(s=>{let i=Dr(s,n);at(s?.testcase)?.forEach(u=>{let p={title:we(u.name,i),spec:i,tags:[],testId:Ar(we(u.name,i).join(", "),i)};o.tests.push(p)})}),e.push(o)}),e}function Zn(t){let e=new Map;return t.forEach(({groupId:r,spec:n,results:o})=>{let s=e.get(r)??{name:r,tags:[],tests:[]};e.set(r,s),o.tests.forEach(({title:i,testId:a})=>{s.tests.push({title:i,spec:n,tags:[],testId:a})})}),Array.from(e.values())}var Zt=require("path");async function Lc(t){return Promise.all(t.map(async e=>{let r=await ct(()=>pt(e));if(!Array.isArray(r?.runs))throw new Error(`${e} is not a Cypress run result: it has no "runs" list. Save the results of the "after:run" event or of cypress.run().`);return r}))}function Bc(t){let e=new Map;for(let r of t)for(let n of r.runs){if(n.tests.length===0){n.error&&I("Skipping %s, Cypress could not load it and it has no test results: %s",n.spec.relative,Uf(n.error));continue}let o=Af(n,r.browserName),s=`${o.groupId}${o.spec}`;if(e.has(s))throw new Error(`The results have ${o.spec} in ${o.groupId} more than once. Upload the results of each spec file once: split the spec files between the machines, or upload the files of each run with its own --ci-build-id.`);e.set(s,o)}return e}function Af(t,e){let r=t.spec.relative,n=t.spec.absolute.slice(0,-r.length),o=p=>(0,Zt.relative)(n,p),s=t.screenshots.map(p=>({...p,path:o(p.path)})),i=[],a=new Date(t.stats.startedAt).getTime(),u=t.tests.map(p=>{let l=bf(p,r,a);return a+=p.duration,l});for(let p of s){let l={path:p.path,type:"screenshot",contentType:"image/png",name:(0,Zt.basename)(p.path)},m=Pf(p.path,t.tests),h=m&&u[m.testIndex].attempts[m.attempt];h?h.artifacts=[...h.artifacts??[],l]:i.push(l)}if(t.video){let p={path:o(t.video),type:"video",contentType:"video/mp4",name:(0,Zt.basename)(t.video)},l=u.flatMap(m=>m.attempts).filter(m=>m.status==="failed");for(let m of l)m.artifacts=[...m.artifacts??[],{...p}];l.length===0&&i.push(p)}return{groupId:e,spec:r,startTime:t.stats.startedAt,artifacts:i,results:{stats:{suites:t.stats.suites,tests:t.stats.tests,passes:t.stats.passes,pending:t.stats.pending,skipped:t.stats.skipped,failures:t.stats.failures,flaky:u.filter(p=>p.isFlaky).length,wallClockStartedAt:t.stats.startedAt,wallClockEndedAt:t.stats.endedAt,wallClockDuration:t.stats.duration},tests:u}}}function bf(t,e,r){let n=Math.round(t.duration/t.attempts.length),o=t.attempts.map(i=>i.state).lastIndexOf("failed"),s=t.attempts.map((i,a)=>{let u=a===o&&t.displayError?[Df(t.displayError)]:[];return{_s:vc(i.state),attempt:a,startTime:new Date(r+a*n).toISOString(),steps:[],duration:n,status:Nf(i.state),artifacts:[],errors:u,error:u[0]}});return{_t:r,testId:br(t.title,e),title:t.title,state:vc(t.state),isFlaky:t.state==="passed"&&t.attempts.some(i=>i.state==="failed"),retries:t.attempts.length-1,expectedStatus:"passed",timeout:0,location:{file:e,line:1,column:1},artifacts:[],attempts:s}}function Pf(t,e){let r=(0,Zt.basename)(t,".png").match(/^(.*?)(?: \(failed\))?(?: \(attempt (\d+)\))?$/);if(!r)return null;let[,n,o]=r,s=e.findIndex(i=>i.title.join(" -- ")===n);return s===-1?null:{testIndex:s,attempt:o?Number(o)-1:0}}function Uf(t){let e=t.split(`
|
|
37
|
+
`).map(r=>r.trim());return e.find(r=>/^\w*Error\b/.test(r))??e[0]}function Df(t){let[e]=t.split(`
|
|
38
|
+
`),r=e.match(/^(\w*Error): (.*)$/);return{message:r?r[2]:e,value:r?.[1],stack:t}}function vc(t){return t==="passed"||t==="failed"?t:"pending"}function Nf(t){return t==="passed"||t==="failed"?t:"skipped"}async function K(t){let e=new Map;return t.forEach(r=>{let n=at(r.testsuites?.testsuite),o=r.testsuites?.name??"No name";n.forEach((s,i)=>{let a=Dr(s,n,i),u=to(s,o,a),p=X(o+a);u.results.tests.length!==0&&e.set(p,u)})}),e}function to(t,e,r){let n=Xn(t.timestamp??""),o=t.time?Ur(t.time):0,s=new Date(Pr(t.timestamp??"")+o),i=at(t.testcase),a=[t["system-out"],t["system-err"],...i.flatMap(f=>[f["system-out"],f["system-err"]])].filter(f=>f).join(`
|
|
39
|
+
`),u=0,p=i.filter(f=>"failure"in f).length,l=i.filter(f=>"skipped"in f).length,m=i.length-p-l;return{groupId:e,spec:r,startTime:n,artifacts:xc(t),_stdout:a,results:{stats:{suites:1,tests:i.length,passes:m,pending:l,skipped:0,failures:p,flaky:0,wallClockStartedAt:n,wallClockEndedAt:s.toISOString(),wallClockDuration:o},tests:i?.map(f=>(i[0]?.time&&(u+=Ur(i[0].time)),Uc(f,t,u,r)))}}}async function Fc(t){let e=new Map;for(let r of t){let n=at(r.testsuites?.testsuite),o=n.find(u=>u.file)?.file;if(!o){(await K([r])).forEach((p,l)=>e.set(l,p));continue}let s=r.testsuites?.name??"No name",i=n.flatMap(u=>at(u.testcase)),a=to({...n[0],file:o,timestamp:Lf(n[0].timestamp),time:r.testsuites?.time,testcase:i},s,o);a.results.tests.forEach((u,p)=>{u.title=vf(i[p]),u.testId=br(u.title,o)}),a.results.tests.length!==0&&e.set(X(s+o),a)}return e}function vf({name:t="",classname:e=""}){return!e||!t.endsWith(e)?[t||e]:[t.slice(0,-e.length).trim(),e].filter(Boolean)}function Lf(t){return!t||/(Z|[+-]\d\d:?\d\d)$/.test(t)?t:`${t}Z`}async function kc({inputFormat:t,framework:e,parsedXMLArray:r}){return t==="junit"?Bf(e,r):new Map}async function Bf(t,e){switch(t){case"cypress":return Fc(e);case"node":return K(e);case"postman":return K(e);case"vitest":return K(e);case"wdio":return K(e);default:return I("Unsupported framework: %s",t),new Map}}var Mc=require("fs/promises"),$c=require("xml2js");async function jc(t){let e=await Promise.all(t.map(n=>ct(()=>(0,Mc.readFile)(n,"utf-8")))),r=(await Promise.all(e.map(Ff))).filter(Boolean);return e.length!==r.length&&I("Some files could not be parsed. Enable debug logging for more details"),r}async function Ff(t){let e=t.trim();if(!e)return null;try{return await(0,$c.parseStringPromise)(e,{explicitArray:!1,mergeAttrs:!0})||null}catch(r){return d("Error parsing XML input",r),null}}function eo(t){return{framework:"junit",frameworkVersion:t.frameworkVersion??null,frameworkConfig:{originFramework:t.framework,originFrameworkVersion:t.frameworkVersion}}}async function Gc(){try{let t=Or();if(!t)throw new Error("Config is missing!");t.outputDir&&await $f(t.outputDir,t.inputFiles);let e=t.outputDir?await At(t.outputDir):await Po(process.cwd(),".currents"),r=await At((0,F.join)(e,"instances")),n=t.inputFormat==="cypress-json"?await Mf(t,e):await kf(t,e);if(n.size===0)throw new Error(`No test results found in ${t.inputFiles.join(", ")}. Check that the tests ran and that the reports are the files the tests wrote.`);let o=await At((0,F.join)(e,"artifacts")),s=process.cwd();return await Promise.all(Array.from(n.values()).map(i=>ct(async()=>{if(await Sr(i.artifacts,i.spec,o,s),i._stdout){let a=`${X(i.spec)}.stdout.txt`;await St((0,F.join)(o,a),i._stdout),i.artifacts||(i.artifacts=[]),i.artifacts.push({path:(0,F.join)("artifacts",a),type:"stdout",contentType:"text/plain",level:"spec"}),delete i._stdout}for(let a of i.results.tests){await Sr(a.artifacts,a.testId,o,s);for(let u of a.attempts)await Sr(u.artifacts,a.testId+u.attempt,o,s)}}))),await Promise.all(Array.from(n.entries()).map(([i,a])=>ct(()=>St((0,F.join)(r,`${X(i)}.json`),JSON.stringify(a))))),C("[currents] Conversion completed, report saved to: %s",e),e}catch(t){throw d("Failed to convert: %o",t),t}}async function kf(t,e){let r=eo(t);d("Report config:",r),C("[currents] Convertion files: %s",t.inputFiles.join(", ")),await St((0,F.join)(e,"config.json"),JSON.stringify(r));let n=await jc(t.inputFiles);if(n.length===0)throw new Error("No valid XML JUnit report was found.");let o=await kc({inputFormat:t.inputFormat,framework:t.framework,parsedXMLArray:n}),s=t.framework==="cypress"?Zn(o):Nc(n);return await St(It(e),JSON.stringify(s)),o}async function Mf(t,e){C("[currents] Convertion files: %s",t.inputFiles.join(", "));let r=await Lc(t.inputFiles),n=eo({...t,frameworkVersion:t.frameworkVersion??r[0]?.cypressVersion});d("Report config:",n),await St((0,F.join)(e,"config.json"),JSON.stringify(n));let o=Bc(r);return await St(It(e),JSON.stringify(Zn(o))),o}async function $f(t,e){let r=(0,F.resolve)(t),n=new Set(e.map(a=>(0,F.resolve)(a))),o=[(0,F.join)(r,"config.json"),It(r),(0,F.join)(r,"instances"),(0,F.join)(r,"artifacts")],s=[...n].find(a=>o.some(u=>a===u||a.startsWith(u+F.sep)));if(s)throw new Error(`The report "${s}" is where the conversion writes its own files. Move the reports out of "${t}", or leave out --output-dir to convert into a new folder in .currents.`);if(await P(r)?await Kc(r,n):void 0)throw new Error(`The folder "${t}" is not empty. Reports already in it would be uploaded with the converted ones. Remove the folder, or leave out --output-dir to convert into a new folder in .currents.`)}async function Kc(t,e){for(let r of await Hc.default.readdir(t,{withFileTypes:!0})){let n=(0,F.join)(t,r.name),o=r.isDirectory()?await Kc(n,e):e.has(n)?void 0:n;if(o)return o}}var jf=d.extend("cli");async function ro(t){return wc(_c(t)),jf("Config: %o",Or()),Gc()}async function Jc(t){await R(async e=>{await ro(e)},t)}var no="convert",Hf=t=>[{comment:"Convert JUnit test reports to the Currents format, to check the result before an upload",commands:[`${t} ${no} --input-format junit --input-file "./*.xml" --framework postman`]}],qc=t=>new Vc.Command().name(no).command(no).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Convert JUnit XML reports to the Currents format").description("Convert JUnit XML reports to the Currents format, without uploading them. The converted reports are saved to --output-dir or a new folder in .currents").addHelpText("after",y(Hf(t))).addOption(N()).addOption(Cr("(required)")).addOption(yr("(required)")).addOption(Rr).addOption(wr("(required, except with cypress-json)")).addOption(_r).action(r=>Jc(r));var zc=require("@commander-js/extra-typings");var oo=g(require("fs/promises")),Nr=g(require("path"));function Gf(t=__dirname){let e=ke("package.json",t);if(!e)throw new Error("The docs folder is missing from this package");return Nr.default.join(e,"docs")}function Kf(t,e){let r=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n)+/),n=r?.[1].match(/^description:[ \t]*(.+?)\r?$/m)?.[1];if(!r||!n)throw new Error(`docs/${t}.md has no description in its front matter`);return{name:t,description:n,body:e.slice(r[0].length)}}async function Jf(t=Gf()){let e=(await oo.default.readdir(t)).filter(r=>r.endsWith(".md")).sort();return Promise.all(e.map(async r=>Kf(Nr.default.basename(r,".md"),await oo.default.readFile(Nr.default.join(t,r),"utf8"))))}function Yc(t){let e=Math.max(...t.map(r=>r.name.length));return t.map(r=>` ${r.name.padEnd(e)} ${r.description}
|
|
40
|
+
`).join("")}async function Wc(t,e){let r=await Jf();if(!e){await pe(`Topics:
|
|
41
|
+
${Yc(r)}
|
|
43
42
|
Run '${t} docs <topic>' to print a guide.
|
|
44
43
|
`);return}let n=r.find(o=>o.name===e);if(!n)throw new Error(`Unknown topic "${e}". Topics:
|
|
45
|
-
${
|
|
44
|
+
${Yc(r)}`);await pe(n.body)}var so="docs",Vf=t=>[{comment:"List the topics",commands:[`${t} ${so}`]},{comment:"Print the guide to CI setup",commands:[`${t} ${so} ci-setup`]}],Qc=t=>new zc.Command().name(so).summary("Print a guide, such as the CI setup steps").description("Print the guide of a topic as Markdown. Without a topic, list the topics.").argument("[topic]","the topic of the guide").addHelpText("after",y(Vf(t))).action(async e=>{await R(()=>Wc(t,e),{})});var Hr=require("@commander-js/extra-typings");var{apiKey:qf,recordKey:Yf,projectId:Wf,ciBuildId:zf,machineId:Qf,debug:Xf}=x,M={apiKey:qf,recordKey:Yf,projectId:Wf,ciBuildId:zf,machineId:Qf,sessionId:{name:"Session ID",env:"CURRENTS_SESSION_ID",cli:"--session-id"},title:{name:"Title",cli:"--title"},debug:Xf};var _e=d.extend("config");function Xc(t){let e=D(M,["projectId","title"],t,vr);return _e("Resolved config: %o",E(e)),e}function Zc(t){let e=D(M,[],t,vr);return _e("Resolved config: %o",E(e)),e}function tp(t){let e=D(M,[],t,vr);return _e("Resolved config: %o",E(e)),e}function ep(t){let e=D(M,["projectId"],t,vr);return _e("Resolved config: %o",E(e)),e}function rp(t){let e=D(M,[],t,Zf);return _e("Resolved config: %o",E(e)),e}function Zf(t){if(!t.apiKey)throw new Q(`run share needs an API key (${M.apiKey.cli} or ${M.apiKey.env}). A record key can share only sessions.`)}function vr(t){if(!(t.recordKey||t.apiKey))throw new Q(`${M.recordKey.name} or ${M.apiKey.name} is required. Set ${M.recordKey.env} or ${M.apiKey.env}, or pass ${M.recordKey.cli} or ${M.apiKey.cli}`)}var xe=g(require("fs/promises")),Nt=g(require("path"));var op=g(require("path"));var np=["trace","screenshot","video","attachment"];var tg=["image/png","image/jpeg","image/webp","image/gif"],sp=t=>op.default.extname(t).toLowerCase()===".zip";function ip(t){return np.includes(t)}function io(t){return sp(t)?"application/zip":Bn(t)?.contentType??"application/octet-stream"}function eg(t){return sp(t)?"trace":Bn(t)?.type??"attachment"}function ao(t,e){let r=eg(t);return e.includes(r)?r:"attachment"}function ap(t,e,r){if(!r.includes(e))throw new Error(`Cannot attach "${t}" as type "${e}" here. The target takes: ${r.join(", ")}`)}function cp(t,e){let r=io(t);if(!(e==="attachment"||e==="trace"&&r==="application/zip"||e==="screenshot"&&tg.includes(r)||e==="video"&&r.startsWith("video/")))throw new Error(`Cannot attach "${t}" as type "${e}": its content type is ${r}`)}var pp=require("fs"),Dt=g(require("fs/promises")),up=g(require("os")),Oe=g(require("path")),dp=require("stream/promises"),mp=g(require("yazl"));async function lp(t){try{return(await ci(t)).some(r=>/^(trace|test|\d+-trace)\.trace$/.test(r))}catch{return!1}}var fp=/^trace-.*\.trace$/,rg=/^trace-.*\.network$/;async function co(t){return(await Dt.default.readdir(t)).some(r=>fp.test(r))}function ng(t){if(!t)return!1;try{let e=JSON.parse(t),r=e.snapshot?.response;if(e.type!=="resource-snapshot"||!r)return!0;let n=r.status>=200&&r.status<400,o=/javascript|ecmascript/i.test(r.content?.mimeType??"");return!(n&&o)}catch{return!0}}async function gp(t,e){return(await Dt.default.readdir(t)).filter(n=>e.test(n)).sort().map(n=>Oe.default.join(t,n))}async function og(t){return(await Promise.all((await gp(t,fp)).map(r=>ct(()=>Dt.default.readFile(r,"utf8"))))).map(r=>r.endsWith(`
|
|
46
45
|
`)?r:r+`
|
|
47
|
-
`).join("")}async function
|
|
48
|
-
`));return r.filter(
|
|
49
|
-
`)}async function
|
|
50
|
-
${a.length} of ${s.length} files were attached before this`)}if(
|
|
51
|
-
`)}async function
|
|
52
|
-
`)
|
|
46
|
+
`).join("")}async function sg(t){let e=await gp(t,rg),r=[];for(let n of e)r.push(...(await Dt.default.readFile(n,"utf8")).split(`
|
|
47
|
+
`));return r.filter(ng).join(`
|
|
48
|
+
`)}async function hp(t){let e=await Dt.default.mkdtemp(Oe.default.join(up.default.tmpdir(),"currents-trace-")),r=()=>Dt.default.rm(e,{recursive:!0,force:!0}),n=Oe.default.join(e,"trace.zip");try{let o=new mp.default.ZipFile;o.addBuffer(Buffer.from(await og(t)),"trace.trace"),o.addBuffer(Buffer.from(await sg(t)),"trace.network");for(let s of["screencast","resources"]){let i=Oe.default.join(t,s);await P(i)&&await le(o,i,s)}await(0,dp.pipeline)(Qe(o),(0,pp.createWriteStream)(n))}catch(o){throw await r(),o}return{zipPath:n,cleanup:r}}var ig=1024**3,Ep=/^\.env($|[._-])|^\.envrc$|\.env$/i,ag=/\.(pem|key)$|^id_(rsa|ed25519|ecdsa|dsa)/i;function cg(t){if(Ep.test(t))throw new Error(`"${t}" looks like an environment file with secrets and is not attached`)}async function po(t,e,r){cg(e);let n=r.type??ao(e,r.allowedTypes);r.type?(cp(e,r.type),ap(e,r.type,r.allowedTypes)):n==="trace"&&!await lp(t)&&(n="attachment");let o=await xe.default.stat(t);if(o.size>ig)throw new Error(`"${e}" is larger than 1 GiB`);if(o.size===0)throw new Error(`"${e}" is empty`);return{path:t,name:e,type:n,contentType:io(e),sizeBytes:o.size}}async function pg(t,e,r){let n=[],o=async s=>{for(let i of await xe.default.readdir(s,{withFileTypes:!0})){let a=Nt.default.join(s,i.name),u=Nt.default.relative(t,a).split(Nt.default.sep).join("/");if(i.name.startsWith("."))I(`Skipping the hidden file "${a}"`);else if(ag.test(i.name)||Ep.test(i.name))I(`Skipping "${a}", which looks like a key or secrets file`);else if(i.isSymbolicLink())I(`Skipping the link "${a}"`);else if(i.isDirectory())await co(a)?await r(a,Nt.default.posix.dirname(u)):await o(a);else if(i.isFile()){if((await xe.default.stat(a)).size===0){I(`Skipping the empty file "${a}"`);continue}n.push(await po(a,u,e))}}};return await o(t),n}async function Ip(t,e){let r=[],n=[],o=async()=>{await Promise.all(n.map(i=>i()))},s=async(i,a=".")=>{let u=await hp(i);n.push(u.cleanup);let p=Nt.default.posix.join(a,`trace-${Me(8)}.zip`);r.push(await po(u.zipPath,p,{...e,type:e.type??ao("trace.zip",e.allowedTypes)}))};try{for(let i of t){let a=await xe.default.stat(i).catch(()=>null);if(!a)throw new Error(`"${i}" does not exist`);if(!a.isDirectory()){r.push(await po(i,Nt.default.basename(i),e));continue}if(await co(i)){await s(i);continue}r.push(...await pg(i,e,s))}}catch(i){throw await o(),i}if(r.length===0)throw new Error("There are no files to attach");return{files:r,cleanup:o}}var Tp={run:["attachment"],instance:["attachment","video","screenshot"],test:["attachment"],attempt:["attachment","video","screenshot","trace"]},Cp=["attachment","video","screenshot","trace"];function yp(t){return t.testId||t.testTitle?t.attempt===void 0?"test":"attempt":t.instanceId||t.spec?"instance":"run"}var Rp=4;async function wp(t){let e=[];for(let r=0;r<t.length;r+=Rp)e.push(...await Promise.all(t.slice(r,r+Rp).map(async({file:n,uploadUrl:o,uploadHeaders:s})=>{try{return await hi({name:n.name,path:n.path,sizeBytes:n.sizeBytes,uploadUrl:o,contentType:n.contentType,headers:s}),{file:n}}catch(i){return{file:n,error:i}}})));return e}var ug=d.extend("files");function dg(t=[]){let e=new Map;for(let r of t){let n=r.indexOf("=");if(n<1)throw new Error(`--meta expects key=value, got "${r}"`);let o=r.slice(0,n);if(!/^[A-Za-z0-9_-]{1,64}$/.test(o))throw new Error(`--meta key "${o}" can only hold up to 64 letters, digits, "_" and "-"`);let s=r.slice(n+1);if(s.length>256)throw new Error(`--meta value of "${o}" is longer than 256 characters`);e.set(o,s)}return e.size>0?Object.fromEntries(e):void 0}function mg(t){if(t!==void 0){if(!ip(t))throw new Error(`--type must be one of trace, screenshot, video, attachment, got "${t}"`);return t}}var lg=50,fg=100*1024**2,_p=200;function gg(t,e={count:lg,bytes:fg}){let r=[],n=0;for(let o of t){let s=r[r.length-1];!s||s.length>=e.count||n+o.sizeBytes>e.bytes?(r.push([o]),n=o.sizeBytes):(s.push(o),n+=o.sizeBytes)}return r}async function uo(t){if(!t.credentials.apiKey&&!t.credentials.recordKey)throw new Error("Pass an API key or a record key");let e=mg(t.type),r=dg(t.meta),n=t.target??{},o="sessionId"in t.owner?Cp:Tp[yp(n)],{files:s,cleanup:i}=await Ip(t.paths,{type:e,allowedTypes:o});if(s.length>_p)throw await i(),new Error(`Found ${s.length} files to attach; the API takes at most ${_p}. Pass the folders or files you need instead`);let a=[],u=[];try{for(let p of gg(s)){let l=p.map(f=>({name:f.name,type:f.type,contentType:f.contentType,sizeBytes:f.sizeBytes,caption:t.caption,meta:r})),m;try{m=await Ns(t.credentials,t.owner,n,l)}catch(f){throw new Error(`${f.message}
|
|
49
|
+
${a.length} of ${s.length} files were attached before this`)}if(ug("Created %d attachments at level %s",m.attachments.length,m.level??"session"),m.attachments.length!==p.length)throw new Error(`The API returned ${m.attachments.length} upload URLs for ${p.length} files`);let h=await wp(p.map((f,O)=>{if(m.attachments[O].name!==f.name)throw new Error(`The API answered "${m.attachments[O].name}" where "${f.name}" was declared`);let{uploadUrl:j,uploadHeaders:Lt}=m.attachments[O];return{file:f,uploadUrl:j,uploadHeaders:Lt}}));for(let f of h)f.error?(T("Failed %s: %s",f.file.name,f.error.message),u.push(f)):(C("Attached %s (%s)",f.file.name,f.file.type),a.push(f.file))}}finally{await i().catch(p=>I("Could not remove temporary files: %s",p.message))}if(u.length>0)throw new Error(`${u.length} of ${s.length} files could not be uploaded`);return{files:a.map(({name:p,type:l,sizeBytes:m})=>({name:p,type:l,sizeBytes:m}))}}var Lr=g(require("fs/promises")),Se=g(require("path")),hg=".currents-session",Op=()=>Se.default.join(process.cwd(),hg,"session.json");async function Eg(t){let e=Se.default.join(t,".gitignore");await P(e)||await Lr.default.writeFile(e,`*
|
|
50
|
+
`)}async function xp(t){let e=Op();await Lr.default.mkdir(Se.default.dirname(e),{recursive:!0}),await Eg(Se.default.dirname(e)),await Lr.default.writeFile(e,JSON.stringify(t,null,2)+`
|
|
51
|
+
`)}async function Ig(){let t=Op();if(!await P(t))return null;let e=await pt(t),r=e?.sessionId||e?.runId;if(typeof r!="string"||!r.trim())return null;let n=typeof e.projectId=="string"?e.projectId:void 0;return{sessionId:r,projectId:n}}async function mo(t){if(t)return t;let e=await Ig();if(!e)throw new Error('No session found. Run "currents session start" first, or pass --session-id');return e.sessionId}var Tg=d.extend("session");async function Cg(){try{let{sha:t,branch:e,message:r,authorName:n,authorEmail:o,remoteOrigin:s}=await Ee();return{sha:t,branch:e,message:r,authorName:n,authorEmail:o,remoteOrigin:s}}catch(t){Tg("No git info: %o",t);return}}function yg(t){if(t)return/^\d+$/.test(t)?{id:t}:{link:t}}function Sp(){let{provider:t,params:e}=ut();return{provider:t,params:e}}function Rg(){if(ut().ciBuildId.source!=="server")throw new Error("The CI build ID is unknown. Pass --ci-build-id or set CURRENTS_CI_BUILD_ID to the value the run was recorded with")}async function Ap(t){let e=await Ds({apiKey:t.apiKey,recordKey:t.recordKey},{projectId:t.projectId,title:t.title,status:t.status,error:t.error,tags:t.tag,commit:await Cg(),ci:Sp(),pr:yg(t.pr)});return await xp({sessionId:e.sessionId,projectId:t.projectId}),t.json?process.stdout.write(JSON.stringify({sessionId:e.sessionId})+`
|
|
52
|
+
`):C("Session started: %s",e.sessionId),e}async function bp(t,e){let r=await mo(t.sessionId);return uo({credentials:{apiKey:t.apiKey,recordKey:t.recordKey},owner:{sessionId:r},paths:e,type:t.type,caption:t.caption,meta:t.meta})}async function Pp(t){let e=await mo(t.sessionId),r=await fn({apiKey:t.apiKey,recordKey:t.recordKey},{sessionId:e,purpose:"report",expiresInDays:t.expiresInDays});return Up(r),r}function Up(t){C(t.pageUrl),C("Markdown: %s",t.url)}async function Dp(t){let{runId:e,instanceId:r,testId:n,attempt:o,purpose:s}=t;for(let[p,l]of[["<run-id>",e],["--instance-id",r],["--test-id",n]])if(l!==void 0&&l.trim()==="")throw new Error(`${p} must not be empty`);if(n&&!r)throw new Error("--test-id needs --instance-id, the spec file of the test");if(o!==void 0&&!n)throw new Error("--attempt needs --test-id");if(o!==void 0&&s!=="fix")throw new Error("--attempt needs --purpose fix: a report holds every attempt");let i={apiKey:t.apiKey},a={runId:e,instanceId:r};if(r&&n){let p=await vs(i,r);if(p.runId!==e)throw new Error(`Instance ${r} belongs to run ${p.runId}, not run ${e}`);a={instanceId:r,testId:n,attempt:o}}let u=await fn(i,{...a,purpose:s,expiresInDays:t.expiresInDays});return Up(u),u}async function Np(t,e){if(t.testTitle&&!t.spec)throw new Error("--test-title needs --spec, the spec file of the test");if(t.attempt!==void 0&&!t.testTitle)throw new Error("--attempt needs --test-title");if(t.group&&!t.spec)throw new Error("--group needs --spec: it picks the spec file of a group");return t.ciBuildId||Rg(),uo({credentials:{apiKey:t.apiKey,recordKey:t.recordKey},owner:t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId}:{projectId:t.projectId,ci:Sp()},target:{spec:t.spec,testTitle:t.testTitle,groupId:t.group,attempt:t.attempt,machineId:t.spec?void 0:t.machineId},paths:e,type:t.type,caption:t.caption,meta:t.meta})}var _=require("@commander-js/extra-typings");var vp=t=>U(M,t),te="(required unless --api-key is set)",ee="(used when --key is not set; needs write access)",Lp=Wt(". Leave it out only if the run was recorded without one, on a CI the reporters recognize"),Bp=new _.Option("--machine-id <id>","the CI machine the files come from; run-level files are listed by machine when it is set").env(vp("machineId")),fo=new _.Option("--session-id <id>",'the session to use instead of the one saved by "session start"').env(vp("sessionId")),Fp=new _.Option("--title <text>","what the session shows, used as the session title (required)"),kp=new _.Option("--status <status>","the result of the session").choices(["passed","failed"]).default("passed"),Mp=new _.Option("--error <text>","what went wrong, for a failed session"),$p=zt("tags to add to the session"),jp=new _.Option("--pr <url|number>","the pull request the session is about; by default taken from the CI environment"),Hp=new _.Option("--json",'print the session ID as JSON on stdout, e.g. {"sessionId": "..."}'),Gp=new _.Option("--spec <spec>","attach to this spec file of the run"),Kp=new _.Option("--test-title <title>",'attach to this test of --spec: the full title joined with " > ", or its last part'),Jp=new _.Option("--group <id>","the group of the spec file; a spec that runs once per Playwright project matches more than once without it");function Vp(t){let e=Number(t);if(!Number.isInteger(e)||e<0)throw new Error("--attempt must be a whole number from 0");return e}var qp=new _.Option("--attempt <n>","attach to this attempt of the test; the first attempt is 0").argParser(Vp),Yp=["trace","screenshot","video","attachment"],Wp="by default taken from the file: a .zip holding trace.trace is a trace; .png, .jpg, .jpeg, .webp and .gif are screenshots; .webm and .mp4 are videos; anything else is an attachment",zp=new _.Option("--type <type>",`the type of every file; ${Wp}`).choices(Yp),Qp=new _.Option("--type <type>",`the type of every file; ${Wp}. The whole run and a test take attachments only, a spec file also takes screenshots and videos, and an attempt (--attempt) takes all four types, including traces. A file of a type its target does not take is attached as an attachment, and a --type the target does not take is an error`).choices(Yp),Br="files or folders to attach. A folder adds every file under it, named by its path in the folder, such as login-chromium/trace.zip, so a Playwright test-results folder attaches in one go; hidden files and folders, links and empty files in it are skipped. A folder of Playwright MCP trace-*.trace files, at the top or inside, is packed into one trace and nothing else in it is attached. At most 200 files, each at most 1 GiB; files named .env or .env.* are refused",Fr=new _.Option("--caption <text>","a short description shown with each file"),wg=(t,e=[])=>[...e,t],kr=new _.Option("--meta <key=value>","a label for each file; repeat for more").argParser(wg),lo=["1","3","7"],Xp=t=>new _.Option("--expires-in-days <days>",t).choices(lo).argParser(e=>{if(!lo.includes(e))throw new _.InvalidArgumentError(`Allowed choices are ${lo.join(", ")}.`);return Number(e)}),Zp=Xp("the number of days the link works").default(7),tu=Xp("the number of days the link works; by default 7 for report and 1 for fix"),eu=new _.Option("--instance-id <id>","one spec file of the run (default: the whole run)"),ru=new _.Option("--test-id <id>","one test of the spec file; needs --instance-id"),nu=new _.Option("--attempt <n>","one attempt of the test, from 0; needs --test-id and --purpose fix (default: the last attempt that failed)").argParser(Vp),ou=new _.Option("--purpose <purpose>",`report: every test with its attempts and files, for a person
|
|
53
|
+
fix: the failure context, for an agent fixing the tests`).choices(["report","fix"]).default("report");var gu=require("@commander-js/extra-typings");var Ct=require("@commander-js/extra-typings");var su=new Ct.Option("--ci-build-id <id>","the CI build ID to record the run with; by default taken from the CI environment, or a random value").env(U(tt,"ciBuildId")),iu=zt("tags to add to the run").env(U(tt,"tag")),au=new Ct.Option("--remove-title-tags","remove tags from test names in Currents, e.g. `Test name @smoke` becomes `Test name` in the dashboard").env(U(tt,"removeTitleTags")).default(!1),cu=new Ct.Option("--disable-title-tags","do not read tags from test names, e.g. `Test name @smoke` is not tagged with `smoke` in the dashboard").env(U(tt,"disableTitleTags")).default(!1),pu=new Ct.Option("--environment <name>","the environment to label the run with, e.g. staging").env(U(tt,"environment")),uu=new Ct.Option("--machine-id <id>","the ID of the machine that ran the tests; by default a random value").env(U(tt,"machineId")),du=new Ct.Option("--fail-on-failures","exit with 1 when a test failed, after the results are uploaded; a test quarantined or skipped by a Currents action does not count").env(U(tt,"failOnFailures")).default(!1),mu=new Ct.Option("--report-dir <folder>","the folder of the reports to upload; by default the newest folder in .currents").env(U(tt,"reportDir"));var ho=require("path");var lu=g(require("fs"));var go=d.extend("cli"),Mr=class{constructor(e){this.configFilePath=null;this.cliOptions=e,go("CLI options: %o",E(this.cliOptions)),this.parsedConfig=Vi(this.cliOptions),go("Parsed config from CLI options: %o",E(this.parsedConfig))}async getConfigFilePath(){if(this.configFilePath)return this.configFilePath;let e=await Be();return lu.default.writeFileSync(e,JSON.stringify(this.parsedConfig)),go("CLI options temp file path: %s",e),this.configFilePath=e,e}};async function fu(t){await R(async e=>{let r=e.inputFormat?await _g(e):e.reportDir,n=new Mr({...e,reportDir:r});Ji(n.parsedConfig);let o=er();C("Currents config: %o",E(o)),await jn()},t)}async function _g({inputFormat:t,inputFile:e,framework:r,frameworkVersion:n,outputDir:o,reportDir:s,debug:i}){if(o&&s&&(0,ho.resolve)(o)!==(0,ho.resolve)(s))throw new Error("--output-dir and --report-dir name different folders. With --input-format, the converted reports are saved to one folder and uploaded from it: pass one of the two options.");return ro({inputFormat:t,inputFile:e,framework:r,frameworkVersion:n,outputDir:o??s,debug:i})}var vt="upload",Og="(required with --input-format)",Ae="run",re=t=>[{comment:"Upload test results to Currents",commands:[`${t} ${Ae} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Convert JUnit XML reports to the Currents format, then upload them",commands:[`${t} ${Ae} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id> --input-format junit --input-file "./*.xml" --framework postman`]},{comment:'Upload test results and add the tags "tagA" and "tagB" to the run',commands:[`${t} ${Ae} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id> --tag tagA --tag tagB`]},{comment:"Upload test results, then fail if a test failed that no Currents action quarantined or skipped",commands:[`${t} ${Ae} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id> --fail-on-failures`]},{comment:"Upload test results from another folder",commands:[`${t} ${Ae} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id> --report-dir <report-dir>`]}],$r=t=>new gu.Command().name(vt).command(vt).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Upload test results of Currents reporters or JUnit").description(`Upload test results created by Currents reporters to https://currents.dev
|
|
53
54
|
|
|
54
55
|
With --input-format, first convert the reports in --input-file to the Currents
|
|
55
56
|
format, then upload the converted reports. They are saved to --output-dir, or
|
|
56
57
|
--report-dir, or a new folder in .currents. A folder you name may hold only the
|
|
57
|
-
reports being converted.`).addHelpText("after",y(
|
|
58
|
+
reports being converted.`).addHelpText("after",y(re(t))).addOption(su).addOption(G()).addOption(it()).addOption(iu).addOption(au).addOption(cu).addOption(pu).addOption(uu).addOption(du).addOption(N()).addOption(mu).addOption(Cr()).addOption(yr(Og)).addOption(wr("(required with --input-format junit)")).addOption(_r).addOption(Rr).action(r=>fu(r));var jr="run",Gr=t=>[{comment:"Attach the Docker logs of a CI machine to the run, after the tests finished",commands:[`${t} ${jr} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --machine-id shard-1 docker-logs.zip`]},{comment:"Attach a screenshot to the first attempt of a test",commands:[`${t} ${jr} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --spec tests/cart.spec.ts --test-title "adds an item" --attempt 0 screenshot.png`]}],xg=t=>new Hr.Command().name("attach").addHelpText("after",y(Gr(t))).description("Upload files to a run recorded in CI").argument("<paths...>",Br).addOption(G(te)).addOption(st(ee)).addOption(it()).addOption(Lp).addOption(Bp).addOption(Gp).addOption(Jp).addOption(Kp).addOption(qp).addOption(Qp).addOption(Fr).addOption(kr).addOption(N()).action(async(e,r)=>{await R(async({key:n,...o})=>{await Np(ep({...o,recordKey:n}),e)},r)}),hu=t=>{let e=`${t} ${jr} share <run-id>`,r=`${e} --instance-id <instance-id> --test-id <test-id> --purpose fix`;return[{comment:"Share a whole run with a reviewer or a colleague outside Currents",commands:[e]},{comment:"Give an agent the failures of a whole run",commands:[`${e} --purpose fix`]},{comment:"Share one spec file, e.g. the copy that ran in the firefox group",commands:[`${e} --instance-id <instance-id>`]},{comment:"Give an agent one failing test (its last failed attempt)",commands:[r]},{comment:"Give an agent one specific attempt of a test",commands:[`${r} --attempt 0`]}]},Sg=t=>new Hr.Command().name("share").usage("<run-id> [options]").summary("Print a public link to a run, a spec file or a test").description('Create a public link to a run, or to one spec file or test of it, and print it. The second line, "Markdown: <url>", is the same content as Markdown, for agents').addHelpText("after",y(hu(t))).argument("<run-id>","the run to share").addOption(eu).addOption(ru).addOption(nu).addOption(ou).addOption(tu).addOption(st("(required; needs write access)")).addOption(N()).action(async(e,r)=>{await R(async n=>{await Dp(rp({...n,runId:e}))},r)}),Eu=t=>new Hr.Command().name(jr).summary("Upload results, attach files, get, share or cancel a run").description("Upload test results to a run, attach files to it, get its data, share a link to it or cancel it").addHelpText("after",y([...re(t).slice(0,2),Gr(t)[0],Vn(t)[0],hu(t)[0],Ce(t)[0]])).showHelpAfterError("(add --help for additional information)").addCommand($r(t)).addCommand(xg(t)).addCommand(qn(t)).addCommand(Sg(t)).addCommand(Tr(t));var be=require("@commander-js/extra-typings");var Kr="session",ne=t=>{let e=`${t} ${Kr} start --api-key <api-key> --project-id <id> --title "Checkout fails on empty cart" --status failed`,r=`${t} ${Kr} attach before.png .playwright-mcp/traces`,n=`${t} ${Kr} share --expires-in-days 7`;return{session:[{comment:"Start a session, attach what you captured and get a link to share",commands:[e,r,n]}],start:[{comment:"Start a session for a failed check",commands:[e]}],attach:[{comment:"Attach a screenshot and a Playwright MCP trace folder",commands:[r]}],share:[{comment:"Print a link that expires in 7 days",commands:[n]}]}},Ag=t=>new be.Command().name("start").addHelpText("after",y(ne(t).start)).summary("Create a session").description('Create a session and save its ID to .currents-session/session.json in the current folder, where "attach" and "share" read it').addOption(G(te)).addOption(st(ee)).addOption(it()).addOption(Fp).addOption(kp).addOption(Mp).addOption($p).addOption(jp).addOption(Hp).addOption(N()).action(async e=>{await R(async({key:r,...n})=>{n.json&&Jt(),await Ap(Xc({...n,recordKey:r}))},e)}),bg=t=>new be.Command().name("attach").summary("Upload screenshots, traces and other files").addHelpText("after",y(ne(t).attach)).description("Upload files, folders or a Playwright MCP trace folder to the session").argument("<paths...>",Br).addOption(G(te)).addOption(st(ee)).addOption(fo).addOption(zp).addOption(Fr).addOption(kr).addOption(N()).action(async(e,r)=>{await R(async({key:n,...o})=>{await bp(Zc({...o,recordKey:n}),e)},r)}),Pg=t=>new be.Command().name("share").addHelpText("after",y(ne(t).share)).summary("Print a public link to the session page").description('Create a public link to the session page and print it. The second line, "Markdown: <url>", is the address of the same content as Markdown, for agents').addOption(G(te)).addOption(st(ee)).addOption(fo).addOption(Zp).addOption(N()).action(async e=>{await R(async({key:r,...n})=>{await Pp(tp({...n,recordKey:r}))},e)}),Iu=t=>new be.Command().name(Kr).summary("Capture agent or browser sessions as evidence").description("Capture ad-hoc, one-off agent or browser sessions as evidence: a bug before and after a fix, or proof that something works. Create a session, attach screenshots, traces, videos and other files to it, and print a link to share it.").addHelpText("after",y(ne(t).session)).showHelpAfterError("(add --help for additional information)").addCommand(Ag(t)).addCommand(bg(t)).addCommand(Pg(t));var se=require("@commander-js/extra-typings");var yt=g(require("fs/promises")),W=g(require("path"));var ft="currents-cli",oe=W.default.join(".agents","skills");function Tu(t=__dirname){let e=W.default.join("skills",ft),r=ke(W.default.join(e,"SKILL.md"),t);if(!r)throw new Error(`The ${ft} skill is missing from this package`);return W.default.join(r,e)}async function Eo(t,e=""){let r=[];for(let n of await yt.default.readdir(W.default.join(t,e),{withFileTypes:!0})){let o=W.default.join(e,n.name);n.isDirectory()?r.push(...await Eo(t,o)):r.push(o)}return r.sort()}async function Ug(t,e){let[r,n]=await Promise.all([Eo(t),Eo(e)]);if(r.join(`
|
|
58
59
|
`)!==n.join(`
|
|
59
|
-
`))return!1;for(let o of r){let[s,i]=await Promise.all([
|
|
60
|
+
`))return!1;for(let o of r){let[s,i]=await Promise.all([yt.default.readFile(W.default.join(t,o)),yt.default.readFile(W.default.join(e,o))]);if(!s.equals(i))return!1}return!0}async function Cu(){await pe(await yt.default.readFile(W.default.join(Tu(),"SKILL.md"),"utf8"))}async function yu({dir:t=oe,force:e=!1}){let r=Tu(),n=W.default.resolve(t,ft),o=W.default.relative(process.cwd(),n)||".";if(await P(n)){if(!(await yt.default.stat(n)).isDirectory())throw new Error(`${o} exists and is not a folder`);if(await Ug(r,n))return C("The %s skill is already in %s",ft,o),n;if(!e)throw new Error(`${o} exists and differs from the skill of this version. Pass --force to replace it`);await yt.default.rm(n,{recursive:!0,force:!0})}return await yt.default.cp(r,n,{recursive:!0,verbatimSymlinks:!0}),C("Wrote the %s skill to %s",ft,o),n}var Jr="skill",Dg=t=>[{comment:"Print the skill",commands:[`${t} ${Jr}`]},{comment:`Add the skill to the project, in ${oe}/${ft}`,commands:[`${t} ${Jr} --install`]},{comment:"Add the skill for Claude Code",commands:[`${t} ${Jr} --install --dir .claude/skills`]}],Ru=t=>new se.Command().name(Jr).summary("Print or install the agent skill for this CLI").description(`Print SKILL.md of the ${ft} skill, which tells coding agents how to use this CLI, or install the skill in the project.
|
|
60
61
|
|
|
61
62
|
Agents read project skills from these folders:
|
|
62
|
-
Codex, Cursor ${
|
|
63
|
-
Claude Code .claude/skills`).addHelpText("after",y(
|
|
63
|
+
Codex, Cursor ${oe}
|
|
64
|
+
Claude Code .claude/skills`).addHelpText("after",y(Dg(t))).addOption(new se.Option("--install",`write the skill folder to <dir>/${ft}`)).addOption(new se.Option("--dir <path>","the skills folder to install to").default(oe)).addOption(new se.Option("--force","replace an installed copy of the skill that differs from this version")).action(async e=>{await R(async r=>{if(!r.install&&(r.force||r.dir!==oe))throw new Error("--dir and --force work with --install only");r.install?await yu({dir:r.dir,force:r.force}):await Cu()},e)});var A="currents",_u=()=>{let t=$r(A),e=new wu.Command(A).version(Bt).description("Currents CLI: upload test results and files to Currents, get, share and cancel runs, capture agent or browser sessions as evidence, and cache files between CI jobs").showHelpAfterError(`(run '${A} --help' for usage)`).enablePositionalOptions().hook("preAction",(i,a)=>{Fs(a),ks(a)}).addCommand(t,{hidden:!0}).addCommand(qc(A),{hidden:!0}).addCommand(Tr(A,{deprecated:!0}),{hidden:!0}).commandsGroup("Test runs:").addCommand(Eu(A)).commandsGroup("Evidence:").addCommand(Iu(A)).commandsGroup("CI utilities:").addCommand(hc(A)).commandsGroup("Other:").addCommand(lc(A)).addCommand(Qc(A)).addCommand(Ru(A)).helpCommand(!0).addHelpText("after",`${y([re(A)[0],re(A)[1],hr(A)[1],Er(A)[1],Ce(A)[0],Gr(A)[0],...ne(A).session])}
|
|
64
65
|
Run '${A} <command> --help' for the options and examples of a command.
|
|
65
66
|
|
|
66
67
|
Agent skill: ${A} skill --install
|
|
67
68
|
Documentation: https://docs.currents.dev
|
|
68
69
|
Support: support@currents.dev
|
|
69
70
|
`),r=`upload is no longer the default command. Run '${A} run upload ...' instead.`,n=t.options.flatMap(i=>[i.long,i.short]),o=e,s=o.unknownOption.bind(e);return o.unknownOption=i=>{if(!n.includes(i.split("=")[0]))return s(i);e.error(r)},e.addHelpText("before",({error:i})=>i&&(process.env.CURRENTS_RECORD_KEY||process.env.CURRENTS_PROJECT_ID)?`error: ${r}
|
|
70
|
-
`:""),e};
|
|
71
|
+
`:""),e};function Ng(){_u().parse()}Ng();
|
|
71
72
|
/*! For license information please see index.js.LEGAL.txt */
|
|
72
73
|
//# sourceMappingURL=index.js.map
|