@testspectra/matchers 1.0.41 → 1.0.43

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/src/spectra.ts CHANGED
@@ -12,19 +12,50 @@ import { MultiElementRunner } from "./runner/collection.js";
12
12
  import { resolveElement } from "./matchers.js";
13
13
 
14
14
  /**
15
- * Main Spectra testing API orchestrator.
16
- * Combines direct actions, single element queries (get), and collections (getAll).
15
+ * Main TestSpectra cross-platform automation and assertion orchestrator.
16
+ *
17
+ * Provides a unified, ergonomic testing API across Web, Android, and iOS.
18
+ * Features single element targeting (`.get`), collection targeting (`.getAll`),
19
+ * and built-in actions (`.click`, `.type`, `.scroll`, `.swipe`, `.navigate`).
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // Single element interaction
24
+ * await Spectra.get("#username").type("admin");
25
+ *
26
+ * // Collection assertion
27
+ * await Spectra.getAll(".item").should("have.length", 5);
28
+ *
29
+ * // Mobile touch swipe
30
+ * await Spectra.swipe({ direction: "left", distance: 350 });
31
+ * ```
17
32
  */
18
33
  export class SpectraStatic {
19
34
  /**
20
- * Targets a single element by selector or Page Object element.
35
+ * Targets a single element by CSS/XPath selector or Page Object element.
36
+ *
37
+ * @param target - Selector string or Page Object element property.
38
+ * @example
39
+ * ```ts
40
+ * await Spectra.get("#login-btn").click();
41
+ * await Spectra.get(LoginPage.submitButton).should("be.visible");
42
+ * ```
43
+ * @returns `SingleElementRunner` for chaining actions and assertions.
21
44
  */
22
45
  get(target: ElementTarget): SingleElementRunner {
23
46
  return new SingleElementRunner(target);
24
47
  }
25
48
 
26
49
  /**
27
- * Targets multiple elements / collections by selector.
50
+ * Targets multiple elements or collections matching a CSS/XPath selector.
51
+ *
52
+ * @param selector - Selector string matching multiple elements.
53
+ * @example
54
+ * ```ts
55
+ * await Spectra.getAll(".product-card").should("have.length.greaterThan", 0);
56
+ * await Spectra.getAll("li.tab").first().click();
57
+ * ```
58
+ * @returns `MultiElementRunner` for collection assertions and indexing.
28
59
  */
29
60
  getAll(selector: string): MultiElementRunner {
30
61
  return new MultiElementRunner(selector);
@@ -32,18 +63,44 @@ export class SpectraStatic {
32
63
 
33
64
  // --- Browser & Navigation Actions ---
34
65
 
66
+ /**
67
+ * Navigates the browser to the specified URL.
68
+ *
69
+ * @param url - Relative URL or absolute URL.
70
+ * @example
71
+ * ```ts
72
+ * await Spectra.navigate("/login");
73
+ * await Spectra.navigate("https://app.testspectra.dev/dashboard");
74
+ * ```
75
+ */
35
76
  navigate(url: string): SingleElementRunner {
36
77
  return new SingleElementRunner(undefined, async () => {
37
78
  await browser.url(url);
38
79
  });
39
80
  }
40
81
 
82
+ /**
83
+ * Navigates back one step in the browser / app history.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * await Spectra.back();
88
+ * ```
89
+ */
41
90
  back(): SingleElementRunner {
42
91
  return new SingleElementRunner(undefined, async () => {
43
92
  await browser.back();
44
93
  });
45
94
  }
46
95
 
96
+ /**
97
+ * Refreshes the current browser page.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * await Spectra.refresh();
102
+ * ```
103
+ */
47
104
  refresh(): SingleElementRunner {
48
105
  return new SingleElementRunner(undefined, async () => {
49
106
  await browser.refresh();
@@ -52,6 +109,17 @@ export class SpectraStatic {
52
109
 
53
110
  // --- Direct Interaction Actions ---
54
111
 
112
+ /**
113
+ * Clicks on the specified element.
114
+ *
115
+ * @param target - Selector string or Page Object element property.
116
+ * @param textOrOptions - Optional text filter or click configuration.
117
+ * @example
118
+ * ```ts
119
+ * await Spectra.click("#submit-button");
120
+ * await Spectra.click(LoginPage.loginBtn);
121
+ * ```
122
+ */
55
123
  click(target: ElementTarget, textOrOptions?: string | ClickOptions): SingleElementRunner {
56
124
  return new SingleElementRunner(target, async () => {
57
125
  const el = await resolveElement(target);
@@ -59,6 +127,16 @@ export class SpectraStatic {
59
127
  });
60
128
  }
61
129
 
130
+ /**
131
+ * Performs a double-click on the specified element.
132
+ *
133
+ * @param target - Selector string or Page Object element property.
134
+ * @param textOrOptions - Optional text filter or click configuration.
135
+ * @example
136
+ * ```ts
137
+ * await Spectra.doubleClick(".grid-row");
138
+ * ```
139
+ */
62
140
  doubleClick(target: ElementTarget, textOrOptions?: string | ClickOptions): SingleElementRunner {
63
141
  return new SingleElementRunner(target, async () => {
64
142
  const el = await resolveElement(target);
@@ -66,6 +144,17 @@ export class SpectraStatic {
66
144
  });
67
145
  }
68
146
 
147
+ /**
148
+ * Performs a long-press touch or hold gesture on the specified element.
149
+ *
150
+ * @param target - Selector string or Page Object element property.
151
+ * @param options - Optional duration in ms or LongPressOptions object.
152
+ * @example
153
+ * ```ts
154
+ * await Spectra.longPress("#message-item", 1500);
155
+ * await Spectra.longPress(ChatPage.audioRecordBtn, { duration: 2000 });
156
+ * ```
157
+ */
69
158
  longPress(target: ElementTarget, options?: LongPressOptions | number): SingleElementRunner {
70
159
  const duration = typeof options === "number" ? options : options?.duration || 1000;
71
160
  return new SingleElementRunner(target, async () => {
@@ -81,6 +170,18 @@ export class SpectraStatic {
81
170
  });
82
171
  }
83
172
 
173
+ /**
174
+ * Types text into the specified element.
175
+ *
176
+ * @param target - Selector string or Page Object element property.
177
+ * @param value - Text string to enter.
178
+ * @param options - Optional typing options (e.g. `clearFirst: true`).
179
+ * @example
180
+ * ```ts
181
+ * await Spectra.type("#email", "user@example.com", { clearFirst: true });
182
+ * await Spectra.type(LoginPage.passwordInput, "SecretPass123");
183
+ * ```
184
+ */
84
185
  type(target: ElementTarget, value: string, options?: TypeOptions): SingleElementRunner {
85
186
  return new SingleElementRunner(target, async () => {
86
187
  const el = await resolveElement(target);
@@ -91,6 +192,15 @@ export class SpectraStatic {
91
192
  });
92
193
  }
93
194
 
195
+ /**
196
+ * Clears the input content from the specified element.
197
+ *
198
+ * @param target - Selector string or Page Object element property.
199
+ * @example
200
+ * ```ts
201
+ * await Spectra.clear("#coupon-input");
202
+ * ```
203
+ */
94
204
  clear(target: ElementTarget): SingleElementRunner {
95
205
  return new SingleElementRunner(target, async () => {
96
206
  const el = await resolveElement(target);
@@ -98,6 +208,16 @@ export class SpectraStatic {
98
208
  });
99
209
  }
100
210
 
211
+ /**
212
+ * Selects an option from a `<select>` dropdown by its visible text.
213
+ *
214
+ * @param target - Selector string or Page Object element property.
215
+ * @param value - Visible text of the option to select.
216
+ * @example
217
+ * ```ts
218
+ * await Spectra.select("#shipping-country", "Indonesia");
219
+ * ```
220
+ */
101
221
  select(target: ElementTarget, value: string): SingleElementRunner {
102
222
  return new SingleElementRunner(target, async () => {
103
223
  const el = await resolveElement(target);
@@ -105,6 +225,15 @@ export class SpectraStatic {
105
225
  });
106
226
  }
107
227
 
228
+ /**
229
+ * Hovers the mouse pointer over the specified element.
230
+ *
231
+ * @param target - Selector string or Page Object element property.
232
+ * @example
233
+ * ```ts
234
+ * await Spectra.hover("#nav-profile-menu");
235
+ * ```
236
+ */
108
237
  hover(target: ElementTarget): SingleElementRunner {
109
238
  return new SingleElementRunner(target, async () => {
110
239
  const el = await resolveElement(target);
@@ -112,12 +241,32 @@ export class SpectraStatic {
112
241
  });
113
242
  }
114
243
 
244
+ /**
245
+ * Simulates pressing a specific keyboard key.
246
+ *
247
+ * @param key - Key name string (e.g. `'Enter'`, `'Tab'`, `'Escape'`).
248
+ * @example
249
+ * ```ts
250
+ * await Spectra.pressKey("Enter");
251
+ * await Spectra.pressKey("Escape");
252
+ * ```
253
+ */
115
254
  pressKey(key: KeyOption | string): SingleElementRunner {
116
255
  return new SingleElementRunner(undefined, async () => {
117
256
  await browser.keys(key);
118
257
  });
119
258
  }
120
259
 
260
+ /**
261
+ * Drags a source element and drops it onto a destination target.
262
+ *
263
+ * @param sourceTarget - Element to drag.
264
+ * @param destTarget - Destination element or drop zone.
265
+ * @example
266
+ * ```ts
267
+ * await Spectra.dragDrop("#task-item-1", "#column-done");
268
+ * ```
269
+ */
121
270
  dragDrop(sourceTarget: ElementTarget, destTarget: ElementTarget): SingleElementRunner {
122
271
  return new SingleElementRunner(sourceTarget, async () => {
123
272
  const source = await resolveElement(sourceTarget);
@@ -128,6 +277,16 @@ export class SpectraStatic {
128
277
 
129
278
  // --- Gesture Actions ---
130
279
 
280
+ /**
281
+ * Scrolls the page or scrolls a specific element into view.
282
+ *
283
+ * @param options - Direction, pixels, or selector to scroll.
284
+ * @example
285
+ * ```ts
286
+ * await Spectra.scroll({ direction: "down", pixels: 400 });
287
+ * await Spectra.scroll({ selector: "#footer" });
288
+ * ```
289
+ */
131
290
  scroll(options?: ScrollOptions): SingleElementRunner {
132
291
  return new SingleElementRunner(options?.selector, async () => {
133
292
  if (options?.selector) {
@@ -146,6 +305,15 @@ export class SpectraStatic {
146
305
  });
147
306
  }
148
307
 
308
+ /**
309
+ * Performs a touch swipe gesture in the given direction (for mobile and touch-enabled browsers).
310
+ *
311
+ * @param options - Swipe configuration with `direction` and optional `distance`.
312
+ * @example
313
+ * ```ts
314
+ * await Spectra.swipe({ direction: "left", distance: 300 });
315
+ * ```
316
+ */
149
317
  swipe(options: SwipeOptions): SingleElementRunner {
150
318
  return new SingleElementRunner(options.selector, async () => {
151
319
  if (typeof (browser as any).touchAction === "function") {
@@ -168,12 +336,31 @@ export class SpectraStatic {
168
336
 
169
337
  // --- Timing Actions ---
170
338
 
339
+ /**
340
+ * Pauses test execution for a specified duration in milliseconds.
341
+ *
342
+ * @param durationMs - Time to wait in milliseconds.
343
+ * @example
344
+ * ```ts
345
+ * await Spectra.wait(1000);
346
+ * ```
347
+ */
171
348
  wait(durationMs: number): SingleElementRunner {
172
349
  return new SingleElementRunner(undefined, async () => {
173
350
  await browser.pause(durationMs);
174
351
  });
175
352
  }
176
353
 
354
+ /**
355
+ * Waits until the specified element is displayed on the screen.
356
+ *
357
+ * @param target - Selector string or Page Object element property.
358
+ * @param timeoutMs - Maximum time in milliseconds to wait (default: 10000).
359
+ * @example
360
+ * ```ts
361
+ * await Spectra.waitForElement("#confirmation-dialog", 5000);
362
+ * ```
363
+ */
177
364
  waitForElement(target: ElementTarget, timeoutMs = 10000): SingleElementRunner {
178
365
  return new SingleElementRunner(target, async () => {
179
366
  const el = await resolveElement(target);
@@ -182,4 +369,8 @@ export class SpectraStatic {
182
369
  }
183
370
  }
184
371
 
372
+ /**
373
+ * Global singleton instance of `SpectraStatic`.
374
+ */
185
375
  export const Spectra = new SpectraStatic();
376
+
package/src/types.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Database Canonical Action and Assertion Types
3
- * Matches backend/src/models/test_step.rs
2
+ * Canonical action keys supported across TestSpectra runner and database models.
3
+ * @see backend/src/models/test_step.rs
4
4
  */
5
-
6
5
  export type ActionKey =
7
6
  | "navigate"
8
7
  | "click"
@@ -21,6 +20,10 @@ export type ActionKey =
21
20
  | "back"
22
21
  | "refresh";
23
22
 
23
+ /**
24
+ * Canonical assertion keys supported across TestSpectra runner and database models.
25
+ * @see backend/src/models/test_step.rs
26
+ */
24
27
  export type AssertionKey =
25
28
  | "elementDisplayed"
26
29
  | "elementNotDisplayed"
@@ -44,6 +47,15 @@ export type AssertionKey =
44
47
  | "pageLoaded"
45
48
  | "noErrors";
46
49
 
50
+ /**
51
+ * Supported keyboard key names for `Spectra.pressKey(key)`.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * await Spectra.pressKey("Enter");
56
+ * await Spectra.pressKey("Tab");
57
+ * ```
58
+ */
47
59
  export type KeyOption =
48
60
  | "Enter"
49
61
  | "Tab"
@@ -56,36 +68,111 @@ export type KeyOption =
56
68
  | "ArrowRight"
57
69
  | "Space";
58
70
 
71
+ /**
72
+ * Cardinal directions for gestures such as swipe and scroll.
73
+ */
59
74
  export type Direction = "up" | "down" | "left" | "right";
60
75
 
76
+ /**
77
+ * Target reference for locating an element.
78
+ * Can be a CSS/XPath selector string, a resolved `WebdriverIO.Element`,
79
+ * or a chainable element promise `ChainablePromiseElement`.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * // Selector string
84
+ * Spectra.get("#submit-btn");
85
+ *
86
+ * // Page Object property
87
+ * Spectra.get(LoginPage.submitButton);
88
+ * ```
89
+ */
61
90
  export type ElementTarget = string | WebdriverIO.Element | ChainablePromiseElement;
62
91
 
92
+ /**
93
+ * Configuration options for scroll actions.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * await Spectra.scroll({ direction: "down", pixels: 300 });
98
+ * await Spectra.scroll({ selector: "#footer" });
99
+ * ```
100
+ */
63
101
  export interface ScrollOptions {
102
+ /** Direction to scroll (default: "down") */
64
103
  direction?: Direction;
104
+ /** Distance in pixels to scroll (default: 500) */
65
105
  pixels?: number;
106
+ /** Optional target element selector to scroll directly into view */
66
107
  selector?: ElementTarget;
67
108
  }
68
109
 
110
+ /**
111
+ * Configuration options for touch swipe gestures (mobile & web).
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * await Spectra.swipe({ direction: "left", distance: 400 });
116
+ * ```
117
+ */
69
118
  export interface SwipeOptions {
119
+ /** Direction of the swipe gesture */
70
120
  direction: Direction;
121
+ /** Distance in pixels to swipe (default: 300) */
71
122
  distance?: number;
123
+ /** Optional element target to anchor the swipe gesture */
72
124
  selector?: ElementTarget;
73
125
  }
74
126
 
127
+ /**
128
+ * Configuration options for long-press gestures.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * await Spectra.longPress("#draggable-card", { duration: 1500 });
133
+ * ```
134
+ */
75
135
  export interface LongPressOptions {
136
+ /** Optional label or text associated with the element */
76
137
  text?: string;
138
+ /** Duration in milliseconds to hold the press (default: 1000) */
77
139
  duration?: number;
78
140
  }
79
141
 
142
+ /**
143
+ * Configuration options for click interactions.
144
+ */
80
145
  export interface ClickOptions {
146
+ /** Optional inner text filter */
81
147
  text?: string;
148
+ /** Click type: standard single click or double click */
82
149
  clickType?: "single" | "double";
83
150
  }
84
151
 
152
+ /**
153
+ * Configuration options for typing input into form elements.
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * await Spectra.type("#username", "john_doe", { clearFirst: true });
158
+ * ```
159
+ */
85
160
  export interface TypeOptions {
161
+ /** Whether to clear existing input value before typing new text (default: false) */
86
162
  clearFirst?: boolean;
87
163
  }
88
164
 
165
+ /**
166
+ * Fluent assertion matcher strings for single element verification.
167
+ * Used in `Spectra.get(target).should(matcher, ...args)`.
168
+ *
169
+ * @example
170
+ * ```ts
171
+ * await Spectra.get("#username").should("be.visible");
172
+ * await Spectra.get("#greeting").should("have.text", "Welcome back");
173
+ * await Spectra.get("#status").should("have.class", "active");
174
+ * ```
175
+ */
89
176
  export type SingleElementMatcher =
90
177
  | "be.visible"
91
178
  | "not.be.visible"
@@ -106,8 +193,20 @@ export type SingleElementMatcher =
106
193
  | "have.title"
107
194
  | "contain.title";
108
195
 
196
+ /**
197
+ * Fluent assertion matcher strings for multi-element collections.
198
+ * Used in `Spectra.getAll(selector).should(matcher, ...args)`.
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * await Spectra.getAll(".product-item").should("have.length", 4);
203
+ * await Spectra.getAll(".product-item").should("have.length.greaterThan", 0);
204
+ * await Spectra.getAll(".badge").should("not.be.empty");
205
+ * ```
206
+ */
109
207
  export type MultiElementMatcher =
110
208
  | "have.length"
111
209
  | "have.length.greaterThan"
112
210
  | "be.empty"
113
211
  | "exist";
212
+