shiplightai 0.1.82 → 0.1.83
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 +45 -45
- package/dist/cjs/fixture.cjs +64 -61
- package/dist/cjs/index.cjs +60 -57
- package/dist/cjs/reporter.cjs +1 -1
- package/dist/cli.js +3 -3
- package/dist/debugger-pw.js +45 -45
- package/dist/fixture.js +61 -58
- package/dist/index.js +59 -56
- package/dist/reporter.js +1 -1
- package/package.json +4 -4
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.83",Le=Ie!=="dev"?Ie:void 0;var hn=3600*1e3,fn=10080*60*1e3;var xt={before:0,main:1,teardown:2,after:3};function Ne(e){let t=e.split(".")[0];return xt[t]??1}function Ce(e){return e.split(".").map(t=>{let r=Number(t);return Number.isNaN(r)?0:r})}function kt(e){return[...e].sort(([t],[r])=>{let i=Ne(t),n=Ne(r);if(i!==n)return i-n;let a=Ce(t),o=Ce(r);for(let p=0;p<Math.max(a.length,o.length);p++){let h=a[p]??-1,l=o[p]??-1;if(h!==l)return h-l}return 0})}function Tt(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 At(e,t){let r=e.toLowerCase();return r.includes("before")?"before":r.includes("after")?"after":t}function ie(e,t="main",r,i,n){r===void 0&&(r=!Tt(e).has("test.step")),n||(n=new Map);let a=[];for(let o of e){if(o.category==="fixture"||o.category==="test.attach")continue;if(o.category==="hook"){let h=At(o.title,t);a.push(...ie(o.steps,h,r,i,n));continue}if(o.category==="test.step"||r&&(o.category==="expect"||o.category==="pw:api")){let h=n.get(t)??0;n.set(t,h+1);let l=`${t}.${h}`,g={stepId:l,description:o.title,status:o.error?"failure":o.duration===-1?"skipped":"success",duration:o.duration>=0?o.duration:void 0};o.error&&(g.error=o.error.message??o.error.stack),i&&o.location&&i.set(l,o.location),a.push(g),o.steps.length>0&&a.push(...ie(o.steps,l,r,i,n))}}return a}function $t(e,t){let r=w.isAbsolute(e)?e:w.join(process.cwd(),e),i=w.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(w.join(r,t),i,"junction"):x.symlinkSync(t,i,"dir")}catch(n){console.warn(`[report] Could not create 'latest' symlink: ${n instanceof Error?n.message:String(n)}`)}}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 l of this.collected){let g=l.test.titlePath().join(" > "),b=r.get(g);b||(b=[],r.set(g,b)),b.push(l)}let i=[];for(let[,l]of r.entries()){let g=l[0].test.location.file,b=[],c,u,m;for(let y=0;y<l.length;y++){let{test:v,result:A}=l[y],$=await this.buildReportTest(v,A,g);c=$,u||(u=$.startTime),m=$.endTime,b.push({attemptNumber:y+1,status:A.status,duration:A.duration,steps:$.steps,error:$.error,videoPath:$.videoPath,tracePath:$.tracePath})}let d=b[b.length-1],{test:S}=l[l.length-1],_={title:S.title,baseTitle:c?.baseTitle,file:w.relative(process.cwd(),g),status:d.status,duration:d.duration,steps:d.steps,error:d.error,videoPath:d.videoPath,tracePath:d.tracePath,actionStepsMap:c?.actionStepsMap,tags:c?.tags,baseUrl:c?.baseUrl,skip:c?.skip,slow:c?.slow,timeout:c?.timeout,parameterSetName:c?.parameterSetName,startTime:u,endTime:m,suiteName:c?.suiteName};b.length>1&&(_.retries=b.length-1,_.attempts=b,b.some(v=>v.status==="failed"||v.status==="timedOut")&&d.status==="passed"&&(_.flaky=!0)),i.push(_)}let n={tests:i,totalDuration:t.duration,timestamp:new Date().toISOString(),shiplightVersion:Le},a=w.isAbsolute(this.outputFolder)?this.outputFolder:w.join(process.cwd(),this.outputFolder);x.mkdirSync(a,{recursive:!0});let o=w.join(a,"screenshots");for(let l=0;l<n.tests.length;l++){let g=n.tests[l],b=g.attempts&&g.attempts.length>0,c=[{obj:g,prefix:b?`test-${l}-attempt-0`:`test-${l}`,screenshotSubDir:`test-${l}`}];if(g.attempts)for(let u=0;u<g.attempts.length;u++)c.push({obj:g.attempts[u],prefix:`test-${l}-attempt-${u+1}`,screenshotSubDir:`test-${l}/attempt-${u}`});for(let{obj:u,prefix:m,screenshotSubDir:d}of c){let S=w.join(o,d),_=!1;for(let y of u.steps)if(y.screenshot&&w.isAbsolute(y.screenshot))try{_||(x.mkdirSync(S,{recursive:!0}),_=!0);let v=`${y.stepId.replace(/\./g,"-")}.png`;x.copyFileSync(y.screenshot,w.join(S,v)),y.screenshot=`screenshots/${d}/${v}`}catch(v){console.warn(`[reporter] Failed to copy screenshot for ${y.stepId}:`,v)}if(u.videoPath&&w.isAbsolute(u.videoPath)){let y=w.extname(u.videoPath)||".webm",v=`${m}-video${y}`;try{x.copyFileSync(u.videoPath,w.join(a,v)),u.videoPath=v}catch{u.videoPath=void 0}}if(u.tracePath&&w.isAbsolute(u.tracePath)){let y=w.extname(u.tracePath)||".zip",v=`${m}-trace${y}`;try{x.copyFileSync(u.tracePath,w.join(a,v)),u.tracePath=v}catch{u.tracePath=void 0}}}}let p=w.join(a,"report-data.json");x.writeFileSync(p,JSON.stringify(n,null,2),"utf-8");let h=w.join(a,"index.html");if(x.writeFileSync(h,Oe({...n,outputDir:a}),"utf-8"),console.log(`
|
|
887
887
|
Shiplight report written to: ${h}`),this.latestSymlinkDir&&$t(this.latestSymlinkDir,w.basename(a)),this.openMode==="always"||this.openMode==="on-failure"&&t.status!=="passed")try{let l=(await import("open")).default;await l(h)}catch{}}printsToStdio(){return!1}async buildReportTest(t,r,i){let n={title:t.title,file:w.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&&(n.error=r.errors.map(c=>c.message||c.stack||String(c)).join(`
|
|
888
888
|
|
|
889
889
|
`)),r.stdout.length>0&&(n.stdout=r.stdout.map(c=>typeof c=="string"?c:c.toString()).join("")),r.stderr.length>0&&(n.stderr=r.stderr.map(c=>typeof c=="string"?c:c.toString()).join(""));for(let c of r.attachments)c.name==="video"&&c.path&&(n.videoPath=c.path),c.name==="trace"&&c.path&&(n.tracePath=c.path);let a=r.attachments.find(c=>c.name==="shiplight-results"),o=null;if(a)try{if(a.body)o=JSON.parse(a.body.toString("utf-8"));else if(a.path){let c=x.readFileSync(a.path,"utf-8");o=JSON.parse(c)}}catch{}let p=i.replace(/\.yaml\.spec\.ts$/,".test.yaml"),h={},l=t.title.match(/^(.*)\s+\[([^\]]+)\]$/),g=l?l[1]:t.title,b=l?l[2]:void 0;if(b&&(n.parameterSetName=b),x.existsSync(p))try{let c=x.readFileSync(p,"utf-8"),u=$e(c,p,this.config.rootDir);if(u.suite){let m=u.suite.tests.find(d=>d.name===g);m&&(h=z(m.testFlow),m.tags?.length&&(n.tags=m.tags),m.skip!==void 0&&(n.skip=m.skip),m.slow&&(n.slow=m.slow),m.timeout!==void 0&&(n.timeout=m.timeout),n.baseTitle=m.name||m.testFlow?.goal),n.suiteName=u.name,u.tags?.length&&(n.suiteTags=u.tags),u.use?.baseURL&&(n.baseUrl=u.use.baseURL)}else u.testFlow&&(h=z(u.testFlow),n.baseTitle=u.name||u.testFlow?.goal,u.tags?.length&&(n.tags=u.tags),u.use?.baseURL&&(n.baseUrl=u.use.baseURL))}catch{}if(o||Object.keys(h).length>0){let c=new Set([...Object.keys(h),...Object.keys(o||{})]),u=Array.from(c).map(d=>[d,null]),m=kt(u);for(let[d]of m){let S=h[d],_=o?.[d],y=S?.description;if(!y||y==="Action"||y==="Draft"){let A=S?.action_entity;y=A?.action_description||A?.action_data?.kwargs?.description||_?.description||d}let v={stepId:d,description:y,status:_?.status||"pending",duration:_?.duration};if(_?.message){let A=typeof _.message=="string"?_.message:JSON.stringify(_.message,null,2);_.status==="failure"?v.error=A:v.message=A}if(_?.screenshot){let A=_.screenshot,$=a?.path?w.dirname(a.path):"",I=w.isAbsolute(A)?A:w.join($,A);x.existsSync(I)&&(v.screenshot=I)}_?.code&&(v.code=_.code),n.steps.push(v)}}if(o===null&&Object.keys(h).length===0&&!i.endsWith(".yaml.spec.ts")){let c=new Map;if(n.steps=ie(r.steps,"main",void 0,c),n.steps.length>0){let u=new Map;n.actionStepsMap=Object.fromEntries(n.steps.map(m=>{let d=c.get(m.stepId),S;if(d?.file){if(!u.has(d.file))try{u.set(d.file,x.readFileSync(d.file,"utf-8").split(`
|
package/dist/cli.js
CHANGED
|
@@ -17,7 +17,7 @@ Install it as a project dependency instead:
|
|
|
17
17
|
`)}catch{}}function Ks(e=yt()){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<Hs)return r}catch{}return null}function Vs(e,t=yt()){try{U.mkdirSync(ee.dirname(t),{recursive:!0}),U.writeFileSync(t,JSON.stringify(e))}catch{}}async function zs(){try{let e=await fetch(Fs,{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 Ys(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),[a,i]=r(t),c=n(s),l=n(a),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&&!i)}async function ur(e={}){let t=e.runningVersion??gt,r=e.cwd??process.cwd(),n=e.cacheFile??yt(),s=e.fetchLatest??zs,o=e.env??process.env,a=e.warn??(l=>console.warn(l));if(o.CI||t==="dev"||!U.existsSync(ee.join(r,"package-lock.json")))return;let i=null,c=Ks(n);if(c)i=c.latest;else{try{i=await s()}catch{i=null}i&&Vs({latest:i,fetchedAt:Date.now()},n)}i&&Ys(t,i)&&a(`
|
|
18
18
|
\x1B[33m\u26A0 shiplightai ${i} is available (you have ${t}).
|
|
19
19
|
Run: npm update shiplightai\x1B[0m
|
|
20
|
-
`)}var gt,Ie,Fs,Hs,Bs,Ge=x(()=>{"use strict";gt="0.1.
|
|
20
|
+
`)}var gt,Ie,Fs,Hs,Bs,Ge=x(()=>{"use strict";gt="0.1.83",Ie=gt!=="dev"?gt:void 0,Fs="https://registry.npmjs.org/shiplightai/latest",Hs=3600*1e3,Bs=10080*60*1e3});import*as N from"fs";import*as O from"path";import{builtinModules as Js}from"node:module";function Me(e){let t;try{t=N.lstatSync(e)}catch(r){return r.code==="ENOENT"?"absent":"inaccessible"}if(t.isSymbolicLink())try{return N.statSync(e).isDirectory()?"directory":"non-directory"}catch(r){return r.code==="ENOENT"?"broken-symlink":"inaccessible"}return t.isDirectory()?"directory":"non-directory"}function fr(e){let t=Me(e);return t==="directory"||t==="non-directory"}function bt(e,t){try{return N.realpathSync(e)}catch(r){throw new Error(`Cannot scaffold: failed to resolve real path of ${e} (${t}): ${r.message}. This is required for the project-root containment check that prevents writes outside the project.`)}}function so(e){let t="shiplight-test-project",r=e.trim();if(!r)return{name:t,original:e};let n=r.toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^[^a-z0-9]+/,"").replace(/[-_.]+$/,"");return n?ro.has(n)?{name:t,original:e}:n.length>no?{name:t,original:e}:{name:n,original:e}:{name:t,original:e}}function oo(e){let t=Me(e);if(!(t==="absent"||t==="directory"))throw t==="broken-symlink"?new Error(`Cannot scaffold into ${e}: path is a broken symlink. Remove or fix the link before scaffolding.`):t==="inaccessible"?new Error(`Cannot scaffold into ${e}: cannot stat path (permission denied or other I/O error).`):new Error(`Cannot scaffold into ${e}: path exists and is not a directory.`)}function ao(e){let t=O.join(e,"package.json"),r;try{r=N.statSync(t)}catch(a){return a.code==="ENOENT"?"absent":"unknown"}if(!r.isFile()||r.size>io)return"unknown";let n;try{n=N.readFileSync(t,"utf-8")}catch{return"unknown"}let s;try{s=JSON.parse(n)}catch{return"unknown"}if(Array.isArray(s)||!s||typeof s!="object")return"unknown";let o=s;return o.type==="module"?"module":o.type==="commonjs"?"commonjs":"unknown"}function vt(e){return e.some(t=>!hr.has(t))}function gr(e,t){let r=O.relative(e,t);return r===""?!0:!(r===".."||r.startsWith(".."+O.sep)||O.isAbsolute(r))}function lo(e,t,r,n){let s=Me(e);if(s==="absent")return;let o=null;try{o=N.lstatSync(e)}catch{}let a=o?.isSymbolicLink()??!1;if(s==="broken-symlink")throw new Error(`Cannot scaffold ${r}: ${e} is a broken symlink. Remove or fix the link before scaffolding.`);if(s==="inaccessible")throw new Error(`Cannot scaffold ${r}: cannot stat ${e} (permission denied or other I/O error). Resolve the access problem before scaffolding.`);if(s==="directory"){let c=a?"a symlink that resolves to a directory":"a directory",l=a?"Remove the symlink (or point it at a file) before scaffolding.":"Remove or rename the directory before scaffolding.";throw new Error(`Cannot scaffold ${r}: ${e} is ${c}, but a file is expected here. ${l}`)}if(!a||n==="skip")return;let i=bt(e,`leaf symlink at ${r}`);if(!gr(t,i))throw new Error(`Cannot scaffold ${r}: ${e} is a symlink that resolves to ${i}, which is outside the project root ${t}. Writes through this link would escape the project.`)}function St(e){let t=O.resolve(e.projectPath),r=so(e.projectName??O.basename(t)),n=r.name;oo(t);let s=[];if(Me(t)==="directory")try{s=N.readdirSync(t)}catch{}N.mkdirSync(t,{recursive:!0});let o=bt(t,"project root"),a=dr.split(`
|
|
21
21
|
`).map(u=>u.trim()).filter(u=>u.length>0&&!u.startsWith("#")),i=co.map(u=>({rel:u,abs:O.join(t,u)})).filter(u=>fr(u.abs)),c=ao(t),l=i.length===0&&c==="commonjs",p=[];if(p.push({kind:"agent_merge",relPath:"package.json",content:Xs.replace(/\{\{name\}\}/g,()=>n),merge:{strategy:"json_merge_deps_and_scripts",humanSummary:"Add shiplightai to dependencies, add test scripts, set type:module and engines.node>=22 (with confirmation).",instructions:`An existing package.json was found. Merge the Shiplight template into it WITHOUT clobbering user fields:
|
|
22
22
|
1. Under .dependencies: add any key from the template's dependencies that is not already present. Do NOT change the version of a key the user already pinned.
|
|
23
23
|
2. Under .scripts: add "test" and "test:headed" only if missing. If a script of the same name already exists, do not overwrite \u2014 instead surface the conflict to the user and suggest renaming.
|
|
@@ -1173,9 +1173,9 @@ Merged ${c.length} tests from ${p} shards into: ${h}`),await bs(f,n),r&&La(c),t)
|
|
|
1173
1173
|
`;for(let l of c)i+=`- ${l}
|
|
1174
1174
|
`;i+=`
|
|
1175
1175
|
</details>
|
|
1176
|
-
`}return i}function La(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,vs(e)),console.log("GitHub step summary written.")}var _s=x(()=>{"use strict";ps();gs();Ge()});var xs,Ts=x(()=>{"use strict";xs="0.1.
|
|
1176
|
+
`}return i}function La(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,vs(e)),console.log("GitHub step summary written.")}var _s=x(()=>{"use strict";ps();gs();Ge()});var xs,Ts=x(()=>{"use strict";xs="0.1.83"});var ks={};ue(ks,{runTranspile:()=>Ra});import*as dt from"path";import{glob as Ca}from"glob";async function Ra(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 Ca(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,a=0;for(let i of n.sort()){let c=dt.resolve(r,i),l=An(c,{version:xs,basePath:r});if(!l.valid){s++,console.log(`
|
|
1177
1177
|
\u2717 ${i}`);for(let f of l.errors)console.log(` ERROR: ${f}`);continue}a++;let p=dt.basename(l.specFile);if(l.warnings.length>0){o++,console.log(`\u26A0 ${i} \u2192 ${p}`);for(let f of l.warnings)console.log(` WARNING: ${f}`)}else console.log(`\u2713 ${i} \u2192 ${p}`)}console.log(`
|
|
1178
|
-
${n.length} file(s): ${a} transpiled, ${s} error(s), ${o} warning(s)`),process.exit(s>0?1:0)}var Ps=x(()=>{"use strict";Ft();Ts()});var $s={};ue($s,{runInspect:()=>Na});import*as ft from"fs";import*as Es from"path";async function Na(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(a=>!a.startsWith("--"));n||(console.error("Error: no file specified"),process.exit(1));let s=Es.resolve(process.cwd(),n);ft.existsSync(s)||(console.error(`Error: file not found: ${s}`),process.exit(1));let o=ft.readFileSync(s,"utf-8");try{let a=Ce(o),i=Y(o);if(r)Da(i,a);else{let c={...a.test_case_id!==void 0?{test_case_id:a.test_case_id}:{},...a.name?{name:a.name}:{},testFlow:i};console.log(JSON.stringify(c,null,t?0:2))}}catch(a){console.error(`Error parsing ${n}: ${a.message}`),process.exit(1)}}function Da(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=As(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function As(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=As(r.statements??[]);t.drafts+=n.drafts,t.actions+=n.actions,t.steps+=n.steps}return t}var Is=x(()=>{"use strict";ge()});var Ms=js((Vu,ja)=>{ja.exports={name:"shiplightai",version:"0.1.
|
|
1178
|
+
${n.length} file(s): ${a} transpiled, ${s} error(s), ${o} warning(s)`),process.exit(s>0?1:0)}var Ps=x(()=>{"use strict";Ft();Ts()});var $s={};ue($s,{runInspect:()=>Na});import*as ft from"fs";import*as Es from"path";async function Na(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(a=>!a.startsWith("--"));n||(console.error("Error: no file specified"),process.exit(1));let s=Es.resolve(process.cwd(),n);ft.existsSync(s)||(console.error(`Error: file not found: ${s}`),process.exit(1));let o=ft.readFileSync(s,"utf-8");try{let a=Ce(o),i=Y(o);if(r)Da(i,a);else{let c={...a.test_case_id!==void 0?{test_case_id:a.test_case_id}:{},...a.name?{name:a.name}:{},testFlow:i};console.log(JSON.stringify(c,null,t?0:2))}}catch(a){console.error(`Error parsing ${n}: ${a.message}`),process.exit(1)}}function Da(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=As(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function As(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=As(r.statements??[]);t.drafts+=n.drafts,t.actions+=n.actions,t.steps+=n.steps}return t}var Is=x(()=>{"use strict";ge()});var Ms=js((Vu,ja)=>{ja.exports={name:"shiplightai",version:"0.1.83",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"}});Ge();import Ua from"dotenv";Ua.config();pr();ur();function Os(){console.log(`
|
|
1179
1179
|
Usage: shiplight <command> [options]
|
|
1180
1180
|
|
|
1181
1181
|
Commands:
|