twd-js 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +20 -24
  2. package/dist/_commonjsHelpers-C6fGbg64.mjs +6 -0
  3. package/dist/_commonjsHelpers-DwGv2jUC.js +1 -0
  4. package/dist/index.cjs.js +35 -35
  5. package/dist/index.d.ts +440 -7
  6. package/dist/index.es.js +2407 -2378
  7. package/dist/mock-sw.js +1 -1
  8. package/dist/runner-ci.cjs.js +1 -1
  9. package/dist/runner-ci.d.ts +28 -12
  10. package/dist/runner-ci.es.js +32 -22
  11. package/dist/runner.cjs.js +1 -1
  12. package/dist/runner.d.ts +55 -41
  13. package/dist/runner.es.js +127 -70
  14. package/dist/vite-plugin.d.ts +21 -1
  15. package/package.json +10 -10
  16. package/dist/asserts/index.d.ts +0 -2
  17. package/dist/commands/mockBridge.d.ts +0 -73
  18. package/dist/commands/url.d.ts +0 -33
  19. package/dist/commands/visit.d.ts +0 -1
  20. package/dist/constants/version.d.ts +0 -1
  21. package/dist/global.d.ts +0 -8
  22. package/dist/initializers/initSidebar.d.ts +0 -22
  23. package/dist/initializers/initTests.d.ts +0 -31
  24. package/dist/plugin/removeMockServiceWorker.d.ts +0 -18
  25. package/dist/proxies/domMessage.d.ts +0 -1
  26. package/dist/proxies/eventsMessage.d.ts +0 -1
  27. package/dist/proxies/screenDom.d.ts +0 -5
  28. package/dist/proxies/userEvent.d.ts +0 -4
  29. package/dist/twd-types.d.ts +0 -106
  30. package/dist/twd.d.ts +0 -178
  31. package/dist/ui/ClosedSidebar.d.ts +0 -6
  32. package/dist/ui/Icons/BaseIcon.d.ts +0 -7
  33. package/dist/ui/Icons/ChevronDown.d.ts +0 -2
  34. package/dist/ui/Icons/ChevronRight.d.ts +0 -2
  35. package/dist/ui/Icons/Loader.d.ts +0 -2
  36. package/dist/ui/Icons/MockRequestIcon.d.ts +0 -2
  37. package/dist/ui/Icons/Play.d.ts +0 -2
  38. package/dist/ui/MockRulesButton.d.ts +0 -1
  39. package/dist/ui/TWDSidebar.d.ts +0 -16
  40. package/dist/ui/TestList.d.ts +0 -17
  41. package/dist/ui/TestListItem.d.ts +0 -39
  42. package/dist/ui/buildTreeFromHandlers.d.ts +0 -14
  43. package/dist/ui/hooks/useLayout.d.ts +0 -6
  44. package/dist/utils/assertionMessage.d.ts +0 -1
  45. package/dist/utils/log.d.ts +0 -1
  46. package/dist/utils/wait.d.ts +0 -3
package/dist/mock-sw.js CHANGED
@@ -1,4 +1,4 @@
1
- const h=e=>{try{return new RegExp(e),!0}catch{return!1}},u=e=>{const s=e.split("?")[0];return/\.([a-zA-Z0-9]+)$/.test(s)};function f(e,s,n){return n.find(t=>{const o=t.method.toLowerCase()===e.toLowerCase();if(t.urlRegex&&h(t.url)){const a=new RegExp(t.url);return o&&a.test(s)}if(u(t.url))return o&&s.includes(t.url);const l=t.url===s||s.includes(t.url);return o&&l&&!u(s)})}function p(e,s,n){e.forEach(t=>t.postMessage({type:"EXECUTED",alias:s.alias,request:n}))}const y=(e,s,n)=>{const o=![204,205,304].includes(s),i=o?JSON.stringify(e):null;return new Response(i,{status:s,headers:o?n||{"Content-Type":"application/json"}:n||{}})},c="1.1.2";let r=[];const g=async e=>{const{method:s}=e.request,n=e.request.url,t=f(s,n,r);t&&(console.log("[TWD] Mock hit:",t.alias,s,n),e.respondWith((async()=>{let o=null;const i=e.request.headers.get("content-type")||"application/json";if(i.includes("application/json"))try{o=await e.request.clone().json()}catch{}else if(i.includes("form"))try{const l=await e.request.clone().formData();o={},l.forEach((a,d)=>{o[d]=a})}catch{}else if(i.includes("text"))try{o=await e.request.clone().text()}catch{}else if(i.includes("octet-stream"))try{o=await e.request.clone().arrayBuffer()}catch{}else if(i.includes("image"))try{o=await e.request.clone().blob()}catch{}else try{o=await e.request.clone().text()}catch{}return self.clients.matchAll().then(l=>{p(l,t,o)}),y(t.response,t.status??200,t.responseHeaders)})()))},m=e=>{e!==c&&console.warn(`[TWD] ⚠️ Version mismatch detected:
1
+ const h=e=>{try{return new RegExp(e),!0}catch{return!1}},u=e=>{const s=e.split("?")[0];return/\.([a-zA-Z0-9]+)$/.test(s)};function f(e,s,n){return n.find(t=>{const o=t.method.toLowerCase()===e.toLowerCase();if(t.urlRegex&&h(t.url)){const a=new RegExp(t.url);return o&&a.test(s)}if(u(t.url))return o&&s.includes(t.url);const l=t.url===s||s.includes(t.url);return o&&l&&!u(s)})}function p(e,s,n){e.forEach(t=>t.postMessage({type:"EXECUTED",alias:s.alias,request:n}))}const y=(e,s,n)=>{const o=![204,205,304].includes(s),i=o?JSON.stringify(e):null;return new Response(i,{status:s,headers:o?n||{"Content-Type":"application/json"}:n||{}})},c="1.2.0";let r=[];const g=async e=>{const{method:s}=e.request,n=e.request.url,t=f(s,n,r);t&&(console.log("[TWD] Mock hit:",t.alias,s,n),e.respondWith((async()=>{let o=null;const i=e.request.headers.get("content-type")||"application/json";if(i.includes("application/json"))try{o=await e.request.clone().json()}catch{}else if(i.includes("form"))try{const l=await e.request.clone().formData();o={},l.forEach((a,d)=>{o[d]=a})}catch{}else if(i.includes("text"))try{o=await e.request.clone().text()}catch{}else if(i.includes("octet-stream"))try{o=await e.request.clone().arrayBuffer()}catch{}else if(i.includes("image"))try{o=await e.request.clone().blob()}catch{}else try{o=await e.request.clone().text()}catch{}return self.clients.matchAll().then(l=>{p(l,t,o)}),y(t.response,t.status??200,t.responseHeaders)})()))},m=e=>{e!==c&&console.warn(`[TWD] ⚠️ Version mismatch detected:
2
2
  Client version: ${e}
3
3
  Service Worker version: ${c}
4
4
 
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("chalk"),$=(e,t)=>{const f=[...e].filter(s=>!s.parent),o=(s,r=0)=>{const c=" ".repeat(r),u=t.find(a=>a.id===s.id);let n="",l="";s.type!=="suite"&&(u?.status==="pass"?n=i.green("✓"):u?.status==="fail"?(n=i.red("✗"),l=` - Error: ${u.error}`):n=i.yellow("○"));const p=s.type==="suite"?`${c}${s.name}`:`${c}${n} ${s.name}`;if(console.log(p),l&&console.log(i.red(`${c}${l}`)),s.children)for(const a of s.children){const d=e.find(y=>y.id===a);d&&o(d,r+1)}};for(const s of f)o(s)},g=async()=>{const e=window.__testRunner,t=[],o=await new e({onStart:()=>{},onPass:s=>{t.push({id:s.id,status:"pass"})},onFail:(s,r)=>{t.push({id:s.id,status:"fail",error:r.message})},onSkip:s=>{t.push({id:s.id,status:"skip"})}}).runAll();return{handlers:Array.from(o.values()),testStatus:t}};exports.executeTests=g;exports.reportResults=$;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=require("./_commonjsHelpers-DwGv2jUC.js");var n={exports:{}},d;function w(){if(d)return n.exports;d=1;var e=String,t=function(){return{isColorSupported:!1,reset:e,bold:e,dim:e,italic:e,underline:e,inverse:e,hidden:e,strikethrough:e,black:e,red:e,green:e,yellow:e,blue:e,magenta:e,cyan:e,white:e,gray:e,bgBlack:e,bgRed:e,bgGreen:e,bgYellow:e,bgBlue:e,bgMagenta:e,bgCyan:e,bgWhite:e,blackBright:e,redBright:e,greenBright:e,yellowBright:e,blueBright:e,magentaBright:e,cyanBright:e,whiteBright:e,bgBlackBright:e,bgRedBright:e,bgGreenBright:e,bgYellowBright:e,bgBlueBright:e,bgMagentaBright:e,bgCyanBright:e,bgWhiteBright:e}};return n.exports=t(),n.exports.createColors=t,n.exports}var y=w();const l=B.getDefaultExportFromCjs(y),m=(e,t)=>{const p=[...e].filter(r=>!r.parent),o=(r,s=0)=>{const a=" ".repeat(s),c=t.find(u=>u.id===r.id);let i="",g="";r.type!=="suite"&&(c?.status==="pass"?i=l.green("✓"):c?.status==="fail"?(i=l.red("✗"),g=` - Error: ${c.error}`):i=l.yellow("○"));const h=r.type==="suite"?`${a}${r.name}`:`${a}${i} ${r.name}`;if(console.log(h),g&&console.log(l.red(`${a}${g}`)),r.children)for(const u of r.children){const b=e.find(f=>f.id===u);b&&o(b,s+1)}};for(const r of p)o(r)},x=async()=>{const e=window.__testRunner,t=[],o=await new e({onStart:()=>{},onPass:r=>{t.push({id:r.id,status:"pass"})},onFail:(r,s)=>{t.push({id:r.id,status:"fail",error:s.message})},onSkip:r=>{t.push({id:r.id,status:"skip"})}}).runAll();return{handlers:Array.from(o.values()),testStatus:t}};exports.executeTests=x;exports.reportResults=m;
@@ -1,12 +1,28 @@
1
- import { Handler } from './runner';
2
- interface TestResult {
3
- id: string;
4
- status: 'pass' | 'fail' | 'skip';
5
- error?: string;
6
- }
7
- export declare const reportResults: (handlers: Handler[], testResults: TestResult[]) => void;
8
- export declare const executeTests: () => Promise<{
9
- handlers: Handler[];
10
- testStatus: TestResult[];
11
- }>;
12
- export {};
1
+ export declare const executeTests: () => Promise<{
2
+ handlers: Handler[];
3
+ testStatus: TestResult[];
4
+ }>;
5
+
6
+ declare interface Handler {
7
+ id: string;
8
+ name: string;
9
+ parent?: string;
10
+ handler: () => void | Promise<void>;
11
+ children?: string[];
12
+ type: 'suite' | 'test';
13
+ status?: 'idle' | 'pass' | 'fail' | 'skip' | 'running';
14
+ logs: string[];
15
+ depth: number;
16
+ only?: boolean;
17
+ skip?: boolean;
18
+ }
19
+
20
+ export declare const reportResults: (handlers: Handler[], testResults: TestResult[]) => void;
21
+
22
+ declare interface TestResult {
23
+ id: string;
24
+ status: 'pass' | 'fail' | 'skip';
25
+ error?: string;
26
+ }
27
+
28
+ export { }
@@ -1,34 +1,44 @@
1
- import i from "chalk";
2
- const y = (e, t) => {
3
- const f = [...e].filter((s) => !s.parent), o = (s, r = 0) => {
4
- const c = " ".repeat(r), a = t.find((u) => u.id === s.id);
5
- let n = "", l = "";
6
- s.type !== "suite" && (a?.status === "pass" ? n = i.green("✓") : a?.status === "fail" ? (n = i.red("✗"), l = ` - Error: ${a.error}`) : n = i.yellow("○"));
7
- const d = s.type === "suite" ? `${c}${s.name}` : `${c}${n} ${s.name}`;
8
- if (console.log(d), l && console.log(i.red(`${c}${l}`)), s.children)
9
- for (const u of s.children) {
10
- const p = e.find(($) => $.id === u);
11
- p && o(p, r + 1);
1
+ import { g as B } from "./_commonjsHelpers-C6fGbg64.mjs";
2
+ var n = { exports: {} }, h;
3
+ function w() {
4
+ if (h) return n.exports;
5
+ h = 1;
6
+ var r = String, t = function() {
7
+ return { isColorSupported: !1, reset: r, bold: r, dim: r, italic: r, underline: r, inverse: r, hidden: r, strikethrough: r, black: r, red: r, green: r, yellow: r, blue: r, magenta: r, cyan: r, white: r, gray: r, bgBlack: r, bgRed: r, bgGreen: r, bgYellow: r, bgBlue: r, bgMagenta: r, bgCyan: r, bgWhite: r, blackBright: r, redBright: r, greenBright: r, yellowBright: r, blueBright: r, magentaBright: r, cyanBright: r, whiteBright: r, bgBlackBright: r, bgRedBright: r, bgGreenBright: r, bgYellowBright: r, bgBlueBright: r, bgMagentaBright: r, bgCyanBright: r, bgWhiteBright: r };
8
+ };
9
+ return n.exports = t(), n.exports.createColors = t, n.exports;
10
+ }
11
+ var y = /* @__PURE__ */ w();
12
+ const a = /* @__PURE__ */ B(y), m = (r, t) => {
13
+ const p = [...r].filter((e) => !e.parent), o = (e, s = 0) => {
14
+ const g = " ".repeat(s), l = t.find((u) => u.id === e.id);
15
+ let i = "", c = "";
16
+ e.type !== "suite" && (l?.status === "pass" ? i = a.green("✓") : l?.status === "fail" ? (i = a.red("✗"), c = ` - Error: ${l.error}`) : i = a.yellow("○"));
17
+ const d = e.type === "suite" ? `${g}${e.name}` : `${g}${i} ${e.name}`;
18
+ if (console.log(d), c && console.log(a.red(`${g}${c}`)), e.children)
19
+ for (const u of e.children) {
20
+ const b = r.find((f) => f.id === u);
21
+ b && o(b, s + 1);
12
22
  }
13
23
  };
14
- for (const s of f) o(s);
15
- }, g = async () => {
16
- const e = window.__testRunner, t = [], o = await new e({
24
+ for (const e of p) o(e);
25
+ }, $ = async () => {
26
+ const r = window.__testRunner, t = [], o = await new r({
17
27
  onStart: () => {
18
28
  },
19
- onPass: (s) => {
20
- t.push({ id: s.id, status: "pass" });
29
+ onPass: (e) => {
30
+ t.push({ id: e.id, status: "pass" });
21
31
  },
22
- onFail: (s, r) => {
23
- t.push({ id: s.id, status: "fail", error: r.message });
32
+ onFail: (e, s) => {
33
+ t.push({ id: e.id, status: "fail", error: s.message });
24
34
  },
25
- onSkip: (s) => {
26
- t.push({ id: s.id, status: "skip" });
35
+ onSkip: (e) => {
36
+ t.push({ id: e.id, status: "skip" });
27
37
  }
28
38
  }).runAll();
29
39
  return { handlers: Array.from(o.values()), testStatus: t };
30
40
  };
31
41
  export {
32
- g as executeTests,
33
- y as reportResults
42
+ $ as executeTests,
43
+ m as reportResults
34
44
  };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=new Map,i=new Map,c=new Map,a=[],h=()=>Math.random().toString(36).substr(2,9),f=(o,t)=>{const s=h(),e=a.at(-1);r.set(s,{id:s,name:o,type:"suite",children:[],logs:[],depth:a.length,parent:e,handler:t}),e&&r.get(e).children.push(s),a.push(s),t(),a.pop()},l=(o,t)=>{const s=h(),e=a.at(-1),n={id:s,name:o,type:"test",depth:a.length,handler:t,logs:[],parent:e};e&&r.get(e).children.push(s),r.set(s,n)};l.only=(o,t)=>{const s=h(),e=a.at(-1),n={id:s,name:o,type:"test",depth:a.length,handler:t,logs:[],parent:e,only:!0};e&&r.get(e).children.push(s),r.set(s,n)};l.skip=(o,t)=>{const s=h(),e=a.at(-1),n={id:s,name:o,type:"test",depth:a.length,handler:t||(()=>{}),logs:[],parent:e,skip:!0};e&&r.get(e).children.push(s),r.set(s,n)};const p=o=>{const t=a.at(-1);if(!t)throw new Error("beforeEach() must be inside a describe()");i.has(t)||i.set(t,[]),i.get(t).push(o)},d=o=>{const t=a.at(-1);if(!t)throw new Error("afterEach() must be inside a describe()");c.has(t)||c.set(t,[]),c.get(t).push(o)},g=o=>{const t=[],s=[];let e=o;for(;e;)i.has(e)&&t.unshift(...i.get(e)),c.has(e)&&s.push(...c.get(e)),e=r.get(e)?.parent;return{before:t,after:s}},y=()=>{r.clear(),i.clear(),c.clear()};class u{events;constructor(t){this.events=t}async runAll(){const t=Array.from(r.values()).filter(e=>!e.parent&&e.type==="suite"),s=Array.from(r.values()).some(e=>e.only);for(const e of t)await this.runSuite(e,s);return r}async runSingle(t){const s=r.get(t);if(!s||s.type!=="test")return;await this.runTest(s,!1)}async runSuite(t,s){this.events.onSuiteStart?.(t);const e=(t.children||[]).map(n=>r.get(n));for(const n of e)n.type==="suite"?await this.runSuite(n,s):n.type==="test"&&await this.runTest(n,s);this.events.onSuiteEnd?.(t)}async runTest(t,s){if(t.skip){this.events.onSkip(t);return}if(s&&!t.only)return;this.events.onStart?.(t);const e=g(t.parent);try{for(const n of e.before)await n();t.logs=[],await t.handler(),this.events.onPass(t)}catch(n){this.events.onFail(t,n)}finally{for(const n of e.after)await n()}}}window.__testRunner=u;exports.TestRunner=u;exports.afterEach=d;exports.beforeEach=p;exports.clearTests=y;exports.describe=f;exports.handlers=r;exports.it=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=new Map,a=new Map,h=new Map,i=[],l=()=>Math.random().toString(36).substr(2,9),f=(r,t)=>{const e=l(),n=i.at(-1);s.set(e,{id:e,name:r,type:"suite",children:[],logs:[],depth:i.length,parent:n,handler:t}),n&&s.get(n).children.push(e),i.push(e),t(),i.pop()};f.only=(r,t)=>{const e=l(),n=i.at(-1);s.set(e,{id:e,name:r,type:"suite",children:[],logs:[],depth:i.length,parent:n,handler:t,only:!0}),n&&s.get(n).children.push(e),i.push(e),t(),i.pop()};f.skip=(r,t)=>{const e=l(),n=i.at(-1);s.set(e,{id:e,name:r,type:"suite",children:[],logs:[],depth:i.length,parent:n,handler:t,skip:!0}),n&&s.get(n).children.push(e),i.push(e),t(),i.pop()};const d=(r,t)=>{const e=l(),n=i.at(-1),o={id:e,name:r,type:"test",depth:i.length,handler:t,logs:[],parent:n};n&&s.get(n).children.push(e),s.set(e,o)};d.only=(r,t)=>{const e=l(),n=i.at(-1),o={id:e,name:r,type:"test",depth:i.length,handler:t,logs:[],parent:n,only:!0};n&&s.get(n).children.push(e),s.set(e,o)};d.skip=(r,t)=>{const e=l(),n=i.at(-1),o={id:e,name:r,type:"test",depth:i.length,handler:t||(()=>{}),logs:[],parent:n,skip:!0};n&&s.get(n).children.push(e),s.set(e,o)};const S=r=>{const t=i.at(-1);if(!t)throw new Error("beforeEach() must be inside a describe()");a.has(t)||a.set(t,[]),a.get(t).push(r)},k=r=>{const t=i.at(-1);if(!t)throw new Error("afterEach() must be inside a describe()");h.has(t)||h.set(t,[]),h.get(t).push(r)},w=r=>{const t=[],e=[];let n=r;for(;n;)a.has(n)&&t.unshift(...a.get(n)),h.has(n)&&e.push(...h.get(n)),n=s.get(n)?.parent;return{before:t,after:e}},u=r=>{const t=s.get(r);return t?t.only?!0:t.children?t.children.some(e=>u(e)):!1:!1},b=r=>{let t=s.get(r);for(;t?.parent;){const e=s.get(t.parent);if(e?.only)return!0;t=e}return!1},g=r=>{let t=s.get(r);for(;t;){if(t.skip)return!0;if(!t.parent)break;t=s.get(t.parent)}return!1},v=()=>{s.clear(),a.clear(),h.clear()};class y{events;constructor(t){this.events=t}async runAll(){const t=Array.from(s.values()).filter(n=>!n.parent&&n.type==="suite"),e=Array.from(s.values()).some(n=>n.only);for(const n of t)await this.runSuite(n,e);return s}async runSingle(t){const e=s.get(t);if(!e||e.type!=="test")return;await this.runTest(e,!1)}async runSuite(t,e){if(g(t.id)&&!u(t.id)){this.events.onSkip?.(t);return}if(e&&!u(t.id))return;this.events.onSuiteStart?.(t);const o=(t.children||[]).map(c=>s.get(c));for(const c of o)c.type==="suite"?await this.runSuite(c,e):c.type==="test"&&await this.runTest(c,e);this.events.onSuiteEnd?.(t)}async runTest(t,e){if((g(t.id)||t.skip)&&!t.only){this.events.onSkip(t);return}const o=b(t.id);if(e&&!t.only&&!o){this.events.onSkip(t);return}this.events.onStart?.(t);const c=w(t.parent);try{for(const p of c.before)await p();t.logs=[],await t.handler(),this.events.onPass(t)}catch(p){this.events.onFail(t,p)}finally{for(const p of c.after)await p()}}}window.__testRunner=y;exports.TestRunner=y;exports.afterEach=k;exports.beforeEach=S;exports.clearTests=v;exports.describe=f;exports.handlers=s;exports.it=d;
package/dist/runner.d.ts CHANGED
@@ -1,41 +1,55 @@
1
- export interface Handler {
2
- id: string;
3
- name: string;
4
- parent?: string;
5
- handler: () => void | Promise<void>;
6
- children?: string[];
7
- type: 'suite' | 'test';
8
- status?: 'idle' | 'pass' | 'fail' | 'skip' | 'running';
9
- logs: string[];
10
- depth: number;
11
- only?: boolean;
12
- skip?: boolean;
13
- }
14
- type HookFn = () => void | Promise<void>;
15
- export declare const handlers: Map<string, Handler>;
16
- export declare const describe: (name: string, handler: () => void) => void;
17
- export declare const it: {
18
- (name: string, handler: () => void | Promise<void>): void;
19
- only(name: string, handler: () => void | Promise<void>): void;
20
- skip(name: string, handler?: () => void | Promise<void>): void;
21
- };
22
- export declare const beforeEach: (fn: HookFn) => void;
23
- export declare const afterEach: (fn: HookFn) => void;
24
- export declare const clearTests: () => void;
25
- export interface RunnerEvents {
26
- onStart: (test: Handler) => void;
27
- onPass: (test: Handler) => void;
28
- onFail: (test: Handler, error: Error) => void;
29
- onSkip: (test: Handler) => void;
30
- onSuiteStart?: (suite: Handler) => void;
31
- onSuiteEnd?: (suite: Handler) => void;
32
- }
33
- export declare class TestRunner {
34
- private events;
35
- constructor(events: RunnerEvents);
36
- runAll(): Promise<Map<string, Handler>>;
37
- runSingle(id: string): Promise<void>;
38
- private runSuite;
39
- private runTest;
40
- }
41
- export {};
1
+ export declare const afterEach: (fn: HookFn) => void;
2
+
3
+ export declare const beforeEach: (fn: HookFn) => void;
4
+
5
+ export declare const clearTests: () => void;
6
+
7
+ export declare const describe: {
8
+ (name: string, handler: () => void): void;
9
+ only(name: string, handler: () => void): void;
10
+ skip(name: string, handler: () => void): void;
11
+ };
12
+
13
+ export declare interface Handler {
14
+ id: string;
15
+ name: string;
16
+ parent?: string;
17
+ handler: () => void | Promise<void>;
18
+ children?: string[];
19
+ type: 'suite' | 'test';
20
+ status?: 'idle' | 'pass' | 'fail' | 'skip' | 'running';
21
+ logs: string[];
22
+ depth: number;
23
+ only?: boolean;
24
+ skip?: boolean;
25
+ }
26
+
27
+ export declare const handlers: Map<string, Handler>;
28
+
29
+ declare type HookFn = () => void | Promise<void>;
30
+
31
+ export declare const it: {
32
+ (name: string, handler: () => void | Promise<void>): void;
33
+ only(name: string, handler: () => void | Promise<void>): void;
34
+ skip(name: string, handler?: () => void | Promise<void>): void;
35
+ };
36
+
37
+ export declare interface RunnerEvents {
38
+ onStart: (test: Handler) => void;
39
+ onPass: (test: Handler) => void;
40
+ onFail: (test: Handler, error: Error) => void;
41
+ onSkip: (test: Handler) => void;
42
+ onSuiteStart?: (suite: Handler) => void;
43
+ onSuiteEnd?: (suite: Handler) => void;
44
+ }
45
+
46
+ export declare class TestRunner {
47
+ private events;
48
+ constructor(events: RunnerEvents);
49
+ runAll(): Promise<Map<string, Handler>>;
50
+ runSingle(id: string): Promise<void>;
51
+ private runSuite;
52
+ private runTest;
53
+ }
54
+
55
+ export { }
package/dist/runner.es.js CHANGED
@@ -1,121 +1,178 @@
1
- const r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), a = [], h = () => Math.random().toString(36).substr(2, 9), p = (o, t) => {
2
- const s = h(), e = a.at(-1);
3
- r.set(s, {
4
- id: s,
5
- name: o,
1
+ const r = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), o = [], p = () => Math.random().toString(36).substr(2, 9), d = (s, t) => {
2
+ const e = p(), n = o.at(-1);
3
+ r.set(e, {
4
+ id: e,
5
+ name: s,
6
6
  type: "suite",
7
7
  children: [],
8
8
  logs: [],
9
- depth: a.length,
10
- parent: e,
9
+ depth: o.length,
10
+ parent: n,
11
11
  handler: t
12
- }), e && r.get(e).children.push(s), a.push(s), t(), a.pop();
13
- }, l = (o, t) => {
14
- const s = h(), e = a.at(-1), n = {
15
- id: s,
16
- name: o,
12
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
13
+ };
14
+ d.only = (s, t) => {
15
+ const e = p(), n = o.at(-1);
16
+ r.set(e, {
17
+ id: e,
18
+ name: s,
19
+ type: "suite",
20
+ children: [],
21
+ logs: [],
22
+ depth: o.length,
23
+ parent: n,
24
+ handler: t,
25
+ only: !0
26
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
27
+ };
28
+ d.skip = (s, t) => {
29
+ const e = p(), n = o.at(-1);
30
+ r.set(e, {
31
+ id: e,
32
+ name: s,
33
+ type: "suite",
34
+ children: [],
35
+ logs: [],
36
+ depth: o.length,
37
+ parent: n,
38
+ handler: t,
39
+ skip: !0
40
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
41
+ };
42
+ const g = (s, t) => {
43
+ const e = p(), n = o.at(-1), i = {
44
+ id: e,
45
+ name: s,
17
46
  type: "test",
18
- depth: a.length,
47
+ depth: o.length,
19
48
  handler: t,
20
49
  logs: [],
21
- parent: e
50
+ parent: n
22
51
  };
23
- e && r.get(e).children.push(s), r.set(s, n);
52
+ n && r.get(n).children.push(e), r.set(e, i);
24
53
  };
25
- l.only = (o, t) => {
26
- const s = h(), e = a.at(-1), n = {
27
- id: s,
28
- name: o,
54
+ g.only = (s, t) => {
55
+ const e = p(), n = o.at(-1), i = {
56
+ id: e,
57
+ name: s,
29
58
  type: "test",
30
- depth: a.length,
59
+ depth: o.length,
31
60
  handler: t,
32
61
  logs: [],
33
- parent: e,
62
+ parent: n,
34
63
  only: !0
35
64
  };
36
- e && r.get(e).children.push(s), r.set(s, n);
65
+ n && r.get(n).children.push(e), r.set(e, i);
37
66
  };
38
- l.skip = (o, t) => {
39
- const s = h(), e = a.at(-1), n = {
40
- id: s,
41
- name: o,
67
+ g.skip = (s, t) => {
68
+ const e = p(), n = o.at(-1), i = {
69
+ id: e,
70
+ name: s,
42
71
  type: "test",
43
- depth: a.length,
72
+ depth: o.length,
44
73
  handler: t || (() => {
45
74
  }),
46
75
  logs: [],
47
- parent: e,
76
+ parent: n,
48
77
  skip: !0
49
78
  };
50
- e && r.get(e).children.push(s), r.set(s, n);
79
+ n && r.get(n).children.push(e), r.set(e, i);
51
80
  };
52
- const d = (o) => {
53
- const t = a.at(-1);
81
+ const w = (s) => {
82
+ const t = o.at(-1);
54
83
  if (!t) throw new Error("beforeEach() must be inside a describe()");
55
- i.has(t) || i.set(t, []), i.get(t).push(o);
56
- }, g = (o) => {
57
- const t = a.at(-1);
84
+ a.has(t) || a.set(t, []), a.get(t).push(s);
85
+ }, b = (s) => {
86
+ const t = o.at(-1);
58
87
  if (!t) throw new Error("afterEach() must be inside a describe()");
59
- c.has(t) || c.set(t, []), c.get(t).push(o);
60
- }, u = (o) => {
61
- const t = [], s = [];
62
- let e = o;
63
- for (; e; )
64
- i.has(e) && t.unshift(...i.get(e)), c.has(e) && s.push(...c.get(e)), e = r.get(e)?.parent;
65
- return { before: t, after: s };
66
- }, y = () => {
67
- r.clear(), i.clear(), c.clear();
88
+ h.has(t) || h.set(t, []), h.get(t).push(s);
89
+ }, y = (s) => {
90
+ const t = [], e = [];
91
+ let n = s;
92
+ for (; n; )
93
+ a.has(n) && t.unshift(...a.get(n)), h.has(n) && e.push(...h.get(n)), n = r.get(n)?.parent;
94
+ return { before: t, after: e };
95
+ }, u = (s) => {
96
+ const t = r.get(s);
97
+ return t ? t.only ? !0 : t.children ? t.children.some((e) => u(e)) : !1 : !1;
98
+ }, k = (s) => {
99
+ let t = r.get(s);
100
+ for (; t?.parent; ) {
101
+ const e = r.get(t.parent);
102
+ if (e?.only) return !0;
103
+ t = e;
104
+ }
105
+ return !1;
106
+ }, f = (s) => {
107
+ let t = r.get(s);
108
+ for (; t; ) {
109
+ if (t.skip) return !0;
110
+ if (!t.parent) break;
111
+ t = r.get(t.parent);
112
+ }
113
+ return !1;
114
+ }, v = () => {
115
+ r.clear(), a.clear(), h.clear();
68
116
  };
69
- class f {
117
+ class S {
70
118
  events;
71
119
  constructor(t) {
72
120
  this.events = t;
73
121
  }
74
122
  async runAll() {
75
123
  const t = Array.from(r.values()).filter(
76
- (e) => !e.parent && e.type === "suite"
77
- ), s = Array.from(r.values()).some((e) => e.only);
78
- for (const e of t)
79
- await this.runSuite(e, s);
124
+ (n) => !n.parent && n.type === "suite"
125
+ ), e = Array.from(r.values()).some((n) => n.only);
126
+ for (const n of t)
127
+ await this.runSuite(n, e);
80
128
  return r;
81
129
  }
82
130
  async runSingle(t) {
83
- const s = r.get(t);
84
- if (!s || s.type !== "test") return;
85
- await this.runTest(s, !1);
131
+ const e = r.get(t);
132
+ if (!e || e.type !== "test") return;
133
+ await this.runTest(e, !1);
86
134
  }
87
- async runSuite(t, s) {
135
+ async runSuite(t, e) {
136
+ if (f(t.id) && !u(t.id)) {
137
+ this.events.onSkip?.(t);
138
+ return;
139
+ }
140
+ if (e && !u(t.id)) return;
88
141
  this.events.onSuiteStart?.(t);
89
- const e = (t.children || []).map((n) => r.get(n));
90
- for (const n of e)
91
- n.type === "suite" ? await this.runSuite(n, s) : n.type === "test" && await this.runTest(n, s);
142
+ const i = (t.children || []).map((c) => r.get(c));
143
+ for (const c of i)
144
+ c.type === "suite" ? await this.runSuite(c, e) : c.type === "test" && await this.runTest(c, e);
92
145
  this.events.onSuiteEnd?.(t);
93
146
  }
94
- async runTest(t, s) {
95
- if (t.skip) {
147
+ async runTest(t, e) {
148
+ if ((f(t.id) || t.skip) && !t.only) {
149
+ this.events.onSkip(t);
150
+ return;
151
+ }
152
+ const i = k(t.id);
153
+ if (e && !t.only && !i) {
96
154
  this.events.onSkip(t);
97
155
  return;
98
156
  }
99
- if (s && !t.only) return;
100
157
  this.events.onStart?.(t);
101
- const e = u(t.parent);
158
+ const c = y(t.parent);
102
159
  try {
103
- for (const n of e.before) await n();
160
+ for (const l of c.before) await l();
104
161
  t.logs = [], await t.handler(), this.events.onPass(t);
105
- } catch (n) {
106
- this.events.onFail(t, n);
162
+ } catch (l) {
163
+ this.events.onFail(t, l);
107
164
  } finally {
108
- for (const n of e.after) await n();
165
+ for (const l of c.after) await l();
109
166
  }
110
167
  }
111
168
  }
112
- window.__testRunner = f;
169
+ window.__testRunner = S;
113
170
  export {
114
- f as TestRunner,
115
- g as afterEach,
116
- d as beforeEach,
117
- y as clearTests,
118
- p as describe,
171
+ S as TestRunner,
172
+ b as afterEach,
173
+ w as beforeEach,
174
+ v as clearTests,
175
+ d as describe,
119
176
  r as handlers,
120
- l as it
177
+ g as it
121
178
  };
@@ -1 +1,21 @@
1
- export { removeMockServiceWorker } from './plugin/removeMockServiceWorker';
1
+ import { Plugin as Plugin_2 } from 'vite';
2
+
3
+ /**
4
+ * Vite plugin to remove the mock service worker file from the build output.
5
+ * This is useful for production builds where you don't want the mock service worker to be included.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { removeMockServiceWorker } from 'twd-js';
10
+ *
11
+ * export default defineConfig({
12
+ * plugins: [
13
+ * // ... other plugins
14
+ * removeMockServiceWorker()
15
+ * ]
16
+ * });
17
+ * ```
18
+ */
19
+ export declare function removeMockServiceWorker(): Plugin_2;
20
+
21
+ export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twd-js",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Test While Developing (TWD) - in-browser testing",
5
5
  "license": "MIT",
6
6
  "author": "BRIKEV",
@@ -65,18 +65,17 @@
65
65
  "devDependencies": {
66
66
  "@testing-library/jest-dom": "^6.9.1",
67
67
  "@testing-library/react": "^16.3.0",
68
- "@types/chai": "^5.2.3",
69
- "@types/react": "^19.2.3",
70
- "@types/react-dom": "^19.2.2",
71
- "@vitejs/plugin-react": "^5.1.0",
72
- "@vitest/coverage-v8": "^4.0.8",
68
+ "@types/react": "^19.2.6",
69
+ "@types/react-dom": "^19.2.3",
70
+ "@vitejs/plugin-react": "^5.1.1",
71
+ "@vitest/coverage-v8": "^4.0.13",
73
72
  "conventional-changelog": "^7.1.1",
74
- "jsdom": "^27.1.0",
73
+ "jsdom": "^27.2.0",
75
74
  "typescript": "^5.9.3",
76
- "vite": "^7.2.2",
75
+ "vite": "^7.2.4",
77
76
  "vite-plugin-dts": "^4.5.4",
78
77
  "vitepress": "^2.0.0-alpha.12",
79
- "vitest": "^4.0.8"
78
+ "vitest": "^4.0.13"
80
79
  },
81
80
  "keywords": [
82
81
  "testing",
@@ -91,7 +90,8 @@
91
90
  "dependencies": {
92
91
  "@testing-library/dom": "^10.4.1",
93
92
  "@testing-library/user-event": "^14.6.1",
93
+ "@types/chai": "^5.2.3",
94
94
  "chai": "^6.2.1",
95
- "chalk": "^5.6.2"
95
+ "picocolors": "^1.1.1"
96
96
  }
97
97
  }
@@ -1,2 +0,0 @@
1
- import { AnyAssertion } from '../twd-types';
2
- export declare const runAssertion: (el: Element, name: AnyAssertion, ...args: any[]) => string;
@@ -1,73 +0,0 @@
1
- export type Rule = {
2
- method: string;
3
- url: string | RegExp;
4
- response: unknown;
5
- alias: string;
6
- executed?: boolean;
7
- request?: any;
8
- status?: number;
9
- responseHeaders?: Record<string, string>;
10
- urlRegex?: boolean;
11
- };
12
- export interface Options {
13
- method: string;
14
- url: string | RegExp;
15
- response: unknown;
16
- status?: number;
17
- responseHeaders?: Record<string, string>;
18
- urlRegex?: boolean;
19
- }
20
- /**
21
- * Initialize the mocking service worker.
22
- * Call this once before using `mockRequest` or `waitFor`.
23
- */
24
- export declare const initRequestMocking: () => Promise<void>;
25
- /**
26
- * Mock a network request.
27
- *
28
- * @param alias Identifier for the mock rule. Useful for `waitFor()`.
29
- * @param options Options to configure the mock:
30
- * - `method`: HTTP method ("GET", "POST", …)
31
- * - `url`: URL string or RegExp to match
32
- * - `response`: Body of the mocked response
33
- * - `status`: (optional) HTTP status code (default: 200)
34
- * - `responseHeaders`: (optional) Response headers
35
- * - `urlRegex`: (optional) Whether the URL is a regex (default: false)
36
- *
37
- * @example
38
- * ```ts
39
- * mockRequest("getUser", {
40
- * method: "GET",
41
- * url: /\/api\/user\/\d+/,
42
- * response: { id: 1, name: "Kevin" },
43
- * status: 200,
44
- * headers: { "x-mock": "true" }
45
- * });
46
- * ```
47
- */
48
- export declare const mockRequest: (alias: string, options: Options) => Promise<void>;
49
- /**
50
- * wait for a list of mocked requests to be made.
51
- * @param aliases The aliases of the mock rules to wait for
52
- * @returns The matched rules (with body if applicable)
53
- * @example
54
- * ```ts
55
- * await waitForRequests(["getUser", "postComment"]);
56
- * ```
57
- */
58
- export declare const waitForRequests: (aliases: string[]) => Promise<Rule[]>;
59
- /**
60
- * Wait for a mocked request to be made.
61
- * @param alias The alias of the mock rule to wait for
62
- * @returns The matched rule (with body if applicable)
63
- */
64
- export declare const waitForRequest: (alias: string) => Promise<Rule>;
65
- /**
66
- * Get the current list of request mock rules.
67
- * @returns The current list of request mock rules.
68
- */
69
- export declare const getRequestMockRules: () => Rule[];
70
- /**
71
- * Clear all request mock rules.
72
- */
73
- export declare const clearRequestMockRules: () => void;