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