twd-js 1.7.1 → 1.7.3
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/README.md +26 -4
- package/dist/asserts/index.d.ts +2 -0
- package/dist/bundled.d.ts +4 -1
- package/dist/bundled.es.js +9861 -602
- package/dist/cli.js +11 -11
- package/dist/commands/mockBridge.d.ts +117 -0
- package/dist/commands/url.d.ts +33 -0
- package/dist/commands/viewport.d.ts +2 -0
- package/dist/commands/visit.d.ts +1 -0
- package/dist/constants/version.d.ts +1 -0
- package/dist/global.d.ts +20 -0
- package/dist/index.cjs.js +33 -33
- package/dist/index.d.ts +8 -664
- package/dist/index.es.js +1695 -1657
- package/dist/initializers/initSidebar.d.ts +29 -0
- package/dist/initializers/initTests.d.ts +36 -0
- package/dist/mock-sw.js +1 -1
- package/dist/plugin/removeMockServiceWorker.d.ts +18 -0
- package/dist/plugin/twdHmr.d.ts +45 -0
- package/dist/proxies/domMessage.d.ts +1 -0
- package/dist/proxies/eventsMessage.d.ts +1 -0
- package/dist/proxies/screenDom.d.ts +45 -0
- package/dist/proxies/userEvent.d.ts +4 -0
- package/dist/runner-ci.d.ts +12 -28
- package/dist/runner.d.ts +52 -63
- package/dist/twd-types.d.ts +120 -0
- package/dist/twd.d.ts +291 -0
- package/dist/ui/ClosedSidebar.d.ts +6 -0
- package/dist/ui/Icons/BaseIcon.d.ts +7 -0
- package/dist/ui/Icons/ChevronDown.d.ts +2 -0
- package/dist/ui/Icons/ChevronRight.d.ts +2 -0
- package/dist/ui/Icons/Loader.d.ts +2 -0
- package/dist/ui/Icons/MockRequestIcon.d.ts +2 -0
- package/dist/ui/Icons/Play.d.ts +2 -0
- package/dist/ui/LogItem.d.ts +6 -0
- package/dist/ui/MockRulesButton.d.ts +1 -0
- package/dist/ui/MockedComponent.d.ts +6 -0
- package/dist/ui/SearchInput.d.ts +6 -0
- package/dist/ui/SkipOnlyName.d.ts +8 -0
- package/dist/ui/TWDSidebar.d.ts +20 -0
- package/dist/ui/TestList.d.ts +8 -0
- package/dist/ui/TestListItem.d.ts +19 -0
- package/dist/ui/componentMocks.d.ts +3 -0
- package/dist/ui/hooks/useLayout.d.ts +6 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/utils/buildTreeFromHandlers.d.ts +16 -0
- package/dist/ui/utils/chaiErrorFormat.d.ts +22 -0
- package/dist/ui/utils/filterTree.d.ts +2 -0
- package/dist/ui/utils/formatLogs.d.ts +30 -0
- package/dist/ui/utils/screenReaderMessages.d.ts +9 -0
- package/dist/ui/utils/styles.d.ts +7 -0
- package/dist/ui/utils/theme.d.ts +74 -0
- package/dist/ui.d.ts +2 -10
- package/dist/utils/assertionMessage.d.ts +1 -0
- package/dist/utils/log.d.ts +1 -0
- package/dist/utils/wait.d.ts +3 -0
- package/dist/utils/waitFor.d.ts +2 -0
- package/dist/vite-plugin.d.ts +2 -67
- package/package.json +31 -7
package/dist/twd.d.ts
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { Options, Rule } from './commands/mockBridge';
|
|
2
|
+
import { AnyAssertion, ArgsFor, TWDElemAPI, WaitForOptions } from './twd-types';
|
|
3
|
+
import { URLCommandAPI } from './commands/url';
|
|
4
|
+
interface TWDAPI {
|
|
5
|
+
/**
|
|
6
|
+
* Finds an element by selector and returns the TWD API for it.
|
|
7
|
+
* @param selector CSS selector
|
|
8
|
+
* @returns {Promise<TWDElemAPI>} The TWD API for the element
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const btn = await twd.get("button");
|
|
13
|
+
*
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
get: (selector: string) => Promise<TWDElemAPI>;
|
|
18
|
+
/**
|
|
19
|
+
* Sets the value of an input element and dispatches an input event. We recommend using this only for range, color, time inputs.
|
|
20
|
+
* @param el The input element
|
|
21
|
+
* @param value The value to set
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const input = await twd.get("input[type='time']");
|
|
26
|
+
* twd.setInputValue(input.el, "13:30");
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
setInputValue: (el: Element, value: string) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Finds multiple elements by selector and returns an array of TWD APIs for them.
|
|
33
|
+
* @param selector CSS selector
|
|
34
|
+
* @returns {Promise<TWDElemAPI[]>} Array of TWD APIs for the elements
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const items = await twd.getAll(".item");
|
|
39
|
+
* items.at(0).should("be.visible");
|
|
40
|
+
* items.at(1).should("contain.text", "Hello");
|
|
41
|
+
* expect(items).to.have.length(3);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
getAll: (selector: string) => Promise<TWDElemAPI[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Simulates visiting a URL (SPA navigation).
|
|
47
|
+
* @param url The URL to visit
|
|
48
|
+
* @param [reload] Whether to force a reload even if already on the URL (optional)
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* twd.visit("/contact");
|
|
53
|
+
* // visit with reload
|
|
54
|
+
* twd.visit("/contact", true);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
visit: (url: string, reload?: boolean) => Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Mock a network request.
|
|
60
|
+
*
|
|
61
|
+
* @param alias Identifier for the mock rule. Useful for `waitForRequest()`.
|
|
62
|
+
* @param options Options to configure the mock:
|
|
63
|
+
* - `method`: HTTP method ("GET", "POST", …)
|
|
64
|
+
* - `url`: URL string or RegExp to match
|
|
65
|
+
* - `response`: Body of the mocked response
|
|
66
|
+
* - `status`: (optional) HTTP status code (default: 200)
|
|
67
|
+
* - `responseHeaders`: (optional) Response headers
|
|
68
|
+
* - `delay`: (optional) Delay in ms before returning the response
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* mockRequest("getUser", {
|
|
73
|
+
* method: "GET",
|
|
74
|
+
* url: /\/api\/user\/\d+/,
|
|
75
|
+
* response: { id: 1, name: "Kevin" },
|
|
76
|
+
* status: 200,
|
|
77
|
+
* responseHeaders: { "x-mock": "true" }
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
mockRequest: (alias: string, options: Options) => Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Wait for a mocked request to be made.
|
|
84
|
+
* @param alias The alias of the mock rule to wait for
|
|
85
|
+
* @param retries The number of retries to make
|
|
86
|
+
* @param retryDelay The delay between retries
|
|
87
|
+
* @return The matched rule (with body if applicable)
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const rule = await twd.waitForRequest("aliasId");
|
|
92
|
+
* console.log(rule.body);
|
|
93
|
+
* const rule = await twd.waitForRequest("aliasId", 5, 100);
|
|
94
|
+
* console.log(rule.body);
|
|
95
|
+
*
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
waitForRequest: (alias: string, retries?: number, retryDelay?: number) => Promise<Rule>;
|
|
99
|
+
/**
|
|
100
|
+
* wait for a list of mocked requests to be made.
|
|
101
|
+
* @param aliases The aliases of the mock rules to wait for
|
|
102
|
+
* @returns The matched rules (with body if applicable)
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* const rules = await waitForRequests(["getUser", "postComment"]);
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
waitForRequests: (aliases: string[]) => Promise<Rule[]>;
|
|
109
|
+
/**
|
|
110
|
+
* URL-related assertions.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* twd.url().should("eq", "http://localhost:3000/contact");
|
|
115
|
+
* twd.url().should("contain.url", "/contact");
|
|
116
|
+
*
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
url: () => URLCommandAPI;
|
|
120
|
+
/**
|
|
121
|
+
* Initializes request mocking (registers the service worker).
|
|
122
|
+
* @param [path] service worker absolute path (optional)
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* await twd.initRequestMocking();
|
|
127
|
+
* // init with custom service worker path
|
|
128
|
+
* await twd.initRequestMocking('/test-path/mock-sw.js');
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
initRequestMocking: (path?: string) => Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Clears all request mock rules.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* twd.clearRequestMockRules();
|
|
138
|
+
*
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
clearRequestMockRules: () => void;
|
|
142
|
+
/**
|
|
143
|
+
* Gets all current request mock rules.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* const rules = twd.getRequestMockRules();
|
|
148
|
+
* console.log(rules);
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
getRequestMockRules: () => Rule[];
|
|
152
|
+
/**
|
|
153
|
+
* Gets the number of times a specific mock rule was hit.
|
|
154
|
+
* @param alias The alias of the mock rule
|
|
155
|
+
* @returns The number of times the rule was matched
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* const count = twd.getRequestCount("getUser");
|
|
160
|
+
* expect(count).to.equal(2);
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
getRequestCount: (alias: string) => number;
|
|
164
|
+
/**
|
|
165
|
+
* Gets a snapshot of all mock rule hit counts.
|
|
166
|
+
* @returns An object mapping rule aliases to their hit counts
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* const counts = twd.getRequestCounts();
|
|
171
|
+
* expect(counts).to.deep.equal({ getUser: 2, listPosts: 1 });
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
getRequestCounts: () => Record<string, number>;
|
|
175
|
+
/**
|
|
176
|
+
* Waits for a specified time.
|
|
177
|
+
* @param time Time in milliseconds to wait
|
|
178
|
+
* @returns A promise that resolves after the specified time
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* await twd.wait(500); // wait for 500ms
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
wait: (time: number) => Promise<void>;
|
|
185
|
+
/**
|
|
186
|
+
* Retries a callback until it stops throwing or the timeout expires.
|
|
187
|
+
* Use this instead of `twd.wait(ms)` to wait for conditions rather than fixed delays.
|
|
188
|
+
*
|
|
189
|
+
* @param callback Function to retry — can be sync or async. Should throw if the condition is not yet met.
|
|
190
|
+
* @param options Optional timeout, interval, and message settings
|
|
191
|
+
* @returns A promise that resolves with the callback's return value when it succeeds
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* // Wait for an analytics event and return it
|
|
196
|
+
* const event = await twd.waitFor(() => {
|
|
197
|
+
* const ev = findEvent("purchase");
|
|
198
|
+
* expect(ev).to.exist;
|
|
199
|
+
* return ev;
|
|
200
|
+
* }, { message: "purchase event to fire" });
|
|
201
|
+
*
|
|
202
|
+
* // Wait for an element (single expression)
|
|
203
|
+
* const heading = await twd.waitFor(() => screenDom.getByRole("heading", { name: /checkout/i }));
|
|
204
|
+
*
|
|
205
|
+
* // Fire-and-forget (void) — still works as before
|
|
206
|
+
* await twd.waitFor(() => {
|
|
207
|
+
* expect(submitButton.disabled).to.be.false;
|
|
208
|
+
* });
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
waitFor: <T>(callback: () => T | Promise<T>, options?: WaitForOptions) => Promise<T>;
|
|
212
|
+
/**
|
|
213
|
+
* Asserts something about the element.
|
|
214
|
+
* @param el The element to assert on
|
|
215
|
+
* @param name The name of the assertion.
|
|
216
|
+
* @param args Arguments for the assertion.
|
|
217
|
+
* @returns The same API for chaining.
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const button = await twd.get("button");
|
|
221
|
+
* const text = screenDom.getByText("Hello");
|
|
222
|
+
* twd.should(button.el, "have.text", "Hello");
|
|
223
|
+
* twd.should(text, "be.empty");
|
|
224
|
+
* twd.should(button.el, "have.class", "active");
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
should: (el: Element, name: AnyAssertion, ...args: ArgsFor<AnyAssertion>) => void;
|
|
228
|
+
/**
|
|
229
|
+
* Mock a component.
|
|
230
|
+
* @param name The name of the component to mock
|
|
231
|
+
* @param component The component to mock
|
|
232
|
+
* @returns The mocked component
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* twd.mockComponent("Button", Button);
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
mockComponent: (name: string, component: React.ComponentType<any>) => void;
|
|
239
|
+
/**
|
|
240
|
+
* Clears all component mocks.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```ts
|
|
244
|
+
* twd.clearComponentMocks();
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
clearComponentMocks: () => void;
|
|
248
|
+
/**
|
|
249
|
+
* Asserts that an element does not exist in the DOM.
|
|
250
|
+
* @param selector CSS selector of the element to check
|
|
251
|
+
* @returns A promise that resolves if the element does not exist, or rejects if it does
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* await twd.notExists(".non-existent");
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
notExists: (selector: string) => Promise<void>;
|
|
259
|
+
/**
|
|
260
|
+
* Simulates a viewport size by constraining body dimensions, overriding
|
|
261
|
+
* `window.innerWidth`/`window.innerHeight` and `window.matchMedia()`, and
|
|
262
|
+
* rewriting CSS `@media` rules to match the simulated dimensions.
|
|
263
|
+
* Call with no arguments to reset to the original viewport.
|
|
264
|
+
*
|
|
265
|
+
* @param width Viewport width in pixels
|
|
266
|
+
* @param height Viewport height in pixels (optional — omit to leave height unconstrained)
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* twd.viewport(375, 667); // mobile
|
|
271
|
+
* twd.viewport(768); // tablet width, height unconstrained
|
|
272
|
+
* twd.viewport(); // reset
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
viewport: (width?: number, height?: number) => void;
|
|
276
|
+
/**
|
|
277
|
+
* Resets the viewport to its original size (undoes a previous `twd.viewport()` call).
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* twd.resetViewport();
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
resetViewport: () => void;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Mini Cypress-style helpers for DOM testing.
|
|
288
|
+
* @namespace twd
|
|
289
|
+
*/
|
|
290
|
+
export declare const twd: TWDAPI;
|
|
291
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MockRulesButton: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface MockedComponentProps<TProps = any> {
|
|
2
|
+
name: string;
|
|
3
|
+
children: React.ReactElement<TProps>;
|
|
4
|
+
}
|
|
5
|
+
export declare function MockedComponent<TProps extends Record<string, any>>({ name, children, }: MockedComponentProps<TProps>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface TWDSidebarProps {
|
|
2
|
+
/**
|
|
3
|
+
* Whether the sidebar is open by default
|
|
4
|
+
*/
|
|
5
|
+
open: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Sidebar position
|
|
8
|
+
* - left: Sidebar on the left side (default)
|
|
9
|
+
* - right: Sidebar on the right side
|
|
10
|
+
*
|
|
11
|
+
* @default "left"
|
|
12
|
+
*/
|
|
13
|
+
position?: 'left' | 'right';
|
|
14
|
+
/**
|
|
15
|
+
* Whether to show the search/filter input
|
|
16
|
+
*/
|
|
17
|
+
search?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const TWDSidebar: ({ open, position, search }: TWDSidebarProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Node } from './utils/buildTreeFromHandlers';
|
|
2
|
+
interface TestListProps {
|
|
3
|
+
roots: Node[];
|
|
4
|
+
runTest: (id: string) => Promise<void>;
|
|
5
|
+
searchQuery?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const TestList: ({ roots, runTest, searchQuery }: TestListProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface Test {
|
|
2
|
+
name: string;
|
|
3
|
+
depth: number;
|
|
4
|
+
status?: 'idle' | 'pass' | 'fail' | 'skip' | 'running';
|
|
5
|
+
logs?: string[];
|
|
6
|
+
id: string;
|
|
7
|
+
parent?: string;
|
|
8
|
+
type: 'test' | 'suite';
|
|
9
|
+
only?: boolean;
|
|
10
|
+
skip?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface TestListItemProps {
|
|
13
|
+
node: Test;
|
|
14
|
+
depth: number;
|
|
15
|
+
id: string;
|
|
16
|
+
runTest: (i: string) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const TestListItem: ({ node, depth, id, runTest }: TestListItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const mockComponent: <TProps extends Record<string, any>>(id: string, component: React.ComponentType<TProps>) => void;
|
|
2
|
+
export declare function clearComponentMocks(): void;
|
|
3
|
+
export declare const getMockForComponent: <TProps = any>(id: string) => React.ComponentType<TProps> | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MockedComponent } from './MockedComponent';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface Test {
|
|
2
|
+
name: string;
|
|
3
|
+
depth: number;
|
|
4
|
+
status?: 'idle' | 'pass' | 'fail' | 'skip' | 'running';
|
|
5
|
+
logs?: string[];
|
|
6
|
+
id: string;
|
|
7
|
+
parent?: string;
|
|
8
|
+
type: 'test' | 'suite';
|
|
9
|
+
only?: boolean;
|
|
10
|
+
skip?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type Node = Test & {
|
|
13
|
+
childrenNodes?: Node[];
|
|
14
|
+
};
|
|
15
|
+
export declare const buildTreeFromHandlers: (handlers: Test[]) => Node[];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface ChaiAssertionError extends Error {
|
|
2
|
+
actual?: unknown;
|
|
3
|
+
expected?: unknown;
|
|
4
|
+
operator?: string;
|
|
5
|
+
showDiff?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const isChaiAssertionError: (error: unknown) => error is ChaiAssertionError;
|
|
8
|
+
declare const formatChaiError: (error: ChaiAssertionError) => {
|
|
9
|
+
type: string;
|
|
10
|
+
actual: {} | null;
|
|
11
|
+
expected: {} | null;
|
|
12
|
+
operator: string | undefined;
|
|
13
|
+
message?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
type: string;
|
|
16
|
+
message: string;
|
|
17
|
+
actual?: undefined;
|
|
18
|
+
expected?: undefined;
|
|
19
|
+
operator?: undefined;
|
|
20
|
+
};
|
|
21
|
+
declare const printChaiError: (error: ChaiAssertionError) => void;
|
|
22
|
+
export { isChaiAssertionError, formatChaiError, printChaiError };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare enum LogType {
|
|
2
|
+
CHAI_DIFF = "chai-diff",
|
|
3
|
+
CHAI_MESSAGE = "chai-message",
|
|
4
|
+
ERROR = "error"
|
|
5
|
+
}
|
|
6
|
+
interface ChaiDiffLog {
|
|
7
|
+
type: LogType.CHAI_DIFF;
|
|
8
|
+
expected: unknown;
|
|
9
|
+
actual: unknown;
|
|
10
|
+
}
|
|
11
|
+
interface ChaiMessageLog {
|
|
12
|
+
type: LogType.CHAI_MESSAGE;
|
|
13
|
+
message: string;
|
|
14
|
+
}
|
|
15
|
+
interface ErrorLog {
|
|
16
|
+
type: LogType.ERROR;
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
export type ParsedLog = ChaiDiffLog | ChaiMessageLog | ErrorLog;
|
|
20
|
+
export declare const parseLogEntry: (log: string) => ParsedLog | null;
|
|
21
|
+
export declare const formatValue: (value: unknown) => string;
|
|
22
|
+
export declare const assertStyles: (text: string) => {
|
|
23
|
+
color: string;
|
|
24
|
+
fontWeight: string;
|
|
25
|
+
} | {
|
|
26
|
+
color?: undefined;
|
|
27
|
+
fontWeight?: undefined;
|
|
28
|
+
};
|
|
29
|
+
export declare const getDisplayText: (log: string, parsedLog: ParsedLog | null) => string;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Handler } from '../../runner';
|
|
2
|
+
/**
|
|
3
|
+
* Generate screen reader message for a specific test result
|
|
4
|
+
*/
|
|
5
|
+
export declare const displaySRMessageSpecificTest: (test: Handler) => string;
|
|
6
|
+
/**
|
|
7
|
+
* Generate screen reader message for all tests result
|
|
8
|
+
*/
|
|
9
|
+
export declare const displaySRMessageAllTests: (tests: Handler[]) => string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const CSS_STYLES = "\n/* ========================\n Animation keyframes\n ======================== */\n@keyframes twd-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* ========================\n Buttons \u2014 shared base\n ======================== */\n.twd-btn {\n cursor: pointer;\n border-radius: var(--twd-border-radius);\n transition: all var(--twd-animation-duration) ease;\n}\n.twd-btn:hover { filter: brightness(1.15); }\n.twd-btn:active { filter: brightness(0.9); }\n.twd-btn:focus-visible {\n outline: 2px solid var(--twd-primary);\n outline-offset: 2px;\n}\n.twd-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.twd-btn:disabled:hover { filter: none; }\n\n/* ========================\n Button variants\n ======================== */\n.twd-btn-primary {\n background: var(--twd-button-primary);\n color: var(--twd-button-primary-text);\n padding: var(--twd-spacing-xs) var(--twd-spacing-md);\n border: none;\n}\n.twd-btn-secondary {\n background: var(--twd-button-secondary);\n color: var(--twd-button-secondary-text);\n padding: var(--twd-spacing-xs) var(--twd-spacing-md);\n border: 1px solid var(--twd-button-border);\n}\n.twd-btn-icon {\n background: transparent;\n border: 1px solid var(--twd-border-light);\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n font-size: var(--twd-font-size-sm);\n}\n.twd-btn-mock-rules {\n background: var(--twd-button-secondary);\n border: 1px solid var(--twd-button-border);\n border-radius: var(--twd-border-radius-lg);\n padding: var(--twd-spacing-md) var(--twd-spacing-lg);\n font-size: var(--twd-font-size-sm);\n color: var(--twd-button-secondary-text);\n display: flex;\n align-items: center;\n gap: var(--twd-spacing-md);\n margin-bottom: 10px;\n width: 100%;\n text-align: left;\n transition: all var(--twd-animation-duration) ease;\n box-shadow: var(--twd-shadow-sm);\n}\n\n/* ========================\n Sidebar layout\n ======================== */\n.twd-sidebar {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: fixed;\n top: 0;\n bottom: 0;\n width: var(--twd-sidebar-width);\n background: var(--twd-background);\n font-size: var(--twd-font-size-md);\n overflow-y: auto;\n box-shadow: var(--twd-shadow);\n text-align: left;\n z-index: var(--twd-z-index-sidebar);\n pointer-events: all;\n isolation: isolate;\n}\n.twd-sidebar-header {\n padding: var(--twd-spacing-md);\n background: var(--twd-background);\n position: sticky;\n top: 0;\n z-index: var(--twd-z-index-sticky);\n border-bottom: 1px solid var(--twd-border);\n}\n.twd-sidebar-header-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--twd-spacing-xl);\n}\n.twd-sidebar-header-buttons {\n display: flex;\n gap: var(--twd-spacing-xs);\n}\n.twd-sidebar-stats {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: var(--twd-font-size-md);\n color: var(--twd-text-secondary);\n margin-bottom: 10px;\n}\n.twd-sidebar-stats-counts {\n display: flex;\n gap: var(--twd-spacing-xs);\n}\n.twd-sidebar-content {\n padding: var(--twd-spacing-md);\n}\n.twd-sidebar-closed {\n position: fixed;\n top: 50%;\n transform: translateY(-50%);\n z-index: var(--twd-z-index-sidebar);\n background: var(--twd-button-primary);\n color: var(--twd-button-primary-text);\n padding: var(--twd-spacing-sm) 10px;\n font-size: var(--twd-font-size-sm);\n}\n.twd-sidebar-version {\n color: var(--twd-text-secondary);\n font-size: var(--twd-font-size-sm);\n align-self: center;\n}\n\n/* ========================\n Test list\n ======================== */\n.twd-test-list {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.twd-test-group {\n background: var(--twd-describe-bg);\n border-left: 3px solid var(--twd-describe-border);\n border-radius: var(--twd-border-radius);\n padding: var(--twd-spacing-xs) var(--twd-spacing-sm);\n margin-bottom: var(--twd-spacing-sm);\n}\n.twd-test-group-toggle {\n font-weight: var(--twd-font-weight-medium);\n font-size: var(--twd-font-size-sm);\n cursor: pointer;\n color: var(--twd-describe-text);\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--twd-spacing-sm);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.twd-test-item {\n display: flex;\n align-items: left;\n justify-content: space-between;\n padding: var(--twd-spacing-sm) var(--twd-spacing-sm);\n border-radius: var(--twd-border-radius);\n}\n.twd-test-item-name {\n font-weight: var(--twd-font-weight-medium);\n font-size: var(--twd-font-size-md);\n color: var(--twd-text);\n max-width: 220px;\n}\n.twd-test-item-logs {\n border-radius: var(--twd-border-radius);\n max-height: 260px;\n overflow-y: auto;\n padding: 0;\n background: var(--twd-background-secondary);\n list-style: none;\n margin-top: var(--twd-spacing-xs);\n text-align: left;\n}\n\n/* ========================\n Status variants\n ======================== */\n.twd-status-pass { background: var(--twd-success-bg); }\n.twd-status-fail { background: var(--twd-error-bg); }\n.twd-status-skip { background: var(--twd-skip-bg); }\n.twd-status-running { background: var(--twd-warning-bg); }\n\n/* ========================\n Search\n ======================== */\n.twd-search-wrapper {\n position: relative;\n margin-bottom: var(--twd-spacing-md);\n}\n.twd-search-input {\n width: 100%;\n padding: var(--twd-spacing-md);\n background: var(--twd-background);\n color: var(--twd-text);\n border: 1px solid var(--twd-border);\n border-radius: var(--twd-border-radius);\n font-size: var(--twd-font-size-md);\n box-sizing: border-box;\n}\n.twd-search-input:focus-visible {\n outline: 2px solid var(--twd-primary);\n outline-offset: 2px;\n}\n\n/* ========================\n Loader\n ======================== */\n.twd-loader {\n animation: twd-spin 1s linear infinite;\n}\n";
|
|
2
|
+
/**
|
|
3
|
+
* Injects all sidebar CSS classes into the document.
|
|
4
|
+
* Guards against double-injection (same pattern as injectTheme).
|
|
5
|
+
* Called once from initSidebar.tsx after injectTheme().
|
|
6
|
+
*/
|
|
7
|
+
export declare function injectStyles(): void;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TWD Theme Configuration
|
|
3
|
+
*
|
|
4
|
+
* This file defines CSS variables that can be customized by users
|
|
5
|
+
* to personalize their TWD UI experience.
|
|
6
|
+
*
|
|
7
|
+
* Users can override these variables by setting them in their CSS:
|
|
8
|
+
*
|
|
9
|
+
* ```css
|
|
10
|
+
* :root {
|
|
11
|
+
* --twd-primary: #2563eb;
|
|
12
|
+
* --twd-background: #1e293b;
|
|
13
|
+
* ... other variables
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
export interface TWDTheme {
|
|
18
|
+
primary: string;
|
|
19
|
+
background: string;
|
|
20
|
+
backgroundSecondary: string;
|
|
21
|
+
border: string;
|
|
22
|
+
borderLight: string;
|
|
23
|
+
text: string;
|
|
24
|
+
textSecondary: string;
|
|
25
|
+
textMuted: string;
|
|
26
|
+
describeBg: string;
|
|
27
|
+
describeText: string;
|
|
28
|
+
describeBorder: string;
|
|
29
|
+
success: string;
|
|
30
|
+
successBg: string;
|
|
31
|
+
error: string;
|
|
32
|
+
errorBg: string;
|
|
33
|
+
warning: string;
|
|
34
|
+
warningBg: string;
|
|
35
|
+
skip: string;
|
|
36
|
+
skipBg: string;
|
|
37
|
+
buttonPrimary: string;
|
|
38
|
+
buttonPrimaryText: string;
|
|
39
|
+
buttonSecondary: string;
|
|
40
|
+
buttonSecondaryText: string;
|
|
41
|
+
buttonBorder: string;
|
|
42
|
+
spacingXs: string;
|
|
43
|
+
spacingSm: string;
|
|
44
|
+
spacingMd: string;
|
|
45
|
+
spacingLg: string;
|
|
46
|
+
spacingXl: string;
|
|
47
|
+
fontSizeXs: string;
|
|
48
|
+
fontSizeSm: string;
|
|
49
|
+
fontSizeMd: string;
|
|
50
|
+
fontSizeLg: string;
|
|
51
|
+
fontWeightNormal: string;
|
|
52
|
+
fontWeightMedium: string;
|
|
53
|
+
fontWeightBold: string;
|
|
54
|
+
sidebarWidth: string;
|
|
55
|
+
borderRadius: string;
|
|
56
|
+
borderRadiusLg: string;
|
|
57
|
+
shadow: string;
|
|
58
|
+
shadowSm: string;
|
|
59
|
+
zIndexSidebar: string;
|
|
60
|
+
zIndexSticky: string;
|
|
61
|
+
animationDuration: string;
|
|
62
|
+
iconColor: string;
|
|
63
|
+
iconColorSecondary: string;
|
|
64
|
+
}
|
|
65
|
+
export declare const defaultTheme: TWDTheme;
|
|
66
|
+
/**
|
|
67
|
+
* Converts theme object to CSS variables string
|
|
68
|
+
*/
|
|
69
|
+
export declare function themeToCSSVariables(theme?: Partial<TWDTheme>): string;
|
|
70
|
+
/**
|
|
71
|
+
* Injects theme CSS variables into the document
|
|
72
|
+
* This should be called once when the sidebar is initialized
|
|
73
|
+
*/
|
|
74
|
+
export declare function injectTheme(theme?: Partial<TWDTheme>): void;
|
package/dist/ui.d.ts
CHANGED
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export declare function MockedComponent<TProps extends Record<string, any>>({ name, children, }: MockedComponentProps<TProps>): JSX.Element;
|
|
4
|
-
|
|
5
|
-
declare interface MockedComponentProps<TProps = any> {
|
|
6
|
-
name: string;
|
|
7
|
-
children: React.ReactElement<TProps>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export { }
|
|
1
|
+
export * from './ui/index'
|
|
2
|
+
export {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const assertionMessage: (valid: boolean, isNegated: boolean, correctMessage: string, errorMessage: string) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const log: (msg: string) => void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const waitForElement: (selector: string, fn: () => HTMLElement | null, timeout?: number, interval?: number) => Promise<HTMLElement>;
|
|
2
|
+
export declare const waitForElements: (selector: string, fn: () => NodeListOf<Element> | null, timeout?: number, interval?: number) => Promise<Element[]>;
|
|
3
|
+
export declare const wait: (time: number) => Promise<void>;
|