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/index.d.ts CHANGED
@@ -1,7 +1,440 @@
1
- export { twd } from './twd';
2
- export { TWDSidebar } from './ui/TWDSidebar';
3
- export { initTests } from './initializers/initTests';
4
- export { expect } from 'chai';
5
- export { userEvent } from './proxies/userEvent';
6
- export { screenDom, configureScreenDom } from './proxies/screenDom';
7
- export type { Chai };
1
+ import { configure } from '@testing-library/dom';
2
+ import { default as default_2 } from '@testing-library/user-event';
3
+ import { expect } from 'chai';
4
+ import { JSX } from 'react/jsx-runtime';
5
+ import { screen as screen_2 } from '@testing-library/dom';
6
+
7
+ /**
8
+ * All assertion names, including negated ones.
9
+ */
10
+ declare type AnyAssertion = Negatable_2<AssertionName>;
11
+
12
+ /**
13
+ * All assertion names, including negated ones.
14
+ */
15
+ declare type AnyURLAssertion = Negatable<URLAssertionName>;
16
+
17
+ /**
18
+ * Maps assertion name to its argument tuple.
19
+ */
20
+ declare type ArgsFor<A extends AnyAssertion> = A extends `not.${infer Base extends AssertionName}` ? AssertionArgs[Base] : A extends AssertionName ? AssertionArgs[A] : never;
21
+
22
+ /**
23
+ * Argument types for each assertion.
24
+ */
25
+ declare type AssertionArgs = {
26
+ "have.text": [expected: string];
27
+ "contain.text": [expected: string];
28
+ "be.empty": [];
29
+ "have.attr": [attr: string, value: string];
30
+ "have.value": [value: string];
31
+ "be.disabled": [];
32
+ "be.enabled": [];
33
+ "be.checked": [];
34
+ "be.selected": [];
35
+ "be.focused": [];
36
+ "be.visible": [];
37
+ "have.class": [className: string];
38
+ };
39
+
40
+ /**
41
+ * Types and interfaces for the TWD testing library.
42
+ *
43
+ * @module twd-types
44
+ */
45
+ /**
46
+ * All supported assertion names for the `should` function.
47
+ *
48
+ * @example
49
+ * api.should("have.text", "Hello");
50
+ * api.should("be.empty");
51
+ */
52
+ declare type AssertionName = "have.text" | "contain.text" | "be.empty" | "have.attr" | "have.value" | "be.disabled" | "be.enabled" | "be.checked" | "be.selected" | "be.focused" | "be.visible" | "have.class";
53
+
54
+ export declare const configureScreenDom: typeof configure;
55
+
56
+ export { expect }
57
+
58
+ /**
59
+ * Initialize Vite test loading.
60
+ * @param testModules - The test modules to load.
61
+ * @param component - The React component to render the sidebar.
62
+ * @param createRoot - Function to create a React root.
63
+ * @example
64
+ * ```ts
65
+ * if (import.meta.env.DEV) {
66
+ * const testModules = import.meta.glob("./example.twd.test.ts");
67
+ * const { initTests, TWDSidebar } = await import('twd-js');
68
+ * await initTests(testModules, <TWDSidebar open={true} position="left" />, createRoot);
69
+ * }
70
+ * ```
71
+ */
72
+ export declare const initTests: (testModules: TestModule, Component: React.ReactNode, createRoot: (el: HTMLElement) => {
73
+ render: (el: React.ReactNode) => void;
74
+ }) => Promise<void>;
75
+
76
+ export declare function MockedComponent<TProps extends Record<string, any>>({ name, children, }: MockedComponentProps<TProps>): JSX.Element;
77
+
78
+ declare interface MockedComponentProps<TProps = any> {
79
+ name: string;
80
+ children: React.ReactElement<TProps>;
81
+ }
82
+
83
+ /**
84
+ * Negatable assertion names (e.g., 'not.have.text').
85
+ */
86
+ declare type Negatable<T extends string> = T | `not.${T}`;
87
+
88
+ /**
89
+ * Negatable assertion names (e.g., 'not.have.text').
90
+ */
91
+ declare type Negatable_2<T extends string> = T | `not.${T}`;
92
+
93
+ declare interface Options {
94
+ method: string;
95
+ url: string | RegExp;
96
+ response: unknown;
97
+ status?: number;
98
+ responseHeaders?: Record<string, string>;
99
+ urlRegex?: boolean;
100
+ }
101
+
102
+ declare type Rule = {
103
+ method: string;
104
+ url: string | RegExp;
105
+ response: unknown;
106
+ alias: string;
107
+ executed?: boolean;
108
+ request?: any;
109
+ status?: number;
110
+ responseHeaders?: Record<string, string>;
111
+ urlRegex?: boolean;
112
+ };
113
+
114
+ declare type ScreenDom = typeof screen_2;
115
+
116
+ export declare const screenDom: ScreenDom;
117
+
118
+ /**
119
+ * Overloads for the `should` function, for best IntelliSense.
120
+ *
121
+ * @example
122
+ * twd.should("have.text", "Hello");
123
+ * twd.should("be.empty");
124
+ * twd.should("have.class", "active");
125
+ */
126
+ declare type ShouldFn = {
127
+ (name: "have.text", expected: string): TWDElemAPI;
128
+ (name: "not.have.text", expected: string): TWDElemAPI;
129
+ (name: "contain.text", expected: string): TWDElemAPI;
130
+ (name: "not.contain.text", expected: string): TWDElemAPI;
131
+ (name: "be.empty"): TWDElemAPI;
132
+ (name: "not.be.empty"): TWDElemAPI;
133
+ (name: "have.attr", attr: string, value: string): TWDElemAPI;
134
+ (name: "not.have.attr", attr: string, value: string): TWDElemAPI;
135
+ (name: "have.value", value: string): TWDElemAPI;
136
+ (name: "not.have.value", value: string): TWDElemAPI;
137
+ (name: "be.disabled"): TWDElemAPI;
138
+ (name: "not.be.disabled"): TWDElemAPI;
139
+ (name: "be.enabled"): TWDElemAPI;
140
+ (name: "not.be.enabled"): TWDElemAPI;
141
+ (name: "be.checked"): TWDElemAPI;
142
+ (name: "not.be.checked"): TWDElemAPI;
143
+ (name: "be.selected"): TWDElemAPI;
144
+ (name: "not.be.selected"): TWDElemAPI;
145
+ (name: "be.focused"): TWDElemAPI;
146
+ (name: "not.be.focused"): TWDElemAPI;
147
+ (name: "be.visible"): TWDElemAPI;
148
+ (name: "not.be.visible"): TWDElemAPI;
149
+ (name: "have.class", className: string): TWDElemAPI;
150
+ (name: "not.have.class", className: string): TWDElemAPI;
151
+ };
152
+
153
+ /**
154
+ * A record of test module paths to their loader functions.
155
+ * Each function returns a promise that resolves when the module is loaded.
156
+ * This is typically used with Vite's `import.meta.glob` to dynamically import test modules.
157
+ * @example
158
+ * ```ts
159
+ * const testModules = {
160
+ * './test1.twd.test.ts': () => import('./test1.twd.test.ts'),
161
+ * './test2.twd.test.ts': () => import('./test2.twd.test.ts'),
162
+ * };
163
+ * ```
164
+ */
165
+ declare type TestModule = Record<string, () => Promise<unknown>>;
166
+
167
+ /**
168
+ * Mini Cypress-style helpers for DOM testing.
169
+ * @namespace twd
170
+ */
171
+ export declare const twd: TWDAPI;
172
+
173
+ declare interface TWDAPI {
174
+ /**
175
+ * Finds an element by selector and returns the TWD API for it.
176
+ * @param selector CSS selector
177
+ * @returns {Promise<TWDElemAPI>} The TWD API for the element
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const btn = await twd.get("button");
182
+ *
183
+ * ```
184
+ *
185
+ */
186
+ get: (selector: string) => Promise<TWDElemAPI>;
187
+ /**
188
+ * Sets the value of an input element and dispatches an input event. We recommend using this only for range, color, time inputs.
189
+ * @param el The input element
190
+ * @param value The value to set
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * const input = await twd.get("input[type='time']");
195
+ * twd.setInputValue(input.el, "13:30");
196
+ *
197
+ * ```
198
+ */
199
+ setInputValue: (el: Element, value: string) => void;
200
+ /**
201
+ * Finds multiple elements by selector and returns an array of TWD APIs for them.
202
+ * @param selector CSS selector
203
+ * @returns {Promise<TWDElemAPI[]>} Array of TWD APIs for the elements
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const items = await twd.getAll(".item");
208
+ * items.at(0).should("be.visible");
209
+ * items.at(1).should("contain.text", "Hello");
210
+ * expect(items).to.have.length(3);
211
+ * ```
212
+ */
213
+ getAll: (selector: string) => Promise<TWDElemAPI[]>;
214
+ /**
215
+ * Simulates visiting a URL (SPA navigation).
216
+ * @param url The URL to visit
217
+ * @param [reload] Whether to force a reload even if already on the URL (optional)
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * twd.visit("/contact");
222
+ * // visit with reload
223
+ * twd.visit("/contact", true);
224
+ * ```
225
+ */
226
+ visit: (url: string, reload?: boolean) => Promise<void>;
227
+ /**
228
+ * Mock a network request.
229
+ *
230
+ * @param alias Identifier for the mock rule. Useful for `waitFor()`.
231
+ * @param options Options to configure the mock:
232
+ * - `method`: HTTP method ("GET", "POST", …)
233
+ * - `url`: URL string or RegExp to match
234
+ * - `response`: Body of the mocked response
235
+ * - `status`: (optional) HTTP status code (default: 200)
236
+ * - `headers`: (optional) Response headers
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * mockRequest("getUser", {
241
+ * method: "GET",
242
+ * url: /\/api\/user\/\d+/,
243
+ * response: { id: 1, name: "Kevin" },
244
+ * status: 200,
245
+ * headers: { "x-mock": "true" }
246
+ * });
247
+ * ```
248
+ */
249
+ mockRequest: (alias: string, options: Options) => Promise<void>;
250
+ /**
251
+ * Wait for a mocked request to be made.
252
+ * @param alias The alias of the mock rule to wait for
253
+ * @return The matched rule (with body if applicable)
254
+ *
255
+ * @example
256
+ * ```ts
257
+ * const rule = await twd.waitFor("aliasId");
258
+ * console.log(rule.body);
259
+ *
260
+ * ```
261
+ */
262
+ waitForRequest: (alias: string) => Promise<Rule>;
263
+ /**
264
+ * wait for a list of mocked requests to be made.
265
+ * @param aliases The aliases of the mock rules to wait for
266
+ * @returns The matched rules (with body if applicable)
267
+ * @example
268
+ * ```ts
269
+ * const rules = await waitForRequests(["getUser", "postComment"]);
270
+ * ```
271
+ */
272
+ waitForRequests: (aliases: string[]) => Promise<Rule[]>;
273
+ /**
274
+ * URL-related assertions.
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * twd.url().should("eq", "http://localhost:3000/contact");
279
+ * twd.url().should("contain.url", "/contact");
280
+ *
281
+ * ```
282
+ */
283
+ url: () => URLCommandAPI;
284
+ /**
285
+ * Initializes request mocking (registers the service worker).
286
+ * Must be called before using `twd.mockRequest()`.
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * await twd.initRequestMocking();
291
+ *
292
+ * ```
293
+ */
294
+ initRequestMocking: () => Promise<void>;
295
+ /**
296
+ * Clears all request mock rules.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * twd.clearRequestMockRules();
301
+ *
302
+ * ```
303
+ */
304
+ clearRequestMockRules: () => void;
305
+ /**
306
+ * Gets all current request mock rules.
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * const rules = twd.getRequestMockRules();
311
+ * console.log(rules);
312
+ * ```
313
+ */
314
+ getRequestMockRules: () => Rule[];
315
+ /**
316
+ * Waits for a specified time.
317
+ * @param time Time in milliseconds to wait
318
+ * @returns A promise that resolves after the specified time
319
+ * @example
320
+ * ```ts
321
+ * await twd.wait(500); // wait for 500ms
322
+ * ```
323
+ */
324
+ wait: (time: number) => Promise<void>;
325
+ /**
326
+ * Asserts something about the element.
327
+ * @param el The element to assert on
328
+ * @param name The name of the assertion.
329
+ * @param args Arguments for the assertion.
330
+ * @returns The same API for chaining.
331
+ * @example
332
+ * ```ts
333
+ * const button = await twd.get("button");
334
+ * const text = screenDom.getByText("Hello");
335
+ * twd.should(button.el, "have.text", "Hello");
336
+ * twd.should(text, "be.empty");
337
+ * twd.should(button.el, "have.class", "active");
338
+ * ```
339
+ */
340
+ should: (el: Element, name: AnyAssertion, ...args: ArgsFor<AnyAssertion>) => void;
341
+ /**
342
+ * Mock a component.
343
+ * @param name The name of the component to mock
344
+ * @param component The component to mock
345
+ * @returns The mocked component
346
+ * @example
347
+ * ```ts
348
+ * twd.mockComponent("Button", Button);
349
+ * ```
350
+ */
351
+ mockComponent: (name: string, component: React.ComponentType<any>) => void;
352
+ /**
353
+ * Clears all component mocks.
354
+ *
355
+ * @example
356
+ * ```ts
357
+ * twd.clearComponentMocks();
358
+ * ```
359
+ */
360
+ clearComponentMocks: () => void;
361
+ /**
362
+ * Asserts that an element does not exist in the DOM.
363
+ * @param selector CSS selector of the element to check
364
+ * @returns A promise that resolves if the element does not exist, or rejects if it does
365
+ *
366
+ * @example
367
+ * ```ts
368
+ * await twd.notExists(".non-existent");
369
+ * ```
370
+ */
371
+ notExists: (selector: string) => Promise<void>;
372
+ }
373
+
374
+ /**
375
+ * The main API returned by `twd.get()`.
376
+ *
377
+ * @example
378
+ * ```ts
379
+ * const btn = await twd.get("button");
380
+ * btn.should("have.text", "Clicked").click();
381
+ *
382
+ * ```
383
+ *
384
+ */
385
+ declare interface TWDElemAPI {
386
+ /** The underlying DOM element. */
387
+ el: Element;
388
+ /**
389
+ * Asserts something about the element.
390
+ * @param name The name of the assertion.
391
+ * @param args Arguments for the assertion.
392
+ * @returns The same API for chaining.
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * const btn = await twd.get("button");
397
+ * btn.should("have.text", "Click me").should("not.be.disabled");
398
+ *
399
+ * ```
400
+ *
401
+ */
402
+ should: ShouldFn;
403
+ }
404
+
405
+ export declare const TWDSidebar: ({ open, position }: TWDSidebarProps) => JSX.Element;
406
+
407
+ declare interface TWDSidebarProps {
408
+ /**
409
+ * Whether the sidebar is open by default
410
+ */
411
+ open: boolean;
412
+ /**
413
+ * Sidebar position
414
+ * - left: Sidebar on the left side (default)
415
+ * - right: Sidebar on the right side
416
+ *
417
+ * @default "left"
418
+ */
419
+ position?: "left" | "right";
420
+ }
421
+
422
+ /**
423
+ * All supported assertion names for the `should` function in url command
424
+ *
425
+ * @example
426
+ * twd.url().should("contain.url", "/new-page");
427
+ * twd.url().should("eq", "http://localhost:3000/new-page");
428
+ */
429
+ declare type URLAssertionName = "eq" | "contain.url";
430
+
431
+ declare type URLCommandAPI = {
432
+ location: Location;
433
+ should: (name: AnyURLAssertion, value: string) => URLCommandAPI | string;
434
+ };
435
+
436
+ declare type UserEvent = typeof default_2;
437
+
438
+ export declare const userEvent: UserEvent;
439
+
440
+ export { }