twd-js 1.5.2 → 1.6.1

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/mock-sw.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(){"use strict";const f=e=>{try{return new RegExp(e),!0}catch{return!1}},h=new Set(["js","mjs","cjs","ts","tsx","jsx","mts","cts","css","scss","sass","less","styl","html","htm","xml","xhtml","vue","svelte","json","yaml","yml","toml","csv","txt","md","mdx","pdf","doc","docx","png","jpg","jpeg","gif","svg","webp","ico","bmp","avif","woff","woff2","ttf","eot","otf","mp3","mp4","webm","ogg","wav","zip","tar","gz","rar","map"]),d=e=>{const o=e.split("?")[0].match(/\.([a-zA-Z0-9]+)$/);return o?h.has(o[1].toLowerCase()):!1},m=(e,n)=>{const o=e.indexOf(n);if(o===-1)return!1;const t=o+n.length,s=e[t];if(s===void 0)return!0;const i=e.indexOf("?");return i!==-1&&t>i?!0:"?#&".includes(s)};function p(e,n,o){return o.find(t=>{const s=t.method.toLowerCase()===e.toLowerCase();if(t.urlRegex&&f(t.url)){const c=new RegExp(t.url);return s&&c.test(n)}if(d(t.url))return s&&n.includes(t.url);const u=t.url===n||m(n,t.url);return s&&u&&!d(n)})}function y(e,n,o,t){e.forEach(s=>s.postMessage({type:"EXECUTED",alias:n.alias,request:o,hitCount:t}))}const g=(e,n,o)=>{const s=![204,205,304].includes(n),i=s?JSON.stringify(e):null;return new Response(i,{status:n,headers:s?o||{"Content-Type":"application/json"}:o||{}})},r="1.5.2";let a=[],l={};const w=async e=>{const{method:n}=e.request,o=e.request.url,t=p(n,o,a);t&&(console.log("[TWD] Mock hit:",t.alias,n,o),e.respondWith((async()=>{let s=null;const i=e.request.headers.get("content-type")||"application/json";if(i.includes("application/json"))try{s=await e.request.clone().json()}catch{}else if(i.includes("form"))try{const c=await e.request.clone().formData();s={},c.forEach((W,v)=>{s[v]=W})}catch{}else if(i.includes("text"))try{s=await e.request.clone().text()}catch{}else if(i.includes("octet-stream"))try{s=await e.request.clone().arrayBuffer()}catch{}else if(i.includes("image"))try{s=await e.request.clone().blob()}catch{}else try{s=await e.request.clone().text()}catch{}l[t.alias]||(l[t.alias]=0),l[t.alias]++;const u=await self.clients.matchAll();return y(u,t,s,l[t.alias]),t.delay&&t.delay>0&&await new Promise(c=>setTimeout(c,t.delay)),g(t.response,t.status??200,t.responseHeaders)})()))},x=e=>{e!==r&&console.warn(`[TWD] ⚠️ Version mismatch detected:
1
+ (function(){"use strict";const f=e=>{try{return new RegExp(e),!0}catch{return!1}},h=new Set(["js","mjs","cjs","ts","tsx","jsx","mts","cts","css","scss","sass","less","styl","html","htm","xml","xhtml","vue","svelte","json","yaml","yml","toml","csv","txt","md","mdx","pdf","doc","docx","png","jpg","jpeg","gif","svg","webp","ico","bmp","avif","woff","woff2","ttf","eot","otf","mp3","mp4","webm","ogg","wav","zip","tar","gz","rar","map"]),d=e=>{const o=e.split("?")[0].match(/\.([a-zA-Z0-9]+)$/);return o?h.has(o[1].toLowerCase()):!1},m=(e,n)=>{const o=e.indexOf(n);if(o===-1)return!1;const t=o+n.length,s=e[t];if(s===void 0)return!0;const i=e.indexOf("?");return i!==-1&&t>i?!0:"?#&".includes(s)};function p(e,n,o){return o.find(t=>{const s=t.method.toLowerCase()===e.toLowerCase();if(t.urlRegex&&f(t.url)){const c=new RegExp(t.url);return s&&c.test(n)}if(d(t.url))return s&&n.includes(t.url);const u=t.url===n||m(n,t.url);return s&&u&&!d(n)})}function y(e,n,o,t){e.forEach(s=>s.postMessage({type:"EXECUTED",alias:n.alias,request:o,hitCount:t}))}const g=(e,n,o)=>{const s=![204,205,304].includes(n),i=s?JSON.stringify(e):null;return new Response(i,{status:n,headers:s?o||{"Content-Type":"application/json"}:o||{}})},r="1.6.1";let a=[],l={};const w=async e=>{const{method:n}=e.request,o=e.request.url,t=p(n,o,a);t&&(console.log("[TWD] Mock hit:",t.alias,n,o),e.respondWith((async()=>{let s=null;const i=e.request.headers.get("content-type")||"application/json";if(i.includes("application/json"))try{s=await e.request.clone().json()}catch{}else if(i.includes("form"))try{const c=await e.request.clone().formData();s={},c.forEach((W,v)=>{s[v]=W})}catch{}else if(i.includes("text"))try{s=await e.request.clone().text()}catch{}else if(i.includes("octet-stream"))try{s=await e.request.clone().arrayBuffer()}catch{}else if(i.includes("image"))try{s=await e.request.clone().blob()}catch{}else try{s=await e.request.clone().text()}catch{}l[t.alias]||(l[t.alias]=0),l[t.alias]++;const u=await self.clients.matchAll();return y(u,t,s,l[t.alias]),t.delay&&t.delay>0&&await new Promise(c=>setTimeout(c,t.delay)),g(t.response,t.status??200,t.responseHeaders)})()))},x=e=>{e!==r&&console.warn(`[TWD] ⚠️ Version mismatch detected:
2
2
  Client version: ${e}
3
3
  Service Worker version: ${r}
4
4
 
@@ -1 +1 @@
1
- "use strict";var S=Object.defineProperty;var E=(s,e,t)=>e in s?S(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var y=(s,e,t)=>E(s,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=()=>typeof window<"u"?(window.__TWD_STATE__||(window.__TWD_STATE__={handlers:new Map,beforeEachHooks:new Map,afterEachHooks:new Map,stack:[]}),window.__TWD_STATE__):{handlers:new Map,beforeEachHooks:new Map,afterEachHooks:new Map,stack:[]},u=b(),r=u.handlers,c=u.beforeEachHooks,h=u.afterEachHooks,o=u.stack,l=()=>Math.random().toString(36).slice(2,11),d=(s,e)=>{const t=l(),n=o.at(-1);r.set(t,{id:t,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:e}),n&&r.get(n).children.push(t),o.push(t),e(),o.pop()};d.only=(s,e)=>{const t=l(),n=o.at(-1);r.set(t,{id:t,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:e,only:!0}),n&&r.get(n).children.push(t),o.push(t),e(),o.pop()};d.skip=(s,e)=>{const t=l(),n=o.at(-1);r.set(t,{id:t,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:e,skip:!0}),n&&r.get(n).children.push(t),o.push(t),e(),o.pop()};const g=(s,e)=>{const t=l(),n=o.at(-1),i={id:t,name:s,type:"test",depth:o.length,handler:e,logs:[],parent:n};n&&r.get(n).children.push(t),r.set(t,i)};g.only=(s,e)=>{const t=l(),n=o.at(-1),i={id:t,name:s,type:"test",depth:o.length,handler:e,logs:[],parent:n,only:!0};n&&r.get(n).children.push(t),r.set(t,i)};g.skip=(s,e)=>{const t=l(),n=o.at(-1),i={id:t,name:s,type:"test",depth:o.length,handler:e||(()=>{}),logs:[],parent:n,skip:!0};n&&r.get(n).children.push(t),r.set(t,i)};const T=s=>{const e=o.at(-1);if(!e)throw new Error("beforeEach() must be inside a describe()");c.has(e)||c.set(e,[]),c.get(e).push(s)},_=s=>{const e=o.at(-1);if(!e)throw new Error("afterEach() must be inside a describe()");h.has(e)||h.set(e,[]),h.get(e).push(s)},v=s=>{const e=[],t=[];let n=s;for(;n;)c.has(n)&&e.unshift(...c.get(n)),h.has(n)&&t.push(...h.get(n)),n=r.get(n)?.parent;return{before:e,after:t}},f=s=>{const e=r.get(s);return e?e.only?!0:e.children?e.children.some(t=>f(t)):!1:!1},m=s=>{let e=r.get(s);for(;e?.parent;){const t=r.get(e.parent);if(t?.only)return!0;e=t}return!1},k=s=>{let e=r.get(s);for(;e;){if(e.skip)return!0;if(!e.parent)break;e=r.get(e.parent)}return!1},H=()=>{r.clear(),c.clear(),h.clear()};class w{constructor(e){y(this,"events");this.events=e}async runAll(){const e=Array.from(r.values()).filter(n=>!n.parent&&n.type==="suite"),t=Array.from(r.values()).some(n=>n.only);for(const n of e)await this.runSuite(n,t);return r}async runSingle(e){const t=r.get(e);if(!t||t.type!=="test")return;await this.runTest(t,!1)}async runSuite(e,t){if(k(e.id)&&!f(e.id)){this.events.onSkip?.(e);return}if(t&&!f(e.id))return;this.events.onSuiteStart?.(e);const i=(e.children||[]).map(a=>r.get(a));for(const a of i)a.type==="suite"?await this.runSuite(a,t):a.type==="test"&&await this.runTest(a,t);this.events.onSuiteEnd?.(e)}async runTest(e,t){if((k(e.id)||e.skip)&&!e.only){this.events.onSkip(e);return}const i=m(e.id);if(t&&!e.only&&!i){this.events.onSkip(e);return}this.events.onStart?.(e);const a=v(e.parent);try{for(const p of a.before)await p();e.logs=[],await e.handler(),this.events.onPass(e)}catch(p){this.events.onFail(e,p)}finally{for(const p of a.after)await p()}}}window.__testRunner=w;exports.TestRunner=w;exports.afterEach=_;exports.beforeEach=T;exports.clearTests=H;exports.describe=d;exports.handlers=r;exports.it=g;
1
+ "use strict";var v=Object.defineProperty;var b=(s,t,e)=>t in s?v(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var g=(s,t,e)=>b(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=()=>typeof window<"u"?(window.__TWD_STATE__||(window.__TWD_STATE__={handlers:new Map,beforeEachHooks:new Map,afterEachHooks:new Map,stack:[]}),window.__TWD_STATE__):{handlers:new Map,beforeEachHooks:new Map,afterEachHooks:new Map,stack:[]},y=T(),r=y.handlers,h=y.beforeEachHooks,u=y.afterEachHooks,o=y.stack,l=()=>Math.random().toString(36).slice(2,11),k=(s,t)=>{const e=l(),n=o.at(-1);r.set(e,{id:e,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:t}),n&&r.get(n).children.push(e),o.push(e),t(),o.pop()};k.only=(s,t)=>{const e=l(),n=o.at(-1);r.set(e,{id:e,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:t,only:!0}),n&&r.get(n).children.push(e),o.push(e),t(),o.pop()};k.skip=(s,t)=>{const e=l(),n=o.at(-1);r.set(e,{id:e,name:s,type:"suite",children:[],logs:[],depth:o.length,parent:n,handler:t,skip:!0}),n&&r.get(n).children.push(e),o.push(e),t(),o.pop()};const w=(s,t)=>{const e=l(),n=o.at(-1),a={id:e,name:s,type:"test",depth:o.length,handler:t,logs:[],parent:n};n&&r.get(n).children.push(e),r.set(e,a)};w.only=(s,t)=>{const e=l(),n=o.at(-1),a={id:e,name:s,type:"test",depth:o.length,handler:t,logs:[],parent:n,only:!0};n&&r.get(n).children.push(e),r.set(e,a)};w.skip=(s,t)=>{const e=l(),n=o.at(-1),a={id:e,name:s,type:"test",depth:o.length,handler:t||(()=>{}),logs:[],parent:n,skip:!0};n&&r.get(n).children.push(e),r.set(e,a)};const _=s=>{const t=o.at(-1);if(!t)throw new Error("beforeEach() must be inside a describe()");h.has(t)||h.set(t,[]),h.get(t).push(s)},m=s=>{const t=o.at(-1);if(!t)throw new Error("afterEach() must be inside a describe()");u.has(t)||u.set(t,[]),u.get(t).push(s)},I=s=>{const t=[],e=[];let n=s;for(;n;)h.has(n)&&t.unshift(...h.get(n)),u.has(n)&&e.push(...u.get(n)),n=r.get(n)?.parent;return{before:t,after:e}},f=s=>{const t=r.get(s);return t?t.only?!0:t.children?t.children.some(e=>f(e)):!1:!1},M=s=>{let t=r.get(s);for(;t?.parent;){const e=r.get(t.parent);if(e?.only)return!0;t=e}return!1},S=s=>{let t=r.get(s);for(;t;){if(t.skip)return!0;if(!t.parent)break;t=r.get(t.parent)}return!1},A=()=>{r.clear(),h.clear(),u.clear()};class E{constructor(t,e){g(this,"events");g(this,"retryCount");this.events=t,this.retryCount=e?.retryCount??1}async runAll(){const t=Array.from(r.values()).filter(n=>!n.parent&&n.type==="suite"),e=Array.from(r.values()).some(n=>n.only);for(const n of t)await this.runSuite(n,e);return r}async runSingle(t){const e=r.get(t);if(!e||e.type!=="test")return;await this.runTest(e,!1)}async runByIds(t){const e=new Set(t),n=Array.from(r.values()).filter(i=>!i.parent&&i.type==="suite"),a=Array.from(r.values()).some(i=>i.only);for(const i of n)await this.runSuiteByIds(i,e,a);return r}async runSuiteByIds(t,e,n){if(!this.hasDescendantInSet(t,e))return;if(S(t.id)&&!f(t.id)){this.events.onSkip?.(t);return}if(n&&!f(t.id))return;this.events.onSuiteStart?.(t);const d=(t.children||[]).map(c=>r.get(c));for(const c of d)c.type==="suite"?await this.runSuiteByIds(c,e,n):c.type==="test"&&e.has(c.id)&&await this.runTest(c,n);this.events.onSuiteEnd?.(t)}hasDescendantInSet(t,e){return e.has(t.id)?!0:t.children?t.children.some(n=>{const a=r.get(n);return a?this.hasDescendantInSet(a,e):!1}):!1}async runSuite(t,e){if(S(t.id)&&!f(t.id)){this.events.onSkip?.(t);return}if(e&&!f(t.id))return;this.events.onSuiteStart?.(t);const a=(t.children||[]).map(i=>r.get(i));for(const i of a)i.type==="suite"?await this.runSuite(i,e):i.type==="test"&&await this.runTest(i,e);this.events.onSuiteEnd?.(t)}async runTest(t,e){if((S(t.id)||t.skip)&&!t.only){this.events.onSkip(t);return}const a=M(t.id);if(e&&!t.only&&!a){this.events.onSkip(t);return}this.events.onStart?.(t);const i=I(t.parent);let d=null;for(let c=1;c<=this.retryCount;c++)try{for(const p of i.before)await p();t.logs=[],await t.handler(),this.events.onPass(t,c>1?c:void 0);return}catch(p){d=p}finally{for(const p of i.after)await p()}this.events.onFail(t,d)}}window.__testRunner=E;exports.TestRunner=E;exports.afterEach=m;exports.beforeEach=_;exports.clearTests=A;exports.describe=k;exports.handlers=r;exports.it=w;
package/dist/runner.d.ts CHANGED
@@ -36,7 +36,7 @@ export declare const it: {
36
36
 
37
37
  export declare interface RunnerEvents {
38
38
  onStart: (test: Handler) => void;
39
- onPass: (test: Handler) => void;
39
+ onPass: (test: Handler, retryAttempt?: number) => void;
40
40
  onFail: (test: Handler, error: Error) => void;
41
41
  onSkip: (test: Handler) => void;
42
42
  onSuiteStart?: (suite: Handler) => void;
@@ -45,11 +45,19 @@ export declare interface RunnerEvents {
45
45
 
46
46
  export declare class TestRunner {
47
47
  private events;
48
- constructor(events: RunnerEvents);
48
+ private retryCount;
49
+ constructor(events: RunnerEvents, options?: TestRunnerOptions);
49
50
  runAll(): Promise<Map<string, Handler>>;
50
51
  runSingle(id: string): Promise<void>;
52
+ runByIds(ids: string[]): Promise<Map<string, Handler>>;
53
+ private runSuiteByIds;
54
+ private hasDescendantInSet;
51
55
  private runSuite;
52
56
  private runTest;
53
57
  }
54
58
 
59
+ export declare interface TestRunnerOptions {
60
+ retryCount?: number;
61
+ }
62
+
55
63
  export { }
package/dist/runner.es.js CHANGED
@@ -1,7 +1,7 @@
1
- var w = Object.defineProperty;
2
- var S = (s, e, t) => e in s ? w(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var d = (s, e, t) => S(s, typeof e != "symbol" ? e + "" : e, t);
4
- const E = () => typeof window < "u" ? (window.__TWD_STATE__ || (window.__TWD_STATE__ = {
1
+ var E = Object.defineProperty;
2
+ var v = (s, t, e) => t in s ? E(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var g = (s, t, e) => v(s, typeof t != "symbol" ? t + "" : t, e);
4
+ const _ = () => typeof window < "u" ? (window.__TWD_STATE__ || (window.__TWD_STATE__ = {
5
5
  handlers: /* @__PURE__ */ new Map(),
6
6
  beforeEachHooks: /* @__PURE__ */ new Map(),
7
7
  afterEachHooks: /* @__PURE__ */ new Map(),
@@ -11,181 +11,213 @@ const E = () => typeof window < "u" ? (window.__TWD_STATE__ || (window.__TWD_STA
11
11
  beforeEachHooks: /* @__PURE__ */ new Map(),
12
12
  afterEachHooks: /* @__PURE__ */ new Map(),
13
13
  stack: []
14
- }, u = E(), r = u.handlers, c = u.beforeEachHooks, h = u.afterEachHooks, o = u.stack, p = () => Math.random().toString(36).slice(2, 11), y = (s, e) => {
15
- const t = p(), n = o.at(-1);
16
- r.set(t, {
17
- id: t,
14
+ }, y = _(), r = y.handlers, h = y.beforeEachHooks, u = y.afterEachHooks, o = y.stack, l = () => Math.random().toString(36).slice(2, 11), k = (s, t) => {
15
+ const e = l(), n = o.at(-1);
16
+ r.set(e, {
17
+ id: e,
18
18
  name: s,
19
19
  type: "suite",
20
20
  children: [],
21
21
  logs: [],
22
22
  depth: o.length,
23
23
  parent: n,
24
- handler: e
25
- }), n && r.get(n).children.push(t), o.push(t), e(), o.pop();
24
+ handler: t
25
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
26
26
  };
27
- y.only = (s, e) => {
28
- const t = p(), n = o.at(-1);
29
- r.set(t, {
30
- id: t,
27
+ k.only = (s, t) => {
28
+ const e = l(), n = o.at(-1);
29
+ r.set(e, {
30
+ id: e,
31
31
  name: s,
32
32
  type: "suite",
33
33
  children: [],
34
34
  logs: [],
35
35
  depth: o.length,
36
36
  parent: n,
37
- handler: e,
37
+ handler: t,
38
38
  only: !0
39
- }), n && r.get(n).children.push(t), o.push(t), e(), o.pop();
39
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
40
40
  };
41
- y.skip = (s, e) => {
42
- const t = p(), n = o.at(-1);
43
- r.set(t, {
44
- id: t,
41
+ k.skip = (s, t) => {
42
+ const e = l(), n = o.at(-1);
43
+ r.set(e, {
44
+ id: e,
45
45
  name: s,
46
46
  type: "suite",
47
47
  children: [],
48
48
  logs: [],
49
49
  depth: o.length,
50
50
  parent: n,
51
- handler: e,
51
+ handler: t,
52
52
  skip: !0
53
- }), n && r.get(n).children.push(t), o.push(t), e(), o.pop();
53
+ }), n && r.get(n).children.push(e), o.push(e), t(), o.pop();
54
54
  };
55
- const k = (s, e) => {
56
- const t = p(), n = o.at(-1), i = {
57
- id: t,
55
+ const w = (s, t) => {
56
+ const e = l(), n = o.at(-1), a = {
57
+ id: e,
58
58
  name: s,
59
59
  type: "test",
60
60
  depth: o.length,
61
- handler: e,
61
+ handler: t,
62
62
  logs: [],
63
63
  parent: n
64
64
  };
65
- n && r.get(n).children.push(t), r.set(t, i);
65
+ n && r.get(n).children.push(e), r.set(e, a);
66
66
  };
67
- k.only = (s, e) => {
68
- const t = p(), n = o.at(-1), i = {
69
- id: t,
67
+ w.only = (s, t) => {
68
+ const e = l(), n = o.at(-1), a = {
69
+ id: e,
70
70
  name: s,
71
71
  type: "test",
72
72
  depth: o.length,
73
- handler: e,
73
+ handler: t,
74
74
  logs: [],
75
75
  parent: n,
76
76
  only: !0
77
77
  };
78
- n && r.get(n).children.push(t), r.set(t, i);
78
+ n && r.get(n).children.push(e), r.set(e, a);
79
79
  };
80
- k.skip = (s, e) => {
81
- const t = p(), n = o.at(-1), i = {
82
- id: t,
80
+ w.skip = (s, t) => {
81
+ const e = l(), n = o.at(-1), a = {
82
+ id: e,
83
83
  name: s,
84
84
  type: "test",
85
85
  depth: o.length,
86
- handler: e || (() => {
86
+ handler: t || (() => {
87
87
  }),
88
88
  logs: [],
89
89
  parent: n,
90
90
  skip: !0
91
91
  };
92
- n && r.get(n).children.push(t), r.set(t, i);
92
+ n && r.get(n).children.push(e), r.set(e, a);
93
93
  };
94
- const H = (s) => {
95
- const e = o.at(-1);
96
- if (!e) throw new Error("beforeEach() must be inside a describe()");
97
- c.has(e) || c.set(e, []), c.get(e).push(s);
98
- }, m = (s) => {
99
- const e = o.at(-1);
100
- if (!e) throw new Error("afterEach() must be inside a describe()");
101
- h.has(e) || h.set(e, []), h.get(e).push(s);
102
- }, _ = (s) => {
103
- const e = [], t = [];
94
+ const A = (s) => {
95
+ const t = o.at(-1);
96
+ if (!t) throw new Error("beforeEach() must be inside a describe()");
97
+ h.has(t) || h.set(t, []), h.get(t).push(s);
98
+ }, H = (s) => {
99
+ const t = o.at(-1);
100
+ if (!t) throw new Error("afterEach() must be inside a describe()");
101
+ u.has(t) || u.set(t, []), u.get(t).push(s);
102
+ }, T = (s) => {
103
+ const t = [], e = [];
104
104
  let n = s;
105
105
  for (; n; )
106
- c.has(n) && e.unshift(...c.get(n)), h.has(n) && t.push(...h.get(n)), n = r.get(n)?.parent;
107
- return { before: e, after: t };
106
+ h.has(n) && t.unshift(...h.get(n)), u.has(n) && e.push(...u.get(n)), n = r.get(n)?.parent;
107
+ return { before: t, after: e };
108
108
  }, f = (s) => {
109
- const e = r.get(s);
110
- return e ? e.only ? !0 : e.children ? e.children.some((t) => f(t)) : !1 : !1;
109
+ const t = r.get(s);
110
+ return t ? t.only ? !0 : t.children ? t.children.some((e) => f(e)) : !1 : !1;
111
111
  }, b = (s) => {
112
- let e = r.get(s);
113
- for (; e?.parent; ) {
114
- const t = r.get(e.parent);
115
- if (t?.only) return !0;
116
- e = t;
112
+ let t = r.get(s);
113
+ for (; t?.parent; ) {
114
+ const e = r.get(t.parent);
115
+ if (e?.only) return !0;
116
+ t = e;
117
117
  }
118
118
  return !1;
119
- }, g = (s) => {
120
- let e = r.get(s);
121
- for (; e; ) {
122
- if (e.skip) return !0;
123
- if (!e.parent) break;
124
- e = r.get(e.parent);
119
+ }, S = (s) => {
120
+ let t = r.get(s);
121
+ for (; t; ) {
122
+ if (t.skip) return !0;
123
+ if (!t.parent) break;
124
+ t = r.get(t.parent);
125
125
  }
126
126
  return !1;
127
- }, A = () => {
128
- r.clear(), c.clear(), h.clear();
127
+ }, M = () => {
128
+ r.clear(), h.clear(), u.clear();
129
129
  };
130
- class T {
131
- constructor(e) {
132
- d(this, "events");
133
- this.events = e;
130
+ class I {
131
+ constructor(t, e) {
132
+ g(this, "events");
133
+ g(this, "retryCount");
134
+ this.events = t, this.retryCount = e?.retryCount ?? 1;
134
135
  }
135
136
  async runAll() {
136
- const e = Array.from(r.values()).filter(
137
+ const t = Array.from(r.values()).filter(
137
138
  (n) => !n.parent && n.type === "suite"
138
- ), t = Array.from(r.values()).some((n) => n.only);
139
- for (const n of e)
140
- await this.runSuite(n, t);
139
+ ), e = Array.from(r.values()).some((n) => n.only);
140
+ for (const n of t)
141
+ await this.runSuite(n, e);
141
142
  return r;
142
143
  }
143
- async runSingle(e) {
144
- const t = r.get(e);
145
- if (!t || t.type !== "test") return;
146
- await this.runTest(t, !1);
144
+ async runSingle(t) {
145
+ const e = r.get(t);
146
+ if (!e || e.type !== "test") return;
147
+ await this.runTest(e, !1);
147
148
  }
148
- async runSuite(e, t) {
149
- if (g(e.id) && !f(e.id)) {
150
- this.events.onSkip?.(e);
149
+ async runByIds(t) {
150
+ const e = new Set(t), n = Array.from(r.values()).filter(
151
+ (i) => !i.parent && i.type === "suite"
152
+ ), a = Array.from(r.values()).some((i) => i.only);
153
+ for (const i of n)
154
+ await this.runSuiteByIds(i, e, a);
155
+ return r;
156
+ }
157
+ async runSuiteByIds(t, e, n) {
158
+ if (!this.hasDescendantInSet(t, e)) return;
159
+ if (S(t.id) && !f(t.id)) {
160
+ this.events.onSkip?.(t);
151
161
  return;
152
162
  }
153
- if (t && !f(e.id)) return;
154
- this.events.onSuiteStart?.(e);
155
- const i = (e.children || []).map((a) => r.get(a));
156
- for (const a of i)
157
- a.type === "suite" ? await this.runSuite(a, t) : a.type === "test" && await this.runTest(a, t);
158
- this.events.onSuiteEnd?.(e);
163
+ if (n && !f(t.id)) return;
164
+ this.events.onSuiteStart?.(t);
165
+ const d = (t.children || []).map((c) => r.get(c));
166
+ for (const c of d)
167
+ c.type === "suite" ? await this.runSuiteByIds(c, e, n) : c.type === "test" && e.has(c.id) && await this.runTest(c, n);
168
+ this.events.onSuiteEnd?.(t);
169
+ }
170
+ hasDescendantInSet(t, e) {
171
+ return e.has(t.id) ? !0 : t.children ? t.children.some((n) => {
172
+ const a = r.get(n);
173
+ return a ? this.hasDescendantInSet(a, e) : !1;
174
+ }) : !1;
159
175
  }
160
- async runTest(e, t) {
161
- if ((g(e.id) || e.skip) && !e.only) {
162
- this.events.onSkip(e);
176
+ async runSuite(t, e) {
177
+ if (S(t.id) && !f(t.id)) {
178
+ this.events.onSkip?.(t);
163
179
  return;
164
180
  }
165
- const i = b(e.id);
166
- if (t && !e.only && !i) {
167
- this.events.onSkip(e);
181
+ if (e && !f(t.id)) return;
182
+ this.events.onSuiteStart?.(t);
183
+ const a = (t.children || []).map((i) => r.get(i));
184
+ for (const i of a)
185
+ i.type === "suite" ? await this.runSuite(i, e) : i.type === "test" && await this.runTest(i, e);
186
+ this.events.onSuiteEnd?.(t);
187
+ }
188
+ async runTest(t, e) {
189
+ if ((S(t.id) || t.skip) && !t.only) {
190
+ this.events.onSkip(t);
168
191
  return;
169
192
  }
170
- this.events.onStart?.(e);
171
- const a = _(e.parent);
172
- try {
173
- for (const l of a.before) await l();
174
- e.logs = [], await e.handler(), this.events.onPass(e);
175
- } catch (l) {
176
- this.events.onFail(e, l);
177
- } finally {
178
- for (const l of a.after) await l();
193
+ const a = b(t.id);
194
+ if (e && !t.only && !a) {
195
+ this.events.onSkip(t);
196
+ return;
179
197
  }
198
+ this.events.onStart?.(t);
199
+ const i = T(t.parent);
200
+ let d = null;
201
+ for (let c = 1; c <= this.retryCount; c++)
202
+ try {
203
+ for (const p of i.before) await p();
204
+ t.logs = [], await t.handler(), this.events.onPass(t, c > 1 ? c : void 0);
205
+ return;
206
+ } catch (p) {
207
+ d = p;
208
+ } finally {
209
+ for (const p of i.after) await p();
210
+ }
211
+ this.events.onFail(t, d);
180
212
  }
181
213
  }
182
- window.__testRunner = T;
214
+ window.__testRunner = I;
183
215
  export {
184
- T as TestRunner,
185
- m as afterEach,
186
- H as beforeEach,
187
- A as clearTests,
188
- y as describe,
216
+ I as TestRunner,
217
+ H as afterEach,
218
+ A as beforeEach,
219
+ M as clearTests,
220
+ k as describe,
189
221
  r as handlers,
190
- k as it
222
+ w as it
191
223
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twd-js",
3
- "version": "1.5.2",
3
+ "version": "1.6.1",
4
4
  "description": "Test While Developing (TWD) - in-browser testing",
5
5
  "license": "MIT",
6
6
  "author": "BRIKEV",
@@ -80,12 +80,12 @@
80
80
  "@preact/preset-vite": "^2.10.3",
81
81
  "@testing-library/jest-dom": "^6.9.1",
82
82
  "@testing-library/react": "^16.3.2",
83
- "@types/react": "^19.2.13",
83
+ "@types/react": "^19.2.14",
84
84
  "@types/react-dom": "^19.2.3",
85
85
  "@vitejs/plugin-react": "^5.1.4",
86
86
  "@vitest/coverage-v8": "^4.0.18",
87
- "conventional-changelog": "^7.1.1",
88
- "jsdom": "^28.0.0",
87
+ "conventional-changelog": "^7.2.0",
88
+ "jsdom": "^28.1.0",
89
89
  "typescript": "^5.9.3",
90
90
  "vite": "^7.3.1",
91
91
  "vite-plugin-dts": "^4.5.4",
@@ -107,6 +107,6 @@
107
107
  "@testing-library/user-event": "^14.6.1",
108
108
  "@types/chai": "^5.2.3",
109
109
  "chai": "^6.2.2",
110
- "preact": "^10.28.3"
110
+ "preact": "^10.28.4"
111
111
  }
112
112
  }