shiplightai 0.1.88 → 0.1.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/debugger-pw.cjs +47 -47
- package/dist/cjs/fixture.cjs +56 -56
- package/dist/cjs/index.cjs +54 -54
- package/dist/cjs/reporter.cjs +1 -1
- package/dist/cli.js +4 -4
- package/dist/debugger-pw.js +48 -48
- package/dist/fixture.js +57 -57
- package/dist/index.js +55 -55
- package/dist/reporter.js +1 -1
- package/package.json +3 -3
package/dist/cjs/reporter.cjs
CHANGED
|
@@ -883,7 +883,7 @@
|
|
|
883
883
|
});
|
|
884
884
|
</script>
|
|
885
885
|
</body>
|
|
886
|
-
</html>`}var Ie="0.1.
|
|
886
|
+
</html>`}var Ie="0.1.89",Ne=Ie!=="dev"?Ie:void 0;var go=3600*1e3,yo=10080*60*1e3;var Tt={before:0,main:1,teardown:2,after:3};function De(e){let t=e.split(".")[0];return Tt[t]??1}function Ce(e){return e.split(".").map(t=>{let r=Number(t);return Number.isNaN(r)?0:r})}function At(e){return[...e].sort(([t],[r])=>{let i=De(t),o=De(r);if(i!==o)return i-o;let a=Ce(t),n=Ce(r);for(let u=0;u<Math.max(a.length,n.length);u++){let d=a[u]??-1,p=n[u]??-1;if(d!==p)return d-p}return 0})}function $t(e){let t=new Set;for(let r of e)if(t.add(r.category),r.category==="hook")for(let i of r.steps)t.add(i.category);return t}function Et(e,t){let r=e.toLowerCase();return r.includes("before")?"before":r.includes("after")?"after":t}function oe(e,t="main",r,i,o){r===void 0&&(r=!$t(e).has("test.step")),o||(o=new Map);let a=[];for(let n of e){if(n.category==="fixture"||n.category==="test.attach")continue;if(n.category==="hook"){let d=Et(n.title,t);a.push(...oe(n.steps,d,r,i,o));continue}if(n.category==="test.step"||r&&(n.category==="expect"||n.category==="pw:api")){let d=o.get(t)??0;o.set(t,d+1);let p=`${t}.${d}`,b={stepId:p,description:n.title,status:n.error?"failure":n.duration===-1?"skipped":"success",duration:n.duration>=0?n.duration:void 0};n.error&&(b.error=n.error.message??n.error.stack),i&&n.location&&i.set(p,n.location),a.push(b),n.steps.length>0&&a.push(...oe(n.steps,p,r,i,o))}}return a}function Mt(e,t){let r=v.isAbsolute(e)?e:v.join(process.cwd(),e),i=v.join(r,"latest");try{if(x.lstatSync(i).isSymbolicLink())x.unlinkSync(i);else{console.warn("[report] 'latest' exists and is not a symlink; skipping update");return}}catch{}try{process.platform==="win32"?x.symlinkSync(v.join(r,t),i,"junction"):x.symlinkSync(t,i,"dir")}catch(o){console.warn(`[report] Could not create 'latest' symlink: ${o instanceof Error?o.message:String(o)}`)}}var ne=class{outputFolder;openMode;latestSymlinkDir;collected=[];config;runStartTime;constructor(t={}){this.outputFolder=t.outputFolder||"shiplight-report",this.openMode=t.open||"on-failure",this.latestSymlinkDir=t.latestSymlinkDir}onBegin(t,r){this.config=t,this.runStartTime=new Date().toISOString()}onTestEnd(t,r){this.collected.push({test:t,result:r})}async onEnd(t){if(this.collected.length===0)return;let r=new Map;for(let p of this.collected){let b=p.test.titlePath().join(" > "),w=r.get(b);w||(w=[],r.set(b,w)),w.push(p)}let i=[];for(let[,p]of r.entries()){let b=p[0].test.location.file,w=[],c,l,m;for(let _=0;_<p.length;_++){let{test:y,result:A}=p[_],$=await this.buildReportTest(y,A,b);c=$,l||(l=$.startTime),m=$.endTime,w.push({attemptNumber:_+1,status:A.status,duration:A.duration,steps:$.steps,error:$.error,videoPath:$.videoPath,tracePath:$.tracePath})}let h=w[w.length-1],{test:S}=p[p.length-1],g={title:S.title,baseTitle:c?.baseTitle,file:v.relative(process.cwd(),b),status:h.status,duration:h.duration,steps:h.steps,error:h.error,videoPath:h.videoPath,tracePath:h.tracePath,actionStepsMap:c?.actionStepsMap,tags:c?.tags,baseUrl:c?.baseUrl,skip:c?.skip,slow:c?.slow,timeout:c?.timeout,parameterSetName:c?.parameterSetName,startTime:l,endTime:m,suiteName:c?.suiteName};w.length>1&&(g.retries=w.length-1,g.attempts=w,w.some(y=>y.status==="failed"||y.status==="timedOut")&&h.status==="passed"&&(g.flaky=!0)),i.push(g)}let o={tests:i,totalDuration:t.duration,timestamp:new Date().toISOString(),shiplightVersion:Ne},a=v.isAbsolute(this.outputFolder)?this.outputFolder:v.join(process.cwd(),this.outputFolder);x.mkdirSync(a,{recursive:!0});let n=v.join(a,"screenshots");for(let p=0;p<o.tests.length;p++){let b=o.tests[p],w=b.attempts&&b.attempts.length>0,c=[{obj:b,prefix:w?`test-${p}-attempt-0`:`test-${p}`,screenshotSubDir:`test-${p}`}];if(b.attempts)for(let l=0;l<b.attempts.length;l++)c.push({obj:b.attempts[l],prefix:`test-${p}-attempt-${l+1}`,screenshotSubDir:`test-${p}/attempt-${l}`});for(let{obj:l,prefix:m,screenshotSubDir:h}of c){let S=v.join(n,h),g=!1;for(let _ of l.steps)if(_.screenshot&&v.isAbsolute(_.screenshot))try{g||(x.mkdirSync(S,{recursive:!0}),g=!0);let y=`${_.stepId.replace(/\./g,"-")}.png`;x.copyFileSync(_.screenshot,v.join(S,y)),_.screenshot=`screenshots/${h}/${y}`}catch(y){console.warn(`[reporter] Failed to copy screenshot for ${_.stepId}:`,y)}if(l.videoPath&&v.isAbsolute(l.videoPath)){let _=v.extname(l.videoPath)||".webm",y=`${m}-video${_}`;try{x.copyFileSync(l.videoPath,v.join(a,y)),l.videoPath=y}catch{l.videoPath=void 0}}if(l.tracePath&&v.isAbsolute(l.tracePath)){let _=v.extname(l.tracePath)||".zip",y=`${m}-trace${_}`;try{x.copyFileSync(l.tracePath,v.join(a,y)),l.tracePath=y}catch{l.tracePath=void 0}}}}let u=v.join(a,"report-data.json");x.writeFileSync(u,JSON.stringify(o,null,2),"utf-8");let d=v.join(a,"index.html");if(x.writeFileSync(d,Le({...o,outputDir:a}),"utf-8"),console.log(`
|
|
887
887
|
Shiplight report written to: ${d}`),this.latestSymlinkDir&&Mt(this.latestSymlinkDir,v.basename(a)),this.openMode==="always"||this.openMode==="on-failure"&&t.status!=="passed")try{let p=(await import("open")).default;await p(d)}catch{}}printsToStdio(){return!1}async buildReportTest(t,r,i){let o={title:t.title,file:v.relative(process.cwd(),i),status:r.status,duration:r.duration,steps:[],startTime:new Date(r.startTime).toISOString(),endTime:new Date(r.startTime.getTime()+r.duration).toISOString()};r.errors.length>0&&(o.error=r.errors.map(c=>c.message||c.stack||String(c)).join(`
|
|
888
888
|
|
|
889
889
|
`)),r.stdout.length>0&&(o.stdout=r.stdout.map(c=>typeof c=="string"?c:c.toString()).join("")),r.stderr.length>0&&(o.stderr=r.stderr.map(c=>typeof c=="string"?c:c.toString()).join(""));for(let c of r.attachments)c.name==="video"&&c.path&&(o.videoPath=c.path),c.name==="trace"&&c.path&&(o.tracePath=c.path);let a=r.attachments.find(c=>c.name==="shiplight-results"),n=null;if(a)try{if(a.body)n=JSON.parse(a.body.toString("utf-8"));else if(a.path){let c=x.readFileSync(a.path,"utf-8");n=JSON.parse(c)}}catch{}let u=i.replace(/\.yaml\.spec\.ts$/,".test.yaml"),d={},p=t.title.match(/^(.*)\s+\[([^\]]+)\]$/),b=p?p[1]:t.title,w=p?p[2]:void 0;if(w&&(o.parameterSetName=w),x.existsSync(u))try{let c=x.readFileSync(u,"utf-8"),l=Ee(c,u,this.config.rootDir);if(l.suite){let m=l.suite.tests.find(h=>h.name===b);m&&(d=z(m.testFlow),m.tags?.length&&(o.tags=m.tags),m.skip!==void 0&&(o.skip=m.skip),m.slow&&(o.slow=m.slow),m.timeout!==void 0&&(o.timeout=m.timeout),o.baseTitle=m.name||m.testFlow?.goal),o.suiteName=l.name,l.tags?.length&&(o.suiteTags=l.tags),l.use?.baseURL&&(o.baseUrl=l.use.baseURL)}else l.testFlow&&(d=z(l.testFlow),o.baseTitle=l.name||l.testFlow?.goal,l.tags?.length&&(o.tags=l.tags),l.use?.baseURL&&(o.baseUrl=l.use.baseURL))}catch{}if(n||Object.keys(d).length>0){let c=new Set([...Object.keys(d),...Object.keys(n||{})]),l=Array.from(c).map(h=>[h,null]),m=At(l);for(let[h]of m){let S=d[h],g=n?.[h],_=S?.description;if(!_||_==="Action"||_==="Draft"){let A=S?.action_entity;_=A?.action_description||A?.action_data?.kwargs?.description||g?.description||h}let y={stepId:h,description:_,status:g?.status||"pending",duration:g?.duration};if(g?.message){let A=typeof g.message=="string"?g.message:JSON.stringify(g.message,null,2);g.status==="failure"?y.error=A:y.message=A}if(g?.screenshot){let A=g.screenshot,$=a?.path?v.dirname(a.path):"",L=v.isAbsolute(A)?A:v.join($,A);x.existsSync(L)&&(y.screenshot=L)}g?.code&&(y.code=g.code),g?.type&&(y.type=g.type),g?.startTime&&(y.startTime=g.startTime),g?.autoHealed&&(y.autoHealed=g.autoHealed),g?.healedAction&&(y.healedAction=g.healedAction),g?.dismissedModalActions?.length&&(y.dismissedModalActions=g.dismissedModalActions),g?.contextBefore&&(y.contextBefore=g.contextBefore),g?.contextAfter&&(y.contextAfter=g.contextAfter),o.steps.push(y)}}if(n===null&&Object.keys(d).length===0&&!i.endsWith(".yaml.spec.ts")){let c=new Map;if(o.steps=oe(r.steps,"main",void 0,c),o.steps.length>0){let l=new Map;o.actionStepsMap=Object.fromEntries(o.steps.map(m=>{let h=c.get(m.stepId),S;if(h?.file){if(!l.has(h.file))try{l.set(h.file,x.readFileSync(h.file,"utf-8").split(`
|
package/dist/cli.js
CHANGED
|
@@ -17,7 +17,7 @@ Install it as a project dependency instead:
|
|
|
17
17
|
`)}catch{}}function $o(e=Mt()){try{let t=U.readFileSync(e,"utf-8"),r=JSON.parse(t);if(typeof r.latest=="string"&&typeof r.fetchedAt=="number"&&Date.now()-r.fetchedAt<ko)return r}catch{}return null}function Io(e,t=Mt()){try{U.mkdirSync(re.dirname(t),{recursive:!0}),U.writeFileSync(t,JSON.stringify(e))}catch{}}async function Mo(){try{let e=await fetch(To,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(3e3)});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}function Oo(e,t){let r=f=>{let h=f.indexOf("-");return h===-1?[f,!1]:[f.slice(0,h),!0]},n=f=>f.split(".").map(h=>parseInt(h,10)||0),[s,o]=r(e),[i,a]=r(t),c=n(s),l=n(i),p=Math.max(c.length,l.length);for(let f=0;f<p;f++){let h=c[f]??0,g=l[f]??0;if(h<g)return!0;if(h>g)return!1}return!!(o&&!a)}async function Ir(e={}){let t=e.runningVersion??$t,r=e.cwd??process.cwd(),n=e.cacheFile??Mt(),s=e.fetchLatest??Mo,o=e.env??process.env,i=e.warn??(l=>console.warn(l));if(o.CI||t==="dev"||!U.existsSync(re.join(r,"package-lock.json")))return;let a=null,c=$o(n);if(c)a=c.latest;else{try{a=await s()}catch{a=null}a&&Io({latest:a,fetchedAt:Date.now()},n)}a&&Oo(t,a)&&i(`
|
|
18
18
|
\x1B[33m\u26A0 shiplightai ${a} is available (you have ${t}).
|
|
19
19
|
Run: npm update shiplightai\x1B[0m
|
|
20
|
-
`)}var $t,je,To,ko,Po,Qe=x(()=>{"use strict";$t="0.1.
|
|
20
|
+
`)}var $t,je,To,ko,Po,Qe=x(()=>{"use strict";$t="0.1.89",je=$t!=="dev"?$t:void 0,To="https://registry.npmjs.org/shiplightai/latest",ko=3600*1e3,Po=10080*60*1e3});import*as ne from"fs";import*as Rt from"path";import*as Mr from"os";function Ot(){return Rt.join(Mr.homedir(),".shiplight")}function Ze(){return Rt.join(Ot(),"session.json")}function Or(){try{let e=ne.readFileSync(Ze(),"utf8"),t=JSON.parse(e);return!t?.account?.email||!t?.apiBase||typeof t?.refreshToken!="string"||typeof t?.accessToken!="string"||typeof t?.accessTokenExpiresAt!="string"?null:t}catch{return null}}function Rr(e){ne.mkdirSync(Ot(),{recursive:!0,mode:448}),ne.chmodSync(Ot(),448),ne.writeFileSync(Ze(),JSON.stringify(e,null,2),{mode:384}),ne.chmodSync(Ze(),384)}function Lr(){try{ne.unlinkSync(Ze())}catch{}}var Lt=x(()=>{"use strict"});var Br={};te(Br,{clampPollInterval:()=>jr,completeLogin:()=>Ur,isSafeUrl:()=>Fe,pollForApproval:()=>Hr,promptSelect:()=>Nr,removeFromEnvFile:()=>Nt,resolveWebBase:()=>Fr,runLogin:()=>Do,sanitize:()=>se,writeToEnvFile:()=>Dr});import{execFileSync as Ct}from"child_process";import*as he from"fs";import*as De from"os";import*as et from"path";import*as Cr from"readline";function se(e){return e.replace(/[\x00-\x1f\x7f]/g,"?")}function Fe(e){try{let t=new URL(e);return t.protocol==="https:"||t.protocol==="http:"}catch{return!1}}function Co(e){if(!Fe(e))return!1;try{let t=process.platform;if(t==="darwin")Ct("open",[e],{stdio:"ignore"});else if(t==="linux")Ct("xdg-open",[e],{stdio:"ignore"});else if(t==="win32")Ct("cmd.exe",["/c","start","",e],{stdio:"ignore"});else return!1;return!0}catch{return!1}}async function Nr(e,t){if(t.length===1)return t[0].value;let r=Cr.createInterface({input:process.stdin,output:process.stderr});console.error(`
|
|
21
21
|
${e}`);for(let n=0;n<t.length;n++)console.error(` ${n+1}. ${se(t[n].label)}`);return new Promise(n=>{r.question(" Enter number: ",s=>{r.close();let o=parseInt(s,10)-1;o>=0&&o<t.length?n(t[o].value):(console.error(` Invalid selection \u2014 defaulting to "${se(t[0].label)}"
|
|
22
22
|
`),n(t[0].value))})})}function No(e){return typeof e=="string"&&e.length>0&&!/[\n\r]/.test(e)}function jr(e){return Math.max(2,e??5)*1e3}function Dr(e){if(!No(e))throw new Error("Invalid token: contains newlines or is empty");let t=et.resolve(process.cwd(),".env"),r="";try{r=he.readFileSync(t,"utf8")}catch{}let n=r.split(`
|
|
23
23
|
`),s=!1,o=n.map(i=>i.startsWith(`${Ee}=`)||i.startsWith(`# ${Ee}=`)?(s=!0,`${Ee}=${e}`):i);s||o.push(`${Ee}=${e}`),he.writeFileSync(t,o.join(`
|
|
@@ -37,7 +37,7 @@ Install it as a project dependency instead:
|
|
|
37
37
|
`);let r=await fetch(`${t}/api/device-auth/codes`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostname:De.hostname(),os:`${process.platform} ${De.release()}`,cliVersion:Ro})});r.ok||(console.error(" Failed to start login. Please try again."),process.exit(1));let n=await r.json();(!n.device_code||!n.verification_url)&&(console.error(" Unexpected server response. Please try again."),process.exit(1)),Co(n.verification_url)&&console.error(` Opening browser to authenticate...
|
|
38
38
|
`);let o=se(n.verification_url);console.error(" If the browser doesn't open, visit:"),console.error(` ${o}
|
|
39
39
|
`);let i=jr(n.interval),a=await Hr(fetch,t,n.device_code,i);await Ur({fetchFn:fetch,apiBase:t,accessToken:a.access_token,refreshToken:a.refresh_token,accessTokenExpiresAt:a.access_token_expires_at,account:a.account,orgs:a.orgs,selectOrgId:async c=>c.length===1?(console.error(` Organization: ${se(c[0].name)}
|
|
40
|
-
`),c[0].id):Nr("Select organization:",c.map(l=>({label:`${l.name} (${l.slug})`,value:l.id})))})}var Ro,Lo,Ee,jo,jt=x(()=>{"use strict";Lt();Ro="0.1.
|
|
40
|
+
`),c[0].id):Nr("Select organization:",c.map(l=>({label:`${l.name} (${l.slug})`,value:l.id})))})}var Ro,Lo,Ee,jo,jt=x(()=>{"use strict";Lt();Ro="0.1.89",Lo=900*1e3,Ee="SHIPLIGHT_API_TOKEN";jo="https://nova.shiplight.ai"});var Wr={};te(Wr,{runLogout:()=>Fo});async function Fo(e){let t=Or();if(!t){console.error(`
|
|
41
41
|
Not logged in.
|
|
42
42
|
`);return}if(Fe(t.apiBase))try{await fetch(`${t.apiBase}/api/device-auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}Lr(),Nt(t.envFilePath),console.error(`
|
|
43
43
|
\u2713 Logged out (${se(t.account.email)})
|
|
@@ -288,7 +288,7 @@ Shutting down...`);let y=setTimeout(()=>{console.error("Cleanup timed out, force
|
|
|
288
288
|
base_url: ${e}
|
|
289
289
|
statements:
|
|
290
290
|
- URL: /
|
|
291
|
-
`});import yd from"dotenv";function Ia(){return globalThis[$a]}function vt(){let e=Ia();return e===void 0?process.env:e}var $a,pr=x(()=>{"use strict";$a="__shiplightDotenvCache__"});var ur=x(()=>{"use strict";cr()});var dr={};te(dr,{lookupActionStores:()=>Ra,updateActionStores:()=>Ca});function Rs(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}function Ls(){let e=vt(),t=e.SHIPLIGHT_API_TOKEN;return t?{apiUrl:Te(t,e.SHIPLIGHT_API_URL),apiToken:t}:null}async function Ra(e){let t=Ls();if(!t||e.length===0)return new Map;let r=new Map;for(let n of Rs(e,Os))for(let[s,o]of await La(t,n))r.set(s,o);return r}async function La(e,t){try{let r=new AbortController,n=setTimeout(()=>r.abort(),Ma),s=await fetch(`${e.apiUrl}/action-entity-cache/lookup`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiToken}`},body:JSON.stringify({test_paths:t}),signal:r.signal});if(clearTimeout(n),!s.ok)return console.warn(`[shiplight] Cache lookup failed: HTTP ${s.status}`),new Map;let o=await s.json(),i=new Map;for(let[a,c]of Object.entries(o.stores??{}))i.set(a,c);return i}catch(r){return r instanceof Error&&r.name!=="AbortError"&&console.warn("[shiplight] Cache lookup error:",r.message),new Map}}async function Ca(e){let t=Ls();if(!t||e.size===0)return 0;let r=0;for(let n of Rs([...e],Os))r+=await Na(t,new Map(n));return r}async function Na(e,t){try{let r=new AbortController,n=setTimeout(()=>r.abort(),Oa),s={};for(let[a,c]of t)s[a]=c;let o=await fetch(`${e.apiUrl}/action-entity-cache/update`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiToken}`},body:JSON.stringify({stores:s}),signal:r.signal});return clearTimeout(n),o.ok?(await o.json()).updated??0:(console.warn(`[shiplight] Cache update failed: HTTP ${o.status}`),0)}catch(r){return r instanceof Error&&r.name!=="AbortError"&&console.warn("[shiplight] Cache update error:",r.message),0}}var Ma,Oa,Os,fr=x(()=>{"use strict";ur();pr();Ma=2e3,Oa=5e3,Os=100});import*as q from"fs";import*as Ye from"path";import{globSync as ja}from"glob";function Cs(e){let t=vt().SHIPLIGHT_API_TOKEN;return process.env.CI&&t?new gr:new hr(e)}function qe(e){return e.replace(/\//g,"__")+".json"}function Fa(e){return e.replace(/\.json$/,"").replace(/__/g,"/")}var Da,hr,gr,Ns=x(()=>{"use strict";we();pr();Da=".shiplight/action-cache";hr=class{constructor(t){this.cwd=t;this.cacheDir=Ye.join(t,Da)}isCloud=!1;cacheDir;async lookup(t){let r=new Map;if(t.length===0||!q.existsSync(this.cacheDir))return r;for(let n of t){let s=Ye.join(this.cacheDir,qe(n));try{if(q.existsSync(s)){let o=q.readFileSync(s,"utf-8");r.set(n,JSON.parse(o))}}catch{}}return r}async update(t){if(t.size===0)return 0;q.mkdirSync(this.cacheDir,{recursive:!0});let r=0;for(let[n,s]of t)try{let o=Ye.join(this.cacheDir,qe(n)),i=Kt();if(q.existsSync(o))try{i=JSON.parse(q.readFileSync(o,"utf-8"))}catch{}let a={...i,entries:{...i.entries,...s.entries}};q.writeFileSync(o,JSON.stringify(a,null,2)),r++}catch{}return r}loadAll(){if(!q.existsSync(this.cacheDir))return;let t=ja("*.json",{cwd:this.cacheDir});if(t.length===0)return;let r=new Map,n=0;for(let s of t)try{let o=q.readFileSync(Ye.join(this.cacheDir,s),"utf-8"),i=JSON.parse(o),a=Fa(s);r.set(a,i),n+=Object.keys(i.entries??{}).length}catch{}if(r.size!==0)return console.log(`[shiplight] Cache: loaded ${n} cached action entit${n===1?"y":"ies"} for ${r.size} test file${r.size!==1?"s":""}`),r}},gr=class{isCloud=!0;async lookup(t){let{lookupActionStores:r}=await Promise.resolve().then(()=>(fr(),dr));return r(t)}async update(t){let{updateActionStores:r}=await Promise.resolve().then(()=>(fr(),dr));return r(t)}loadAll(){}}});var St,mr=x(()=>{"use strict";St="0.1.
|
|
291
|
+
`});import yd from"dotenv";function Ia(){return globalThis[$a]}function vt(){let e=Ia();return e===void 0?process.env:e}var $a,pr=x(()=>{"use strict";$a="__shiplightDotenvCache__"});var ur=x(()=>{"use strict";cr()});var dr={};te(dr,{lookupActionStores:()=>Ra,updateActionStores:()=>Ca});function Rs(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}function Ls(){let e=vt(),t=e.SHIPLIGHT_API_TOKEN;return t?{apiUrl:Te(t,e.SHIPLIGHT_API_URL),apiToken:t}:null}async function Ra(e){let t=Ls();if(!t||e.length===0)return new Map;let r=new Map;for(let n of Rs(e,Os))for(let[s,o]of await La(t,n))r.set(s,o);return r}async function La(e,t){try{let r=new AbortController,n=setTimeout(()=>r.abort(),Ma),s=await fetch(`${e.apiUrl}/action-entity-cache/lookup`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiToken}`},body:JSON.stringify({test_paths:t}),signal:r.signal});if(clearTimeout(n),!s.ok)return console.warn(`[shiplight] Cache lookup failed: HTTP ${s.status}`),new Map;let o=await s.json(),i=new Map;for(let[a,c]of Object.entries(o.stores??{}))i.set(a,c);return i}catch(r){return r instanceof Error&&r.name!=="AbortError"&&console.warn("[shiplight] Cache lookup error:",r.message),new Map}}async function Ca(e){let t=Ls();if(!t||e.size===0)return 0;let r=0;for(let n of Rs([...e],Os))r+=await Na(t,new Map(n));return r}async function Na(e,t){try{let r=new AbortController,n=setTimeout(()=>r.abort(),Oa),s={};for(let[a,c]of t)s[a]=c;let o=await fetch(`${e.apiUrl}/action-entity-cache/update`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiToken}`},body:JSON.stringify({stores:s}),signal:r.signal});return clearTimeout(n),o.ok?(await o.json()).updated??0:(console.warn(`[shiplight] Cache update failed: HTTP ${o.status}`),0)}catch(r){return r instanceof Error&&r.name!=="AbortError"&&console.warn("[shiplight] Cache update error:",r.message),0}}var Ma,Oa,Os,fr=x(()=>{"use strict";ur();pr();Ma=2e3,Oa=5e3,Os=100});import*as q from"fs";import*as Ye from"path";import{globSync as ja}from"glob";function Cs(e){let t=vt().SHIPLIGHT_API_TOKEN;return process.env.CI&&t?new gr:new hr(e)}function qe(e){return e.replace(/\//g,"__")+".json"}function Fa(e){return e.replace(/\.json$/,"").replace(/__/g,"/")}var Da,hr,gr,Ns=x(()=>{"use strict";we();pr();Da=".shiplight/action-cache";hr=class{constructor(t){this.cwd=t;this.cacheDir=Ye.join(t,Da)}isCloud=!1;cacheDir;async lookup(t){let r=new Map;if(t.length===0||!q.existsSync(this.cacheDir))return r;for(let n of t){let s=Ye.join(this.cacheDir,qe(n));try{if(q.existsSync(s)){let o=q.readFileSync(s,"utf-8");r.set(n,JSON.parse(o))}}catch{}}return r}async update(t){if(t.size===0)return 0;q.mkdirSync(this.cacheDir,{recursive:!0});let r=0;for(let[n,s]of t)try{let o=Ye.join(this.cacheDir,qe(n)),i=Kt();if(q.existsSync(o))try{i=JSON.parse(q.readFileSync(o,"utf-8"))}catch{}let a={...i,entries:{...i.entries,...s.entries}};q.writeFileSync(o,JSON.stringify(a,null,2)),r++}catch{}return r}loadAll(){if(!q.existsSync(this.cacheDir))return;let t=ja("*.json",{cwd:this.cacheDir});if(t.length===0)return;let r=new Map,n=0;for(let s of t)try{let o=q.readFileSync(Ye.join(this.cacheDir,s),"utf-8"),i=JSON.parse(o),a=Fa(s);r.set(a,i),n+=Object.keys(i.entries??{}).length}catch{}if(r.size!==0)return console.log(`[shiplight] Cache: loaded ${n} cached action entit${n===1?"y":"ies"} for ${r.size} test file${r.size!==1?"s":""}`),r}},gr=class{isCloud=!0;async lookup(t){let{lookupActionStores:r}=await Promise.resolve().then(()=>(fr(),dr));return r(t)}async update(t){let{updateActionStores:r}=await Promise.resolve().then(()=>(fr(),dr));return r(t)}loadAll(){}}});var St,mr=x(()=>{"use strict";St="0.1.89"});import{readFileSync as $d,statSync as Id,existsSync as Ua}from"fs";import{resolve as js,relative as Od}from"path";import{globSync as Ld}from"glob";function Ds(e,t=process.argv.slice(2)){let r=[],n=js(e);for(let s of t){if(s.startsWith("-"))continue;let o=s.endsWith(".yaml.spec.ts")?s.replace(/\.yaml\.spec\.ts$/,".test.yaml"):s;if(!o.endsWith(".test.yaml"))continue;let i=js(e,o);Ua(i)&&r.push(i.startsWith(n)?i.slice(n.length+1):o)}return r.length>0?r:null}var jd,Fs=x(()=>{"use strict";gt();mr();jd=`// @generated by shiplightai v${St}`});var Js={};te(Js,{buildPlaywrightSpawnOptions:()=>Hs,buildTestPathsFromGitInfo:()=>Gs,cloudKeyToCwdRelPath:()=>_r,extractConfigArg:()=>vr,extractVarOverrideArgs:()=>zs,loadVarsFile:()=>br,parseVarsArg:()=>wr,preTestDownload:()=>Ks,resolveProjectRootDir:()=>Bs,rewriteTestYamlArg:()=>Vs,runTests:()=>Wa});import{spawn as Ha,execFileSync as Us}from"child_process";import*as D from"fs";import*as R from"path";import{pathToFileURL as Ba}from"url";import{globSync as yr}from"glob";async function Wa(e){(e.includes("--help")||e.includes("-h"))&&(console.log("Usage: shiplight test [playwright-args...]"),console.log(""),console.log("Delegates to `npx playwright test` with all arguments forwarded."),console.log("Auto-detects playwright.config.ts in the current directory."),console.log(""),console.log("Shiplight options:"),console.log(" --vars KEY=VAL[,KEY=VAL...] Override runtime {{VAR}} values (repeatable)."),console.log(" Comma separates pairs, so values cannot"),console.log(" contain commas \u2014 use --vars-file for those."),console.log(" In the space-separated form, the value cannot"),console.log(" start with `--` (it is treated as the next"),console.log(" flag); use --vars=KEY=--value instead."),console.log(' --vars-file <path> JSON file of overrides ({ KEY: "value", ... }).'),console.log(" Values must be strings \u2014 quote numbers."),console.log(""),console.log("Examples:"),console.log(" shiplight test # run all tests"),console.log(" shiplight test --headed # run tests with browser visible"),console.log(" shiplight test tests/login.test.yaml # run a specific YAML test"),console.log(" shiplight test tests/login.test.ts # run a specific TS test"),console.log(" shiplight test --grep 'login' # filter tests by name"),console.log(" shiplight test --vars SAUCE_USER=standard_user"),console.log(" shiplight test --vars-file ./local-vars.json"),process.exit(0));let t=process.cwd(),r=Bs(e,t);vr(e)===void 0&&(["playwright.config.ts","playwright.config.js","playwright.config.mjs"].some(u=>D.existsSync(R.join(t,u)))||(console.warn("Warning: No playwright.config.ts found in current directory."),console.warn(`Make sure you're running from your project root.
|
|
292
292
|
`)));let n=e.includes("--magic"),s=e.filter(h=>h!=="--magic"),o={};try{let{extracted:h,remaining:g}=zs(s,t);s=g,o=h}catch(h){console.error(`[shiplight] ${h.message}`),process.exit(2)}let i=s.map(h=>h.endsWith(".test.yaml")?Vs(h,t):h),a=Cs(r),c=Ds(r,i);await Ks(r,a,c),je&&process.stdout.write(`shiplightai v${je}
|
|
293
293
|
`);let l={...process.env};n&&(l.SHIPLIGHT_MAGIC="1"),Object.keys(o).length>0&&(l.SHIPLIGHT_VARS_OVERRIDE=JSON.stringify(o)),l.SHIPLIGHT_PROJECT_ROOT=r;let p=Ha("npx",["playwright","test",...i],Hs(t,l)),f=await new Promise(h=>{p.on("close",g=>h(g??1))});await Ka(r,a),process.exit(f)}function Hs(e,t){return{stdio:"inherit",shell:process.platform==="win32",cwd:e,env:t}}function vr(e){for(let t=0;t<e.length;t++){let r=e[t];if(r==="-c"||r==="--config")return e[t+1];if(r.startsWith("--config="))return r.slice(9);if(r.startsWith("-c="))return r.slice(3);if(r.startsWith("-c")&&r.length>2)return r.slice(2)}}function Bs(e,t){let r=vr(e),n=r?R.resolve(t,r):t;try{return D.statSync(n).isDirectory()?n:R.dirname(n)}catch{return t}}function Sr(){try{return Us("git",["rev-parse","--show-toplevel"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return null}}function Ga(){try{let e=Us("git",["rev-parse","--abbrev-ref","HEAD"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(e&&e!=="HEAD")return`${e}:`}catch{}return""}function Ws(e,t,r){if(!r)return{testPaths:[...e],branchPrefix:""};let n=Ga(),s=Sr();return Gs(e,t,n,s)}function Gs(e,t,r,n){return{testPaths:e.map(o=>{let i=n?R.relative(n,R.resolve(t,o)):o;return`${r}${i}`}),branchPrefix:r}}function _r(e,t,r,n){let s=t&&e.startsWith(t)?e.slice(t.length):e;return r?R.relative(n,R.resolve(r,s)):s}async function Ks(e,t,r){try{let n=r??yr("**/*.test.yaml",{cwd:e,ignore:["**/node_modules/**"]});if(n.length===0)return;let{testPaths:s,branchPrefix:o}=Ws(n,e,t.isCloud),i=await t.lookup(s);if(i.size===0)return;let a=R.join(e,".shiplight","action-cache");D.mkdirSync(a,{recursive:!0});let c=Sr(),l=0;for(let[p,f]of i){let h=t.isCloud?_r(p,o,c,e):p,g=R.join(a,qe(h));D.writeFileSync(g,JSON.stringify(f,null,2)),l++}console.log(`[shiplight] Cache: downloaded ${l} action store${l!==1?"s":""}`)}catch(n){console.warn("[shiplight] Cache download failed:",n.message)}}async function Ka(e,t){try{let r=R.join(e,"test-results");if(!D.existsSync(r))return;let n=yr("**/new-action-entities.json",{cwd:r});if(n.length===0)return;let s={};for(let f of n)try{let h=D.readFileSync(R.join(r,f),"utf-8"),g=JSON.parse(h);g?.entries&&Object.assign(s,g.entries)}catch{}if(Object.keys(s).length===0)return;let o=yr("**/*.test.yaml",{cwd:e,ignore:["**/node_modules/**"]}),{testPaths:i,branchPrefix:a}=Ws(o,e,t.isCloud),c=new Map;for(let f=0;f<o.length;f++){let h=o[f],g=i[f],u=R.join(e,h.replace(/\.test\.yaml$/,".yaml.spec.ts"));if(!D.existsSync(u))continue;let d=D.readFileSync(u,"utf-8"),w={};for(let[b,y]of Object.entries(s))d.includes(b)&&(w[b]=y);if(Object.keys(w).length>0){let b=t.isCloud?_r(g,a,Sr(),e):g,y=R.join(e,".shiplight","action-cache",qe(b)),m={};if(D.existsSync(y))try{m=JSON.parse(D.readFileSync(y,"utf-8")).entries}catch{}c.set(g,{version:"1.0",entries:{...m,...w}})}}if(c.size===0)return;let l=await t.update(c),p=Array.from(c.values()).reduce((f,h)=>f+Object.keys(h.entries).length,0);console.log(`[shiplight] Cache: saved ${p} action entit${p!==1?"ies":"y"} for ${l} test${l!==1?"s":""}`)}catch(r){console.warn("[shiplight] Cache upload failed:",r.message)}}function Vs(e,t){let r=e.replace(/\.test\.yaml$/,".yaml.spec.ts");return process.platform==="win32"&&Va.test(e)?Ba(R.resolve(t,r)).href:r}function wr(e){let t={};for(let r of e.split(",")){let n=r.trim();if(n==="")continue;let s=n.indexOf("=");if(s<=0)throw new Error(`Invalid --vars entry "${n}": expected KEY=VALUE`);let o=n.slice(0,s).trim();t[o]=n.slice(s+1)}return t}function br(e,t){let r=R.isAbsolute(e)?e:R.join(t,e);if(!D.existsSync(r))throw new Error(`--vars-file not found: ${r}`);let n;try{n=JSON.parse(D.readFileSync(r,"utf-8"))}catch(o){throw new Error(`--vars-file ${r} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new Error(`--vars-file ${r} must be a JSON object`);let s={};for(let[o,i]of Object.entries(n)){if(typeof i!="string")throw new Error(`--vars-file ${r}: key "${o}" must be a string (got ${typeof i})`);s[o]=i}return s}function zs(e,t){let r={},n={},s=[];for(let o=0;o<e.length;o++){let i=e[o];if(i==="--vars"||i==="--vars-file"){let a=e[o+1];if(a===void 0||a.startsWith("--"))throw new Error(`${i} requires a value`);i==="--vars"?Object.assign(n,wr(a)):Object.assign(r,br(a,t)),o+=1;continue}if(i.startsWith("--vars=")){Object.assign(n,wr(i.slice(7)));continue}if(i.startsWith("--vars-file=")){Object.assign(r,br(i.slice(12),t));continue}s.push(i)}return{extracted:{...r,...n},remaining:s}}var Va,Ys=x(()=>{"use strict";Ns();Qe();Fs();Va=/[^\x00-\x7F]/});import qs from"node:path";function L(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function xt(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),r=(e%6e4/1e3).toFixed(0);return`${t}m ${r}s`}function za(e){return`passed after ${e||"?"} ${e===1?"retry":"retries"}`}function Ja(e,t){let r=e||"?",n=e===1?"retry":"retries";return t==="passed"?`passed after ${r} ${n}`:`failed after ${r} ${n}`}function _t(e){switch(e){case"passed":case"success":return'<span class="status-icon passed">✔</span>';case"flaky":return'<span class="status-icon flaky">↻</span>';case"failed":case"failure":case"timedOut":return'<span class="status-icon failed">✘</span>';case"skipped":return'<span class="status-icon skipped">─</span>';case"interrupted":return'<span class="status-icon failed">⚠</span>';default:return'<span class="status-icon pending">○</span>'}}function Ya(e){return`<span class="badge badge-${e}">${e}</span>`}function qa(e){if(!e.code)return"";let t=e.code.split(`
|
|
294
294
|
`);return e.codeStartLine!=null&&e.codeLine!=null?`<div class="step-code"><pre class="code-block">${t.map((s,o)=>{let i=e.codeStartLine+o,a=i===e.codeLine,c=String(i).padStart(4);return`<span class="code-line${a?" code-line-active":""}">${c} \u2502 ${L(s)}</span>`}).join("")}</pre></div>`:`<div class="step-code"><pre class="code-block">${t.map(n=>`<span class="code-line code-line-body">${L(n)}</span>`).join("")}</pre></div>`}function Xa(e){let t=e.duration!=null?`<span class="step-duration">${xt(e.duration)}</span>`:"",r=_t(e.status);if(e.screenshot||e.message||e.error||e.code){let s="";e.screenshot&&(s=`<img src="${L(e.screenshot)}" alt="Step screenshot" class="step-screenshot" />`);let o=e.screenshot?"":qa(e),i="";e.error&&(i=`<div class="step-error"><pre>${L(e.error)}</pre></div>`);let a="";e.message&&!e.error&&(a=`<div class="step-message">${L(e.message)}</div>`);let c=e.status==="failure"?" open":"";return`
|
|
@@ -1204,7 +1204,7 @@ Merged ${c.length} tests from ${p} shards into: ${h}`),await co(f,n),r&&kc(c),t)
|
|
|
1204
1204
|
</details>
|
|
1205
1205
|
`}return a}function kc(e){let t=process.env.GITHUB_STEP_SUMMARY;if(!t){console.warn("Warning: $GITHUB_STEP_SUMMARY not set, skipping GitHub summary.");return}M.appendFileSync(t,lo(e)),console.log("GitHub step summary written.")}var uo=x(()=>{"use strict";Zs();so();Qe()});var fo={};te(fo,{runTranspile:()=>Ec});import*as kt from"path";import{glob as Pc}from"glob";async function Ec(e){(e.includes("--help")||e.includes("-h"))&&(console.log("Usage: shiplight transpile [glob]"),console.log(""),console.log("Transpiles YAML test files to Playwright spec files (.yaml.spec.ts)."),console.log("Validates syntax and reports action coverage warnings."),console.log("Default glob: **/*.test.yaml"),console.log(""),console.log("Examples:"),console.log(" shiplight transpile # transpile all YAML tests"),console.log(' shiplight transpile "tests/**/*.test.yaml" # transpile specific directory'),console.log(" shiplight transpile tests/login.test.yaml # transpile a single file"),process.exit(0));let t=e[0]||"**/*.test.yaml",r=process.cwd(),n=await Pc(t,{cwd:r,ignore:["node_modules/**","*.yaml.spec.ts"]});n.length===0&&(console.log(`No files matched: ${t}`),process.exit(0));let s=0,o=0,i=0;for(let a of n.sort()){let c=kt.resolve(r,a),l=cs(c,{version:St,basePath:r});if(!l.valid){s++,console.log(`
|
|
1206
1206
|
\u2717 ${a}`);for(let f of l.errors)console.log(` ERROR: ${f}`);continue}i++;let p=kt.basename(l.specFile);if(l.warnings.length>0){o++,console.log(`\u26A0 ${a} \u2192 ${p}`);for(let f of l.warnings)console.log(` WARNING: ${f}`)}else console.log(`\u2713 ${a} \u2192 ${p}`)}console.log(`
|
|
1207
|
-
${n.length} file(s): ${i} transpiled, ${s} error(s), ${o} warning(s)`),process.exit(s>0?1:0)}var ho=x(()=>{"use strict";gt();mr()});var yo={};te(yo,{runInspect:()=>Ac});import*as Pt from"fs";import*as go from"path";async function Ac(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(console.log("Usage: shiplight inspect <file.test.yaml> [options]"),console.log(""),console.log("Parse a YAML test file and output the resulting TestFlow JSON."),console.log("Useful for verifying YAML \u2192 JSON conversion."),console.log(""),console.log("Options:"),console.log(" --pretty Pretty-print JSON (default)"),console.log(" --compact Compact JSON output"),console.log(" --stats Show statement statistics only"),console.log(""),console.log("Examples:"),console.log(" shiplight inspect tests/login.test.yaml"),console.log(" shiplight inspect tests/suite.test.yaml --stats"),console.log(" shiplight inspect tests/login.test.yaml --compact | jq ."),process.exit(e.length===0?1:0));let t=e.includes("--compact"),r=e.includes("--stats"),n=e.find(i=>!i.startsWith("--"));n||(console.error("Error: no file specified"),process.exit(1));let s=go.resolve(process.cwd(),n);Pt.existsSync(s)||(console.error(`Error: file not found: ${s}`),process.exit(1));let o=Pt.readFileSync(s,"utf-8");try{let i=We(o),a=Y(o);if(r)$c(a,i);else{let c={...i.test_case_id!==void 0?{test_case_id:i.test_case_id}:{},...i.name?{name:i.name}:{},testFlow:a};console.log(JSON.stringify(c,null,t?0:2))}}catch(i){console.error(`Error parsing ${n}: ${i.message}`),process.exit(1)}}function $c(e,t){if(console.log(`File: ${t.name||"(unnamed)"}`),t.test_case_id!==void 0&&console.log(`Cloud ID: ${t.test_case_id}`),console.log(`Version: ${e.version||"unknown"}`),e.testGroup){let r=e.testGroup;console.log("Type: suite (testGroup)"),console.log(`Tests: ${r.tests.length}`);for(let n of r.tests){let s=n.skip?` [SKIP${typeof n.skip=="string"?`: ${n.skip}`:""}]`:"";console.log(` - ${n.name}: ${n.statements.length} statements${n.teardown?`, ${n.teardown.length} teardown`:""}${s}`)}r.beforeAll?.length&&console.log(`Hooks: beforeAll (${r.beforeAll.length})`),r.afterAll?.length&&console.log(`Hooks: afterAll (${r.afterAll.length})`),r.beforeEach?.length&&console.log(`Hooks: beforeEach (${r.beforeEach.length})`),r.afterEach?.length&&console.log(`Hooks: afterEach (${r.afterEach.length})`)}else{console.log("Type: single test"),console.log(`Goal: ${e.goal}`),e.url&&console.log(`URL: ${e.url}`),e.baseURL&&console.log(`Base URL: ${e.baseURL}`),console.log(`Statements: ${e.statements?.length??0}`),e.teardown?.length&&console.log(`Teardown: ${e.teardown.length}`);let r=mo(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function mo(e){let t={drafts:0,actions:0,steps:0};for(let r of e)if(r.type==="DRAFT")t.drafts++;else if(r.type==="ACTION")t.actions++;else if(r.type==="STEP"){t.steps++;let n=mo(r.statements??[]);t.drafts+=n.drafts,t.actions+=n.actions,t.steps+=n.steps}return t}var wo=x(()=>{"use strict";we()});var bo=_o((cf,Ic)=>{Ic.exports={name:"shiplightai",version:"0.1.
|
|
1207
|
+
${n.length} file(s): ${i} transpiled, ${s} error(s), ${o} warning(s)`),process.exit(s>0?1:0)}var ho=x(()=>{"use strict";gt();mr()});var yo={};te(yo,{runInspect:()=>Ac});import*as Pt from"fs";import*as go from"path";async function Ac(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(console.log("Usage: shiplight inspect <file.test.yaml> [options]"),console.log(""),console.log("Parse a YAML test file and output the resulting TestFlow JSON."),console.log("Useful for verifying YAML \u2192 JSON conversion."),console.log(""),console.log("Options:"),console.log(" --pretty Pretty-print JSON (default)"),console.log(" --compact Compact JSON output"),console.log(" --stats Show statement statistics only"),console.log(""),console.log("Examples:"),console.log(" shiplight inspect tests/login.test.yaml"),console.log(" shiplight inspect tests/suite.test.yaml --stats"),console.log(" shiplight inspect tests/login.test.yaml --compact | jq ."),process.exit(e.length===0?1:0));let t=e.includes("--compact"),r=e.includes("--stats"),n=e.find(i=>!i.startsWith("--"));n||(console.error("Error: no file specified"),process.exit(1));let s=go.resolve(process.cwd(),n);Pt.existsSync(s)||(console.error(`Error: file not found: ${s}`),process.exit(1));let o=Pt.readFileSync(s,"utf-8");try{let i=We(o),a=Y(o);if(r)$c(a,i);else{let c={...i.test_case_id!==void 0?{test_case_id:i.test_case_id}:{},...i.name?{name:i.name}:{},testFlow:a};console.log(JSON.stringify(c,null,t?0:2))}}catch(i){console.error(`Error parsing ${n}: ${i.message}`),process.exit(1)}}function $c(e,t){if(console.log(`File: ${t.name||"(unnamed)"}`),t.test_case_id!==void 0&&console.log(`Cloud ID: ${t.test_case_id}`),console.log(`Version: ${e.version||"unknown"}`),e.testGroup){let r=e.testGroup;console.log("Type: suite (testGroup)"),console.log(`Tests: ${r.tests.length}`);for(let n of r.tests){let s=n.skip?` [SKIP${typeof n.skip=="string"?`: ${n.skip}`:""}]`:"";console.log(` - ${n.name}: ${n.statements.length} statements${n.teardown?`, ${n.teardown.length} teardown`:""}${s}`)}r.beforeAll?.length&&console.log(`Hooks: beforeAll (${r.beforeAll.length})`),r.afterAll?.length&&console.log(`Hooks: afterAll (${r.afterAll.length})`),r.beforeEach?.length&&console.log(`Hooks: beforeEach (${r.beforeEach.length})`),r.afterEach?.length&&console.log(`Hooks: afterEach (${r.afterEach.length})`)}else{console.log("Type: single test"),console.log(`Goal: ${e.goal}`),e.url&&console.log(`URL: ${e.url}`),e.baseURL&&console.log(`Base URL: ${e.baseURL}`),console.log(`Statements: ${e.statements?.length??0}`),e.teardown?.length&&console.log(`Teardown: ${e.teardown.length}`);let r=mo(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function mo(e){let t={drafts:0,actions:0,steps:0};for(let r of e)if(r.type==="DRAFT")t.drafts++;else if(r.type==="ACTION")t.actions++;else if(r.type==="STEP"){t.steps++;let n=mo(r.statements??[]);t.drafts+=n.drafts,t.actions+=n.actions,t.steps+=n.steps}return t}var wo=x(()=>{"use strict";we()});var bo=_o((cf,Ic)=>{Ic.exports={name:"shiplightai",version:"0.1.89",type:"module",description:"Shiplight CLI for running and debugging .test.yaml files",main:"dist/index.js",types:"dist/index.d.ts",bin:{shiplight:"dist/cli.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/cjs/index.cjs",default:"./dist/index.js"},"./fixture":{types:"./dist/fixture.d.ts",import:"./dist/fixture.js",require:"./dist/cjs/fixture.cjs",default:"./dist/fixture.js"},"./debugger-pw":{types:"./dist/debugger-pw.d.ts",import:"./dist/debugger-pw.js",require:"./dist/cjs/debugger-pw.cjs",default:"./dist/debugger-pw.js"},"./debugger-manager":{types:"./dist/debugger-manager.d.ts",import:"./dist/debugger-manager.js",require:"./dist/cjs/debugger-manager.cjs",default:"./dist/debugger-manager.js"},"./debugger-server":{types:"./dist/debugger-server.d.ts",import:"./dist/debugger-server.js",require:"./dist/cjs/debugger-server.cjs",default:"./dist/debugger-server.js"},"./reporter":{types:"./dist/reporter.d.ts",import:"./dist/reporter.js",require:"./dist/cjs/reporter.cjs",default:"./dist/reporter.js"},"./package.json":"./package.json"},files:["dist","!dist/**/*.map","README.md"],publishConfig:{registry:"https://registry.npmjs.org",access:"public"},scripts:{prebuild:"pnpm typecheck",build:"tsup",pack:"pnpm build && pnpm pack",clean:"rm -rf dist",dev:"tsup --watch","dev:run":"node --import tsx/esm src/cli.ts",test:"pnpm test:unit && pnpm test:logic","test:unit":"tsx --test $(find src -name '*.test.ts' ! -name '*.e2e.test.ts')","test:logic":"playwright test -c playwright.logic.config.ts","test:e2e":"playwright test -c playwright.config.ts","test:browser":"tsx --test $(find src -name '*.e2e.test.ts')",typecheck:"tsc --noEmit"},dependencies:{"@ai-sdk/anthropic":"^3.0.1","@ai-sdk/google":"^3.0.1","@ai-sdk/google-vertex":"^4.0.1","@ai-sdk/openai":"^3.0.1","@ai-sdk/provider":"^3.0.1","@anthropic-ai/claude-agent-sdk":"^0.1.72","@babel/parser":"^7.28.5","@babel/plugin-transform-typescript":"^7.27.0","@google/genai":"^1.34.0","google-auth-library":"^10.0.0","@babel/preset-env":"^7.26.9","@babel/preset-typescript":"^7.27.0","@modelcontextprotocol/sdk":"^1.29.0","@shiplightai/devtools-assets":"workspace:*",ai:"^6.0.3",axios:"^1.15.0",chalk:"^4.1.2",commander:"^11.0.0",dotenv:"^16.0.3",express:"^5.2.1","fs-extra":"^11.2.0",glob:"^13.0.0","html-to-text":"^9.0.5",open:"^10.1.0",openai:"^6.25.0",ora:"^5.4.1",otplib:"^13.4.0","p-retry":"^6.2.1",sharp:"^0.34.5",uuid:"^11.1.0",yaml:"^2.8.3",zod:"^3.22.0","zod-to-json-schema":"^3.24.6"},devDependencies:{"@playwright/test":"1.60.0","@types/express":"^4.17.21","@types/node":"^24.0.0","mcp-tools":"workspace:*","sdk-core":"workspace:*","sdk-internal":"workspace:*","shiplight-tools":"workspace:*","shiplight-types":"workspace:*",tsup:"^8.3.5",typescript:"5.5.4"},peerDependencies:{"@playwright/test":"^1.60.0"},engines:{node:">=22.0.0"},keywords:["playwright","yaml","testing","automation","ai","shiplight","mcp"],author:"Shiplight",license:"MIT"}});Qe();import Mc from"dotenv";Mc.config();$r();Ir();function vo(){console.log(`
|
|
1208
1208
|
Usage: shiplight <command> [options]
|
|
1209
1209
|
|
|
1210
1210
|
Commands:
|