@testspectra/matchers 1.0.70 → 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
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import { executeMultiMatcher } from
|
|
2
|
-
import {
|
|
1
|
+
import { executeMultiMatcher } from '../matchers.js';
|
|
2
|
+
import { trackCommand } from '../reporter.js';
|
|
3
|
+
import { SingleElementRunner } from './single.js';
|
|
3
4
|
/**
|
|
4
5
|
* Fluent assertion, filtering, and iteration runner for multi-element collections.
|
|
5
6
|
*
|
|
6
|
-
* Implements `PromiseLike<void
|
|
7
|
+
* Implements `PromiseLike<void>` and `CollectionReceiverAssertions<MultiElementRunner>`,
|
|
8
|
+
* allowing assertions across matching elements,
|
|
7
9
|
* array index access (`.eq()`, `.first()`, `.last()`), and sequential iteration (`.each()`).
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ```ts
|
|
11
13
|
* // Assert collection size
|
|
12
|
-
* await Spectra.getAll(".cart-item").
|
|
14
|
+
* await Spectra.getAll(".cart-item").shouldHaveLength(3);
|
|
13
15
|
*
|
|
14
16
|
* // Target specific element from collection
|
|
15
17
|
* await Spectra.getAll(".todo-item").first().click();
|
|
16
|
-
* await Spectra.getAll(".todo-item").eq(2).
|
|
18
|
+
* await Spectra.getAll(".todo-item").eq(2).shouldHaveText("Buy Milk");
|
|
17
19
|
*
|
|
18
20
|
* // Iteration
|
|
19
21
|
* await Spectra.getAll(".nav-link").each(async (link, i) => {
|
|
20
|
-
* await link.
|
|
22
|
+
* await link.shouldBeVisible();
|
|
21
23
|
* });
|
|
22
24
|
* ```
|
|
23
25
|
*/
|
|
@@ -27,22 +29,46 @@ export class MultiElementRunner {
|
|
|
27
29
|
constructor(selector) {
|
|
28
30
|
this._selector = selector;
|
|
29
31
|
}
|
|
32
|
+
_pushAssertion(matcher, args = []) {
|
|
33
|
+
this._assertions.push({ matcher, args });
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
30
36
|
// --- Collection Assertions ---
|
|
31
37
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* @param matcher - Multi-element matcher string (e.g. `'have.length'`, `'be.empty'`).
|
|
35
|
-
* @param args - Expected values or limits for the matcher.
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* await Spectra.getAll(".product-card").should("have.length.greaterThan", 0);
|
|
39
|
-
* await Spectra.getAll(".error-badge").should("be.empty");
|
|
40
|
-
* ```
|
|
41
|
-
* @returns Current collection runner instance for chaining.
|
|
38
|
+
* Asserts that the collection contains exactly `count` elements.
|
|
42
39
|
*/
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
|
|
40
|
+
shouldHaveLength(count) {
|
|
41
|
+
return this._pushAssertion('have.length', [count]);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Asserts that the collection does not contain `count` elements.
|
|
45
|
+
*/
|
|
46
|
+
shouldNotHaveLength(count) {
|
|
47
|
+
return this._pushAssertion('not.have.length', [count]);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Asserts that the collection contains more than `min` elements.
|
|
51
|
+
*/
|
|
52
|
+
shouldHaveLengthGreaterThan(min) {
|
|
53
|
+
return this._pushAssertion('have.length.greaterThan', [min]);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Asserts that the collection contains less than `max` elements.
|
|
57
|
+
*/
|
|
58
|
+
shouldHaveLengthLessThan(max) {
|
|
59
|
+
return this._pushAssertion('have.length.lessThan', [max]);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Asserts that the collection is empty (contains 0 elements).
|
|
63
|
+
*/
|
|
64
|
+
shouldBeEmpty() {
|
|
65
|
+
return this._pushAssertion('be.empty');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Asserts that the collection is not empty (contains at least 1 element).
|
|
69
|
+
*/
|
|
70
|
+
shouldNotBeEmpty() {
|
|
71
|
+
return this._pushAssertion('not.be.empty');
|
|
46
72
|
}
|
|
47
73
|
// --- Item Navigation ---
|
|
48
74
|
/**
|
|
@@ -56,8 +82,16 @@ export class MultiElementRunner {
|
|
|
56
82
|
* @returns `SingleElementRunner` for the indexed element.
|
|
57
83
|
*/
|
|
58
84
|
eq(index) {
|
|
59
|
-
const
|
|
60
|
-
|
|
85
|
+
const targetSelector = `${this._selector}[${index}]`;
|
|
86
|
+
const elPromise = (async () => {
|
|
87
|
+
if (typeof $$ !== 'undefined') {
|
|
88
|
+
const elements = await $$(this._selector);
|
|
89
|
+
return elements[index];
|
|
90
|
+
}
|
|
91
|
+
return { selector: targetSelector };
|
|
92
|
+
})();
|
|
93
|
+
elPromise.selector = targetSelector;
|
|
94
|
+
return new SingleElementRunner(elPromise);
|
|
61
95
|
}
|
|
62
96
|
/**
|
|
63
97
|
* Returns a `SingleElementRunner` targeting the first element in the collection (`index = 0`).
|
|
@@ -76,13 +110,22 @@ export class MultiElementRunner {
|
|
|
76
110
|
*
|
|
77
111
|
* @example
|
|
78
112
|
* ```ts
|
|
79
|
-
* await Spectra.getAll(".step-indicator").last().
|
|
113
|
+
* await Spectra.getAll(".step-indicator").last().shouldHaveClass("current");
|
|
80
114
|
* ```
|
|
81
115
|
* @returns `SingleElementRunner` for the last element.
|
|
82
116
|
*/
|
|
83
117
|
last() {
|
|
84
|
-
const
|
|
85
|
-
|
|
118
|
+
const targetSelector = `${this._selector}[last()]`;
|
|
119
|
+
const elPromise = (async () => {
|
|
120
|
+
if (typeof $$ !== 'undefined') {
|
|
121
|
+
const elements = await $$(this._selector);
|
|
122
|
+
const arr = Array.isArray(elements) ? elements : await elements;
|
|
123
|
+
return arr[arr.length - 1];
|
|
124
|
+
}
|
|
125
|
+
return { selector: targetSelector };
|
|
126
|
+
})();
|
|
127
|
+
elPromise.selector = targetSelector;
|
|
128
|
+
return new SingleElementRunner(elPromise);
|
|
86
129
|
}
|
|
87
130
|
// --- Iteration Callback ---
|
|
88
131
|
/**
|
|
@@ -92,7 +135,7 @@ export class MultiElementRunner {
|
|
|
92
135
|
* @example
|
|
93
136
|
* ```ts
|
|
94
137
|
* await Spectra.getAll(".checkbox").each(async (item, index) => {
|
|
95
|
-
* await item.
|
|
138
|
+
* await item.shouldBeVisible();
|
|
96
139
|
* });
|
|
97
140
|
* ```
|
|
98
141
|
*/
|
|
@@ -112,7 +155,16 @@ export class MultiElementRunner {
|
|
|
112
155
|
async then(onfulfilled, onrejected) {
|
|
113
156
|
try {
|
|
114
157
|
for (const assert of this._assertions) {
|
|
115
|
-
|
|
158
|
+
const payload = {
|
|
159
|
+
type: 'assertion',
|
|
160
|
+
key: assert.matcher,
|
|
161
|
+
target: this._selector,
|
|
162
|
+
args: assert.args,
|
|
163
|
+
isCollection: true,
|
|
164
|
+
};
|
|
165
|
+
await trackCommand('assertion', payload, async () => {
|
|
166
|
+
await executeMultiMatcher(this._selector, assert.matcher, assert.args);
|
|
167
|
+
});
|
|
116
168
|
}
|
|
117
169
|
const res = (onfulfilled ? await onfulfilled() : undefined);
|
|
118
170
|
return res;
|
package/dist/runner/single.d.ts
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ElementReceiverAssertions, ElementTarget, TypeOptions } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Fluent interaction and assertion runner for a single element or browser context.
|
|
4
4
|
*
|
|
5
|
-
* Implements `PromiseLike<void
|
|
6
|
-
* multiple actions and `.should
|
|
5
|
+
* Implements `PromiseLike<void>` and `ElementReceiverAssertions<SingleElementRunner>`,
|
|
6
|
+
* allowing it to be awaited directly or chained with multiple actions and direct `.should...` assertions.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
10
|
* // Direct action + chained assertion
|
|
11
11
|
* await Spectra.get("#submit-btn")
|
|
12
12
|
* .click()
|
|
13
|
-
* .
|
|
13
|
+
* .shouldNotBeVisible();
|
|
14
14
|
*
|
|
15
15
|
* // Query + multiple assertions
|
|
16
16
|
* await Spectra.get(LoginPage.usernameInput)
|
|
17
|
-
* .
|
|
18
|
-
* .
|
|
19
|
-
* .
|
|
17
|
+
* .shouldBeVisible()
|
|
18
|
+
* .shouldBeEnabled()
|
|
19
|
+
* .shouldHaveValue("admin");
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export declare class SingleElementRunner implements PromiseLike<void> {
|
|
22
|
+
export declare class SingleElementRunner implements PromiseLike<void>, ElementReceiverAssertions<SingleElementRunner> {
|
|
23
23
|
private _target;
|
|
24
24
|
private _action;
|
|
25
|
+
private _actionPayload;
|
|
25
26
|
private _assertions;
|
|
26
|
-
constructor(target?: ElementTarget, action?: () => Promise<any
|
|
27
|
+
constructor(target?: ElementTarget, action?: () => Promise<any>, actionPayload?: any);
|
|
27
28
|
/**
|
|
28
29
|
* Clicks on the target element.
|
|
29
30
|
*
|
|
@@ -110,32 +111,122 @@ export declare class SingleElementRunner implements PromiseLike<void> {
|
|
|
110
111
|
*/
|
|
111
112
|
waitForElement(timeoutMs?: number): this;
|
|
112
113
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* @param matcher - Single element matcher string (e.g. `'be.visible'`, `'have.text'`).
|
|
116
|
-
* @param args - Additional parameters for the matcher (e.g. expected text or value).
|
|
117
|
-
* @example
|
|
118
|
-
* ```ts
|
|
119
|
-
* await Spectra.get("#status-badge").should("be.visible");
|
|
120
|
-
* await Spectra.get("#username").should("have.value", "alice");
|
|
121
|
-
* await Spectra.get("#banner").should("have.class", "alert-success");
|
|
122
|
-
* ```
|
|
123
|
-
* @returns Current runner instance for method chaining.
|
|
114
|
+
* Performs a right-click (context menu) interaction on the target element.
|
|
124
115
|
*/
|
|
125
|
-
|
|
116
|
+
rightClick(): this;
|
|
126
117
|
/**
|
|
127
|
-
*
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
*
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
*
|
|
118
|
+
* Drags the target element and drops it onto the specified destination element.
|
|
119
|
+
*/
|
|
120
|
+
dragDrop(destination: ElementTarget): this;
|
|
121
|
+
/**
|
|
122
|
+
* Scrolls the target element into view.
|
|
123
|
+
*/
|
|
124
|
+
scrollIntoView(): this;
|
|
125
|
+
private _pushAssertion;
|
|
126
|
+
/**
|
|
127
|
+
* Asserts that the target element is displayed and visible to the user.
|
|
128
|
+
*/
|
|
129
|
+
shouldBeVisible(): this;
|
|
130
|
+
/**
|
|
131
|
+
* Asserts that the target element is not displayed or hidden from view.
|
|
132
|
+
*/
|
|
133
|
+
shouldNotBeVisible(): this;
|
|
134
|
+
/**
|
|
135
|
+
* Asserts that the target element exists in the DOM.
|
|
136
|
+
*/
|
|
137
|
+
shouldExist(): this;
|
|
138
|
+
/**
|
|
139
|
+
* Asserts that the target element does not exist in the DOM.
|
|
140
|
+
*/
|
|
141
|
+
shouldNotExist(): this;
|
|
142
|
+
/**
|
|
143
|
+
* Asserts that the target element is clickable.
|
|
144
|
+
*/
|
|
145
|
+
shouldBeClickable(): this;
|
|
146
|
+
/**
|
|
147
|
+
* Asserts that the target element is not clickable.
|
|
148
|
+
*/
|
|
149
|
+
shouldNotBeClickable(): this;
|
|
150
|
+
/**
|
|
151
|
+
* Asserts that the target element is enabled (not disabled).
|
|
152
|
+
*/
|
|
153
|
+
shouldBeEnabled(): this;
|
|
154
|
+
/**
|
|
155
|
+
* Asserts that the target element is disabled.
|
|
156
|
+
*/
|
|
157
|
+
shouldBeDisabled(): this;
|
|
158
|
+
/**
|
|
159
|
+
* Asserts that the target checkbox or radio element is checked.
|
|
160
|
+
*/
|
|
161
|
+
shouldBeChecked(): this;
|
|
162
|
+
/**
|
|
163
|
+
* Asserts that the target checkbox or radio element is not checked.
|
|
164
|
+
*/
|
|
165
|
+
shouldNotBeChecked(): this;
|
|
166
|
+
/**
|
|
167
|
+
* Asserts that the target element currently has focus.
|
|
168
|
+
*/
|
|
169
|
+
shouldBeFocused(): this;
|
|
170
|
+
/**
|
|
171
|
+
* Asserts that the target element does not have focus.
|
|
172
|
+
*/
|
|
173
|
+
shouldNotBeFocused(): this;
|
|
174
|
+
/**
|
|
175
|
+
* Asserts that the target element has exact inner text matching the expected value.
|
|
176
|
+
*/
|
|
177
|
+
shouldHaveText(expected: string | RegExp): this;
|
|
178
|
+
/**
|
|
179
|
+
* Asserts that the target element does not have inner text matching the expected value.
|
|
180
|
+
*/
|
|
181
|
+
shouldNotHaveText(expected: string | RegExp): this;
|
|
182
|
+
/**
|
|
183
|
+
* Asserts that the target element's text contains the given substring.
|
|
184
|
+
*/
|
|
185
|
+
shouldContainText(substring: string): this;
|
|
186
|
+
/**
|
|
187
|
+
* Asserts that the target element's text does not contain the given substring.
|
|
188
|
+
*/
|
|
189
|
+
shouldNotContainText(substring: string): this;
|
|
190
|
+
/**
|
|
191
|
+
* Asserts that the target input element has the exact expected value.
|
|
192
|
+
*/
|
|
193
|
+
shouldHaveValue(value: string): this;
|
|
194
|
+
/**
|
|
195
|
+
* Asserts that the target input element does not have the expected value.
|
|
196
|
+
*/
|
|
197
|
+
shouldNotHaveValue(value: string): this;
|
|
198
|
+
/**
|
|
199
|
+
* Asserts that the target input element's value contains the given substring.
|
|
200
|
+
*/
|
|
201
|
+
shouldContainValue(substring: string): this;
|
|
202
|
+
/**
|
|
203
|
+
* Asserts that the target input element's value does not contain the given substring.
|
|
204
|
+
*/
|
|
205
|
+
shouldNotContainValue(substring: string): this;
|
|
206
|
+
/**
|
|
207
|
+
* Asserts that the target element has the specified HTML attribute and optional value.
|
|
208
|
+
*/
|
|
209
|
+
shouldHaveAttribute(name: string, value?: string): this;
|
|
210
|
+
/**
|
|
211
|
+
* Asserts that the target element does not have the specified HTML attribute.
|
|
212
|
+
*/
|
|
213
|
+
shouldNotHaveAttribute(name: string): this;
|
|
214
|
+
/**
|
|
215
|
+
* Asserts that the target element has the specified CSS class.
|
|
216
|
+
*/
|
|
217
|
+
shouldHaveClass(className: string): this;
|
|
218
|
+
/**
|
|
219
|
+
* Asserts that the target element does not have the specified CSS class.
|
|
220
|
+
*/
|
|
221
|
+
shouldNotHaveClass(className: string): this;
|
|
222
|
+
/**
|
|
223
|
+
* Asserts that the target element has the specified computed CSS property value.
|
|
224
|
+
*/
|
|
225
|
+
shouldHaveCss(property: string, value: string): this;
|
|
226
|
+
/**
|
|
227
|
+
* Asserts that the target element does not have the specified computed CSS property value.
|
|
137
228
|
*/
|
|
138
|
-
|
|
229
|
+
shouldNotHaveCss(property: string, value: string): this;
|
|
139
230
|
/**
|
|
140
231
|
* Standard Promise `then` implementation.
|
|
141
232
|
* Executes queued action first (if any), followed sequentially by all queued assertions.
|