@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
package/dist/runner/single.js
CHANGED
|
@@ -1,31 +1,46 @@
|
|
|
1
|
-
import { executeSingleMatcher, resolveElement } from
|
|
1
|
+
import { executeSingleMatcher, resolveElement } from '../matchers.js';
|
|
2
|
+
import { trackCommand } from '../reporter.js';
|
|
3
|
+
function getRawTarget(target) {
|
|
4
|
+
if (!target)
|
|
5
|
+
return '';
|
|
6
|
+
if (typeof target === 'string')
|
|
7
|
+
return target;
|
|
8
|
+
if (target.selector)
|
|
9
|
+
return target.selector;
|
|
10
|
+
if (target.constructor && target.constructor.name && target.constructor.name !== 'Object')
|
|
11
|
+
return target.constructor.name;
|
|
12
|
+
return String(target);
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
15
|
* Fluent interaction and assertion runner for a single element or browser context.
|
|
4
16
|
*
|
|
5
|
-
* Implements `PromiseLike<void
|
|
6
|
-
* multiple actions and `.should
|
|
17
|
+
* Implements `PromiseLike<void>` and `ElementReceiverAssertions<SingleElementRunner>`,
|
|
18
|
+
* allowing it to be awaited directly or chained with multiple actions and direct `.should...` assertions.
|
|
7
19
|
*
|
|
8
20
|
* @example
|
|
9
21
|
* ```ts
|
|
10
22
|
* // Direct action + chained assertion
|
|
11
23
|
* await Spectra.get("#submit-btn")
|
|
12
24
|
* .click()
|
|
13
|
-
* .
|
|
25
|
+
* .shouldNotBeVisible();
|
|
14
26
|
*
|
|
15
27
|
* // Query + multiple assertions
|
|
16
28
|
* await Spectra.get(LoginPage.usernameInput)
|
|
17
|
-
* .
|
|
18
|
-
* .
|
|
19
|
-
* .
|
|
29
|
+
* .shouldBeVisible()
|
|
30
|
+
* .shouldBeEnabled()
|
|
31
|
+
* .shouldHaveValue("admin");
|
|
20
32
|
* ```
|
|
21
33
|
*/
|
|
22
34
|
export class SingleElementRunner {
|
|
23
35
|
_target;
|
|
24
36
|
_action = null;
|
|
37
|
+
_actionPayload = null;
|
|
25
38
|
_assertions = [];
|
|
26
|
-
constructor(target, action) {
|
|
39
|
+
constructor(target, action, actionPayload) {
|
|
27
40
|
this._target = target;
|
|
28
41
|
this._action = action || null;
|
|
42
|
+
this._actionPayload =
|
|
43
|
+
actionPayload || (action ? { type: 'action', key: 'action', target: getRawTarget(target), args: [] } : null);
|
|
29
44
|
}
|
|
30
45
|
// --- Chained Actions on current target ---
|
|
31
46
|
/**
|
|
@@ -38,7 +53,8 @@ export class SingleElementRunner {
|
|
|
38
53
|
* @returns Current runner instance for method chaining.
|
|
39
54
|
*/
|
|
40
55
|
click() {
|
|
41
|
-
const target = this.requireTarget(
|
|
56
|
+
const target = this.requireTarget('click');
|
|
57
|
+
this._actionPayload = { type: 'action', key: 'click', target: getRawTarget(target), args: [] };
|
|
42
58
|
this._action = async () => {
|
|
43
59
|
const el = await resolveElement(target);
|
|
44
60
|
await el.click();
|
|
@@ -55,7 +71,8 @@ export class SingleElementRunner {
|
|
|
55
71
|
* @returns Current runner instance for method chaining.
|
|
56
72
|
*/
|
|
57
73
|
doubleClick() {
|
|
58
|
-
const target = this.requireTarget(
|
|
74
|
+
const target = this.requireTarget('doubleClick');
|
|
75
|
+
this._actionPayload = { type: 'action', key: 'doubleClick', target: getRawTarget(target), args: [] };
|
|
59
76
|
this._action = async () => {
|
|
60
77
|
const el = await resolveElement(target);
|
|
61
78
|
await el.doubleClick();
|
|
@@ -73,14 +90,12 @@ export class SingleElementRunner {
|
|
|
73
90
|
* @returns Current runner instance for method chaining.
|
|
74
91
|
*/
|
|
75
92
|
longPress(durationMs = 1000) {
|
|
76
|
-
const target = this.requireTarget(
|
|
93
|
+
const target = this.requireTarget('longPress');
|
|
94
|
+
this._actionPayload = { type: 'action', key: 'longPress', target: getRawTarget(target), args: [durationMs] };
|
|
77
95
|
this._action = async () => {
|
|
78
96
|
const el = await resolveElement(target);
|
|
79
|
-
if (typeof el.touchAction ===
|
|
80
|
-
await el.touchAction([
|
|
81
|
-
{ action: "longPress", ms: durationMs },
|
|
82
|
-
{ action: "release" },
|
|
83
|
-
]);
|
|
97
|
+
if (typeof el.touchAction === 'function') {
|
|
98
|
+
await el.touchAction([{ action: 'longPress', ms: durationMs }, { action: 'release' }]);
|
|
84
99
|
}
|
|
85
100
|
else {
|
|
86
101
|
await el.click();
|
|
@@ -100,7 +115,8 @@ export class SingleElementRunner {
|
|
|
100
115
|
* @returns Current runner instance for method chaining.
|
|
101
116
|
*/
|
|
102
117
|
type(value, options) {
|
|
103
|
-
const target = this.requireTarget(
|
|
118
|
+
const target = this.requireTarget('type');
|
|
119
|
+
this._actionPayload = { type: 'action', key: 'type', target: getRawTarget(target), args: [value] };
|
|
104
120
|
this._action = async () => {
|
|
105
121
|
const el = await resolveElement(target);
|
|
106
122
|
if (options?.clearFirst) {
|
|
@@ -120,7 +136,8 @@ export class SingleElementRunner {
|
|
|
120
136
|
* @returns Current runner instance for method chaining.
|
|
121
137
|
*/
|
|
122
138
|
clear() {
|
|
123
|
-
const target = this.requireTarget(
|
|
139
|
+
const target = this.requireTarget('clear');
|
|
140
|
+
this._actionPayload = { type: 'action', key: 'clear', target: getRawTarget(target), args: [] };
|
|
124
141
|
this._action = async () => {
|
|
125
142
|
const el = await resolveElement(target);
|
|
126
143
|
await el.clearValue();
|
|
@@ -138,7 +155,8 @@ export class SingleElementRunner {
|
|
|
138
155
|
* @returns Current runner instance for method chaining.
|
|
139
156
|
*/
|
|
140
157
|
select(value) {
|
|
141
|
-
const target = this.requireTarget(
|
|
158
|
+
const target = this.requireTarget('select');
|
|
159
|
+
this._actionPayload = { type: 'action', key: 'selectOption', target: getRawTarget(target), args: [value] };
|
|
142
160
|
this._action = async () => {
|
|
143
161
|
const el = await resolveElement(target);
|
|
144
162
|
await el.selectByVisibleText(value);
|
|
@@ -155,7 +173,8 @@ export class SingleElementRunner {
|
|
|
155
173
|
* @returns Current runner instance for method chaining.
|
|
156
174
|
*/
|
|
157
175
|
hover() {
|
|
158
|
-
const target = this.requireTarget(
|
|
176
|
+
const target = this.requireTarget('hover');
|
|
177
|
+
this._actionPayload = { type: 'action', key: 'hover', target: getRawTarget(target), args: [] };
|
|
159
178
|
this._action = async () => {
|
|
160
179
|
const el = await resolveElement(target);
|
|
161
180
|
await el.moveTo();
|
|
@@ -173,40 +192,223 @@ export class SingleElementRunner {
|
|
|
173
192
|
* @returns Current runner instance for method chaining.
|
|
174
193
|
*/
|
|
175
194
|
waitForElement(timeoutMs = 10000) {
|
|
176
|
-
const target = this.requireTarget(
|
|
195
|
+
const target = this.requireTarget('waitForElement');
|
|
196
|
+
this._actionPayload = { type: 'action', key: 'waitForElement', target: getRawTarget(target), args: [timeoutMs] };
|
|
177
197
|
this._action = async () => {
|
|
178
198
|
const el = await resolveElement(target);
|
|
179
199
|
await el.waitForDisplayed({ timeout: timeoutMs });
|
|
180
200
|
};
|
|
181
201
|
return this;
|
|
182
202
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Performs a right-click (context menu) interaction on the target element.
|
|
205
|
+
*/
|
|
206
|
+
rightClick() {
|
|
207
|
+
const target = this.requireTarget('rightClick');
|
|
208
|
+
this._actionPayload = { type: 'action', key: 'rightClick', target: getRawTarget(target), args: [] };
|
|
209
|
+
this._action = async () => {
|
|
210
|
+
const el = await resolveElement(target);
|
|
211
|
+
await el.click({ button: 'right' });
|
|
212
|
+
};
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Drags the target element and drops it onto the specified destination element.
|
|
217
|
+
*/
|
|
218
|
+
dragDrop(destination) {
|
|
219
|
+
const target = this.requireTarget('dragDrop');
|
|
220
|
+
this._actionPayload = {
|
|
221
|
+
type: 'action',
|
|
222
|
+
key: 'dragDrop',
|
|
223
|
+
target: getRawTarget(target),
|
|
224
|
+
args: [getRawTarget(destination)],
|
|
225
|
+
};
|
|
226
|
+
this._action = async () => {
|
|
227
|
+
const sourceEl = await resolveElement(target);
|
|
228
|
+
const destEl = await resolveElement(destination);
|
|
229
|
+
await sourceEl.dragAndDrop(destEl);
|
|
230
|
+
};
|
|
208
231
|
return this;
|
|
209
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Scrolls the target element into view.
|
|
235
|
+
*/
|
|
236
|
+
scrollIntoView() {
|
|
237
|
+
const target = this.requireTarget('scrollIntoView');
|
|
238
|
+
this._actionPayload = { type: 'action', key: 'scrollIntoView', target: getRawTarget(target), args: [] };
|
|
239
|
+
this._action = async () => {
|
|
240
|
+
const el = await resolveElement(target);
|
|
241
|
+
await el.scrollIntoView();
|
|
242
|
+
};
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
_pushAssertion(matcher, args = []) {
|
|
246
|
+
this._assertions.push({
|
|
247
|
+
target: this._target,
|
|
248
|
+
matcher,
|
|
249
|
+
args,
|
|
250
|
+
});
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
// --- Fluent Assertion Matchers ---
|
|
254
|
+
/**
|
|
255
|
+
* Asserts that the target element is displayed and visible to the user.
|
|
256
|
+
*/
|
|
257
|
+
shouldBeVisible() {
|
|
258
|
+
return this._pushAssertion('be.visible');
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Asserts that the target element is not displayed or hidden from view.
|
|
262
|
+
*/
|
|
263
|
+
shouldNotBeVisible() {
|
|
264
|
+
return this._pushAssertion('not.be.visible');
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Asserts that the target element exists in the DOM.
|
|
268
|
+
*/
|
|
269
|
+
shouldExist() {
|
|
270
|
+
return this._pushAssertion('exist');
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Asserts that the target element does not exist in the DOM.
|
|
274
|
+
*/
|
|
275
|
+
shouldNotExist() {
|
|
276
|
+
return this._pushAssertion('not.exist');
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Asserts that the target element is clickable.
|
|
280
|
+
*/
|
|
281
|
+
shouldBeClickable() {
|
|
282
|
+
return this._pushAssertion('be.clickable');
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Asserts that the target element is not clickable.
|
|
286
|
+
*/
|
|
287
|
+
shouldNotBeClickable() {
|
|
288
|
+
return this._pushAssertion('not.be.clickable');
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Asserts that the target element is enabled (not disabled).
|
|
292
|
+
*/
|
|
293
|
+
shouldBeEnabled() {
|
|
294
|
+
return this._pushAssertion('be.enabled');
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Asserts that the target element is disabled.
|
|
298
|
+
*/
|
|
299
|
+
shouldBeDisabled() {
|
|
300
|
+
return this._pushAssertion('be.disabled');
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Asserts that the target checkbox or radio element is checked.
|
|
304
|
+
*/
|
|
305
|
+
shouldBeChecked() {
|
|
306
|
+
return this._pushAssertion('be.checked');
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Asserts that the target checkbox or radio element is not checked.
|
|
310
|
+
*/
|
|
311
|
+
shouldNotBeChecked() {
|
|
312
|
+
return this._pushAssertion('not.be.checked');
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Asserts that the target element currently has focus.
|
|
316
|
+
*/
|
|
317
|
+
shouldBeFocused() {
|
|
318
|
+
return this._pushAssertion('be.focused');
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Asserts that the target element does not have focus.
|
|
322
|
+
*/
|
|
323
|
+
shouldNotBeFocused() {
|
|
324
|
+
return this._pushAssertion('not.be.focused');
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Asserts that the target element has exact inner text matching the expected value.
|
|
328
|
+
*/
|
|
329
|
+
shouldHaveText(expected) {
|
|
330
|
+
return this._pushAssertion('have.text', [expected]);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Asserts that the target element does not have inner text matching the expected value.
|
|
334
|
+
*/
|
|
335
|
+
shouldNotHaveText(expected) {
|
|
336
|
+
return this._pushAssertion('not.have.text', [expected]);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Asserts that the target element's text contains the given substring.
|
|
340
|
+
*/
|
|
341
|
+
shouldContainText(substring) {
|
|
342
|
+
return this._pushAssertion('contain.text', [substring]);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Asserts that the target element's text does not contain the given substring.
|
|
346
|
+
*/
|
|
347
|
+
shouldNotContainText(substring) {
|
|
348
|
+
return this._pushAssertion('not.contain.text', [substring]);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Asserts that the target input element has the exact expected value.
|
|
352
|
+
*/
|
|
353
|
+
shouldHaveValue(value) {
|
|
354
|
+
return this._pushAssertion('have.value', [value]);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Asserts that the target input element does not have the expected value.
|
|
358
|
+
*/
|
|
359
|
+
shouldNotHaveValue(value) {
|
|
360
|
+
return this._pushAssertion('not.have.value', [value]);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Asserts that the target input element's value contains the given substring.
|
|
364
|
+
*/
|
|
365
|
+
shouldContainValue(substring) {
|
|
366
|
+
return this._pushAssertion('contain.value', [substring]);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Asserts that the target input element's value does not contain the given substring.
|
|
370
|
+
*/
|
|
371
|
+
shouldNotContainValue(substring) {
|
|
372
|
+
return this._pushAssertion('not.contain.value', [substring]);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Asserts that the target element has the specified HTML attribute and optional value.
|
|
376
|
+
*/
|
|
377
|
+
shouldHaveAttribute(name, value) {
|
|
378
|
+
return value !== undefined
|
|
379
|
+
? this._pushAssertion('have.attr', [name, value])
|
|
380
|
+
: this._pushAssertion('have.attr', [name]);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Asserts that the target element does not have the specified HTML attribute.
|
|
384
|
+
*/
|
|
385
|
+
shouldNotHaveAttribute(name) {
|
|
386
|
+
return this._pushAssertion('not.have.attr', [name]);
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Asserts that the target element has the specified CSS class.
|
|
390
|
+
*/
|
|
391
|
+
shouldHaveClass(className) {
|
|
392
|
+
return this._pushAssertion('have.class', [className]);
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Asserts that the target element does not have the specified CSS class.
|
|
396
|
+
*/
|
|
397
|
+
shouldNotHaveClass(className) {
|
|
398
|
+
return this._pushAssertion('not.have.class', [className]);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Asserts that the target element has the specified computed CSS property value.
|
|
402
|
+
*/
|
|
403
|
+
shouldHaveCss(property, value) {
|
|
404
|
+
return this._pushAssertion('have.css', [property, value]);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Asserts that the target element does not have the specified computed CSS property value.
|
|
408
|
+
*/
|
|
409
|
+
shouldNotHaveCss(property, value) {
|
|
410
|
+
return this._pushAssertion('not.have.css', [property, value]);
|
|
411
|
+
}
|
|
210
412
|
// --- Execution when awaited ---
|
|
211
413
|
/**
|
|
212
414
|
* Standard Promise `then` implementation.
|
|
@@ -215,10 +417,26 @@ export class SingleElementRunner {
|
|
|
215
417
|
async then(onfulfilled, onrejected) {
|
|
216
418
|
try {
|
|
217
419
|
if (this._action) {
|
|
218
|
-
|
|
420
|
+
const payload = this._actionPayload || {
|
|
421
|
+
type: 'action',
|
|
422
|
+
key: 'action',
|
|
423
|
+
target: getRawTarget(this._target),
|
|
424
|
+
args: [],
|
|
425
|
+
};
|
|
426
|
+
await trackCommand('action', payload, async () => {
|
|
427
|
+
await this._action();
|
|
428
|
+
});
|
|
219
429
|
}
|
|
220
430
|
for (const assert of this._assertions) {
|
|
221
|
-
|
|
431
|
+
const payload = {
|
|
432
|
+
type: 'assertion',
|
|
433
|
+
key: assert.matcher,
|
|
434
|
+
target: getRawTarget(assert.target),
|
|
435
|
+
args: assert.args,
|
|
436
|
+
};
|
|
437
|
+
await trackCommand('assertion', payload, async () => {
|
|
438
|
+
await executeSingleMatcher(assert.target, assert.matcher, assert.args);
|
|
439
|
+
});
|
|
222
440
|
}
|
|
223
441
|
const res = (onfulfilled ? await onfulfilled() : undefined);
|
|
224
442
|
return res;
|
package/dist/spectra.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ClickOptions, ElementTarget, KeyOption, LongPressOptions, ScrollOptions, SwipeOptions, TypeOptions } from
|
|
2
|
-
import { SingleElementRunner } from
|
|
3
|
-
import { MultiElementRunner } from
|
|
1
|
+
import { BrowserReceiverAssertions, ClickOptions, ElementTarget, KeyOption, LongPressOptions, ScrollOptions, SwipeOptions, TypeOptions } from './types.js';
|
|
2
|
+
import { SingleElementRunner } from './runner/single.js';
|
|
3
|
+
import { MultiElementRunner } from './runner/collection.js';
|
|
4
|
+
import { MockHandle, InterceptRule } from './intercept/index.js';
|
|
4
5
|
/**
|
|
5
6
|
* Main TestSpectra cross-platform automation and assertion orchestrator.
|
|
6
7
|
*
|
|
@@ -14,7 +15,7 @@ import { MultiElementRunner } from "./runner/collection.js";
|
|
|
14
15
|
* await Spectra.get("#username").type("admin");
|
|
15
16
|
*
|
|
16
17
|
* // Collection assertion
|
|
17
|
-
* await Spectra.getAll(".item").
|
|
18
|
+
* await Spectra.getAll(".item").shouldHaveLength(5);
|
|
18
19
|
*
|
|
19
20
|
* // Mobile touch swipe
|
|
20
21
|
* await Spectra.swipe({ direction: "left", distance: 350 });
|
|
@@ -28,7 +29,7 @@ export declare class SpectraStatic {
|
|
|
28
29
|
* @example
|
|
29
30
|
* ```ts
|
|
30
31
|
* await Spectra.get("#login-btn").click();
|
|
31
|
-
* await Spectra.get(LoginPage.submitButton).
|
|
32
|
+
* await Spectra.get(LoginPage.submitButton).shouldBeVisible();
|
|
32
33
|
* ```
|
|
33
34
|
* @returns `SingleElementRunner` for chaining actions and assertions.
|
|
34
35
|
*/
|
|
@@ -39,7 +40,7 @@ export declare class SpectraStatic {
|
|
|
39
40
|
* @param selector - Selector string matching multiple elements.
|
|
40
41
|
* @example
|
|
41
42
|
* ```ts
|
|
42
|
-
* await Spectra.getAll(".product-card").
|
|
43
|
+
* await Spectra.getAll(".product-card").shouldHaveLengthGreaterThan(0);
|
|
43
44
|
* await Spectra.getAll("li.tab").first().click();
|
|
44
45
|
* ```
|
|
45
46
|
* @returns `MultiElementRunner` for collection assertions and indexing.
|
|
@@ -85,7 +86,7 @@ export declare class SpectraStatic {
|
|
|
85
86
|
* await Spectra.click(LoginPage.loginBtn);
|
|
86
87
|
* ```
|
|
87
88
|
*/
|
|
88
|
-
click(target: ElementTarget,
|
|
89
|
+
click(target: ElementTarget, _textOrOptions?: string | ClickOptions): SingleElementRunner;
|
|
89
90
|
/**
|
|
90
91
|
* Performs a double-click on the specified element.
|
|
91
92
|
*
|
|
@@ -96,7 +97,7 @@ export declare class SpectraStatic {
|
|
|
96
97
|
* await Spectra.doubleClick(".grid-row");
|
|
97
98
|
* ```
|
|
98
99
|
*/
|
|
99
|
-
doubleClick(target: ElementTarget,
|
|
100
|
+
doubleClick(target: ElementTarget, _textOrOptions?: string | ClickOptions): SingleElementRunner;
|
|
100
101
|
/**
|
|
101
102
|
* Performs a long-press touch or hold gesture on the specified element.
|
|
102
103
|
*
|
|
@@ -217,6 +218,29 @@ export declare class SpectraStatic {
|
|
|
217
218
|
* ```
|
|
218
219
|
*/
|
|
219
220
|
waitForElement(target: ElementTarget, timeoutMs?: number): SingleElementRunner;
|
|
221
|
+
/**
|
|
222
|
+
* Intercepts HTTP/HTTPS network traffic matching the given URL rule.
|
|
223
|
+
*
|
|
224
|
+
* @param rule - URL pattern string or InterceptRule configuration.
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* const mock = await Spectra.intercept({
|
|
228
|
+
* url: "/api/v1/users",
|
|
229
|
+
* method: "GET",
|
|
230
|
+
* response: { status: 200, body: [{ id: 1, name: "Admin" }] }
|
|
231
|
+
* });
|
|
232
|
+
* ```
|
|
233
|
+
* @returns `MockHandle` for sequential queue responses, abort, and assertions.
|
|
234
|
+
*/
|
|
235
|
+
intercept(rule: InterceptRule | string): Promise<MockHandle>;
|
|
236
|
+
/**
|
|
237
|
+
* Clears all active mock rules and resets the mock registry for worker isolation.
|
|
238
|
+
*/
|
|
239
|
+
clearMocks(): void;
|
|
240
|
+
/**
|
|
241
|
+
* Browser-level assertions and utilities (cookies, localStorage, url, title).
|
|
242
|
+
*/
|
|
243
|
+
get browser(): BrowserReceiverAssertions;
|
|
220
244
|
}
|
|
221
245
|
/**
|
|
222
246
|
* Global singleton instance of `SpectraStatic`.
|