@testim/testim-cli 4.136.0 → 4.137.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/cli.js +1 -1
- package/cli.js.map +2 -2
- package/npm-shrinkwrap.json +202 -211
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ Testim had missing write access to ${r||e}
|
|
|
13
13
|
- installed where chromedriver expects it (see https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver#requirements).
|
|
14
14
|
- exists in your PATH environment variables.
|
|
15
15
|
3. Try adding --chrome-binary-location flag to Testim CLI specifying the exact location of chrome binary in your computer (e.g on Windows "C:/Program Files/Google/Chrome/Application/chrome.exe").
|
|
16
|
-
4. You can always use a standalone Selenium grid and providing it's details with the --host and --port flags (see https://www.npmjs.com/package/selenium-standalone)`)),n.fail(a),o}}async function jw(){let s=`${Os}/extension/sessionPlayer_LATEST_RELEASE`;return(await Mt(s)).body.toString("utf8")}async function $w(s,e){if(!ke(s)||ke(s)&&e||$e)return s;let t=await jw();return`${s}-${t}`}function Xc(){let s=mt();return Xr.resolve(s,"testim-bin")}function Ww(){let s=Xc();return Xr.resolve(s,"sessionPlayer.zip")}async function Wm(s,e,t=!1){try{return await Ti(s,e),await st(e,Xc())}catch(r){if(t)throw r;return await Wm(s,e,!0)}}async function hr(s,e){Ui.info("prepare player",{location:s,canary:e});let t=Ww();return Ft(async()=>{let r=await $w(s,e);return await Wm(r,t),{}},"preparePlayer",$m,[s,e,t])()}var Fm,Bm,Xr,jm,Ui,$m,Kc,Um,Zs=w(()=>{"use strict";Fm=I(require("ms")),Bm=I(require("fs")),Xr=I(require("path"));de();Kt();jm=require("serialize-error");W();jc();Y();F();Ui=C("prepare runner and testim start"),$m=(0,Fm.default)("0.5 day"),Kc=16,Um=`The size of the custom extension is more than ${Kc}MB`});function Vw(){let s=en.type().toLowerCase();return s==="darwin"?en.arch()==="arm"?"mac_arm":"mac":s==="windows_nt"?en.arch()==="x64"?"win64":"win32":"linux"}async function Bi(){let s=Vw(),e="https://storage.googleapis.com/chromium-browser-snapshots",t={linux:"Linux_x64",mac:"Mac",mac_arm:"Mac_Arm",win32:"Win",win64:"Win_x64"};if(!(s in t))throw new x(`Unsupported platform: ${s}`);let r=parseInt(tn,10)>591479?"chrome-win":"chrome-win32",n={linux:"chrome-linux",mac:"chrome-mac",mac_arm:"chrome-mac",win32:r,win64:r},i={linux:"chrome",mac:"Chromium.app/Contents/MacOS/Chromium",mac_arm:"Chromium.app/Contents/MacOS/Chromium",win32:"chrome.exe",win64:"chrome.exe"},o=`${e}/${t[s]}/${tn}/${n[s]}.zip`,a=Fi.join(Qc,n[s]),l=`${a}.zip`,c=Fi.join(a,i[s]);if(await he(c))return c;if(!await he(l)){let m=(0,Zc.default)("Downloading Chromium").start();try{await Vm.promises.mkdir(Qc),await Ke(o,l)}catch(u){let f=`Failed to download Chromium: ${u.message}`;throw m.fail(f),new Error(f)}m.succeed()}let d=(0,Zc.default)("Extracting Chromium").start();try{await st(l,Qc)}catch(m){let u=`Failed to extract Chromium: ${m.message}`;throw d.fail(u),new Error(u)}return d.succeed(),c}var Vm,en,Fi,Zc,tn,Qc,el=w(()=>{"use strict";Vm=I(require("fs")),en=I(require("os")),Fi=I(require("path")),Zc=I(require("ora"));Y();F();tn="1000968",Qc=Fi.join(Ut,`chrome-${tn}`)});async function qm(s,e){return yr=s,nl=e,await tl()}function zm(s,e){yr=e.projectId,nl=e.token,rn=e.userAccessKey,nt=s.token,nn=il(nt),on=s.refreshToken,rl=s.ngrokToken,sl=s.isNgrokWhitelisted,Gm=e.publicIp,Hm=e.initializedFromCache}function Hw(s=yr,e=nl){return Ft(()=>(sn.info("request to get cli token from server"),We({url:`${fe}/auth/token`,body:{projectId:s,token:e}})),"getTokenV3",Gw*10,{projectId:s,token:e})()}async function qw(){sn.info("request to refresh JWT cli token from server");let s=await We({url:`${fe}/auth/refreshToken`,body:{token:nt,refreshToken:on}});return nt=s.token,nn=il(nt),s.refreshToken&&(on=s.refreshToken),nt}async function tl(){try{let s=await Hw();return sn.info("successfully get cli token from server"),nt=s.token,nn=il(nt),on=s.refreshToken,rl=s.ngrokToken,sl=s.isNgrokWhitelisted,nt}catch(s){throw s.message.includes("Unauthorized")?new x("Error trying to retrieve CLI token. Your CLI token and project might not match. Please make sure to pass `--project` and `--token` that match to each other or make sure they match in your ~/.testim file."):(sn.error(`While trying to retrieve CLI token. caught error: ${s}`,{projectId:yr}),new x(`While trying to retrieve CLI token, caught error: ${s}`))}}function il(s){return require("jsonwebtoken").decode(s).exp*1e3}async function Rt(){if(!nn)return tl();let s=O.flags.accessTokenExpiryMargin.getValue();if(nn<Date.now()+4*s)try{return await qw()}catch(e){return sn.error("failed to refresh token, executing fallback",e),tl()}return nt}function ji(){return on}function br(){return nt?{uid:require("jsonwebtoken").decode(nt).id,ngrokToken:rl,isNgrokWhitelisted:sl}:{}}async function $i(){if(!rn||!yr)return;if(await ol({userAccessKey:rn,projectId:yr}))return rn;let e=`user access key "${rn}" is invalid for project "${yr}"`;throw new x(e)}function Wi(){return Gm}function Vi(){return Hm}var sn,nt,nn,on,rl,sl,yr,nl,rn,Gm,Hm,Gw,it=w(()=>{"use strict";de();Ve();Kt();Y();W();ge();le();sn=C("testim-custom-token"),yr=null,nl=null,Gw=5*60*1e3});var Km={};H(Km,{isCi:()=>Qr});var Qr,Gi=w(()=>{"use strict";Qr=Boolean(process.env.CI||process.env.CONTINUOUS_INTEGRATION||process.env.BUILD_NUMBER||process.env.RUN_ID||!1)});var Re={};H(Re,{addTestRetry:()=>kl,clearTestResult:()=>xl,deleteCloudflareTunnel:()=>Dl,fetchLambdatestConfig:()=>Il,fixGridAppIDStructure:()=>Fl,forceUpdateCloudflareTunnelRoutes:()=>Ll,getAllGrids:()=>Sl,getAppDetails:()=>un,getApplitoolsIntegrationData:()=>_l,getBrowserStackSessionMetaData:()=>rv,getCloudflareTunnel:()=>Ol,getEditorUrl:()=>Zw,getGridSlot:()=>vl,getHybridGridProvider:()=>wl,getLabFeaturesByProjectId:()=>Rl,getMobileDevicesFromGrid:()=>Nl,getRealData:()=>Al,getS3Artifact:()=>cn,getS3ArtifactText:()=>ll,getSuiteTestList:()=>gl,getTestPlan:()=>Qw,getTestPlanTestList:()=>fl,getTestResults:()=>wr,getUsageForCurrentBillingPeriod:()=>hl,initializeUserWithAuth:()=>El,isTestResultCompleted:()=>yl,keepAliveCompanySlots:()=>Wl,keepAliveGrid:()=>bl,loadSfdcCredential:()=>ul,loadTest:()=>ln,releaseCompanySlot:()=>jl,releaseGridSlot:()=>Tl,reportExecutionFinished:()=>Hi,reportExecutionStarted:()=>ml,requestCompanySlot:()=>Bl,saveRemoteStep:()=>Cl,saveTestPlanResult:()=>pl,updateCompanySlot:()=>$l,updateExecutionTests:()=>dl,updateRemoteRunFailure:()=>Ml,updateTestDataArtifact:()=>zi,updateTestResult:()=>qi,updateTestStatus:()=>Tr,uploadAppToGrid:()=>Ul,uploadRunDataArtifact:()=>Pl,validateUserAccessKey:()=>ol});async function Zr(){let s=await Rt();if(!s)throw new Error("Failed to get token from server");return{Authorization:`Bearer ${s}`}}async function Se({url:s,body:e,headers:t={},timeout:r,retry:n}){let i=await Zr(),o={...t,...i};return We({url:`${fe}${s||""}`,body:e,headers:o,timeout:r,retry:n})}async function Jw(s,e,t,r={},n=void 0){let i=await Zr(),o={...r,...i};return await Bs(`${fe}${s||""}`,e,t,o,n)}async function an(s,e){let t=await Zr();return await wc(`${fe}${s||""}`,e,t)}async function Yw(s,e){let t=await Zr();return await Fs(`${fe}${s||""}`,e,t)}async function Xw(s,e){let t=await Zr();return await js(`${fe}${s||""}`,e||void 0,t)}async function Ie(s,e,t,r){let n=await Zr();return await be(`${fe}${s||""}`,e||void 0,n,r,t)}function cn(s,e){return(0,Z.default)(()=>Ie(`/storage${s}`,null,{isBinary:!0},e),{retries:te,factor:1})}function ll(s){return(0,Z.default)(()=>Xw(`/storage${s}`))}async function Qw(s,e){let t=n=>n==null?[]:typeof n=="string"&&JSON.parse(n)||n;return(await(0,Z.default)(()=>Ie("/testPlan",{projectId:s,name:e.join(",")}),{retries:te,factor:1})).map(({testConfigIds:n,beforeAllLabels:i,testLabels:o,afterAllLabels:a,...l})=>Object.assign(l,{testConfigIds:t(n),beforeAllLabels:t(i),testLabels:t(o),afterAllLabels:t(a)}))}async function ul({branch:s,projectId:e}){let t=await(0,Z.default)(()=>Ie(`/branch/branchData/${encodeURIComponent(s)}`,{projectId:e}),{retries:te,factor:1});return t==null?void 0:t.sfdcCredential}function ln({testId:s,branch:e,projectId:t,skipSharedSteps:r=!1,useBranchMap:n=!0}){return(0,Z.default)(()=>Ie(`/test/${s}`,{projectId:t,branch:e,skipSharedSteps:r,useBranchMap:n}),{retries:te,factor:1})}function pl(s,e,t){return(0,Z.default)(()=>Se({url:"/testPlan/result",body:{projectId:s,testPlanId:e,result:t}}),{retries:te,factor:1})}function Tr(s,e,t,r,n,i,o=te){return(0,Z.default)(()=>an("/result/run/test",{runId:e,testId:t,resultId:r,status:n,projectId:s,runnerVersion:zw,...i}),{retries:o,factor:1})}function dl(s,e,t,r,n,i,o,a){return(0,Z.default)(()=>an("/result/run/tests",{runId:s,runnerStatuses:e,status:t,reason:r,success:n,startTime:i,endTime:o,projectId:a}),{retries:te,factor:1})}async function ml({executionId:s,projectId:e,labels:t,startTime:r,executions:n,config:i,resultLabels:o,remoteRunId:a,localRunUserId:l,isLocalRun:c,intersections:d}){let{isCi:m}=await Promise.resolve().then(()=>(Gi(),Km));return Se({timeout:9e4,url:"/result/run",body:{runId:s,projectId:e,labels:t,startTime:r,execution:n,status:"RUNNING",config:i,resultLabels:o,remoteRunId:a,intersections:d,metadata:{isCiRun:m,localRunUserId:l,isLocalRun:c}},retry:3})}function Hi(s,e,t,r,n={},i=void 0,o=void 0){let a=Date.now();return(0,Z.default)(()=>an("/result/run",{runId:e,projectId:t,endTime:a,status:s,success:r,tmsOptions:n,remoteRunId:i,resultExtraData:o}),{retries:te,factor:1})}async function fl(s,e,t,r,n){return(0,Z.default)(()=>Se({url:"/testPlan/list",body:{projectId:s,names:e,planIds:t,branch:r,intersections:n},timeout:12e4}),{retries:te,factor:1})}function gl({projectId:s,labels:e,testIds:t,testNames:r,testConfigNames:n,suiteNames:i,suiteIds:o,branch:a,rerunFailedByRunId:l,testConfigIds:c,intersections:d}){return(0,Z.default)(()=>Se({url:"/suite/v2/list",body:{projectId:s,labels:e,testIds:t,testNames:r,testConfigNames:n,suiteNames:i,suiteIds:o,branch:a,rerunFailedByRunId:l,testConfigIds:c,intersections:d}}),{retries:te,factor:1})}async function un({appId:s,projectId:e}){try{return await(0,Z.default)(()=>Ie(`/mobile-app/app/${s}?projectId=${e}`),{retries:te,factor:1})}catch(t){throw new Error(`Could not load app with the ID ${s}`,{cause:t})}}async function hl(s){try{return await(0,Z.default)(()=>Ie(`/plan/project/${s}/usage-current-billing-period`),{retries:te,factor:1})}catch(e){At.error("failed getting usage for current billing period",{projectId:s,error:e});return}}function yl(s,e,t){return(0,Z.default)(()=>Ie(`/result/${s}/isComplete`,{projectId:e,testRetryKey:t}),{retries:te,factor:1})}function wr(s,e,t,r){return(0,Z.default)(()=>Ie(`/test/v2/${s}/result/${e}`,{projectId:t,branch:r}),{retries:te,factor:1})}function bl(s,e){return Se({url:`/grid/keep-alive?reqId=${re()}`,body:{projectId:s,slots:e},timeout:1e4})}function Tl(s,e,t,r,n){return Se({url:`/grid/release?reqId=${re()}`,body:{companyId:s,projectId:e,slotId:t,gridId:r,browser:n}})}function wl(s){return Se({url:"/grid/hybrid/provider",body:s})}function vl(s){return(0,Z.default)(()=>Ie("/grid/grid-slot",{...s,reqId:re()}),{retries:te,factor:1})}async function El({projectId:s,token:e,branchName:t,lightweightMode:r,localGrid:n,publicIp:i,gridId:o,grid:a,clientCliVersion:l,clientNodeVersion:c,clientNpmVersion:d}){var m,u;try{return await(0,Z.default)(()=>We({url:`${fe}/executions/initialize`,body:{projectId:s,token:e,branchName:t||"master",lightweightMode:r,localGrid:n,publicIp:i,gridId:o,gridName:a,clientCliVersion:l,clientNodeVersion:c,clientNpmVersion:d}}),{retries:te,factor:1})}catch(f){if(At.error("error initializing info from server",f),(m=f.message)!=null&&m.includes("Bad Request"))throw new x("Error trying to retrieve CLI token. Your CLI token and project might not match. Please make sure to pass `--project` and `--token` that match to each other or make sure they match in your ~/.testim file.");if((u=f.code)!=null&&u.includes("ENOTFOUND"))throw new x("Due to network connectivity issues, Testim CLI has been unable to connect to the Testim backend.");if(f.text)try{let h=JSON.parse(f.text),g=h.clientMessage.color||"red",y=h.clientMessage.bgColor||"bgBlack";console.log(al.default[y](al.default[g](h.clientMessage.text))),h.exitCode&&process.exit(h.exitCode)}catch{At.error("Error parsing error message from server",f)}throw f}}async function Zw(){if(_s)return{editorUrl:_s};try{return await(0,Z.default)(()=>Ie("/system-info/editor-url"),{retries:te,onFailedAttempt:s=>{if(s.attemptNumber>=te)throw s},factor:1})}catch(s){return At.error("cannot retrieve editor-url from server",{err:s}),{editorUrl:"https://app.testim.io"}}}function Sl(s){return(0,Z.default)(()=>Ie("/grid",{companyId:s}),{retries:te,factor:1})}function Al(s,e,t){return(0,Z.default)(()=>Ie(`/real-data/${e}?${t}&projectId=${s}`),{retries:te,factor:1})}function qi(s,e,t,r,n){return(0,Z.default)(()=>Se({url:"/result/test",body:{projectId:s,resultId:e,testId:t,testResult:r,remoteRunId:n}}),{retries:te,factor:1})}function xl(s,e,t,r){return(0,Z.default)(()=>Se({url:"/result/test/clear",body:{projectId:s,resultId:e,testId:t,testResult:r}}),{retries:te,factor:1})}function Cl(s,e,t,r){return(0,Z.default)(()=>Se({url:"/remoteStep",body:{projectId:s,resultId:e,stepId:t,remoteStep:r}}),{retries:te,factor:1})}function ev(s){return s.startsWith("/")?s:`/${s}`}function tv(s,e,t){let r=ev(s);return t&&(r=`/${t}${r}`),e&&(r=`/${e}${r}`),r}async function Ym(s,e,t,r,n,i="application/octet-stream"){let o=null;i==="application/json"&&(o=".json");let a=`${n}_${re()}${o||""}`,l=`${e}/${t}/${a}`,c=tv(l,Id,s),d=Buffer.from(Jm.gzip(r,{level:3})),m={file:{fileName:a,buffer:d}};return await(0,Z.default)(()=>Jw(`/storage${c}`,{},m,{"X-Asset-Encoding":"gzip"}),{retries:te,factor:1}),c}function kl({projectId:s,runId:e,testId:t,newResultId:r,originalTestResultId:n,previousTestResultId:i,testResult:o}){return(0,Z.default)(()=>Se({url:"/result/test/retry",body:{projectId:s,newResultId:r,originalTestResultId:n,previousTestResultId:i,testId:t,runId:e,testResult:o}}),{retries:te,factor:1})}async function _l(s){try{return await Ie(`/integration/applitools/v3/connected?projectId=${s}`)}catch(e){return At.warn("could'nt get applitools integration data.",{err:e}),{}}}async function Ol(s,e){try{return await an("/tunnel",{companyId:s,routes:e})}catch(t){return At.warn("could'nt get tunnel.",{err:t}),{}}}async function Ll(s,e){try{return await Se({url:`/tunnel/${e}`,body:{companyId:s}})}catch(t){At.warn("could'nt get tunnel.",{err:t});return}}async function Dl(s,e){try{return await Yw(`/tunnel/${e}`,{companyId:s})}catch(t){At.warn("could'nt get tunnel.",{err:t});return}}function Ml(s){return We({url:`${fe}/result/remoteRunFailure`,body:s})}async function Nl({projectId:s,projectType:e,gridId:t,companyId:r,selectors:n}){let i=`${Kw}/mobileDevices/${t}/${r}?projectType=${e}`;i=n?`${i}&selectors=${encodeURIComponent(n)}`:i;try{return await(0,Z.default)(()=>Ie(i,{projectId:s}),{retries:te,factor:1})}catch(o){return At.warn("could'nt get devices from headspin grid.",{err:o}),null}}async function Ul({projectId:s,gridId:e,app:t,timeout:r}){return(0,Z.default)(()=>Se({url:`/mobile-app/app/upload-to-grid?projectId=${s}&gridId=${e}`,body:t,timeout:r}),{retries:te,factor:1})}async function Fl(s){return(0,Z.default)(()=>Se({url:"/mobile-app/app/fix-grid-app-id",body:s}),{retries:te,factor:1})}async function Bl(s,e){return(0,Z.default)(()=>Se({url:"/slot-management/request-slot",body:{companyId:s,projectId:e}}),{retries:te,factor:1})}async function jl(s,e,t){return(0,Z.default)(()=>Se({url:"/slot-management/release-slot",body:{companyId:s,projectId:e,slotId:t}}),{retries:te,factor:1})}async function $l(s,e,t){return(0,Z.default)(()=>an("/slot-management/update-slot",{slotId:t.slotId,companyId:s,projectId:e,slot:t}),{retries:te,factor:1})}function Wl(s,e,t){return Se({url:`/slot-management/keep-alive?reqId=${re()}`,body:{slots:t,companyId:s,projectId:e},timeout:1e4})}async function rv(s,e){return await be(`${Ls}/sessions/${s}`,void 0,{Authorization:`Basic ${Buffer.from(`${e.user}:${e.key}`).toString("base64")}`})}async function ol(s){try{return await Ie("/v2/project/validateUserAccessKey",s),!0}catch(e){return At.error("error validating user access key",{error:e}),!1}}var al,Xt,Jm,Z,cl,zw,At,te,Kw,Il,Rl,Pl,zi,ge=w(()=>{"use strict";al=I(require("chalk")),Xt=I(require("lodash")),Jm=I(require("pako"));F();de();ne();Ve();it();Z=I(require("p-retry")),cl=I(require("object-hash"));Y();W();zw=qe(),At=C("testim service api"),te=3,Kw="/grid";Il=async()=>(0,Z.default)(()=>Ie("/grid/lt/config"),{retries:te,factor:1}),Rl=async s=>(0,Z.default)(()=>Ie(`/labFeature/v2/project/${s}`),{retries:te,factor:1});Pl=Xt.memoize(async(s,e,t,r)=>{if(!Xt.isEmpty(r))return await Ym(s,e,t,JSON.stringify(r),"test-run-data","application/json")},(s,e,t,r)=>`${(0,cl.default)(r)}:${e}:${t}`),zi=Xt.memoize(async(s,e,t,r,n)=>!r||Xt.isEmpty(r)?void 0:await Ym(s,e,t,JSON.stringify((()=>{let o=Xt.clone(r);if(n!=null&&n.hiddenParams){let{hiddenParams:a}=n;(a||[]).forEach(l=>{o[l]&&Object.assign(o,{[l]:Pc.HIDDEN_PARAM})})}return o})()),"test-test-data","application/json"),(s,e,t,r)=>`${(0,cl.default)(r)}:${e}:${t}`)});async function Xm(){let s=await Promise.any(sv.map(async e=>{try{return await be(e)}catch{return null}}));return s==null?void 0:s.ip}var sv,Qm=w(()=>{"use strict";Ve();sv=["https://api.ipify.org?format=json","https://ipinfo.io/json","https://api.my-ip.io/ip.json"]});function Ki(){return qe()}var Vl=w(()=>{"use strict";F()});var Qt={};H(Qt,{getSessionPlayer:()=>X,options:()=>Hl});var Ji,Hl,Gl,X,Te=w(()=>{"use strict";Ji=require("path");W();Hl={playerPath:void 0},X=()=>{if(Gl)return Gl;let s=(je(),Fe(Be));s.log("getSessionPlayerRequire start");let{getSessionPlayerFolder:e}=(Zs(),Fe(Qs)),t=e(),r=Hl.playerPath?(0,Ji.resolve)(Hl.playerPath,"src/background/sessionPlayerInit.ts"):(0,Ji.join)(t,"sessionPlayer.js"),n=require(r);return s.log("getSessionPlayerRequire end"),Gl=n,process.env.LOGGER_CONSOLE&&process.env.DEBUG&&n.setLoggerFormatter&&n.setLoggerFormatter(lc),n}});function ov(s){q.EXTENSION!==s&&process.nextTick(()=>{try{(Te(),Fe(Qt)).getSessionPlayer()}catch{}})}function av(s){var e,t;(t=(e=s.clientConfig)==null?void 0:e.clientMessages)!=null&&t.length&&s.clientConfig.clientMessages.forEach(r=>{let n=r.color||"yellow",i=r.bgColor||"bgBlack";console.log(ql.default[i](ql.default[n](r.text)))})}async function pn(s){let{project:e,token:t,userAccessKey:r,lightweightMode:n,useLocalChromeDriver:i,useChromeLauncher:o,mode:a,gridId:l,grid:c}=s,d=Boolean(n==null?void 0:n.general),m=Boolean(i||o),u=d?iv:nv,f=Ki(),h=Ac(),g=await Pm(),y=null;if(O.flags.getPublicIpFrom3rdPartyServices.isEnabled()&&!m)try{y=await Xm()}catch(b){Zm.error("failed to get public ip",b)}let T=!0;U("before initializeUserWithAuth");let v=await Ft(async()=>(ov(a),T=!1,await El({projectId:e,token:t,branchName:s.branch,lightweightMode:n,localGrid:m,publicIp:y,gridId:l,grid:c,clientCliVersion:f,clientNodeVersion:h,clientNpmVersion:g})),"initializeUserWithAuth",u,{project:e,token:t,branchName:s.branch,lightweightModeGeneral:d,localGrid:m,gridId:l,grid:c,publicIp:y})();return av(v),s.publicIps=[v.clientPublicIp],U("after initializeUserWithAuth"),y&&v.clientPublicIp&&v.clientPublicIp!==y&&(Zm.error("public ip mismatch",{publicIpFromExternalService:y,publicIpFromServices:v.clientPublicIp}),s.publicIps.push(y)),zm(v.authData,{projectId:e,token:t,userAccessKey:r,publicIp:v.clientPublicIp,initializedFromCache:T}),v}var ql,Zm,nv,iv,ef=w(()=>{"use strict";ql=I(require("chalk"));je();ge();Kt();it();Qm();ne();W();le();Vl();F();Yr();Zm=C("initializeUserWithAuth"),nv=1e3*60*5,iv=1e3*60*60*10});async function sf(s){var r;let e=Promise.resolve();s.useLocalChromeDriver&&(s.chromeBinaryLocation=s.downloadBrowser?await Bi():s.chromeBinaryLocation,e=Xs({projectId:s.project,userId:s.user},{chromeBinaryLocation:s.chromeBinaryLocation},Boolean((r=s.lightweightMode)==null?void 0:r.general)),s.useLocalChromeDriver=!0),!s.playerRequirePath&&s.mode!==q.EXTENSION&&await hr(s.playerLocation,s.canary),s.mode!==q.SELENIUM&&s.mode!==q.APPIUM&&!s.ext&&await Yc(s.extensionLocation);let t;if(s.installCustomExtension){let n=Boolean(s.useLocalChromeDriver||s.useChromeLauncher);t=await Jc(s.installCustomExtension,n)}return await e,t}async function nf(s){var o;cv.info("prepare MockNetwork",{location:s});let e=await Ic(s),t=Buffer.isBuffer(e)?e:e.body;if(t.byteLength>tf*1e6)throw new Error(`${zl} exceeded ${tf}MB`);let r;try{r=JSON.parse(t.toString("utf-8"))}catch(a){throw new Error(`${zl} cannot be parsed.${Yi.EOL}${a}`)}let n=new rf.default;if(!n.validate(Fc,r)){let a=(o=n.errors)==null?void 0:o.map((l,c)=>`${++c}) ${l.dataPath} ${l.message}`).join(Yi.EOL);throw new Error(`${zl} is malformed.${Yi.EOL}${a}`)}return r.entries}var Yi,rf,tf,zl,cv,Kl=w(()=>{"use strict";Yi=I(require("os"));F();am();Zs();rf=I(require("ajv"));ne();el();ef();tf=1,zl="JSON file supplied to --mock-network-pattern",cv=(W(),Fe(mc)).getLogger("prepare runner")});function af(s,e=process){async function t(r){await ce(oe(of,async n=>n()),1e4).catch(()=>null),s(r)}e.on("uncaughtException",async r=>{dn.error("Caught exception",{err:r}),console.log("Uncaught exception"),r.message&&console.log("Message =",r.message),r.reason&&console.log("Reason =",r.reason),await t(r)}),e.on("unhandledRejection",r=>{var n;if(dn.fatal("Caught unhandled promise rejection",r),!((n=r==null?void 0:r.message)!=null&&n.includes("ENOTFOUND x-api.rollout.io")))throw r}),e.on("rejectionHandled",()=>{dn.error("Caught rejection handled")}),e.once("SIGTERM",()=>{let r="Runner aborted - SIGTERM event",n=new Error(r);throw dn.error(r),t(n),n}),e.once("SIGINT",()=>{let r="Runner aborted - SIGINT event",n=new Error(r);throw dn.error(r),t(n),n}),e.once("exit",r=>{s(r)})}function es(s){of.push(s)}var dn,of,mn=w(()=>{"use strict";W();F();dn=C("process-handler"),of=[]});function Ql(s,e){var o;let t=s.canary?"-master.zip":".zip",r=`${e?Td:Os}/extension/testim-headless${t}`,n=O.flags.testimHeadlessExtensionDownloadUrl.getValue({companyId:(o=s.company)==null?void 0:o.companyId,projectId:s.project});return n||(fv.warn("testimHeadlessExtensionDownloadUrl flag is not set, defaulting to MV3 extension",{resultId:s.resultId,executionId:s.executionId,projectId:s.project}),n="https://testimstatic.blob.core.windows.net/extension/testim-headless.zip"),!(s.ext||s.extensionPath)&&n&&(r=n,s.testimHeadlessExtensionDownloadUrl=n),{chrome:r,"edge-chromium":r}}function df(s){let{chrome:e}=Ql(s,!1);return e}function Qi(s){let e=`${Os}/extension/sessionPlayer`;return s.canary?`${e}-master`:e}var fv,fn=w(()=>{"use strict";de();le();W();fv=C("runOptionsUtils")});function yf(s){$e||(s!=null&&s.userId||(s={anonymousId:hf}),gf.identify(s))}function gt(s,e){return gn("ci",s,e)}function gn(s,e,t){if($e)return;let r=s?{userId:s}:{anonymousId:hf};gf.track(Object.assign(r,{event:e,properties:t}))}var ff,gf,hf,ts=w(()=>{"use strict";de();ff=require("@segment/analytics-node"),gf=new ff.Analytics({writeKey:"sJOSIGKa5x5rJEGsaOlCjrgozAf7FnVY",flushAt:1}),hf=require("crypto").randomBytes(20).toString("hex")});function bf(s){return s.start&&gn(null,"cli-start-command",{downloadBrowser:Boolean(s.downloadBrowser)}),!!(s.startV2||s.start||s.agent)}async function Tf(s){let e=!!s.start;if(Number.isNaN(s.agentPort))throw new x("Agent port is not number");let t=Qi(s);return console.log("Start Testim CLI on Agent mode"),{project:s.project,token:s.token,agentMode:!0,agentPort:s.agentPort,agentBind:s.agentBind,openEditor:s.openEditor,startTestimBrowser:e,ext:s.ext,extensionPath:s.extensionPath,playerLocation:s.playerPath||t,canary:s.canary,playerPath:s.playerPath,playerRequirePath:s.playerRequirePath,downloadBrowser:Boolean(s.downloadBrowser)}}var wf=w(()=>{"use strict";fn();ts();Y()});var vf,hv,yv,Zl,Ef=w(()=>{"use strict";vf="TST_CREDS",hv=["username","password"],yv="$encrypted",Zl={get proxyPlaceholder(){return new Proxy({},{get(s,e){let t={};for(let r of hv)t[r]={[yv]:`${e}.${r}`};return t}})},containsEncryptedCredentials(s){return s.includes(vf)},injectProxyCredentialsStoreToGlobal(){Object.assign(globalThis,{[vf]:this.proxyPlaceholder})}}});async function If(s,e){var t;return(t=s.lightweightMode)!=null&&t.onlyTestIdsNoSuite&&s.testId?{tests:[s.testId.map(n=>({testId:n,testConfig:{},resultId:re()}))]}:await gl({projectId:s.project,labels:s.label,testIds:s.testId,testNames:s.name,testConfigNames:s.testConfigNames,suiteNames:s.suites,suiteIds:s.suiteIds,branch:e,rerunFailedByRunId:s.rerunFailedByRunId,testConfigIds:s.testConfigIds,intersections:s.intersections})}function eu(s){let e=Object.keys(s).length,t=Object.keys(s).reduce((r,n)=>r+(s[n].success===!0?1:0),0);return e===t}async function tu(s,e){let t=s.mode===q.EXTENSION?vr:yn,r=Sf.difference(Vs(s,e),t);if(r.length>0)throw gt("invalid-config-run",{browser:r.join(", "),mode:"runner"}),new x(`browser type <${r}> is not supported in ${s.mode} mode.`);return e}var Sf,vr,yn,Zi=w(()=>{"use strict";Sf=I(require("lodash"));F();ts();ge();Y();ne();vr=["edge-chromium","chrome"],yn=[...vr,"firefox","safari","safari technology preview"]});function to(s){let{platform:e}=process;e==="win32"?(0,eo.exec)(`start chrome ${s}`):e==="darwin"?(0,eo.exec)(`open -a "Google Chrome" ${s}`):e==="linux"&&(0,eo.exec)(`google-chrome ${s}`)}var eo,ru=w(()=>{"use strict";eo=require("child_process")});var au={};H(au,{doLogin:()=>ou,getProjectId:()=>bv,getToken:()=>Tv});async function bv(){return xf("projectId")}async function Tv(){return xf("token")}function Af(s,e){return Promise.race([s,ae(e).then(()=>{throw new ie("timeout")})])}async function wv(){let s=(await import("express")).default(),e=async function(){return Af(new Promise(n=>{s.get("/loginInfo",(i,o)=>{n(JSON.parse(Buffer.from(i.query.info,"base64").toString())),o.status(200).end()})}),6e4).catch(()=>null)}();await new Promise((r,n)=>{let i=s.listen(42543,o=>{o&&n(o),r(i.address().port)})});try{let{getEditorUrl:r}=await Promise.resolve().then(()=>(ge(),Re)),{editorUrl:n}=await r();to(`${n}/#/new-test`)}catch{console.log("Unable to open Testim automatically - please manually go to https://app.testim.io")}return await e}async function ou({overwriteExisting:s=!0,projects:e=null}={}){let t=su.homedir(),r=nu.join(t,".testim");if(await he(r)&&!s)return;let i={},[{default:o},{default:a}]=await Promise.all([import("prompts"),import("ora")]),l=a("Getting credentials from Tricentis Testim extension ...").start();if(e||(e=await Af(wv(),62e3).catch(()=>null)),e!=null&&e.token){i.token=e.token,i.projectId=e.projectId,l.succeed(),await Rf(r,i);return}if(e!=null&&e.length){l.succeed();let c=e.length===1?{project:e[0]}:await o({type:"select",name:"project",message:"There are multiple projects associated with your user account. Please select the project you would like to connect to:",choices:e.map(d=>({title:d.name,value:d}))});i.token=c.project.ci.token,i.projectId=c.project.id,await Rf(r,i);return}l.fail(),console.log("Error getting credentials - please pass `--token` and `--project` to the CLI or try again")}async function Rf(s,e){await iu.promises.writeFile(s,ro.stringify(e)),console.log(`Testim credentials saved in '${s}'`)}async function xf(s){let e=su.homedir(),t=nu.join(e,".testim"),r=await he(t),n={};if(r)try{n=ro.parse((await iu.promises.readFile(t)).toString())}catch{}return n||={},n[s]}var su,nu,ro,iu,so=w(()=>{"use strict";su=I(require("os")),nu=I(require("path")),ro=I(require("yaml"));F();iu=require("fs");Y();ru()});var Mf={};H(Mf,{process:()=>Cv});var lu,_f,no,Of,Bt,Le,Lf,vv,Oe,du,Ev,Sv,Pf,Df,Iv,uu,pu,mu,cu,xt,Rv,p,Av,xv,kf,Cv,Nf=w(()=>{"use strict";lu=I(require("ms")),_f=I(require("chalk")),no=I(require("node:fs")),Of=I(require("node:url")),Bt=I(require("lodash")),Le=I(require("node:path"));F();fn();wf();Kt();Lf=require("commander");ne();Y();Ur();F();le();Ef();Zi();vv=s=>s.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),Oe=(s,e)=>(e.push(s),e),du=new Lf.Command,Ev=s=>s.split(","),Sv=(s,e)=>!s||s.length===0?e:s,Pf=["enable-heavy-ad-intervention","heavy-ad-privacy-mitigations","use-fake-device-for-media-stream","use-fake-ui-for-media-stream","proxy-server"],Df=()=>{function s(g){return g.includes("-h, --help")}function e(g){return g.includes("--params [params-json-string]")}function t(g){return g.includes("--ext")||g.includes("--extension-path")||g.includes("--headless-extension-download-path")}function r(g){return g.includes("--player-path")||g.includes("--player-require-path")}function n(g){return g.includes("--executionId")||g.includes("--source")||g.includes("--resultId")||g.includes("--remoteRunId")||g.includes("--schedulerId")}function i(g){return g.includes("--get-browser-timeout")||g.includes("--get-browser-retries")||g.includes("--get-session-timeout")||g.includes("--get-session-retries")||g.includes("--driver-request-timeout")||g.includes("--driver-request-retries")}function o(g){return g.includes("--user")}function a(g){return g.includes("shouldMonitorPerformance")}function l(g){return g.includes("--save-rca-locally")}function c(g){return g.includes("--exit-code-ignore-failing-tests")}function d(g){return g.includes("--high-speed")}function m(g){return g.includes("--urls")}function u(g){return g.includes("--test-start-timeout")}function f(g){return g.includes("--install-lazy-deps")}function h(g){return g.includes("--print-final-caps")||g.includes("--print-grids")}du.help(g=>g.split(`
|
|
16
|
+
4. You can always use a standalone Selenium grid and providing it's details with the --host and --port flags (see https://www.npmjs.com/package/selenium-standalone)`)),n.fail(a),o}}async function jw(){let s=`${Os}/extension/sessionPlayer_LATEST_RELEASE`;return(await Mt(s)).body.toString("utf8")}async function $w(s,e){if(!ke(s)||ke(s)&&e||$e)return s;let t=await jw();return`${s}-${t}`}function Xc(){let s=mt();return Xr.resolve(s,"testim-bin")}function Ww(){let s=Xc();return Xr.resolve(s,"sessionPlayer.zip")}async function Wm(s,e,t=!1){try{return await Ti(s,e),await st(e,Xc())}catch(r){if(t)throw r;return await Wm(s,e,!0)}}async function hr(s,e){Ui.info("prepare player",{location:s,canary:e});let t=Ww();return Ft(async()=>{let r=await $w(s,e);return await Wm(r,t),{}},"preparePlayer",$m,[s,e,t])()}var Fm,Bm,Xr,jm,Ui,$m,Kc,Um,Zs=w(()=>{"use strict";Fm=I(require("ms")),Bm=I(require("fs")),Xr=I(require("path"));de();Kt();jm=require("serialize-error");W();jc();Y();F();Ui=C("prepare runner and testim start"),$m=(0,Fm.default)("0.5 day"),Kc=16,Um=`The size of the custom extension is more than ${Kc}MB`});function Vw(){let s=en.type().toLowerCase();return s==="darwin"?en.arch()==="arm"?"mac_arm":"mac":s==="windows_nt"?en.arch()==="x64"?"win64":"win32":"linux"}async function Bi(){let s=Vw(),e="https://storage.googleapis.com/chromium-browser-snapshots",t={linux:"Linux_x64",mac:"Mac",mac_arm:"Mac_Arm",win32:"Win",win64:"Win_x64"};if(!(s in t))throw new x(`Unsupported platform: ${s}`);let r=parseInt(tn,10)>591479?"chrome-win":"chrome-win32",n={linux:"chrome-linux",mac:"chrome-mac",mac_arm:"chrome-mac",win32:r,win64:r},i={linux:"chrome",mac:"Chromium.app/Contents/MacOS/Chromium",mac_arm:"Chromium.app/Contents/MacOS/Chromium",win32:"chrome.exe",win64:"chrome.exe"},o=`${e}/${t[s]}/${tn}/${n[s]}.zip`,a=Fi.join(Qc,n[s]),l=`${a}.zip`,c=Fi.join(a,i[s]);if(await he(c))return c;if(!await he(l)){let m=(0,Zc.default)("Downloading Chromium").start();try{await Vm.promises.mkdir(Qc),await Ke(o,l)}catch(u){let f=`Failed to download Chromium: ${u.message}`;throw m.fail(f),new Error(f)}m.succeed()}let d=(0,Zc.default)("Extracting Chromium").start();try{await st(l,Qc)}catch(m){let u=`Failed to extract Chromium: ${m.message}`;throw d.fail(u),new Error(u)}return d.succeed(),c}var Vm,en,Fi,Zc,tn,Qc,el=w(()=>{"use strict";Vm=I(require("fs")),en=I(require("os")),Fi=I(require("path")),Zc=I(require("ora"));Y();F();tn="1000968",Qc=Fi.join(Ut,`chrome-${tn}`)});async function qm(s,e){return yr=s,nl=e,await tl()}function zm(s,e){yr=e.projectId,nl=e.token,rn=e.userAccessKey,nt=s.token,nn=il(nt),on=s.refreshToken,rl=s.ngrokToken,sl=s.isNgrokWhitelisted,Gm=e.publicIp,Hm=e.initializedFromCache}function Hw(s=yr,e=nl){return Ft(()=>(sn.info("request to get cli token from server"),We({url:`${fe}/auth/token`,body:{projectId:s,token:e}})),"getTokenV3",Gw*10,{projectId:s,token:e})()}async function qw(){sn.info("request to refresh JWT cli token from server");let s=await We({url:`${fe}/auth/refreshToken`,body:{token:nt,refreshToken:on}});return nt=s.token,nn=il(nt),s.refreshToken&&(on=s.refreshToken),nt}async function tl(){try{let s=await Hw();return sn.info("successfully get cli token from server"),nt=s.token,nn=il(nt),on=s.refreshToken,rl=s.ngrokToken,sl=s.isNgrokWhitelisted,nt}catch(s){throw s.message.includes("Unauthorized")?new x("Error trying to retrieve CLI token. Your CLI token and project might not match. Please make sure to pass `--project` and `--token` that match to each other or make sure they match in your ~/.testim file."):(sn.error(`While trying to retrieve CLI token. caught error: ${s}`,{projectId:yr}),new x(`While trying to retrieve CLI token, caught error: ${s}`))}}function il(s){return require("jsonwebtoken").decode(s).exp*1e3}async function Rt(){if(!nn)return tl();let s=O.flags.accessTokenExpiryMargin.getValue();if(nn<Date.now()+4*s)try{return await qw()}catch(e){return sn.error("failed to refresh token, executing fallback",e),tl()}return nt}function ji(){return on}function br(){return nt?{uid:require("jsonwebtoken").decode(nt).id,ngrokToken:rl,isNgrokWhitelisted:sl}:{}}async function $i(){if(!rn||!yr)return;if(await ol({userAccessKey:rn,projectId:yr}))return rn;let e=`user access key "${rn}" is invalid for project "${yr}"`;throw new x(e)}function Wi(){return Gm}function Vi(){return Hm}var sn,nt,nn,on,rl,sl,yr,nl,rn,Gm,Hm,Gw,it=w(()=>{"use strict";de();Ve();Kt();Y();W();ge();le();sn=C("testim-custom-token"),yr=null,nl=null,Gw=5*60*1e3});var Km={};H(Km,{isCi:()=>Qr});var Qr,Gi=w(()=>{"use strict";Qr=Boolean(process.env.CI||process.env.CONTINUOUS_INTEGRATION||process.env.BUILD_NUMBER||process.env.RUN_ID||!1)});var Re={};H(Re,{addTestRetry:()=>kl,clearTestResult:()=>xl,deleteCloudflareTunnel:()=>Dl,fetchLambdatestConfig:()=>Il,fixGridAppIDStructure:()=>Fl,forceUpdateCloudflareTunnelRoutes:()=>Ll,getAllGrids:()=>Sl,getAppDetails:()=>un,getApplitoolsIntegrationData:()=>_l,getBrowserStackSessionMetaData:()=>rv,getCloudflareTunnel:()=>Ol,getEditorUrl:()=>Zw,getGridSlot:()=>vl,getHybridGridProvider:()=>wl,getLabFeaturesByProjectId:()=>Rl,getMobileDevicesFromGrid:()=>Nl,getRealData:()=>Al,getS3Artifact:()=>cn,getS3ArtifactText:()=>ll,getSuiteTestList:()=>gl,getTestPlan:()=>Qw,getTestPlanTestList:()=>fl,getTestResults:()=>wr,getUsageForCurrentBillingPeriod:()=>hl,initializeUserWithAuth:()=>El,isTestResultCompleted:()=>yl,keepAliveCompanySlots:()=>Wl,keepAliveGrid:()=>bl,loadSfdcCredential:()=>ul,loadTest:()=>ln,releaseCompanySlot:()=>jl,releaseGridSlot:()=>Tl,reportExecutionFinished:()=>Hi,reportExecutionStarted:()=>ml,requestCompanySlot:()=>Bl,saveRemoteStep:()=>Cl,saveTestPlanResult:()=>pl,updateCompanySlot:()=>$l,updateExecutionTests:()=>dl,updateRemoteRunFailure:()=>Ml,updateTestDataArtifact:()=>zi,updateTestResult:()=>qi,updateTestStatus:()=>Tr,uploadAppToGrid:()=>Ul,uploadRunDataArtifact:()=>Pl,validateUserAccessKey:()=>ol});async function Zr(){let s=await Rt();if(!s)throw new Error("Failed to get token from server");return{Authorization:`Bearer ${s}`}}async function Se({url:s,body:e,headers:t={},timeout:r,retry:n}){let i=await Zr(),o={...t,...i};return We({url:`${fe}${s||""}`,body:e,headers:o,timeout:r,retry:n})}async function Jw(s,e,t,r={},n=void 0){let i=await Zr(),o={...r,...i};return await Bs(`${fe}${s||""}`,e,t,o,n)}async function an(s,e){let t=await Zr();return await wc(`${fe}${s||""}`,e,t)}async function Yw(s,e){let t=await Zr();return await Fs(`${fe}${s||""}`,e,t)}async function Xw(s,e){let t=await Zr();return await js(`${fe}${s||""}`,e||void 0,t)}async function Ie(s,e,t,r){let n=await Zr();return await be(`${fe}${s||""}`,e||void 0,n,r,t)}function cn(s,e){return(0,Z.default)(()=>Ie(`/storage${s}`,null,{isBinary:!0},e),{retries:te,factor:1})}function ll(s){return(0,Z.default)(()=>Xw(`/storage${s}`))}async function Qw(s,e){let t=n=>n==null?[]:typeof n=="string"&&JSON.parse(n)||n;return(await(0,Z.default)(()=>Ie("/testPlan",{projectId:s,name:e.join(",")}),{retries:te,factor:1})).map(({testConfigIds:n,beforeAllLabels:i,testLabels:o,afterAllLabels:a,...l})=>Object.assign(l,{testConfigIds:t(n),beforeAllLabels:t(i),testLabels:t(o),afterAllLabels:t(a)}))}async function ul({branch:s,projectId:e}){let t=await(0,Z.default)(()=>Ie(`/branch/branchData/${encodeURIComponent(s)}`,{projectId:e}),{retries:te,factor:1});return t==null?void 0:t.sfdcCredential}function ln({testId:s,branch:e,projectId:t,skipSharedSteps:r=!1,useBranchMap:n=!0}){return(0,Z.default)(()=>Ie(`/test/${s}`,{projectId:t,branch:e,skipSharedSteps:r,useBranchMap:n}),{retries:te,factor:1})}function pl(s,e,t){return(0,Z.default)(()=>Se({url:"/testPlan/result",body:{projectId:s,testPlanId:e,result:t}}),{retries:te,factor:1})}function Tr(s,e,t,r,n,i,o=te){return(0,Z.default)(()=>an("/result/run/test",{runId:e,testId:t,resultId:r,status:n,projectId:s,runnerVersion:zw,...i}),{retries:o,factor:1})}function dl(s,e,t,r,n,i,o,a){return(0,Z.default)(()=>an("/result/run/tests",{runId:s,runnerStatuses:e,status:t,reason:r,success:n,startTime:i,endTime:o,projectId:a}),{retries:te,factor:1})}async function ml({executionId:s,projectId:e,labels:t,startTime:r,executions:n,config:i,resultLabels:o,remoteRunId:a,localRunUserId:l,isLocalRun:c,intersections:d}){let{isCi:m}=await Promise.resolve().then(()=>(Gi(),Km));return Se({timeout:9e4,url:"/result/run",body:{runId:s,projectId:e,labels:t,startTime:r,execution:n,status:"RUNNING",config:i,resultLabels:o,remoteRunId:a,intersections:d,metadata:{isCiRun:m,localRunUserId:l,isLocalRun:c}},retry:3})}function Hi(s,e,t,r,n={},i=void 0,o=void 0){let a=Date.now();return(0,Z.default)(()=>an("/result/run",{runId:e,projectId:t,endTime:a,status:s,success:r,tmsOptions:n,remoteRunId:i,resultExtraData:o}),{retries:te,factor:1})}async function fl(s,e,t,r,n){return(0,Z.default)(()=>Se({url:"/testPlan/list",body:{projectId:s,names:e,planIds:t,branch:r,intersections:n},timeout:12e4}),{retries:te,factor:1})}function gl({projectId:s,labels:e,testIds:t,testNames:r,testConfigNames:n,suiteNames:i,suiteIds:o,branch:a,rerunFailedByRunId:l,testConfigIds:c,intersections:d}){return(0,Z.default)(()=>Se({url:"/suite/v2/list",body:{projectId:s,labels:e,testIds:t,testNames:r,testConfigNames:n,suiteNames:i,suiteIds:o,branch:a,rerunFailedByRunId:l,testConfigIds:c,intersections:d}}),{retries:te,factor:1})}async function un({appId:s,projectId:e}){try{return await(0,Z.default)(()=>Ie(`/mobile-app/app/${s}?projectId=${e}`),{retries:te,factor:1})}catch(t){throw new Error(`Could not load app with the ID ${s}`,{cause:t})}}async function hl(s){try{return await(0,Z.default)(()=>Ie(`/plan/project/${s}/usage-current-billing-period`),{retries:te,factor:1})}catch(e){At.error("failed getting usage for current billing period",{projectId:s,error:e});return}}function yl(s,e,t){return(0,Z.default)(()=>Ie(`/result/${s}/isComplete`,{projectId:e,testRetryKey:t}),{retries:te,factor:1})}function wr(s,e,t,r){return(0,Z.default)(()=>Ie(`/test/v2/${s}/result/${e}`,{projectId:t,branch:r}),{retries:te,factor:1})}function bl(s,e){return Se({url:`/grid/keep-alive?reqId=${re()}`,body:{projectId:s,slots:e},timeout:1e4})}function Tl(s,e,t,r,n){return Se({url:`/grid/release?reqId=${re()}`,body:{companyId:s,projectId:e,slotId:t,gridId:r,browser:n}})}function wl(s){return Se({url:"/grid/hybrid/provider",body:s})}function vl(s){return(0,Z.default)(()=>Ie("/grid/grid-slot",{...s,reqId:re()}),{retries:te,factor:1})}async function El({projectId:s,token:e,branchName:t,lightweightMode:r,localGrid:n,publicIp:i,gridId:o,grid:a,clientCliVersion:l,clientNodeVersion:c,clientNpmVersion:d}){var m,u;try{return await(0,Z.default)(()=>We({url:`${fe}/executions/initialize`,body:{projectId:s,token:e,branchName:t||"master",lightweightMode:r,localGrid:n,publicIp:i,gridId:o,gridName:a,clientCliVersion:l,clientNodeVersion:c,clientNpmVersion:d},timeout:6e4}),{retries:te,factor:1})}catch(f){if(At.error("error initializing info from server",f),(m=f.message)!=null&&m.includes("Bad Request"))throw new x("Error trying to retrieve CLI token. Your CLI token and project might not match. Please make sure to pass `--project` and `--token` that match to each other or make sure they match in your ~/.testim file.");if((u=f.code)!=null&&u.includes("ENOTFOUND"))throw new x("Due to network connectivity issues, Testim CLI has been unable to connect to the Testim backend.");if(f.text)try{let h=JSON.parse(f.text),g=h.clientMessage.color||"red",y=h.clientMessage.bgColor||"bgBlack";console.log(al.default[y](al.default[g](h.clientMessage.text))),h.exitCode&&process.exit(h.exitCode)}catch{At.error("Error parsing error message from server",f)}throw f}}async function Zw(){if(_s)return{editorUrl:_s};try{return await(0,Z.default)(()=>Ie("/system-info/editor-url"),{retries:te,onFailedAttempt:s=>{if(s.attemptNumber>=te)throw s},factor:1})}catch(s){return At.error("cannot retrieve editor-url from server",{err:s}),{editorUrl:"https://app.testim.io"}}}function Sl(s){return(0,Z.default)(()=>Ie("/grid",{companyId:s}),{retries:te,factor:1})}function Al(s,e,t){return(0,Z.default)(()=>Ie(`/real-data/${e}?${t}&projectId=${s}`),{retries:te,factor:1})}function qi(s,e,t,r,n){return(0,Z.default)(()=>Se({url:"/result/test",body:{projectId:s,resultId:e,testId:t,testResult:r,remoteRunId:n}}),{retries:te,factor:1})}function xl(s,e,t,r){return(0,Z.default)(()=>Se({url:"/result/test/clear",body:{projectId:s,resultId:e,testId:t,testResult:r}}),{retries:te,factor:1})}function Cl(s,e,t,r){return(0,Z.default)(()=>Se({url:"/remoteStep",body:{projectId:s,resultId:e,stepId:t,remoteStep:r}}),{retries:te,factor:1})}function ev(s){return s.startsWith("/")?s:`/${s}`}function tv(s,e,t){let r=ev(s);return t&&(r=`/${t}${r}`),e&&(r=`/${e}${r}`),r}async function Ym(s,e,t,r,n,i="application/octet-stream"){let o=null;i==="application/json"&&(o=".json");let a=`${n}_${re()}${o||""}`,l=`${e}/${t}/${a}`,c=tv(l,Id,s),d=Buffer.from(Jm.gzip(r,{level:3})),m={file:{fileName:a,buffer:d}};return await(0,Z.default)(()=>Jw(`/storage${c}`,{},m,{"X-Asset-Encoding":"gzip"}),{retries:te,factor:1}),c}function kl({projectId:s,runId:e,testId:t,newResultId:r,originalTestResultId:n,previousTestResultId:i,testResult:o}){return(0,Z.default)(()=>Se({url:"/result/test/retry",body:{projectId:s,newResultId:r,originalTestResultId:n,previousTestResultId:i,testId:t,runId:e,testResult:o}}),{retries:te,factor:1})}async function _l(s){try{return await Ie(`/integration/applitools/v3/connected?projectId=${s}`)}catch(e){return At.warn("could'nt get applitools integration data.",{err:e}),{}}}async function Ol(s,e){try{return await an("/tunnel",{companyId:s,routes:e})}catch(t){return At.warn("could'nt get tunnel.",{err:t}),{}}}async function Ll(s,e){try{return await Se({url:`/tunnel/${e}`,body:{companyId:s}})}catch(t){At.warn("could'nt get tunnel.",{err:t});return}}async function Dl(s,e){try{return await Yw(`/tunnel/${e}`,{companyId:s})}catch(t){At.warn("could'nt get tunnel.",{err:t});return}}function Ml(s){return We({url:`${fe}/result/remoteRunFailure`,body:s})}async function Nl({projectId:s,projectType:e,gridId:t,companyId:r,selectors:n}){let i=`${Kw}/mobileDevices/${t}/${r}?projectType=${e}`;i=n?`${i}&selectors=${encodeURIComponent(n)}`:i;try{return await(0,Z.default)(()=>Ie(i,{projectId:s}),{retries:te,factor:1})}catch(o){return At.warn("could'nt get devices from headspin grid.",{err:o}),null}}async function Ul({projectId:s,gridId:e,app:t,timeout:r}){return(0,Z.default)(()=>Se({url:`/mobile-app/app/upload-to-grid?projectId=${s}&gridId=${e}`,body:t,timeout:r}),{retries:te,factor:1})}async function Fl(s){return(0,Z.default)(()=>Se({url:"/mobile-app/app/fix-grid-app-id",body:s}),{retries:te,factor:1})}async function Bl(s,e){return(0,Z.default)(()=>Se({url:"/slot-management/request-slot",body:{companyId:s,projectId:e}}),{retries:te,factor:1})}async function jl(s,e,t){return(0,Z.default)(()=>Se({url:"/slot-management/release-slot",body:{companyId:s,projectId:e,slotId:t}}),{retries:te,factor:1})}async function $l(s,e,t){return(0,Z.default)(()=>an("/slot-management/update-slot",{slotId:t.slotId,companyId:s,projectId:e,slot:t}),{retries:te,factor:1})}function Wl(s,e,t){return Se({url:`/slot-management/keep-alive?reqId=${re()}`,body:{slots:t,companyId:s,projectId:e},timeout:1e4})}async function rv(s,e){return await be(`${Ls}/sessions/${s}`,void 0,{Authorization:`Basic ${Buffer.from(`${e.user}:${e.key}`).toString("base64")}`})}async function ol(s){try{return await Ie("/v2/project/validateUserAccessKey",s),!0}catch(e){return At.error("error validating user access key",{error:e}),!1}}var al,Xt,Jm,Z,cl,zw,At,te,Kw,Il,Rl,Pl,zi,ge=w(()=>{"use strict";al=I(require("chalk")),Xt=I(require("lodash")),Jm=I(require("pako"));F();de();ne();Ve();it();Z=I(require("p-retry")),cl=I(require("object-hash"));Y();W();zw=qe(),At=C("testim service api"),te=3,Kw="/grid";Il=async()=>(0,Z.default)(()=>Ie("/grid/lt/config"),{retries:te,factor:1}),Rl=async s=>(0,Z.default)(()=>Ie(`/labFeature/v2/project/${s}`),{retries:te,factor:1});Pl=Xt.memoize(async(s,e,t,r)=>{if(!Xt.isEmpty(r))return await Ym(s,e,t,JSON.stringify(r),"test-run-data","application/json")},(s,e,t,r)=>`${(0,cl.default)(r)}:${e}:${t}`),zi=Xt.memoize(async(s,e,t,r,n)=>!r||Xt.isEmpty(r)?void 0:await Ym(s,e,t,JSON.stringify((()=>{let o=Xt.clone(r);if(n!=null&&n.hiddenParams){let{hiddenParams:a}=n;(a||[]).forEach(l=>{o[l]&&Object.assign(o,{[l]:Pc.HIDDEN_PARAM})})}return o})()),"test-test-data","application/json"),(s,e,t,r)=>`${(0,cl.default)(r)}:${e}:${t}`)});async function Xm(){let s=await Promise.any(sv.map(async e=>{try{return await be(e)}catch{return null}}));return s==null?void 0:s.ip}var sv,Qm=w(()=>{"use strict";Ve();sv=["https://api.ipify.org?format=json","https://ipinfo.io/json","https://api.my-ip.io/ip.json"]});function Ki(){return qe()}var Vl=w(()=>{"use strict";F()});var Qt={};H(Qt,{getSessionPlayer:()=>X,options:()=>Hl});var Ji,Hl,Gl,X,Te=w(()=>{"use strict";Ji=require("path");W();Hl={playerPath:void 0},X=()=>{if(Gl)return Gl;let s=(je(),Fe(Be));s.log("getSessionPlayerRequire start");let{getSessionPlayerFolder:e}=(Zs(),Fe(Qs)),t=e(),r=Hl.playerPath?(0,Ji.resolve)(Hl.playerPath,"src/background/sessionPlayerInit.ts"):(0,Ji.join)(t,"sessionPlayer.js"),n=require(r);return s.log("getSessionPlayerRequire end"),Gl=n,process.env.LOGGER_CONSOLE&&process.env.DEBUG&&n.setLoggerFormatter&&n.setLoggerFormatter(lc),n}});function ov(s){q.EXTENSION!==s&&process.nextTick(()=>{try{(Te(),Fe(Qt)).getSessionPlayer()}catch{}})}function av(s){var e,t;(t=(e=s.clientConfig)==null?void 0:e.clientMessages)!=null&&t.length&&s.clientConfig.clientMessages.forEach(r=>{let n=r.color||"yellow",i=r.bgColor||"bgBlack";console.log(ql.default[i](ql.default[n](r.text)))})}async function pn(s){let{project:e,token:t,userAccessKey:r,lightweightMode:n,useLocalChromeDriver:i,useChromeLauncher:o,mode:a,gridId:l,grid:c}=s,d=Boolean(n==null?void 0:n.general),m=Boolean(i||o),u=d?iv:nv,f=Ki(),h=Ac(),g=await Pm(),y=null;if(O.flags.getPublicIpFrom3rdPartyServices.isEnabled()&&!m)try{y=await Xm()}catch(b){Zm.error("failed to get public ip",b)}let T=!0;U("before initializeUserWithAuth");let v=await Ft(async()=>(ov(a),T=!1,await El({projectId:e,token:t,branchName:s.branch,lightweightMode:n,localGrid:m,publicIp:y,gridId:l,grid:c,clientCliVersion:f,clientNodeVersion:h,clientNpmVersion:g})),"initializeUserWithAuth",u,{project:e,token:t,branchName:s.branch,lightweightModeGeneral:d,localGrid:m,gridId:l,grid:c,publicIp:y})();return av(v),s.publicIps=[v.clientPublicIp],U("after initializeUserWithAuth"),y&&v.clientPublicIp&&v.clientPublicIp!==y&&(Zm.error("public ip mismatch",{publicIpFromExternalService:y,publicIpFromServices:v.clientPublicIp}),s.publicIps.push(y)),zm(v.authData,{projectId:e,token:t,userAccessKey:r,publicIp:v.clientPublicIp,initializedFromCache:T}),v}var ql,Zm,nv,iv,ef=w(()=>{"use strict";ql=I(require("chalk"));je();ge();Kt();it();Qm();ne();W();le();Vl();F();Yr();Zm=C("initializeUserWithAuth"),nv=1e3*60*5,iv=1e3*60*60*10});async function sf(s){var r;let e=Promise.resolve();s.useLocalChromeDriver&&(s.chromeBinaryLocation=s.downloadBrowser?await Bi():s.chromeBinaryLocation,e=Xs({projectId:s.project,userId:s.user},{chromeBinaryLocation:s.chromeBinaryLocation},Boolean((r=s.lightweightMode)==null?void 0:r.general)),s.useLocalChromeDriver=!0),!s.playerRequirePath&&s.mode!==q.EXTENSION&&await hr(s.playerLocation,s.canary),s.mode!==q.SELENIUM&&s.mode!==q.APPIUM&&!s.ext&&await Yc(s.extensionLocation);let t;if(s.installCustomExtension){let n=Boolean(s.useLocalChromeDriver||s.useChromeLauncher);t=await Jc(s.installCustomExtension,n)}return await e,t}async function nf(s){var o;cv.info("prepare MockNetwork",{location:s});let e=await Ic(s),t=Buffer.isBuffer(e)?e:e.body;if(t.byteLength>tf*1e6)throw new Error(`${zl} exceeded ${tf}MB`);let r;try{r=JSON.parse(t.toString("utf-8"))}catch(a){throw new Error(`${zl} cannot be parsed.${Yi.EOL}${a}`)}let n=new rf.default;if(!n.validate(Fc,r)){let a=(o=n.errors)==null?void 0:o.map((l,c)=>`${++c}) ${l.dataPath} ${l.message}`).join(Yi.EOL);throw new Error(`${zl} is malformed.${Yi.EOL}${a}`)}return r.entries}var Yi,rf,tf,zl,cv,Kl=w(()=>{"use strict";Yi=I(require("os"));F();am();Zs();rf=I(require("ajv"));ne();el();ef();tf=1,zl="JSON file supplied to --mock-network-pattern",cv=(W(),Fe(mc)).getLogger("prepare runner")});function af(s,e=process){async function t(r){await ce(oe(of,async n=>n()),1e4).catch(()=>null),s(r)}e.on("uncaughtException",async r=>{dn.error("Caught exception",{err:r}),console.log("Uncaught exception"),r.message&&console.log("Message =",r.message),r.reason&&console.log("Reason =",r.reason),await t(r)}),e.on("unhandledRejection",r=>{var n;if(dn.fatal("Caught unhandled promise rejection",r),!((n=r==null?void 0:r.message)!=null&&n.includes("ENOTFOUND x-api.rollout.io")))throw r}),e.on("rejectionHandled",()=>{dn.error("Caught rejection handled")}),e.once("SIGTERM",()=>{let r="Runner aborted - SIGTERM event",n=new Error(r);throw dn.error(r),t(n),n}),e.once("SIGINT",()=>{let r="Runner aborted - SIGINT event",n=new Error(r);throw dn.error(r),t(n),n}),e.once("exit",r=>{s(r)})}function es(s){of.push(s)}var dn,of,mn=w(()=>{"use strict";W();F();dn=C("process-handler"),of=[]});function Ql(s,e){var o;let t=s.canary?"-master.zip":".zip",r=`${e?Td:Os}/extension/testim-headless${t}`,n=O.flags.testimHeadlessExtensionDownloadUrl.getValue({companyId:(o=s.company)==null?void 0:o.companyId,projectId:s.project});return n||(fv.warn("testimHeadlessExtensionDownloadUrl flag is not set, defaulting to MV3 extension",{resultId:s.resultId,executionId:s.executionId,projectId:s.project}),n="https://testimstatic.blob.core.windows.net/extension/testim-headless.zip"),!(s.ext||s.extensionPath)&&n&&(r=n,s.testimHeadlessExtensionDownloadUrl=n),{chrome:r,"edge-chromium":r}}function df(s){let{chrome:e}=Ql(s,!1);return e}function Qi(s){let e=`${Os}/extension/sessionPlayer`;return s.canary?`${e}-master`:e}var fv,fn=w(()=>{"use strict";de();le();W();fv=C("runOptionsUtils")});function yf(s){$e||(s!=null&&s.userId||(s={anonymousId:hf}),gf.identify(s))}function gt(s,e){return gn("ci",s,e)}function gn(s,e,t){if($e)return;let r=s?{userId:s}:{anonymousId:hf};gf.track(Object.assign(r,{event:e,properties:t}))}var ff,gf,hf,ts=w(()=>{"use strict";de();ff=require("@segment/analytics-node"),gf=new ff.Analytics({writeKey:"sJOSIGKa5x5rJEGsaOlCjrgozAf7FnVY",flushAt:1}),hf=require("crypto").randomBytes(20).toString("hex")});function bf(s){return s.start&&gn(null,"cli-start-command",{downloadBrowser:Boolean(s.downloadBrowser)}),!!(s.startV2||s.start||s.agent)}async function Tf(s){let e=!!s.start;if(Number.isNaN(s.agentPort))throw new x("Agent port is not number");let t=Qi(s);return console.log("Start Testim CLI on Agent mode"),{project:s.project,token:s.token,agentMode:!0,agentPort:s.agentPort,agentBind:s.agentBind,openEditor:s.openEditor,startTestimBrowser:e,ext:s.ext,extensionPath:s.extensionPath,playerLocation:s.playerPath||t,canary:s.canary,playerPath:s.playerPath,playerRequirePath:s.playerRequirePath,downloadBrowser:Boolean(s.downloadBrowser)}}var wf=w(()=>{"use strict";fn();ts();Y()});var vf,hv,yv,Zl,Ef=w(()=>{"use strict";vf="TST_CREDS",hv=["username","password"],yv="$encrypted",Zl={get proxyPlaceholder(){return new Proxy({},{get(s,e){let t={};for(let r of hv)t[r]={[yv]:`${e}.${r}`};return t}})},containsEncryptedCredentials(s){return s.includes(vf)},injectProxyCredentialsStoreToGlobal(){Object.assign(globalThis,{[vf]:this.proxyPlaceholder})}}});async function If(s,e){var t;return(t=s.lightweightMode)!=null&&t.onlyTestIdsNoSuite&&s.testId?{tests:[s.testId.map(n=>({testId:n,testConfig:{},resultId:re()}))]}:await gl({projectId:s.project,labels:s.label,testIds:s.testId,testNames:s.name,testConfigNames:s.testConfigNames,suiteNames:s.suites,suiteIds:s.suiteIds,branch:e,rerunFailedByRunId:s.rerunFailedByRunId,testConfigIds:s.testConfigIds,intersections:s.intersections})}function eu(s){let e=Object.keys(s).length,t=Object.keys(s).reduce((r,n)=>r+(s[n].success===!0?1:0),0);return e===t}async function tu(s,e){let t=s.mode===q.EXTENSION?vr:yn,r=Sf.difference(Vs(s,e),t);if(r.length>0)throw gt("invalid-config-run",{browser:r.join(", "),mode:"runner"}),new x(`browser type <${r}> is not supported in ${s.mode} mode.`);return e}var Sf,vr,yn,Zi=w(()=>{"use strict";Sf=I(require("lodash"));F();ts();ge();Y();ne();vr=["edge-chromium","chrome"],yn=[...vr,"firefox","safari","safari technology preview"]});function to(s){let{platform:e}=process;e==="win32"?(0,eo.exec)(`start chrome ${s}`):e==="darwin"?(0,eo.exec)(`open -a "Google Chrome" ${s}`):e==="linux"&&(0,eo.exec)(`google-chrome ${s}`)}var eo,ru=w(()=>{"use strict";eo=require("child_process")});var au={};H(au,{doLogin:()=>ou,getProjectId:()=>bv,getToken:()=>Tv});async function bv(){return xf("projectId")}async function Tv(){return xf("token")}function Af(s,e){return Promise.race([s,ae(e).then(()=>{throw new ie("timeout")})])}async function wv(){let s=(await import("express")).default(),e=async function(){return Af(new Promise(n=>{s.get("/loginInfo",(i,o)=>{n(JSON.parse(Buffer.from(i.query.info,"base64").toString())),o.status(200).end()})}),6e4).catch(()=>null)}();await new Promise((r,n)=>{let i=s.listen(42543,o=>{o&&n(o),r(i.address().port)})});try{let{getEditorUrl:r}=await Promise.resolve().then(()=>(ge(),Re)),{editorUrl:n}=await r();to(`${n}/#/new-test`)}catch{console.log("Unable to open Testim automatically - please manually go to https://app.testim.io")}return await e}async function ou({overwriteExisting:s=!0,projects:e=null}={}){let t=su.homedir(),r=nu.join(t,".testim");if(await he(r)&&!s)return;let i={},[{default:o},{default:a}]=await Promise.all([import("prompts"),import("ora")]),l=a("Getting credentials from Tricentis Testim extension ...").start();if(e||(e=await Af(wv(),62e3).catch(()=>null)),e!=null&&e.token){i.token=e.token,i.projectId=e.projectId,l.succeed(),await Rf(r,i);return}if(e!=null&&e.length){l.succeed();let c=e.length===1?{project:e[0]}:await o({type:"select",name:"project",message:"There are multiple projects associated with your user account. Please select the project you would like to connect to:",choices:e.map(d=>({title:d.name,value:d}))});i.token=c.project.ci.token,i.projectId=c.project.id,await Rf(r,i);return}l.fail(),console.log("Error getting credentials - please pass `--token` and `--project` to the CLI or try again")}async function Rf(s,e){await iu.promises.writeFile(s,ro.stringify(e)),console.log(`Testim credentials saved in '${s}'`)}async function xf(s){let e=su.homedir(),t=nu.join(e,".testim"),r=await he(t),n={};if(r)try{n=ro.parse((await iu.promises.readFile(t)).toString())}catch{}return n||={},n[s]}var su,nu,ro,iu,so=w(()=>{"use strict";su=I(require("os")),nu=I(require("path")),ro=I(require("yaml"));F();iu=require("fs");Y();ru()});var Mf={};H(Mf,{process:()=>Cv});var lu,_f,no,Of,Bt,Le,Lf,vv,Oe,du,Ev,Sv,Pf,Df,Iv,uu,pu,mu,cu,xt,Rv,p,Av,xv,kf,Cv,Nf=w(()=>{"use strict";lu=I(require("ms")),_f=I(require("chalk")),no=I(require("node:fs")),Of=I(require("node:url")),Bt=I(require("lodash")),Le=I(require("node:path"));F();fn();wf();Kt();Lf=require("commander");ne();Y();Ur();F();le();Ef();Zi();vv=s=>s.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),Oe=(s,e)=>(e.push(s),e),du=new Lf.Command,Ev=s=>s.split(","),Sv=(s,e)=>!s||s.length===0?e:s,Pf=["enable-heavy-ad-intervention","heavy-ad-privacy-mitigations","use-fake-device-for-media-stream","use-fake-ui-for-media-stream","proxy-server"],Df=()=>{function s(g){return g.includes("-h, --help")}function e(g){return g.includes("--params [params-json-string]")}function t(g){return g.includes("--ext")||g.includes("--extension-path")||g.includes("--headless-extension-download-path")}function r(g){return g.includes("--player-path")||g.includes("--player-require-path")}function n(g){return g.includes("--executionId")||g.includes("--source")||g.includes("--resultId")||g.includes("--remoteRunId")||g.includes("--schedulerId")}function i(g){return g.includes("--get-browser-timeout")||g.includes("--get-browser-retries")||g.includes("--get-session-timeout")||g.includes("--get-session-retries")||g.includes("--driver-request-timeout")||g.includes("--driver-request-retries")}function o(g){return g.includes("--user")}function a(g){return g.includes("shouldMonitorPerformance")}function l(g){return g.includes("--save-rca-locally")}function c(g){return g.includes("--exit-code-ignore-failing-tests")}function d(g){return g.includes("--high-speed")}function m(g){return g.includes("--urls")}function u(g){return g.includes("--test-start-timeout")}function f(g){return g.includes("--install-lazy-deps")}function h(g){return g.includes("--print-final-caps")||g.includes("--print-grids")}du.help(g=>g.split(`
|
|
17
17
|
`).filter(T=>!t(T)&&!e(T)&&!s(T)&&!r(T)&&!n(T)&&!a(T)&&!o(T)&&!i(T)&&!l(T)&&!c(T)&&!d(T)&&!m(T)&&!u(T)&&!f(T)&&!h(T)).join(`
|
|
18
18
|
`))},Iv=(s,e)=>{let t=e?`Please use ${e} instead.`:"";console.log(_f.default.yellow(`
|
|
19
19
|
WARNING: ${s} is deprecated. ${t}
|