ripplo 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Hs=Object.create;var Ft=Object.defineProperty;var Ks=Object.getOwnPropertyDescriptor;var Qs=Object.getOwnPropertyNames;var Ys=Object.getPrototypeOf,Zs=Object.prototype.hasOwnProperty;var y=(e,t)=>()=>(e&&(t=e(e=0)),t);var nt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),el=(e,t)=>{for(var n in t)Ft(e,n,{get:t[n],enumerable:!0})},tl=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Qs(t))!Zs.call(e,o)&&o!==n&&Ft(e,o,{get:()=>t[o],enumerable:!(r=Ks(t,o))||r.enumerable});return e};var Wr=(e,t,n)=>(n=e!=null?Hs(Ys(e)):{},tl(t||!e||!e.__esModule?Ft(n,"default",{value:e,enumerable:!0}):n,e));function qr(e){return e.data}function Fr(e){return{as(t){return{data:{label:t,node:e}}}}}var rt=y(()=>{"use strict"});function ot(e){let t=e.getPreconditions(),n=e.getTests();nl(n);let r=n.map(a=>rl(a)),o=sl(t,n);return{config:e.getConfig(),graph:o,tests:r}}function nl(e){let t=new Map;e.forEach(n=>{let r=t.get(n.id);if(r!=null)throw new Error(`Duplicate test id "${n.id}" used by "${r}" and "${n.name}"`);t.set(n.id,n.name)})}function rl(e){let t=e.id,{accessedKeys:n,vars:r}=Mr(e.requiresKeys),o=e.startsAtFn==null?void 0:e.startsAtFn(r),a=e.stepsFn==null?[]:e.stepsFn(r),i=o==null?a:[ol(o),...a],l=al(i,n,e.requiresKeys),s=[];return Object.keys(e.requiresKeys).length>0&&n.size===0&&e.implemented&&s.push("Test requires preconditions but never references their data \u2014 destructure and use precondition data in steps()"),{additionalChecks:[],description:e.description,expectedOutcome:e.expectedOutcome,name:e.name,slug:t,spec:l,warnings:s}}function ol(e){return Fr({type:"goto",url:{type:"static",value:e}}).as(`navigate to ${e}`)}function Mr(e){let t=new Set,n={};return Object.keys(e).forEach(r=>{n[r]=new Proxy({},{get(o,a){if(typeof a=="string"){let i=`${r}.${a}`;return t.add(i),`{{${i}}}`}}})}),{accessedKeys:t,vars:n}}function al(e,t,n){let r={};e.forEach((i,l)=>{let s=`step-${String(l)}`,d=l<e.length-1?`step-${String(l+1)}`:void 0;r[s]=il(i,s,d)});let o={};t.forEach(i=>{o[i]={default:`test-${i}`,type:"string"}});let a={...n};return{entryNode:"step-0",nodes:r,variableNamespaces:a,variables:o,version:2}}function il(e,t,n){let{label:r,node:o}=qr(e);return{...o,id:t,label:r,next:n}}function sl(e,t){let n={};e.forEach(a=>{n[a.name]={depends:[...a.dependsOn],description:a.description,returns:[...a.returns]}});let r={},o=[];return t.forEach(a=>{if(!a.implemented||a.startsAtFn==null)return;let i=ll(a.requires,e),{vars:l}=Mr(a.requiresKeys),s=a.startsAtFn(l),d=dl(i,s);r[d]={preconditions:[...i],route:s},o.push({from:d,requiresKeys:a.requiresKeys,to:d,workflow:a.id})}),{edges:o,preconditions:n,states:r,version:3}}function ll(e,t){let n=new Map(t.map(i=>[i.name,i])),r=[],o=new Set;function a(i){o.has(i)||(o.add(i),n.get(i)?.dependsOn.forEach(l=>{a(l)}),r.push(i))}return e.forEach(i=>{a(i)}),r}function dl(e,t){let n=e.toSorted((r,o)=>r.localeCompare(o));return cl(`${n.join("-")}-${t}`)}function cl(e){return e.toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"")}var Mt=y(()=>{"use strict";rt()});var Jr=y(()=>{"use strict";Mt();rt()});import pl from"path";import{createJiti as ul}from"jiti";async function V(e){let t=pl.join(e,".ripplo","index.ts");try{let r=await ul(import.meta.url,{moduleCache:!1}).import(t),a=r!=null&&typeof r=="object"&&"default"in r?r.default:r,i=ot(a);return{builder:a,ok:!0,result:i}}catch(n){return{error:n instanceof Error?n.message:String(n),ok:!1}}}var oe=y(()=>{"use strict";Jr()});function Gt(e){return typeof e=="function"}function Il(e){return Te(e)?"array":typeof e}function Xt(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function Zr(e,t){return e!=null&&typeof e=="object"&&t in e}function jl(e,t){return e!=null&&typeof e!="object"&&e.hasOwnProperty&&e.hasOwnProperty(t)}function Bl(e,t){return $l.call(e,t)}function Vl(e){return!Bl(Dl,e)}function ql(e){return String(e).replace(/[&<>"'`=\/]/g,function(n){return Wl[n]})}function Xl(e,t){if(!e)return[];var n=!1,r=[],o=[],a=[],i=!1,l=!1,s="",d=0;function c(){if(i&&!l)for(;a.length;)delete o[a.pop()];else a=[];i=!1,l=!1}var u,p,m;function g(P){if(typeof P=="string"&&(P=P.split(Ml,2)),!Te(P)||P.length!==2)throw new Error("Invalid tags: "+P);u=new RegExp(Xt(P[0])+"\\s*"),p=new RegExp("\\s*"+Xt(P[1])),m=new RegExp("\\s*"+Xt("}"+P[1]))}g(t||Y.tags);for(var k=new Be(e),h,A,S,N,C,T;!k.eos();){if(h=k.pos,S=k.scanUntil(u),S)for(var O=0,I=S.length;O<I;++O)N=S.charAt(O),Vl(N)?(a.push(o.length),s+=N):(l=!0,n=!0,s+=" "),o.push(["text",N,h,h+1]),h+=1,N===`
|
|
2
|
+
var Hs=Object.create;var Ft=Object.defineProperty;var Ks=Object.getOwnPropertyDescriptor;var Qs=Object.getOwnPropertyNames;var Ys=Object.getPrototypeOf,Zs=Object.prototype.hasOwnProperty;var y=(e,t)=>()=>(e&&(t=e(e=0)),t);var nt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),el=(e,t)=>{for(var n in t)Ft(e,n,{get:t[n],enumerable:!0})},tl=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Qs(t))!Zs.call(e,o)&&o!==n&&Ft(e,o,{get:()=>t[o],enumerable:!(r=Ks(t,o))||r.enumerable});return e};var Wr=(e,t,n)=>(n=e!=null?Hs(Ys(e)):{},tl(t||!e||!e.__esModule?Ft(n,"default",{value:e,enumerable:!0}):n,e));function qr(e){return e.data}function Fr(e){return{as(t){return{data:{label:t,node:e}}}}}var rt=y(()=>{"use strict"});function ot(e){let t=e.getPreconditions(),n=e.getTests();nl(n);let r=n.map(a=>rl(a)),o=sl(t,n);return{config:e.getConfig(),graph:o,tests:r}}function nl(e){let t=new Map;e.forEach(n=>{let r=t.get(n.id);if(r!=null)throw new Error(`Duplicate test id "${n.id}" used by "${r}" and "${n.name}"`);t.set(n.id,n.name)})}function rl(e){let t=e.id,{accessedKeys:n,vars:r}=Mr(e.requiresKeys),o=e.startsAtFn==null?void 0:e.startsAtFn(r),a=e.stepsFn==null?[]:e.stepsFn(r),i=o==null?a:[ol(o),...a],l=al(i,n,e.requiresKeys),s=[];return Object.keys(e.requiresKeys).length>0&&n.size===0&&e.implemented&&s.push("Test requires preconditions but never references their data \u2014 destructure and use precondition data in steps()"),{additionalChecks:[],description:e.description,expectedOutcome:e.expectedOutcome,implemented:e.implemented,name:e.name,slug:t,spec:l,warnings:s}}function ol(e){return Fr({type:"goto",url:{type:"static",value:e}}).as(`navigate to ${e}`)}function Mr(e){let t=new Set,n={};return Object.keys(e).forEach(r=>{n[r]=new Proxy({},{get(o,a){if(typeof a=="string"){let i=`${r}.${a}`;return t.add(i),`{{${i}}}`}}})}),{accessedKeys:t,vars:n}}function al(e,t,n){let r={};e.forEach((i,l)=>{let s=`step-${String(l)}`,d=l<e.length-1?`step-${String(l+1)}`:void 0;r[s]=il(i,s,d)});let o={};t.forEach(i=>{o[i]={default:`test-${i}`,type:"string"}});let a={...n};return{entryNode:"step-0",nodes:r,variableNamespaces:a,variables:o,version:2}}function il(e,t,n){let{label:r,node:o}=qr(e);return{...o,id:t,label:r,next:n}}function sl(e,t){let n={};e.forEach(a=>{n[a.name]={depends:[...a.dependsOn],description:a.description,returns:[...a.returns]}});let r={},o=[];return t.forEach(a=>{if(!a.implemented||a.startsAtFn==null)return;let i=ll(a.requires,e),{vars:l}=Mr(a.requiresKeys),s=a.startsAtFn(l),d=dl(i,s);r[d]={preconditions:[...i],route:s},o.push({from:d,requiresKeys:a.requiresKeys,to:d,workflow:a.id})}),{edges:o,preconditions:n,states:r,version:3}}function ll(e,t){let n=new Map(t.map(i=>[i.name,i])),r=[],o=new Set;function a(i){o.has(i)||(o.add(i),n.get(i)?.dependsOn.forEach(l=>{a(l)}),r.push(i))}return e.forEach(i=>{a(i)}),r}function dl(e,t){let n=e.toSorted((r,o)=>r.localeCompare(o));return cl(`${n.join("-")}-${t}`)}function cl(e){return e.toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"")}var Mt=y(()=>{"use strict";rt()});var Jr=y(()=>{"use strict";Mt();rt()});import pl from"path";import{createJiti as ul}from"jiti";async function V(e){let t=pl.join(e,".ripplo","index.ts");try{let r=await ul(import.meta.url,{moduleCache:!1}).import(t),a=r!=null&&typeof r=="object"&&"default"in r?r.default:r,i=ot(a);return{builder:a,ok:!0,result:i}}catch(n){return{error:n instanceof Error?n.message:String(n),ok:!1}}}var oe=y(()=>{"use strict";Jr()});function Gt(e){return typeof e=="function"}function Il(e){return Te(e)?"array":typeof e}function Xt(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function Zr(e,t){return e!=null&&typeof e=="object"&&t in e}function jl(e,t){return e!=null&&typeof e!="object"&&e.hasOwnProperty&&e.hasOwnProperty(t)}function Bl(e,t){return $l.call(e,t)}function Vl(e){return!Bl(Dl,e)}function ql(e){return String(e).replace(/[&<>"'`=\/]/g,function(n){return Wl[n]})}function Xl(e,t){if(!e)return[];var n=!1,r=[],o=[],a=[],i=!1,l=!1,s="",d=0;function c(){if(i&&!l)for(;a.length;)delete o[a.pop()];else a=[];i=!1,l=!1}var u,p,m;function g(P){if(typeof P=="string"&&(P=P.split(Ml,2)),!Te(P)||P.length!==2)throw new Error("Invalid tags: "+P);u=new RegExp(Xt(P[0])+"\\s*"),p=new RegExp("\\s*"+Xt(P[1])),m=new RegExp("\\s*"+Xt("}"+P[1]))}g(t||Y.tags);for(var k=new Be(e),h,A,S,N,C,T;!k.eos();){if(h=k.pos,S=k.scanUntil(u),S)for(var O=0,I=S.length;O<I;++O)N=S.charAt(O),Vl(N)?(a.push(o.length),s+=N):(l=!0,n=!0,s+=" "),o.push(["text",N,h,h+1]),h+=1,N===`
|
|
3
3
|
`&&(c(),s="",d=0,n=!1);if(!k.scan(u))break;if(i=!0,A=k.scan(zl)||"name",k.scan(Fl),A==="="?(S=k.scanUntil(eo),k.scan(eo),k.scanUntil(p)):A==="{"?(S=k.scanUntil(m),k.scan(Jl),k.scanUntil(p),A="&"):S=k.scanUntil(p),!k.scan(p))throw new Error("Unclosed tag at "+k.pos);if(A==">"?C=[A,S,h,k.pos,s,d,n]:C=[A,S,h,k.pos],d++,o.push(C),A==="#"||A==="^")r.push(C);else if(A==="/"){if(T=r.pop(),!T)throw new Error('Unopened section "'+S+'" at '+h);if(T[1]!==S)throw new Error('Unclosed section "'+T[1]+'" at '+h)}else A==="name"||A==="{"||A==="&"?l=!0:A==="="&&g(S)}if(c(),T=r.pop(),T)throw new Error('Unclosed section "'+T[1]+'" at '+k.pos);return Hl(Gl(o))}function Gl(e){for(var t=[],n,r,o=0,a=e.length;o<a;++o)n=e[o],n&&(n[0]==="text"&&r&&r[0]==="text"?(r[1]+=n[1],r[3]=n[3]):(t.push(n),r=n));return t}function Hl(e){for(var t=[],n=t,r=[],o,a,i=0,l=e.length;i<l;++i)switch(o=e[i],o[0]){case"#":case"^":n.push(o),r.push(o),n=o[4]=[];break;case"/":a=r.pop(),a[5]=o[2],n=r.length>0?r[r.length-1][4]:t;break;default:n.push(o)}return t}function Be(e){this.string=e,this.tail=e,this.pos=0}function Ne(e,t){this.view=e,this.cache={".":this.view},this.parent=t}function F(){this.templateCache={_cache:{},set:function(t,n){this._cache[t]=n},get:function(t){return this._cache[t]},clear:function(){this._cache={}}}}var _l,Te,$l,Dl,Wl,Fl,Ml,eo,Jl,zl,Y,$e,to,no=y(()=>{"use strict";_l=Object.prototype.toString,Te=Array.isArray||function(t){return _l.call(t)==="[object Array]"};$l=RegExp.prototype.test;Dl=/\S/;Wl={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};Fl=/\s*/,Ml=/\s+/,eo=/\s*=/,Jl=/\s*\}/,zl=/#|\^|\/|>|\{|&|=|!/;Be.prototype.eos=function(){return this.tail===""};Be.prototype.scan=function(t){var n=this.tail.match(t);if(!n||n.index!==0)return"";var r=n[0];return this.tail=this.tail.substring(r.length),this.pos+=r.length,r};Be.prototype.scanUntil=function(t){var n=this.tail.search(t),r;switch(n){case-1:r=this.tail,this.tail="";break;case 0:r="";break;default:r=this.tail.substring(0,n),this.tail=this.tail.substring(n)}return this.pos+=r.length,r};Ne.prototype.push=function(t){return new Ne(t,this)};Ne.prototype.lookup=function(t){var n=this.cache,r;if(n.hasOwnProperty(t))r=n[t];else{for(var o=this,a,i,l,s=!1;o;){if(t.indexOf(".")>0)for(a=o.view,i=t.split("."),l=0;a!=null&&l<i.length;)l===i.length-1&&(s=Zr(a,i[l])||jl(a,i[l])),a=a[i[l++]];else a=o.view[t],s=Zr(o.view,t);if(s){r=a;break}o=o.parent}n[t]=r}return Gt(r)&&(r=r.call(this.view)),r};F.prototype.clearCache=function(){typeof this.templateCache<"u"&&this.templateCache.clear()};F.prototype.parse=function(t,n){var r=this.templateCache,o=t+":"+(n||Y.tags).join(":"),a=typeof r<"u",i=a?r.get(o):void 0;return i==null&&(i=Xl(t,n),a&&r.set(o,i)),i};F.prototype.render=function(t,n,r,o){var a=this.getConfigTags(o),i=this.parse(t,a),l=n instanceof Ne?n:new Ne(n,void 0);return this.renderTokens(i,l,r,t,o)};F.prototype.renderTokens=function(t,n,r,o,a){for(var i="",l,s,d,c=0,u=t.length;c<u;++c)d=void 0,l=t[c],s=l[0],s==="#"?d=this.renderSection(l,n,r,o,a):s==="^"?d=this.renderInverted(l,n,r,o,a):s===">"?d=this.renderPartial(l,n,r,a):s==="&"?d=this.unescapedValue(l,n):s==="name"?d=this.escapedValue(l,n,a):s==="text"&&(d=this.rawValue(l)),d!==void 0&&(i+=d);return i};F.prototype.renderSection=function(t,n,r,o,a){var i=this,l="",s=n.lookup(t[1]);function d(p){return i.render(p,n,r,a)}if(s){if(Te(s))for(var c=0,u=s.length;c<u;++c)l+=this.renderTokens(t[4],n.push(s[c]),r,o,a);else if(typeof s=="object"||typeof s=="string"||typeof s=="number")l+=this.renderTokens(t[4],n.push(s),r,o,a);else if(Gt(s)){if(typeof o!="string")throw new Error("Cannot use higher-order sections without the original template");s=s.call(n.view,o.slice(t[3],t[5]),d),s!=null&&(l+=s)}else l+=this.renderTokens(t[4],n,r,o,a);return l}};F.prototype.renderInverted=function(t,n,r,o,a){var i=n.lookup(t[1]);if(!i||Te(i)&&i.length===0)return this.renderTokens(t[4],n,r,o,a)};F.prototype.indentPartial=function(t,n,r){for(var o=n.replace(/[^ \t]/g,""),a=t.split(`
|
|
4
4
|
`),i=0;i<a.length;i++)a[i].length&&(i>0||!r)&&(a[i]=o+a[i]);return a.join(`
|
|
5
5
|
`)};F.prototype.renderPartial=function(t,n,r,o){if(r){var a=this.getConfigTags(o),i=Gt(r)?r(t[1]):r[t[1]];if(i!=null){var l=t[6],s=t[5],d=t[4],c=i;s==0&&d&&(c=this.indentPartial(i,d,l));var u=this.parse(c,a);return this.renderTokens(u,n,r,c,o)}}};F.prototype.unescapedValue=function(t,n){var r=n.lookup(t[1]);if(r!=null)return r};F.prototype.escapedValue=function(t,n,r){var o=this.getConfigEscape(r)||Y.escape,a=n.lookup(t[1]);if(a!=null)return typeof a=="number"&&o===Y.escape?String(a):o(a)};F.prototype.rawValue=function(t){return t[1]};F.prototype.getConfigTags=function(t){return Te(t)?t:t&&typeof t=="object"?t.tags:void 0};F.prototype.getConfigEscape=function(t){if(t&&typeof t=="object"&&!Te(t))return t.escape};Y={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:void 0,escape:void 0,parse:void 0,render:void 0,Scanner:void 0,Context:void 0,Writer:void 0,set templateCache(e){$e.templateCache=e},get templateCache(){return $e.templateCache}},$e=new F;Y.clearCache=function(){return $e.clearCache()};Y.parse=function(t,n){return $e.parse(t,n)};Y.render=function(t,n,r,o){if(typeof t!="string")throw new TypeError('Invalid template! Template should be a "string" but "'+Il(t)+'" was given as the first argument for mustache#render(template, view, partials)');return $e.render(t,n,r,o)};Y.escape=ql;Y.Scanner=Be;Y.Context=Ne;Y.Writer=F;to=Y});function De({defs:e}){return e==null?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Ql({def:n,name:t})]))}function Ql({def:e,name:t}){if(e.type==="env"){let n=process.env[e.key];if(n==null)throw new Error(`Environment variable "${e.key}" not set for variable "${t}"`);return n}return e.default??Kl[e.type]??""}function Ve({ref:e,variables:t}){if(e.type==="static")return e.value;let n=t[e.name];if(n==null||typeof n=="object")throw new Error(`Variable "${e.name}" is not defined`);return n}function J({ref:e,variables:t}){let n=String(Ve({ref:e,variables:t}));return Ht({raw:n,variables:t})}function Ht({raw:e,variables:t}){return to.render(e,t,{},{escape:n=>n})}function Kt({ref:e,variables:t}){let n=Ve({ref:e,variables:t});if(typeof n=="number")return n;let r=Number(n);if(Number.isNaN(r))throw new TypeError(`Cannot convert "${String(n)}" to number`);return r}function Le({name:e,store:t,value:n}){return{...t,[e]:n}}var Kl,le=y(()=>{"use strict";no();Kl={boolean:!1,number:0,string:""}});function _({locator:e,page:t,variables:n}){switch(e.by){case"testId":return t.getByTestId(ro(e.value,n));case"role":return t.getByRole(e.role,{exact:!0,name:e.name==null?void 0:ro(e.name,n)})}}function ro(e,t){return t==null?e:Ht({raw:e,variables:t})}var be=y(()=>{"use strict";le()});async function oo({node:e,page:t,timeout:n}){await _({locator:e.source,page:t,variables:void 0}).dragTo(_({locator:e.target,page:t,variables:void 0}),{timeout:n})}async function ao({node:e,page:t,timeout:n}){await _({locator:e.locator,page:t,variables:void 0}).click({button:"right",timeout:n})}function io({node:e,page:t,variables:n}){return t.once("dialog",async r=>{e.action==="accept"?await r.accept(e.promptText??void 0):await r.dismiss()}),{variables:n}}async function so({node:e,page:t,variables:n}){if(e.action==="write"){if(e.value==null)throw new Error("clipboard write requires a value");let o=J({ref:e.value,variables:n}),a=JSON.stringify(o);return await t.evaluate(`navigator.clipboard.writeText(${a})`),{variables:n}}if(e.variable==null)throw new Error("clipboard read requires a variable name to store the result");let r=String(await t.evaluate("navigator.clipboard.readText()"));return{variables:Le({name:e.variable,store:n,value:r})}}async function lo({node:e,page:t}){let n=t.context();e.state==="granted"?await n.grantPermissions([e.permission]):await n.clearPermissions()}var co=y(()=>{"use strict";be();le()});async function Qt({node:e,page:t,timeout:n,variables:r}){switch(e.type){case"click":case"check":case"uncheck":case"clear":case"dblclick":case"focus":case"hover":case"scrollIntoView":return Zl({node:e,page:t,timeout:n,variables:r});case"rightClick":return await ao({node:e,page:t,timeout:n}),{variables:r};case"goto":{let o=J({ref:e.url,variables:r});return await t.goto(o,{timeout:n,waitUntil:"domcontentloaded"}),e.waitForReady===!0&&await t.waitForFunction("(document.body?.textContent?.trim().length ?? 0) > 0",{timeout:n}),{variables:r}}case"fill":return td({node:e,page:t,timeout:n,variables:r});case"select":return nd({node:e,page:t,timeout:n,variables:r});case"type":return rd({node:e,page:t,timeout:n,variables:r});case"press":return await ed({node:e,page:t,timeout:n}),{variables:r};case"drag":return await oo({node:e,page:t,timeout:n}),{variables:r};case"upload":return od({node:e,page:t,timeout:n,variables:r});case"extractText":return ad({node:e,page:t,timeout:n,variables:r});case"setVariable":{let o=Ve({ref:e.value,variables:r});return{variables:Le({name:e.variable,store:r,value:o})}}case"fail":throw new Error(e.message);case"setViewport":return await t.setViewportSize({height:e.height,width:e.width}),{variables:r};case"handleDialog":return io({node:e,page:t,variables:r});case"clipboard":return so({node:e,page:t,variables:r});case"setPermission":return await lo({node:e,page:t}),{variables:r}}}async function Zl({node:e,page:t,timeout:n,variables:r}){return await _({locator:e.locator,page:t,variables:r})[Yl[e.type]]({timeout:n}),{variables:r}}async function ed({node:e,page:t,timeout:n}){e.locator==null?await t.keyboard.press(e.key):await _({locator:e.locator,page:t,variables:void 0}).press(e.key,{timeout:n})}async function td({node:e,page:t,timeout:n,variables:r}){let o=J({ref:e.value,variables:r});return await _({locator:e.locator,page:t,variables:r}).fill(o,{timeout:n}),{variables:r}}async function nd({node:e,page:t,timeout:n,variables:r}){let o=J({ref:e.value,variables:r});return await _({locator:e.locator,page:t,variables:r}).selectOption(o,{timeout:n}),{variables:r}}async function rd({node:e,page:t,timeout:n,variables:r}){let o=J({ref:e.value,variables:r});return await _({locator:e.locator,page:t,variables:r}).pressSequentially(o,{timeout:n}),{variables:r}}async function od({node:e,page:t,timeout:n,variables:r}){return await _({locator:e.locator,page:t,variables:r}).setInputFiles(e.files,{timeout:n}),{variables:r}}async function ad({node:e,page:t,timeout:n,variables:r}){let o=await _({locator:e.locator,page:t,variables:r}).textContent({timeout:n});if(o==null)throw new Error("extractText: element had no text content");return{variables:Le({name:e.variable,store:r,value:o})}}var Yl,Yt=y(()=>{"use strict";co();be();le();Yl={check:"check",clear:"clear",click:"click",dblclick:"dblclick",focus:"focus",hover:"hover",scrollIntoView:"scrollIntoViewIfNeeded",uncheck:"uncheck"}});async function de({page:e,runStartTime:t,targets:n}){let r=e.viewportSize();if(r==null)throw new Error("Page has no viewport set");let[o,a]=await Promise.all([e.screenshot({type:"png"}),sd(n)]),i=o.toString("base64");return{annotations:a,screenshotBase64:i,snapshotTimestamp:Math.round(performance.now()-t),url:e.url(),viewportHeight:r.height,viewportWidth:r.width}}function id(e){return"locator"in e}async function sd(e){return(await Promise.all(e.map(n=>ld(n)))).filter(n=>n!=null)}async function ld(e){if(!id(e))return{height:0,label:e.label,type:e.type,width:0,x:0,y:0};if(!await e.locator.isVisible().catch(()=>!1))return;let n=await e.locator.boundingBox().catch(()=>null);if(n!=null)return{height:Math.round(n.height),label:e.label,type:e.type,width:Math.round(n.width),x:Math.round(n.x),y:Math.round(n.y)}}function at({node:e,page:t}){if(e.type==="assertUrl")return[{label:e.type,type:"urlBar"}];if(e.type==="drag"){let o=_({locator:e.source,page:t,variables:void 0}),a=_({locator:e.target,page:t,variables:void 0});return[{label:"drag-source",locator:o,type:"action"},{label:"drag-target",locator:a,type:"action"}]}if(!dd(e))return[];let n=e.type.startsWith("assert")?"assertion":"action",r=_({locator:e.locator,page:t,variables:void 0});return[{label:e.type,locator:r,type:n}]}function dd(e){return"locator"in e&&e.locator!=null}var We=y(()=>{"use strict";be()});import{z as cd}from"zod";function R({description:e,execute:t,name:n,schema:r}){let o=cd.toJSONSchema(r,{target:"draft-2020-12"});return{anthropicTool:{description:e,input_schema:{...o,type:"object"},name:n},name:n,async execute(a,i){let l=r.parse(i);return{...await Promise.resolve(t(a,l)),kind:"action"}}}}async function L(e){let t=e.specNode==null?[]:at({node:e.specNode,page:e.page}),n=await de({page:e.page,runStartTime:e.runStartTime,targets:t}),r=[...e.assertions],o={annotations:n.annotations,assertions:r,detail:e.detail,duration:Math.round(e.duration),nodeId:`agent-step-${String(e.stepIndex)}`,nodeType:e.nodeType,screenshotBase64:n.screenshotBase64,snapshotTimestamp:n.snapshotTimestamp,status:e.status,stepIndex:e.stepIndex,title:e.title,url:n.url,viewportHeight:n.viewportHeight,viewportWidth:n.viewportWidth},a=r.length>0?r.map(i=>`${i.status}: ${i.description} \u2014 ${i.detail??""}`).join(`
|
|
@@ -238,7 +238,7 @@ ${n}`].join(`
|
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
`)});import{Box as ks,Text as se}from"ink";import{jsx as Ae,jsxs as Ye}from"react/jsx-runtime";function vr({config:e,error:t,selectProject:n,stage:r}){return Ye(ks,{flexDirection:"column",padding:1,children:[Ye(se,{bold:!0,children:[" ","ripplo setup"]}),Ae(se,{children:""}),Ye(se,{children:[Ae(se,{color:"green",children:" \u2713 "}),Ae(se,{children:"Authenticated"})]}),r==="scaffolding"?Ye(se,{children:[Ae(se,{color:"yellow",children:" * "}),Ae(se,{children:"Setting up local environment..."})]}):Ae(hs,{selectProject:n,serverUrl:e.ripploServerUrl}),t==null?null:Ae(ks,{marginTop:1,children:Ye(se,{color:"red",children:[" ","Error: ",t]})})]})}var As=y(()=>{"use strict";Ss()});import{useEffect as Rm,useState as Nm}from"react";function Ee(){let[e,t]=Nm(ws);return Rm(()=>{function n(){t(ws())}return process.stdout.on("resize",n),()=>{process.stdout.off("resize",n)}},[]),e}function ws(){return{height:process.stdout.rows,width:process.stdout.columns}}var Ut=y(()=>{"use strict"});import{useEffect as Tm,useRef as Lm,useState as bm}from"react";function Rs({config:e,cwd:t}){let[n,r]=bm({config:e,devSessionId:void 0,syncError:void 0,syncing:!0}),o=Lm(void 0);return Tm(()=>{function a({devSessionId:l}){r(s=>({...s,devSessionId:l,syncError:void 0,syncing:!1}))}function i(l){r(s=>({...s,syncError:l,syncing:!1}))}return Xi({config:e,cwd:t}).then(({devSessionId:l,hash:s})=>{a({devSessionId:l}),o.current=hr({config:e,cwd:t,lastHash:s,onSyncError:i,onSyncSuccess:a})}).catch(l=>{let s=l instanceof Error?l.message:String(l);i(s),o.current=hr({config:e,cwd:t,lastHash:"",onSyncError:i,onSyncSuccess:a})}),()=>{o.current?.()}},[e,t]),n}var Ns=y(()=>{"use strict";Sr()});import RR from"chalk";import{z as Ts}from"zod";async function Ls(){let e=new AbortController,t=setTimeout(()=>{e.abort()},3e3);try{let n=await fetch(`https://registry.npmjs.org/${Cm}/latest`,{headers:{accept:"application/json"},signal:e.signal});if(!n.ok)return;let r=await n.json();return vm.parse(r).version}catch{return}finally{clearTimeout(t)}}var xr,Cm,vm,bs=y(()=>{"use strict";ae();xr="0.1.1",Cm="ripplo",vm=Ts.object({version:Ts.string()})});import{useEffect as xm,useState as Pm}from"react";import{Text as we}from"ink";import{jsx as Oe,jsxs as _m}from"react/jsx-runtime";function Cs({activeRunCount:e,browsersReady:t,connected:n,ripploServerUrl:r,syncError:o,width:a}){let i=Um(),l=i!=null&&i!==xr,s=Em({connected:n,syncError:o}),d=t?"":" warming up browsers...",c=e>0?` ${String(e)} running`:"",u=`v${xr}`,p=l?` \u2192 v${i}`:"",m="q to quit",g=` ripplo ${u}${p} | ${r} ${s}${d}${c}`,k=Math.max(0,a-g.length-m.length-1);return _m(we,{inverse:!0,children:[Oe(we,{bold:!0,children:" ripplo "}),Oe(we,{dimColor:!0,children:u}),l?Oe(we,{color:"yellow",children:` \u2192 v${i}`}):null,` | ${r} `,Oe(we,{color:Om({connected:n,syncError:o}),children:s}),t?null:Oe(we,{color:"yellow",children:d}),c," ".repeat(k),Oe(we,{dimColor:!0,children:m})," "]})}function Em({connected:e,syncError:t}){return t!=null?"sync failed":e?"connected":"connecting..."}function Om({connected:e,syncError:t}){return t!=null?"red":e?"green":"yellow"}function Um(){let[e,t]=Pm();return xm(()=>{Ls().then(n=>{n!=null&&t(n)})},[]),e}var vs=y(()=>{"use strict";bs()});import{Box as _t,Text as Ze,useApp as Im,useInput as jm}from"ink";import{jsx as Ue,jsxs as It}from"react/jsx-runtime";function xs({config:e,cwd:t}){let n=Im(),{height:r,width:o}=Ee(),{config:a,devSessionId:i,syncError:l}=Rs({config:e,cwd:t}),{activeRunCount:s,browsersReady:d,connected:c}=ns({config:a,cwd:t,devSessionId:i});jm(p=>{p==="q"&&n.exit()});let u=`${a.ripploServerUrl}/projects/${a.projectId}/developer`;return It(_t,{flexDirection:"column",height:r,width:o,children:[Ue(Cs,{activeRunCount:s,browsersReady:d,connected:c,ripploServerUrl:a.ripploServerUrl,syncError:l,width:o}),It(_t,{flexDirection:"column",flexGrow:1,padding:1,children:[It(_t,{children:[Ue(Ze,{children:"Developer dashboard: "}),Ue(Ze,{color:"cyan",children:u})]}),It(_t,{marginTop:1,children:[Ue(Ze,{dimColor:!0,children:"Run "}),Ue(Ze,{color:"yellow",children:"ripplo doctor"}),Ue(Ze,{dimColor:!0,children:" for health checks"})]})]})]})}var Ps=y(()=>{"use strict";Ut();Ns();Ar();vs()});import{Text as Es}from"ink";import $m from"ink-spinner";import{jsx as Os,jsxs as Dm}from"react/jsx-runtime";function Us({loading:e}){return e?Dm(Es,{color:Bm,children:[Os($m,{type:"dots"})," Starting..."]}):Os(Es,{children:""})}var Bm,_s=y(()=>{"use strict";Bm="#24CFFF"});import{useEffect as Vm,useState as et}from"react";import{Box as Re,Text as Pr,useInput as Wm}from"ink";import{jsx as ye,jsxs as Er}from"react/jsx-runtime";function js({onDismiss:e}){let{height:t,width:n}=Ee(),[r,o]=et(0),[a,i]=et(!1),[l,s]=et(!1),[d,c]=et(!1),[u,p]=et(!1);Wm(()=>{u&&e()}),Vm(()=>{let k=80+jt.length*70+80,h=[...jt.map((A,S)=>setTimeout(()=>{o(S+1)},80+S*70)),setTimeout(()=>{i(!0)},k),setTimeout(()=>{s(!0)},k+200),setTimeout(()=>{c(!0)},k+400),setTimeout(()=>{c(!1),p(!0)},k+2e3),setTimeout(()=>{e()},k+2800)];return()=>{h.forEach(A=>{clearTimeout(A)})}},[e]);let m=jt.length+5,g=Math.max(0,Math.floor((t-m)/2));return Er(Re,{flexDirection:"column",height:t,width:n,children:[ye(Re,{height:g}),Er(Re,{alignItems:"flex-start",flexDirection:"row",justifyContent:"center",children:[ye(Re,{flexDirection:"column",children:jt.map((k,h)=>ye(Pr,{color:Is,children:h<r?k:""},k))}),Er(Re,{flexDirection:"column",paddingLeft:4,paddingTop:5,children:[ye(Pr,{bold:!0,color:Is,children:a?qm:""}),ye(Re,{marginTop:1,children:ye(Pr,{color:"gray",dimColor:!0,children:l?"developer CLI":""})}),ye(Re,{marginTop:2,children:ye(Us,{loading:d})})]})]})]})}var jt,Is,qm,$s=y(()=>{"use strict";Ut();_s();jt=[" XXXX XXXXXXX "," XX XX X X "," XXX XX XX X X ","XXXXXX XX XX XXXXXXX ","XX XXX XX XX ","XX XXX XX XXXXXXXX "," XX XX XX XX "," XX XX XX XX "," XX XXXXX XX"," XX XX XX XX"," XX XX XXXX "," XXX XX "," XXXXXXXXX XX "," XXX XX "," XXXXXXX "],Is="#24CFFF",qm="ripplo"});import{createAuthClient as Fm}from"better-auth/client";import{deviceAuthorizationClient as Mm}from"better-auth/client/plugins";function $t({baseURL:e}){return Fm({baseURL:e,fetchOptions:{headers:{"User-Agent":"Ripplo CLI"}},plugins:[Mm()]})}var Or=y(()=>{"use strict"});import{exec as Jm}from"child_process";async function Ds({cwd:e,onDeviceCode:t,url:n}){let r=n??Ke().RIPPLO_SERVER_URL,o=$t({baseURL:r}),a=await o.device.code({client_id:Bs});if(a.error!=null)throw new Error(`Failed to request device code: ${a.error.error_description}`);let{device_code:i,user_code:l,verification_uri_complete:s}=a.data;t({userCode:l,verificationUrl:s}),Ym(s);let d=await Xm({authClient:o,deviceCode:i});return _n(e,d),d}async function Xm({authClient:e,deviceCode:t}){for(;;){await Km(zm);let n=await e.device.token({client_id:Bs,device_code:t,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(n.data?.access_token!=null)return n.data.access_token;if(n.error==null)continue;if(!Hm(n.error.error))throw new Error(`Authorization failed: ${n.error.error_description}`)}}function Hm(e){return Gm.has(e)}function Km(e){return new Promise(t=>{setTimeout(t,e)})}function Qm(){return process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open"}function Ym(e){let t=Qm();Jm(`${t} "${e}"`,()=>{})}var zm,Bs,Gm,Vs=y(()=>{"use strict";ae();Or();Tt();zm=5e3,Bs="ripplo-cli";Gm=new Set(["authorization_pending","slow_down"])});import{useCallback as Ur,useEffect as Zm,useState as _e}from"react";import{execSync as ef}from"child_process";import re from"fs";import Z from"path";function qs({cwd:e,initialToken:t,serverUrl:n}){let[r,o]=_e(t==null?"login":"validating"),[a,i]=_e(),[l,s]=_e(),[d,c]=_e(t),[u,p]=_e(!1),[m,g]=_e();Zm(()=>{if(t==null)return;$t({baseURL:n}).getSession({fetchOptions:{headers:{Authorization:`Bearer ${t}`}}}).then(N=>{if(N.data==null){o("login");return}return _r({cwd:e,serverUrl:n,token:t})}).then(N=>{if(N==null){o("select-project");return}i(N),o("complete")}).catch(N=>{s(N instanceof Error?N.message:String(N)),o("login")})},[e,t,n]);let k=Ur(()=>{u||(p(!0),s(void 0),Ds({cwd:e,onDeviceCode:g,url:n}).then(S=>(c(S),_r({cwd:e,serverUrl:n,token:S}))).then(S=>{S==null?o("select-project"):(i(S),o("complete"))}).catch(S=>{p(!1),g(void 0),s(S instanceof Error?S.message:String(S))}))},[e,u,n]),h=Ur(S=>{let N=a?.token??d??t;if(N==null){s("No authentication token available");return}o("scaffolding"),s(void 0),tf({cwd:e,projectId:S.id}).then(()=>_r({cwd:e,serverUrl:n,token:N})).then(C=>{i(C??{appUrl:"",preconditionsUrl:"",projectId:S.id,ripploServerUrl:n,token:N,webhookSecret:""}),o("complete")}).catch(C=>{s(C instanceof Error?C.message:String(C)),o("select-project")})},[a,e,t,n,d]),A=Ur(()=>{i(void 0),o("login"),p(!1),g(void 0),s(void 0)},[]);return{config:a,deviceCodeInfo:m,error:l,loginStarted:u,resetToLogin:A,selectProject:h,setStage:o,stage:r,startLogin:k,token:d}}async function _r({cwd:e,serverUrl:t,token:n}){let r=await V(e);if(r.ok)return{...r.result.config,ripploServerUrl:t,token:n}}async function tf({cwd:e,projectId:t}){of({cwd:e,projectId:t}),pf(e),nf(e),await kn()}function nf(e){let t=rf(e),n=t==="yarn"?`yarn add -D ${Ws.join(" ")}`:`${t} add -D ${Ws.join(" ")}`;w.info("Installing dependencies: %s",n),ef(n,{cwd:e,stdio:"pipe"})}function rf(e){return re.existsSync(Z.join(e,"pnpm-lock.yaml"))?"pnpm":re.existsSync(Z.join(e,"yarn.lock"))?"yarn":re.existsSync(Z.join(e,"bun.lockb"))||re.existsSync(Z.join(e,"bun.lock"))?"bun":"npm"}function of({cwd:e,projectId:t}){let n=Z.join(e,".ripplo"),r=Z.join(n,"tests"),o=Z.join(n,"preconditions");re.mkdirSync(r,{recursive:!0}),re.mkdirSync(o,{recursive:!0}),Bt(Z.join(n,"ripplo.ts"),af(t)),Bt(Z.join(n,"index.ts"),lf),Bt(Z.join(n,".env"),sf()),Bt(Z.join(n,"tsconfig.json"),df)}function Bt(e,t){re.existsSync(e)||re.writeFileSync(e,t)}function af(e){return`import { config } from "dotenv";
|
|
241
|
+
`)});import{Box as ks,Text as se}from"ink";import{jsx as Ae,jsxs as Ye}from"react/jsx-runtime";function vr({config:e,error:t,selectProject:n,stage:r}){return Ye(ks,{flexDirection:"column",padding:1,children:[Ye(se,{bold:!0,children:[" ","ripplo setup"]}),Ae(se,{children:""}),Ye(se,{children:[Ae(se,{color:"green",children:" \u2713 "}),Ae(se,{children:"Authenticated"})]}),r==="scaffolding"?Ye(se,{children:[Ae(se,{color:"yellow",children:" * "}),Ae(se,{children:"Setting up local environment..."})]}):Ae(hs,{selectProject:n,serverUrl:e.ripploServerUrl}),t==null?null:Ae(ks,{marginTop:1,children:Ye(se,{color:"red",children:[" ","Error: ",t]})})]})}var As=y(()=>{"use strict";Ss()});import{useEffect as Rm,useState as Nm}from"react";function Ee(){let[e,t]=Nm(ws);return Rm(()=>{function n(){t(ws())}return process.stdout.on("resize",n),()=>{process.stdout.off("resize",n)}},[]),e}function ws(){return{height:process.stdout.rows,width:process.stdout.columns}}var Ut=y(()=>{"use strict"});import{useEffect as Tm,useRef as Lm,useState as bm}from"react";function Rs({config:e,cwd:t}){let[n,r]=bm({config:e,devSessionId:void 0,syncError:void 0,syncing:!0}),o=Lm(void 0);return Tm(()=>{function a({devSessionId:l}){r(s=>({...s,devSessionId:l,syncError:void 0,syncing:!1}))}function i(l){r(s=>({...s,syncError:l,syncing:!1}))}return Xi({config:e,cwd:t}).then(({devSessionId:l,hash:s})=>{a({devSessionId:l}),o.current=hr({config:e,cwd:t,lastHash:s,onSyncError:i,onSyncSuccess:a})}).catch(l=>{let s=l instanceof Error?l.message:String(l);i(s),o.current=hr({config:e,cwd:t,lastHash:"",onSyncError:i,onSyncSuccess:a})}),()=>{o.current?.()}},[e,t]),n}var Ns=y(()=>{"use strict";Sr()});import RR from"chalk";import{z as Ts}from"zod";async function Ls(){let e=new AbortController,t=setTimeout(()=>{e.abort()},3e3);try{let n=await fetch(`https://registry.npmjs.org/${Cm}/latest`,{headers:{accept:"application/json"},signal:e.signal});if(!n.ok)return;let r=await n.json();return vm.parse(r).version}catch{return}finally{clearTimeout(t)}}var xr,Cm,vm,bs=y(()=>{"use strict";ae();xr="0.1.2",Cm="ripplo",vm=Ts.object({version:Ts.string()})});import{useEffect as xm,useState as Pm}from"react";import{Text as we}from"ink";import{jsx as Oe,jsxs as _m}from"react/jsx-runtime";function Cs({activeRunCount:e,browsersReady:t,connected:n,ripploServerUrl:r,syncError:o,width:a}){let i=Um(),l=i!=null&&i!==xr,s=Em({connected:n,syncError:o}),d=t?"":" warming up browsers...",c=e>0?` ${String(e)} running`:"",u=`v${xr}`,p=l?` \u2192 v${i}`:"",m="q to quit",g=` ripplo ${u}${p} | ${r} ${s}${d}${c}`,k=Math.max(0,a-g.length-m.length-1);return _m(we,{inverse:!0,children:[Oe(we,{bold:!0,children:" ripplo "}),Oe(we,{dimColor:!0,children:u}),l?Oe(we,{color:"yellow",children:` \u2192 v${i}`}):null,` | ${r} `,Oe(we,{color:Om({connected:n,syncError:o}),children:s}),t?null:Oe(we,{color:"yellow",children:d}),c," ".repeat(k),Oe(we,{dimColor:!0,children:m})," "]})}function Em({connected:e,syncError:t}){return t!=null?"sync failed":e?"connected":"connecting..."}function Om({connected:e,syncError:t}){return t!=null?"red":e?"green":"yellow"}function Um(){let[e,t]=Pm();return xm(()=>{Ls().then(n=>{n!=null&&t(n)})},[]),e}var vs=y(()=>{"use strict";bs()});import{Box as _t,Text as Ze,useApp as Im,useInput as jm}from"ink";import{jsx as Ue,jsxs as It}from"react/jsx-runtime";function xs({config:e,cwd:t}){let n=Im(),{height:r,width:o}=Ee(),{config:a,devSessionId:i,syncError:l}=Rs({config:e,cwd:t}),{activeRunCount:s,browsersReady:d,connected:c}=ns({config:a,cwd:t,devSessionId:i});jm(p=>{p==="q"&&n.exit()});let u=`${a.ripploServerUrl}/projects/${a.projectId}/developer`;return It(_t,{flexDirection:"column",height:r,width:o,children:[Ue(Cs,{activeRunCount:s,browsersReady:d,connected:c,ripploServerUrl:a.ripploServerUrl,syncError:l,width:o}),It(_t,{flexDirection:"column",flexGrow:1,padding:1,children:[It(_t,{children:[Ue(Ze,{children:"Developer dashboard: "}),Ue(Ze,{color:"cyan",children:u})]}),It(_t,{marginTop:1,children:[Ue(Ze,{dimColor:!0,children:"Run "}),Ue(Ze,{color:"yellow",children:"ripplo doctor"}),Ue(Ze,{dimColor:!0,children:" for health checks"})]})]})]})}var Ps=y(()=>{"use strict";Ut();Ns();Ar();vs()});import{Text as Es}from"ink";import $m from"ink-spinner";import{jsx as Os,jsxs as Dm}from"react/jsx-runtime";function Us({loading:e}){return e?Dm(Es,{color:Bm,children:[Os($m,{type:"dots"})," Starting..."]}):Os(Es,{children:""})}var Bm,_s=y(()=>{"use strict";Bm="#24CFFF"});import{useEffect as Vm,useState as et}from"react";import{Box as Re,Text as Pr,useInput as Wm}from"ink";import{jsx as ye,jsxs as Er}from"react/jsx-runtime";function js({onDismiss:e}){let{height:t,width:n}=Ee(),[r,o]=et(0),[a,i]=et(!1),[l,s]=et(!1),[d,c]=et(!1),[u,p]=et(!1);Wm(()=>{u&&e()}),Vm(()=>{let k=80+jt.length*70+80,h=[...jt.map((A,S)=>setTimeout(()=>{o(S+1)},80+S*70)),setTimeout(()=>{i(!0)},k),setTimeout(()=>{s(!0)},k+200),setTimeout(()=>{c(!0)},k+400),setTimeout(()=>{c(!1),p(!0)},k+2e3),setTimeout(()=>{e()},k+2800)];return()=>{h.forEach(A=>{clearTimeout(A)})}},[e]);let m=jt.length+5,g=Math.max(0,Math.floor((t-m)/2));return Er(Re,{flexDirection:"column",height:t,width:n,children:[ye(Re,{height:g}),Er(Re,{alignItems:"flex-start",flexDirection:"row",justifyContent:"center",children:[ye(Re,{flexDirection:"column",children:jt.map((k,h)=>ye(Pr,{color:Is,children:h<r?k:""},k))}),Er(Re,{flexDirection:"column",paddingLeft:4,paddingTop:5,children:[ye(Pr,{bold:!0,color:Is,children:a?qm:""}),ye(Re,{marginTop:1,children:ye(Pr,{color:"gray",dimColor:!0,children:l?"developer CLI":""})}),ye(Re,{marginTop:2,children:ye(Us,{loading:d})})]})]})]})}var jt,Is,qm,$s=y(()=>{"use strict";Ut();_s();jt=[" XXXX XXXXXXX "," XX XX X X "," XXX XX XX X X ","XXXXXX XX XX XXXXXXX ","XX XXX XX XX ","XX XXX XX XXXXXXXX "," XX XX XX XX "," XX XX XX XX "," XX XXXXX XX"," XX XX XX XX"," XX XX XXXX "," XXX XX "," XXXXXXXXX XX "," XXX XX "," XXXXXXX "],Is="#24CFFF",qm="ripplo"});import{createAuthClient as Fm}from"better-auth/client";import{deviceAuthorizationClient as Mm}from"better-auth/client/plugins";function $t({baseURL:e}){return Fm({baseURL:e,fetchOptions:{headers:{"User-Agent":"Ripplo CLI"}},plugins:[Mm()]})}var Or=y(()=>{"use strict"});import{exec as Jm}from"child_process";async function Ds({cwd:e,onDeviceCode:t,url:n}){let r=n??Ke().RIPPLO_SERVER_URL,o=$t({baseURL:r}),a=await o.device.code({client_id:Bs});if(a.error!=null)throw new Error(`Failed to request device code: ${a.error.error_description}`);let{device_code:i,user_code:l,verification_uri_complete:s}=a.data;t({userCode:l,verificationUrl:s}),Ym(s);let d=await Xm({authClient:o,deviceCode:i});return _n(e,d),d}async function Xm({authClient:e,deviceCode:t}){for(;;){await Km(zm);let n=await e.device.token({client_id:Bs,device_code:t,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(n.data?.access_token!=null)return n.data.access_token;if(n.error==null)continue;if(!Hm(n.error.error))throw new Error(`Authorization failed: ${n.error.error_description}`)}}function Hm(e){return Gm.has(e)}function Km(e){return new Promise(t=>{setTimeout(t,e)})}function Qm(){return process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open"}function Ym(e){let t=Qm();Jm(`${t} "${e}"`,()=>{})}var zm,Bs,Gm,Vs=y(()=>{"use strict";ae();Or();Tt();zm=5e3,Bs="ripplo-cli";Gm=new Set(["authorization_pending","slow_down"])});import{useCallback as Ur,useEffect as Zm,useState as _e}from"react";import{execSync as ef}from"child_process";import re from"fs";import Z from"path";function qs({cwd:e,initialToken:t,serverUrl:n}){let[r,o]=_e(t==null?"login":"validating"),[a,i]=_e(),[l,s]=_e(),[d,c]=_e(t),[u,p]=_e(!1),[m,g]=_e();Zm(()=>{if(t==null)return;$t({baseURL:n}).getSession({fetchOptions:{headers:{Authorization:`Bearer ${t}`}}}).then(N=>{if(N.data==null){o("login");return}return _r({cwd:e,serverUrl:n,token:t})}).then(N=>{if(N==null){o("select-project");return}i(N),o("complete")}).catch(N=>{s(N instanceof Error?N.message:String(N)),o("login")})},[e,t,n]);let k=Ur(()=>{u||(p(!0),s(void 0),Ds({cwd:e,onDeviceCode:g,url:n}).then(S=>(c(S),_r({cwd:e,serverUrl:n,token:S}))).then(S=>{S==null?o("select-project"):(i(S),o("complete"))}).catch(S=>{p(!1),g(void 0),s(S instanceof Error?S.message:String(S))}))},[e,u,n]),h=Ur(S=>{let N=a?.token??d??t;if(N==null){s("No authentication token available");return}o("scaffolding"),s(void 0),tf({cwd:e,projectId:S.id}).then(()=>_r({cwd:e,serverUrl:n,token:N})).then(C=>{i(C??{appUrl:"",preconditionsUrl:"",projectId:S.id,ripploServerUrl:n,token:N,webhookSecret:""}),o("complete")}).catch(C=>{s(C instanceof Error?C.message:String(C)),o("select-project")})},[a,e,t,n,d]),A=Ur(()=>{i(void 0),o("login"),p(!1),g(void 0),s(void 0)},[]);return{config:a,deviceCodeInfo:m,error:l,loginStarted:u,resetToLogin:A,selectProject:h,setStage:o,stage:r,startLogin:k,token:d}}async function _r({cwd:e,serverUrl:t,token:n}){let r=await V(e);if(r.ok)return{...r.result.config,ripploServerUrl:t,token:n}}async function tf({cwd:e,projectId:t}){of({cwd:e,projectId:t}),pf(e),nf(e),await kn()}function nf(e){let t=rf(e),n=t==="yarn"?`yarn add -D ${Ws.join(" ")}`:`${t} add -D ${Ws.join(" ")}`;w.info("Installing dependencies: %s",n),ef(n,{cwd:e,stdio:"pipe"})}function rf(e){return re.existsSync(Z.join(e,"pnpm-lock.yaml"))?"pnpm":re.existsSync(Z.join(e,"yarn.lock"))?"yarn":re.existsSync(Z.join(e,"bun.lockb"))||re.existsSync(Z.join(e,"bun.lock"))?"bun":"npm"}function of({cwd:e,projectId:t}){let n=Z.join(e,".ripplo"),r=Z.join(n,"tests"),o=Z.join(n,"preconditions");re.mkdirSync(r,{recursive:!0}),re.mkdirSync(o,{recursive:!0}),Bt(Z.join(n,"ripplo.ts"),af(t)),Bt(Z.join(n,"index.ts"),lf),Bt(Z.join(n,".env"),sf()),Bt(Z.join(n,"tsconfig.json"),df)}function Bt(e,t){re.existsSync(e)||re.writeFileSync(e,t)}function af(e){return`import { config } from "dotenv";
|
|
242
242
|
import { createRipplo } from "@ripplo/testing";
|
|
243
243
|
import { z } from "zod";
|
|
244
244
|
|
|
@@ -382,7 +382,7 @@ Results: ${String(o)} passed, ${String(a)} failed out of ${String(t)} runs
|
|
|
382
382
|
`),i.size>0&&(process.stdout.write(`
|
|
383
383
|
Failure patterns:
|
|
384
384
|
`),i.forEach((s,d)=>{process.stdout.write(` ${String(s)}x: ${d}
|
|
385
|
-
`)})),process.exit(a>0?1:0)}Mt();rt();var Di=Wr(nr(),1);import{z as Qe}from"zod";import{z as ne}from"zod";var wu=Qe.object({appUrl:Qe.string(),preconditionsUrl:Qe.string(),projectId:Qe.string(),webhookSecret:Qe.string()});var GA=ne.object({preconditions:ne.array(ne.string().min(1))}),HA=ne.object({data:ne.record(ne.string(),ne.record(ne.string(),ne.string())),preconditions:ne.array(ne.string().min(1))});function Vi(e){let t=[];return e.tests.forEach(n=>{let r=Ru(n),o=a=>{t.push({...a,test:n.slug})};_u.forEach(a=>{a(r,n,o)})}),{diagnostics:t}}function Ru(e){let t=[],n=e.spec.entryNode,r=new Set;for(;n!=null&&!r.has(n);){r.add(n);let o=e.spec.nodes[n];if(o==null)break;t.push(o),n=o.next}return t}function Nu(e,t,n){e.forEach(r=>{r.type==="assertText"&&"operator"in r&&r.operator!=="equals"&&n({message:`${r.type} uses operator "${r.operator}" \u2014 only "equals" is allowed for determinism`,rule:"exact-text-match",step:r.label??r.id})})}function Tu(e,t,n){Object.keys(t.spec.variables??{}).length>0&&e.forEach(o=>{if(o.type==="fill"&&Eu(o.value)){let a=o.value.value;!Ou(a)&&Uu(a)&&n({message:`fill() uses hardcoded value "${a}" \u2014 consider using precondition data via {{namespace.key}}`,rule:"no-hardcoded-data",step:o.label??o.id})}})}function Lu(e,t,n){if(Object.keys(t.spec.variables??{}).length===0)return;e.some(a=>JSON.stringify(a).includes("{{"))||n({message:"Test requires preconditions but steps() never references precondition data \u2014 destructure and use it",rule:"prefer-precondition-data",step:void 0})}function bu(e,t,n){e.forEach(r=>{(r.label==null||r.label.length===0)&&n({message:`Step "${r.id}" lacks .as("...") label \u2014 every step must be labeled`,rule:"missing-label",step:r.id})})}function Cu(e,t,n){let r=new Map;e.forEach(o=>{if(o.label==null)return;let a=r.get(o.label);a==null?r.set(o.label,o.id):n({message:`Duplicate label "${o.label}" \u2014 also used by ${a}`,rule:"no-duplicate-labels",step:o.label})})}function vu(e,t,n){let r=0;e.forEach(o=>{Wi(o)?r=0:(r++,r===3&&n({message:"3+ consecutive actions without an assertion \u2014 add verification between actions",rule:"assert-after-action",step:o.label??o.id}))})}function xu(e,t,n){if(e.length===0)return;let r=e.at(-1);r!=null&&!Wi(r)&&n({message:"Last step is an action, not an assertion \u2014 expectedOutcome should be verified by assertions at the end",rule:"assert-matches-outcome",step:r.label??r.id})}function Pu(e,t,n){e.length===0&&n({message:"Test has zero steps",rule:"no-empty-steps",step:void 0})}function Eu(e){return!(typeof e!="object"||e==null||!("type"in e)||e.type!=="static"||!("value"in e)||typeof e.value!="string")}function Ou(e){return e.includes("{{")}function Uu(e){return e.includes("@")||/\b[a-f0-9]{8,}\b/.test(e)||/^(test|ripplo|example|sample|demo)/i.test(e)}function Wi(e){return e.type.startsWith("assert")}var _u=[Nu,Tu,Lu,bu,Cu,vu,xu,Pu];oe();async function qi(e){let{ids:t,requireImplemented:n}=e,r=process.cwd(),o=await V(r);o.ok||(process.stderr.write(`Compilation failed: ${o.error}
|
|
385
|
+
`)})),process.exit(a>0?1:0)}Mt();rt();var Di=Wr(nr(),1);import{z as Qe}from"zod";import{z as ne}from"zod";var wu=Qe.object({appUrl:Qe.string(),preconditionsUrl:Qe.string(),projectId:Qe.string(),webhookSecret:Qe.string()});var GA=ne.object({preconditions:ne.array(ne.string().min(1))}),HA=ne.object({data:ne.record(ne.string(),ne.record(ne.string(),ne.string())),preconditions:ne.array(ne.string().min(1))});function Vi(e){let t=[];return e.tests.forEach(n=>{let r=Ru(n),o=a=>{t.push({...a,test:n.slug})};_u.forEach(a=>{a(r,n,o)})}),{diagnostics:t}}function Ru(e){let t=[],n=e.spec.entryNode,r=new Set;for(;n!=null&&!r.has(n);){r.add(n);let o=e.spec.nodes[n];if(o==null)break;t.push(o),n=o.next}return t}function Nu(e,t,n){e.forEach(r=>{r.type==="assertText"&&"operator"in r&&r.operator!=="equals"&&n({message:`${r.type} uses operator "${r.operator}" \u2014 only "equals" is allowed for determinism`,rule:"exact-text-match",step:r.label??r.id})})}function Tu(e,t,n){Object.keys(t.spec.variables??{}).length>0&&e.forEach(o=>{if(o.type==="fill"&&Eu(o.value)){let a=o.value.value;!Ou(a)&&Uu(a)&&n({message:`fill() uses hardcoded value "${a}" \u2014 consider using precondition data via {{namespace.key}}`,rule:"no-hardcoded-data",step:o.label??o.id})}})}function Lu(e,t,n){if(Object.keys(t.spec.variables??{}).length===0)return;e.some(a=>JSON.stringify(a).includes("{{"))||n({message:"Test requires preconditions but steps() never references precondition data \u2014 destructure and use it",rule:"prefer-precondition-data",step:void 0})}function bu(e,t,n){e.forEach(r=>{(r.label==null||r.label.length===0)&&n({message:`Step "${r.id}" lacks .as("...") label \u2014 every step must be labeled`,rule:"missing-label",step:r.id})})}function Cu(e,t,n){let r=new Map;e.forEach(o=>{if(o.label==null)return;let a=r.get(o.label);a==null?r.set(o.label,o.id):n({message:`Duplicate label "${o.label}" \u2014 also used by ${a}`,rule:"no-duplicate-labels",step:o.label})})}function vu(e,t,n){let r=0;e.forEach(o=>{Wi(o)?r=0:(r++,r===3&&n({message:"3+ consecutive actions without an assertion \u2014 add verification between actions",rule:"assert-after-action",step:o.label??o.id}))})}function xu(e,t,n){if(e.length===0)return;let r=e.at(-1);r!=null&&!Wi(r)&&n({message:"Last step is an action, not an assertion \u2014 expectedOutcome should be verified by assertions at the end",rule:"assert-matches-outcome",step:r.label??r.id})}function Pu(e,t,n){t.implemented&&e.length===0&&n({message:"Test has zero steps",rule:"no-empty-steps",step:void 0})}function Eu(e){return!(typeof e!="object"||e==null||!("type"in e)||e.type!=="static"||!("value"in e)||typeof e.value!="string")}function Ou(e){return e.includes("{{")}function Uu(e){return e.includes("@")||/\b[a-f0-9]{8,}\b/.test(e)||/^(test|ripplo|example|sample|demo)/i.test(e)}function Wi(e){return e.type.startsWith("assert")}var _u=[Nu,Tu,Lu,bu,Cu,vu,xu,Pu];oe();async function qi(e){let{ids:t,requireImplemented:n}=e,r=process.cwd(),o=await V(r);o.ok||(process.stderr.write(`Compilation failed: ${o.error}
|
|
386
386
|
`),process.exit(1));let a=Vi(o.result),i=t.length===0?a.diagnostics:a.diagnostics.filter(c=>t.includes(c.test));i.forEach(c=>{let u=c.step==null?"":` [${c.step}]`;process.stderr.write(`${c.test}${u} (${c.rule}) ${c.message}
|
|
387
387
|
`)});let l=new Set(o.builder.getUnimplemented().tests),s=n.filter(c=>l.has(c));s.forEach(c=>{process.stderr.write(`${c} (not-implemented) test is still marked .notImplemented()
|
|
388
388
|
`)});let d=i.length+s.length;d>0&&(process.stderr.write(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ripplo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI for Ripplo — AI-powered end-to-end testing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://ripplo.ai",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"tsup": "^8.5.1",
|
|
55
55
|
"typescript": "^5.9.3",
|
|
56
56
|
"@ripplo/eslint-config": "0.0.0",
|
|
57
|
-
"@ripplo/runtime": "^0.0.0",
|
|
58
|
-
"@ripplo/testing": "^0.0.2",
|
|
59
57
|
"@ripplo/graphql": "^0.0.0",
|
|
60
|
-
"@ripplo/
|
|
58
|
+
"@ripplo/runtime": "^0.0.0",
|
|
59
|
+
"@ripplo/spec": "^0.0.0",
|
|
60
|
+
"@ripplo/testing": "^0.0.3"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"dev": "tsx watch src/index.ts",
|