@testspectra/matchers 1.0.69 → 1.1.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.
- package/LICENSE.md +48 -0
- package/dist/__tests__/intercept.test.d.ts +1 -0
- package/dist/__tests__/intercept.test.js +183 -0
- package/dist/__tests__/matchers.test.d.ts +1 -0
- package/dist/__tests__/matchers.test.js +161 -0
- package/dist/index.d.ts +3 -21
- package/dist/index.js +3 -21
- package/dist/intercept/cdp-handler.d.ts +22 -0
- package/dist/intercept/cdp-handler.js +123 -0
- package/dist/intercept/index.d.ts +4 -0
- package/dist/intercept/index.js +4 -0
- package/dist/intercept/mock-handle.d.ts +49 -0
- package/dist/intercept/mock-handle.js +124 -0
- package/dist/intercept/mock-registry.d.ts +18 -0
- package/dist/intercept/mock-registry.js +97 -0
- package/dist/intercept/types.d.ts +43 -0
- package/dist/intercept/types.js +1 -0
- package/dist/matchers.d.ts +5 -1
- package/dist/matchers.js +116 -29
- package/dist/proto.d.ts +18 -283
- package/dist/proto.js +1 -114
- package/dist/reporter.d.ts +30 -0
- package/dist/reporter.js +85 -0
- package/dist/runner/collection.d.ts +33 -20
- package/dist/runner/collection.js +78 -26
- package/dist/runner/single.d.ts +123 -32
- package/dist/runner/single.js +266 -48
- package/dist/spectra.d.ts +32 -8
- package/dist/spectra.js +157 -40
- package/dist/types.d.ts +1195 -28
- package/package.json +16 -12
- package/src/index.ts +3 -22
- package/src/proto.ts +22 -433
- package/src/types.ts +1403 -96
- package/tsconfig.json +2 -2
- package/src/matchers.ts +0 -146
- package/src/runner/collection.ts +0 -153
- package/src/runner/single.ts +0 -301
- package/src/spectra.ts +0 -376
package/dist/proto.d.ts
CHANGED
|
@@ -1,288 +1,23 @@
|
|
|
1
|
+
import type { SpectraBrowserBridge, SpectraStatic } from './types.js';
|
|
1
2
|
declare global {
|
|
3
|
+
/**
|
|
4
|
+
* The global TestSpectra static automation and assertion instance.
|
|
5
|
+
*/
|
|
6
|
+
var Spectra: SpectraStatic;
|
|
7
|
+
/**
|
|
8
|
+
* The global TestSpectra browser bridge instance.
|
|
9
|
+
*/
|
|
10
|
+
var browser: SpectraBrowserBridge;
|
|
11
|
+
/**
|
|
12
|
+
* Global fixture store injected by TestSpectra runner.
|
|
13
|
+
*/
|
|
14
|
+
var Fixture: Record<string, any>;
|
|
15
|
+
/**
|
|
16
|
+
* Global step library injected by TestSpectra runner.
|
|
17
|
+
*/
|
|
18
|
+
var Step: Record<string, any>;
|
|
2
19
|
namespace WebdriverIO {
|
|
3
|
-
interface
|
|
4
|
-
/**
|
|
5
|
-
* Asserts that the element is displayed on the screen and visible to the user.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* await LoginPage.submitButton.shouldBeVisible();
|
|
10
|
-
* ```
|
|
11
|
-
* @returns The element instance for chaining.
|
|
12
|
-
*/
|
|
13
|
-
shouldBeVisible(): Promise<Element>;
|
|
14
|
-
/**
|
|
15
|
-
* Asserts that the element is NOT displayed or is hidden from view.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```ts
|
|
19
|
-
* await LoginPage.errorMessage.shouldNotBeVisible();
|
|
20
|
-
* ```
|
|
21
|
-
* @returns The element instance for chaining.
|
|
22
|
-
*/
|
|
23
|
-
shouldNotBeVisible(): Promise<Element>;
|
|
24
|
-
/**
|
|
25
|
-
* Asserts that the element exists in the DOM/UI hierarchy.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* await LoginPage.rememberMeCheckbox.shouldExist();
|
|
30
|
-
* ```
|
|
31
|
-
* @returns The element instance for chaining.
|
|
32
|
-
*/
|
|
33
|
-
shouldExist(): Promise<Element>;
|
|
34
|
-
/**
|
|
35
|
-
* Asserts that the element does NOT exist in the DOM/UI hierarchy.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* await LoginPage.loadingSpinner.shouldNotExist();
|
|
40
|
-
* ```
|
|
41
|
-
* @returns The element instance for chaining.
|
|
42
|
-
*/
|
|
43
|
-
shouldNotExist(): Promise<Element>;
|
|
44
|
-
/**
|
|
45
|
-
* Asserts that the element is enabled for interaction.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* await LoginPage.loginButton.shouldBeEnabled();
|
|
50
|
-
* ```
|
|
51
|
-
* @returns The element instance for chaining.
|
|
52
|
-
*/
|
|
53
|
-
shouldBeEnabled(): Promise<Element>;
|
|
54
|
-
/**
|
|
55
|
-
* Asserts that the element is disabled (cannot be interacted with).
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```ts
|
|
59
|
-
* await LoginPage.disabledSubmit.shouldBeDisabled();
|
|
60
|
-
* ```
|
|
61
|
-
* @returns The element instance for chaining.
|
|
62
|
-
*/
|
|
63
|
-
shouldBeDisabled(): Promise<Element>;
|
|
64
|
-
/**
|
|
65
|
-
* Asserts that the form element (radio button, checkbox, option) is selected.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* await SettingsPage.darkModeRadio.shouldBeSelected();
|
|
70
|
-
* ```
|
|
71
|
-
* @returns The element instance for chaining.
|
|
72
|
-
*/
|
|
73
|
-
shouldBeSelected(): Promise<Element>;
|
|
74
|
-
/**
|
|
75
|
-
* Asserts that the checkbox or radio element is checked.
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```ts
|
|
79
|
-
* await SettingsPage.termsCheckbox.shouldBeChecked();
|
|
80
|
-
* ```
|
|
81
|
-
* @returns The element instance for chaining.
|
|
82
|
-
*/
|
|
83
|
-
shouldBeChecked(): Promise<Element>;
|
|
84
|
-
/**
|
|
85
|
-
* Asserts that the input element has the exact given value.
|
|
86
|
-
*
|
|
87
|
-
* @param expectedValue - The exact expected value.
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* await LoginPage.usernameInput.shouldHaveValue("admin@test.com");
|
|
91
|
-
* ```
|
|
92
|
-
* @returns The element instance for chaining.
|
|
93
|
-
*/
|
|
94
|
-
shouldHaveValue(expectedValue: string): Promise<Element>;
|
|
95
|
-
/**
|
|
96
|
-
* Asserts that the input element's value contains the given substring.
|
|
97
|
-
*
|
|
98
|
-
* @param expectedValue - Substring expected to be present in the value.
|
|
99
|
-
* @example
|
|
100
|
-
* ```ts
|
|
101
|
-
* await LoginPage.tokenInput.shouldContainValue("JWT_");
|
|
102
|
-
* ```
|
|
103
|
-
* @returns The element instance for chaining.
|
|
104
|
-
*/
|
|
105
|
-
shouldContainValue(expectedValue: string): Promise<Element>;
|
|
106
|
-
/**
|
|
107
|
-
* Asserts that the element's text content matches the exact expected text.
|
|
108
|
-
*
|
|
109
|
-
* @param expectedText - The exact expected text content.
|
|
110
|
-
* @example
|
|
111
|
-
* ```ts
|
|
112
|
-
* await LoginPage.headerTitle.shouldHaveText("Welcome to TestSpectra");
|
|
113
|
-
* ```
|
|
114
|
-
* @returns The element instance for chaining.
|
|
115
|
-
*/
|
|
116
|
-
shouldHaveText(expectedText: string): Promise<Element>;
|
|
117
|
-
/**
|
|
118
|
-
* Asserts that the element's text content contains the expected substring.
|
|
119
|
-
*
|
|
120
|
-
* @param expectedText - Substring expected to be within the element text.
|
|
121
|
-
* @example
|
|
122
|
-
* ```ts
|
|
123
|
-
* await LoginPage.welcomeBanner.shouldContainText("Welcome");
|
|
124
|
-
* ```
|
|
125
|
-
* @returns The element instance for chaining.
|
|
126
|
-
*/
|
|
127
|
-
shouldContainText(expectedText: string): Promise<Element>;
|
|
128
|
-
/**
|
|
129
|
-
* Asserts that the element has the specified CSS class.
|
|
130
|
-
*
|
|
131
|
-
* @param className - Expected CSS class name.
|
|
132
|
-
* @example
|
|
133
|
-
* ```ts
|
|
134
|
-
* await NavigationBar.homeTab.shouldHaveClass("is-active");
|
|
135
|
-
* ```
|
|
136
|
-
* @returns The element instance for chaining.
|
|
137
|
-
*/
|
|
138
|
-
shouldHaveClass(className: string): Promise<Element>;
|
|
139
|
-
/**
|
|
140
|
-
* Asserts that the element has the specified attribute, optionally checking its exact value.
|
|
141
|
-
*
|
|
142
|
-
* @param attributeName - Name of the attribute (e.g. `aria-label`, `disabled`, `href`).
|
|
143
|
-
* @param expectedValue - Optional expected value of the attribute.
|
|
144
|
-
* @example
|
|
145
|
-
* ```ts
|
|
146
|
-
* await NavigationBar.logoLink.shouldHaveAttribute("href", "/dashboard");
|
|
147
|
-
* await NavigationBar.cartButton.shouldHaveAttribute("aria-expanded");
|
|
148
|
-
* ```
|
|
149
|
-
* @returns The element instance for chaining.
|
|
150
|
-
*/
|
|
151
|
-
shouldHaveAttribute(attributeName: string, expectedValue?: string): Promise<Element>;
|
|
20
|
+
interface Browser extends SpectraBrowserBridge {
|
|
152
21
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Optional settings for HTTP network interception responses.
|
|
155
|
-
*/
|
|
156
|
-
interface InterceptFixtureOptions {
|
|
157
|
-
/** HTTP status code to return in the mocked response (default: 200) */
|
|
158
|
-
statusCode?: number;
|
|
159
|
-
/** Custom HTTP response headers */
|
|
160
|
-
headers?: Record<string, string>;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Structured mock payload object with optional status code and headers.
|
|
164
|
-
*/
|
|
165
|
-
interface InterceptFixtureObject<TData = unknown> {
|
|
166
|
-
/** HTTP status code */
|
|
167
|
-
statusCode?: number;
|
|
168
|
-
/** Response body payload */
|
|
169
|
-
body: TData;
|
|
170
|
-
/** Custom HTTP response headers */
|
|
171
|
-
headers?: Record<string, string>;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Input payload for API mocking: JSON object, string, or structured fixture object.
|
|
175
|
-
*/
|
|
176
|
-
type InterceptInput<TData = unknown> = InterceptFixtureObject<TData> | TData | string;
|
|
177
|
-
interface Mock {
|
|
178
|
-
/**
|
|
179
|
-
* Dynamically set or change the fixture response for this mock instance.
|
|
180
|
-
* Supports fixture file paths, structured `{ statusCode, body, headers }` objects, or raw data.
|
|
181
|
-
*
|
|
182
|
-
* @param fixture - Data payload or Fixture reference.
|
|
183
|
-
* @param options - Optional status code and header overrides.
|
|
184
|
-
* @example
|
|
185
|
-
* ```ts
|
|
186
|
-
* const mock = await browser.intercept("/api/user", "GET");
|
|
187
|
-
* await mock.respondWith({ name: "Admin", role: "superadmin" });
|
|
188
|
-
* ```
|
|
189
|
-
*/
|
|
190
|
-
respondWith<TData = unknown>(fixture: InterceptInput<TData>, options?: InterceptFixtureOptions): Promise<void>;
|
|
191
|
-
}
|
|
192
|
-
interface Browser {
|
|
193
|
-
/**
|
|
194
|
-
* Intercepts and mocks network API requests matching the specified endpoint.
|
|
195
|
-
* Supports automatic base URL resolution and TestSpectra JSON Fixtures.
|
|
196
|
-
*
|
|
197
|
-
* @param path - URL path or route to intercept (e.g. `"/api/users"` or `"https://api.example.com/v1/*"`).
|
|
198
|
-
* @param method - HTTP request method (`"GET"`, `"POST"`, `"PUT"`, `"DELETE"`, `"PATCH"`).
|
|
199
|
-
* @param fixture - Optional initial response payload or Fixture object.
|
|
200
|
-
* @param options - Optional status code and header configuration.
|
|
201
|
-
* @example
|
|
202
|
-
* ```ts
|
|
203
|
-
* // Intercept with JSON Fixture
|
|
204
|
-
* await browser.intercept("/api/status", "GET", Fixture.userData);
|
|
205
|
-
*
|
|
206
|
-
* // Intercept with custom payload & status code
|
|
207
|
-
* await browser.intercept("/api/auth/login", "POST", { token: "xyz" }, { statusCode: 200 });
|
|
208
|
-
* ```
|
|
209
|
-
* @returns `Mock` instance allowing dynamic response modification.
|
|
210
|
-
*/
|
|
211
|
-
intercept<TData = unknown>(path: string, method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", fixture?: InterceptInput<TData>, options?: InterceptFixtureOptions): Promise<Mock>;
|
|
212
|
-
/**
|
|
213
|
-
* Asserts that the current browser page URL exactly matches the expected URL.
|
|
214
|
-
*
|
|
215
|
-
* @param expectedUrl - The exact URL expected.
|
|
216
|
-
* @example
|
|
217
|
-
* ```ts
|
|
218
|
-
* await browser.shouldHaveUrl("https://app.example.com/dashboard");
|
|
219
|
-
* ```
|
|
220
|
-
*/
|
|
221
|
-
shouldHaveUrl(expectedUrl: string): Promise<void>;
|
|
222
|
-
/**
|
|
223
|
-
* Asserts that the current browser page URL contains the given substring.
|
|
224
|
-
*
|
|
225
|
-
* @param expectedUrl - Substring expected in the current URL.
|
|
226
|
-
* @example
|
|
227
|
-
* ```ts
|
|
228
|
-
* await browser.shouldContainUrl("/dashboard");
|
|
229
|
-
* ```
|
|
230
|
-
*/
|
|
231
|
-
shouldContainUrl(expectedUrl: string): Promise<void>;
|
|
232
|
-
/**
|
|
233
|
-
* Asserts that the current browser page title matches the expected title.
|
|
234
|
-
*
|
|
235
|
-
* @param expectedTitle - The exact title expected.
|
|
236
|
-
* @example
|
|
237
|
-
* ```ts
|
|
238
|
-
* await browser.shouldHaveTitle("Dashboard - TestSpectra");
|
|
239
|
-
* ```
|
|
240
|
-
*/
|
|
241
|
-
shouldHaveTitle(expectedTitle: string): Promise<void>;
|
|
242
|
-
/**
|
|
243
|
-
* Asserts that the current browser page title contains the expected substring.
|
|
244
|
-
*
|
|
245
|
-
* @param expectedTitle - Substring expected in the title.
|
|
246
|
-
* @example
|
|
247
|
-
* ```ts
|
|
248
|
-
* await browser.shouldContainTitle("Dashboard");
|
|
249
|
-
* ```
|
|
250
|
-
*/
|
|
251
|
-
shouldContainTitle(expectedTitle: string): Promise<void>;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
interface Promise<T> {
|
|
255
|
-
/** Asserts that the element promise resolves to a visible element. */
|
|
256
|
-
shouldBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
257
|
-
/** Asserts that the element promise resolves to a hidden/non-visible element. */
|
|
258
|
-
shouldNotBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
259
|
-
/** Asserts that the element promise resolves to an existing element in the DOM. */
|
|
260
|
-
shouldExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
261
|
-
/** Asserts that the element promise resolves to an element that does not exist in the DOM. */
|
|
262
|
-
shouldNotExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
263
|
-
/** Asserts that the element promise resolves to an enabled element. */
|
|
264
|
-
shouldBeEnabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
265
|
-
/** Asserts that the element promise resolves to a disabled element. */
|
|
266
|
-
shouldBeDisabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
267
|
-
/** Asserts that the element promise resolves to a selected element. */
|
|
268
|
-
shouldBeSelected(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
269
|
-
/** Asserts that the element promise resolves to a checked checkbox or radio. */
|
|
270
|
-
shouldBeChecked(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
271
|
-
/** Asserts that the element promise resolves to an element with the exact value. */
|
|
272
|
-
shouldHaveValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
|
|
273
|
-
/** Asserts that the element promise resolves to an element whose value contains the substring. */
|
|
274
|
-
shouldContainValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
|
|
275
|
-
/** Asserts that the element promise resolves to an element with the exact text content. */
|
|
276
|
-
shouldHaveText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
|
|
277
|
-
/** Asserts that the element promise resolves to an element whose text contains the substring. */
|
|
278
|
-
shouldContainText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
|
|
279
|
-
/** Asserts that the element promise resolves to an element having the CSS class. */
|
|
280
|
-
shouldHaveClass(this: Promise<WebdriverIO.Element>, className: string): Promise<WebdriverIO.Element>;
|
|
281
|
-
/** Asserts that the element promise resolves to an element having the attribute. */
|
|
282
|
-
shouldHaveAttribute(this: Promise<WebdriverIO.Element>, attributeName: string, expectedValue?: string): Promise<WebdriverIO.Element>;
|
|
283
22
|
}
|
|
284
23
|
}
|
|
285
|
-
/**
|
|
286
|
-
* Install direct callable assertion methods onto WebdriverIO browser/element and Promise prototypes.
|
|
287
|
-
*/
|
|
288
|
-
export declare function installPrototypes(): void;
|
package/dist/proto.js
CHANGED
|
@@ -1,114 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Install direct callable assertion methods onto WebdriverIO browser/element and Promise prototypes.
|
|
4
|
-
*/
|
|
5
|
-
export function installPrototypes() {
|
|
6
|
-
const elementCommands = {
|
|
7
|
-
async shouldBeVisible() {
|
|
8
|
-
const el = await resolveElement(this);
|
|
9
|
-
await expect(el).toBeDisplayed();
|
|
10
|
-
return el;
|
|
11
|
-
},
|
|
12
|
-
async shouldNotBeVisible() {
|
|
13
|
-
const el = await resolveElement(this);
|
|
14
|
-
await expect(el).not.toBeDisplayed();
|
|
15
|
-
return el;
|
|
16
|
-
},
|
|
17
|
-
async shouldExist() {
|
|
18
|
-
const el = await resolveElement(this);
|
|
19
|
-
await expect(el).toExist();
|
|
20
|
-
return el;
|
|
21
|
-
},
|
|
22
|
-
async shouldNotExist() {
|
|
23
|
-
const el = await resolveElement(this);
|
|
24
|
-
await expect(el).not.toExist();
|
|
25
|
-
return el;
|
|
26
|
-
},
|
|
27
|
-
async shouldBeEnabled() {
|
|
28
|
-
const el = await resolveElement(this);
|
|
29
|
-
await expect(el).toBeEnabled();
|
|
30
|
-
return el;
|
|
31
|
-
},
|
|
32
|
-
async shouldBeDisabled() {
|
|
33
|
-
const el = await resolveElement(this);
|
|
34
|
-
await expect(el).toBeDisabled();
|
|
35
|
-
return el;
|
|
36
|
-
},
|
|
37
|
-
async shouldBeSelected() {
|
|
38
|
-
const el = await resolveElement(this);
|
|
39
|
-
await expect(el).toBeSelected();
|
|
40
|
-
return el;
|
|
41
|
-
},
|
|
42
|
-
async shouldBeChecked() {
|
|
43
|
-
const el = await resolveElement(this);
|
|
44
|
-
await expect(el).toBeSelected();
|
|
45
|
-
return el;
|
|
46
|
-
},
|
|
47
|
-
async shouldHaveValue(val) {
|
|
48
|
-
const el = await resolveElement(this);
|
|
49
|
-
await expect(el).toHaveValue(val);
|
|
50
|
-
return el;
|
|
51
|
-
},
|
|
52
|
-
async shouldContainValue(val) {
|
|
53
|
-
const el = await resolveElement(this);
|
|
54
|
-
await expect(el).toHaveValue(expect.stringContaining(val));
|
|
55
|
-
return el;
|
|
56
|
-
},
|
|
57
|
-
async shouldHaveText(text) {
|
|
58
|
-
const el = await resolveElement(this);
|
|
59
|
-
await expect(el).toHaveText(text);
|
|
60
|
-
return el;
|
|
61
|
-
},
|
|
62
|
-
async shouldContainText(text) {
|
|
63
|
-
const el = await resolveElement(this);
|
|
64
|
-
await expect(el).toHaveText(expect.stringContaining(text));
|
|
65
|
-
return el;
|
|
66
|
-
},
|
|
67
|
-
async shouldHaveClass(cls) {
|
|
68
|
-
const el = await resolveElement(this);
|
|
69
|
-
await expect(el).toHaveElementClass(cls);
|
|
70
|
-
return el;
|
|
71
|
-
},
|
|
72
|
-
async shouldHaveAttribute(name, val) {
|
|
73
|
-
const el = await resolveElement(this);
|
|
74
|
-
if (val !== undefined) {
|
|
75
|
-
await expect(el).toHaveAttribute(name, val);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
await expect(el).toHaveAttribute(name);
|
|
79
|
-
}
|
|
80
|
-
return el;
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
const browserCommands = {
|
|
84
|
-
async shouldHaveUrl(url) {
|
|
85
|
-
await expect(browser).toHaveUrl(url);
|
|
86
|
-
},
|
|
87
|
-
async shouldContainUrl(url) {
|
|
88
|
-
await expect(browser).toHaveUrl(expect.stringContaining(url));
|
|
89
|
-
},
|
|
90
|
-
async shouldHaveTitle(title) {
|
|
91
|
-
await expect(browser).toHaveTitle(title);
|
|
92
|
-
},
|
|
93
|
-
async shouldContainTitle(title) {
|
|
94
|
-
await expect(browser).toHaveTitle(expect.stringContaining(title));
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
if (typeof browser !== "undefined" && browser.addCommand) {
|
|
98
|
-
for (const [name, fn] of Object.entries(elementCommands)) {
|
|
99
|
-
browser.addCommand(name, fn, true);
|
|
100
|
-
}
|
|
101
|
-
for (const [name, fn] of Object.entries(browserCommands)) {
|
|
102
|
-
browser.addCommand(name, fn, false);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Attach to Promise.prototype for ChainablePromiseElement unwrapping
|
|
106
|
-
for (const [name, fn] of Object.entries(elementCommands)) {
|
|
107
|
-
if (typeof Promise.prototype[name] !== "function") {
|
|
108
|
-
Promise.prototype[name] = async function (...args) {
|
|
109
|
-
const el = await this;
|
|
110
|
-
return await fn.call(el, ...args);
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* # @testspectra/matchers - Interactive Command Reporter
|
|
4
|
+
*
|
|
5
|
+
* Real-time, single-line colorful reporter for every action, assertion,
|
|
6
|
+
* and browser command executed within the TestSpectra test lifecycle.
|
|
7
|
+
*/
|
|
8
|
+
export declare const colors: {
|
|
9
|
+
reset: string;
|
|
10
|
+
bold: string;
|
|
11
|
+
dim: string;
|
|
12
|
+
italic: string;
|
|
13
|
+
underline: string;
|
|
14
|
+
red: string;
|
|
15
|
+
green: string;
|
|
16
|
+
yellow: string;
|
|
17
|
+
blue: string;
|
|
18
|
+
magenta: string;
|
|
19
|
+
cyan: string;
|
|
20
|
+
white: string;
|
|
21
|
+
gray: string;
|
|
22
|
+
passBadge: string;
|
|
23
|
+
failBadge: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function formatTarget(target: any): string;
|
|
26
|
+
export declare function formatArgs(args: any[]): string;
|
|
27
|
+
/**
|
|
28
|
+
* Tracks and reports a single TestSpectra command with live interactive single-line feedback.
|
|
29
|
+
*/
|
|
30
|
+
export declare function trackCommand<T>(category: 'action' | 'assertion' | 'browser' | 'step', commandText: string | object, fn: () => Promise<T>): Promise<T>;
|
package/dist/reporter.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* # @testspectra/matchers - Interactive Command Reporter
|
|
4
|
+
*
|
|
5
|
+
* Real-time, single-line colorful reporter for every action, assertion,
|
|
6
|
+
* and browser command executed within the TestSpectra test lifecycle.
|
|
7
|
+
*/
|
|
8
|
+
export const colors = {
|
|
9
|
+
reset: '\x1b[0m',
|
|
10
|
+
bold: '\x1b[1m',
|
|
11
|
+
dim: '\x1b[90m',
|
|
12
|
+
italic: '\x1b[3m',
|
|
13
|
+
underline: '\x1b[4m',
|
|
14
|
+
// Vibrant ANSI colors
|
|
15
|
+
red: '\x1b[38;2;248;113;113m', // Light coral red
|
|
16
|
+
green: '\x1b[38;2;52;211;153m', // Emerald green
|
|
17
|
+
yellow: '\x1b[38;2;251;191;36m', // Amber yellow
|
|
18
|
+
blue: '\x1b[38;2;96;165;250m', // Sky blue
|
|
19
|
+
magenta: '\x1b[38;2;192;132;252m', // Purple
|
|
20
|
+
cyan: '\x1b[38;2;45;212;191m', // Teal / Cyan
|
|
21
|
+
white: '\x1b[38;2;241;245;249m', // Crisp white
|
|
22
|
+
gray: '\x1b[38;2;148;163;184m', // Slate gray
|
|
23
|
+
// Status symbols
|
|
24
|
+
passBadge: '\x1b[38;2;52;211;153m✓\x1b[0m',
|
|
25
|
+
failBadge: '\x1b[38;2;248;113;113m✗\x1b[0m',
|
|
26
|
+
};
|
|
27
|
+
export function formatTarget(target) {
|
|
28
|
+
if (target === undefined || target === null)
|
|
29
|
+
return 'Spectra';
|
|
30
|
+
if (typeof target === 'string') {
|
|
31
|
+
return `Spectra.get("${target}")`;
|
|
32
|
+
}
|
|
33
|
+
if (typeof target === 'object') {
|
|
34
|
+
if (target.selector) {
|
|
35
|
+
return `Spectra.get("${target.selector}")`;
|
|
36
|
+
}
|
|
37
|
+
if (target.constructor && target.constructor.name && target.constructor.name !== 'Object') {
|
|
38
|
+
return target.constructor.name;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return String(target);
|
|
42
|
+
}
|
|
43
|
+
export function formatArgs(args) {
|
|
44
|
+
if (!args || args.length === 0)
|
|
45
|
+
return '';
|
|
46
|
+
return args
|
|
47
|
+
.map((a) => {
|
|
48
|
+
if (typeof a === 'string')
|
|
49
|
+
return `"${a}"`;
|
|
50
|
+
if (typeof a === 'number' || typeof a === 'boolean')
|
|
51
|
+
return String(a);
|
|
52
|
+
if (a === null)
|
|
53
|
+
return 'null';
|
|
54
|
+
if (a === undefined)
|
|
55
|
+
return 'undefined';
|
|
56
|
+
try {
|
|
57
|
+
return JSON.stringify(a);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return String(a);
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.join(', ');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Tracks and reports a single TestSpectra command with live interactive single-line feedback.
|
|
67
|
+
*/
|
|
68
|
+
export async function trackCommand(category, commandText, fn) {
|
|
69
|
+
const start = Date.now();
|
|
70
|
+
const payload = typeof commandText === 'object' ? JSON.stringify(commandText) : commandText;
|
|
71
|
+
console.log(`[TESTSPECTRA_STEP_START] ${payload}`);
|
|
72
|
+
try {
|
|
73
|
+
const result = await fn();
|
|
74
|
+
const duration = Date.now() - start;
|
|
75
|
+
console.log(`[TESTSPECTRA_STEP_PASS] ${payload} (${duration}ms)`);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
const duration = Date.now() - start;
|
|
80
|
+
console.log(`[TESTSPECTRA_STEP_FAIL] ${payload} (${duration}ms)`);
|
|
81
|
+
const msg = err && err.message ? err.message : String(err);
|
|
82
|
+
console.log(`[TESTSPECTRA_TEST_ERROR] ${msg}`);
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -1,43 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SingleElementRunner } from
|
|
1
|
+
import { CollectionReceiverAssertions } from '../types.js';
|
|
2
|
+
import { SingleElementRunner } from './single.js';
|
|
3
3
|
/**
|
|
4
4
|
* Fluent assertion, filtering, and iteration runner for multi-element collections.
|
|
5
5
|
*
|
|
6
|
-
* Implements `PromiseLike<void
|
|
6
|
+
* Implements `PromiseLike<void>` and `CollectionReceiverAssertions<MultiElementRunner>`,
|
|
7
|
+
* allowing assertions across matching elements,
|
|
7
8
|
* array index access (`.eq()`, `.first()`, `.last()`), and sequential iteration (`.each()`).
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
10
11
|
* ```ts
|
|
11
12
|
* // Assert collection size
|
|
12
|
-
* await Spectra.getAll(".cart-item").
|
|
13
|
+
* await Spectra.getAll(".cart-item").shouldHaveLength(3);
|
|
13
14
|
*
|
|
14
15
|
* // Target specific element from collection
|
|
15
16
|
* await Spectra.getAll(".todo-item").first().click();
|
|
16
|
-
* await Spectra.getAll(".todo-item").eq(2).
|
|
17
|
+
* await Spectra.getAll(".todo-item").eq(2).shouldHaveText("Buy Milk");
|
|
17
18
|
*
|
|
18
19
|
* // Iteration
|
|
19
20
|
* await Spectra.getAll(".nav-link").each(async (link, i) => {
|
|
20
|
-
* await link.
|
|
21
|
+
* await link.shouldBeVisible();
|
|
21
22
|
* });
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
|
-
export declare class MultiElementRunner implements PromiseLike<void> {
|
|
25
|
+
export declare class MultiElementRunner implements PromiseLike<void>, CollectionReceiverAssertions<MultiElementRunner> {
|
|
25
26
|
private _selector;
|
|
26
27
|
private _assertions;
|
|
27
28
|
constructor(selector: string);
|
|
29
|
+
private _pushAssertion;
|
|
28
30
|
/**
|
|
29
|
-
*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*
|
|
38
|
-
|
|
31
|
+
* Asserts that the collection contains exactly `count` elements.
|
|
32
|
+
*/
|
|
33
|
+
shouldHaveLength(count: number): this;
|
|
34
|
+
/**
|
|
35
|
+
* Asserts that the collection does not contain `count` elements.
|
|
36
|
+
*/
|
|
37
|
+
shouldNotHaveLength(count: number): this;
|
|
38
|
+
/**
|
|
39
|
+
* Asserts that the collection contains more than `min` elements.
|
|
40
|
+
*/
|
|
41
|
+
shouldHaveLengthGreaterThan(min: number): this;
|
|
42
|
+
/**
|
|
43
|
+
* Asserts that the collection contains less than `max` elements.
|
|
44
|
+
*/
|
|
45
|
+
shouldHaveLengthLessThan(max: number): this;
|
|
46
|
+
/**
|
|
47
|
+
* Asserts that the collection is empty (contains 0 elements).
|
|
48
|
+
*/
|
|
49
|
+
shouldBeEmpty(): this;
|
|
50
|
+
/**
|
|
51
|
+
* Asserts that the collection is not empty (contains at least 1 element).
|
|
39
52
|
*/
|
|
40
|
-
|
|
53
|
+
shouldNotBeEmpty(): this;
|
|
41
54
|
/**
|
|
42
55
|
* Returns a `SingleElementRunner` targeting the element at the specified 0-based index.
|
|
43
56
|
*
|
|
@@ -64,7 +77,7 @@ export declare class MultiElementRunner implements PromiseLike<void> {
|
|
|
64
77
|
*
|
|
65
78
|
* @example
|
|
66
79
|
* ```ts
|
|
67
|
-
* await Spectra.getAll(".step-indicator").last().
|
|
80
|
+
* await Spectra.getAll(".step-indicator").last().shouldHaveClass("current");
|
|
68
81
|
* ```
|
|
69
82
|
* @returns `SingleElementRunner` for the last element.
|
|
70
83
|
*/
|
|
@@ -76,7 +89,7 @@ export declare class MultiElementRunner implements PromiseLike<void> {
|
|
|
76
89
|
* @example
|
|
77
90
|
* ```ts
|
|
78
91
|
* await Spectra.getAll(".checkbox").each(async (item, index) => {
|
|
79
|
-
* await item.
|
|
92
|
+
* await item.shouldBeVisible();
|
|
80
93
|
* });
|
|
81
94
|
* ```
|
|
82
95
|
*/
|