@testspectra/matchers 1.0.70 → 1.1.0-rc.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.
Files changed (51) hide show
  1. package/LICENSE.md +48 -0
  2. package/dist/__tests__/intercept.test.d.ts +1 -0
  3. package/dist/__tests__/intercept.test.js +183 -0
  4. package/dist/__tests__/matcher-contracts.test.d.ts +1 -0
  5. package/dist/__tests__/matcher-contracts.test.js +498 -0
  6. package/dist/__tests__/matchers.test.d.ts +1 -0
  7. package/dist/__tests__/matchers.test.js +161 -0
  8. package/dist/contract.d.ts +141 -0
  9. package/dist/contract.js +10 -0
  10. package/dist/index.d.ts +4 -21
  11. package/dist/index.js +4 -21
  12. package/dist/intercept/cdp-handler.d.ts +22 -0
  13. package/dist/intercept/cdp-handler.js +123 -0
  14. package/dist/intercept/index.d.ts +4 -0
  15. package/dist/intercept/index.js +4 -0
  16. package/dist/intercept/mock-handle.d.ts +49 -0
  17. package/dist/intercept/mock-handle.js +124 -0
  18. package/dist/intercept/mock-registry.d.ts +18 -0
  19. package/dist/intercept/mock-registry.js +97 -0
  20. package/dist/intercept/types.d.ts +43 -0
  21. package/dist/intercept/types.js +1 -0
  22. package/dist/matchers.d.ts +15 -4
  23. package/dist/matchers.js +609 -81
  24. package/dist/proto.d.ts +18 -283
  25. package/dist/proto.js +1 -114
  26. package/dist/reporter.d.ts +30 -0
  27. package/dist/reporter.js +97 -0
  28. package/dist/runner/collection.d.ts +33 -20
  29. package/dist/runner/collection.js +104 -26
  30. package/dist/runner/single.d.ts +125 -34
  31. package/dist/runner/single.js +290 -55
  32. package/dist/semantic.d.ts +11 -0
  33. package/dist/semantic.js +141 -0
  34. package/dist/spectra.d.ts +32 -8
  35. package/dist/spectra.js +157 -40
  36. package/dist/types.d.ts +1226 -28
  37. package/package.json +13 -8
  38. package/src/contract.ts +182 -0
  39. package/src/index.ts +4 -22
  40. package/src/proto.ts +22 -433
  41. package/src/runtime/assertions.ts +450 -0
  42. package/src/runtime/element_actions.ts +169 -0
  43. package/src/runtime/element_proxy.ts +159 -0
  44. package/src/runtime/element_state.ts +91 -0
  45. package/src/runtime/spectra.ts +109 -0
  46. package/src/types.ts +1424 -96
  47. package/tsconfig.json +2 -2
  48. package/src/matchers.ts +0 -146
  49. package/src/runner/collection.ts +0 -153
  50. package/src/runner/single.ts +0 -301
  51. package/src/spectra.ts +0 -376
package/package.json CHANGED
@@ -1,21 +1,26 @@
1
1
  {
2
2
  "name": "@testspectra/matchers",
3
- "version": "1.0.70",
4
- "description": "Cross-platform action commands and direct callable assertion matchers for TestSpectra",
3
+ "version": "1.1.0-rc.0",
4
+ "description": "Canonical TypeScript contracts and ambient type definitions for TestSpectra",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
7
14
  "scripts": {
8
15
  "build": "tsc",
9
16
  "watch": "tsc -w",
17
+ "typecheck": "tsc --noEmit",
10
18
  "prepublishOnly": "npm run build"
11
19
  },
12
20
  "devDependencies": {
13
- "@types/node": "^20.14.0",
14
- "@wdio/globals": "^9.2.8",
15
- "@wdio/mocha-framework": "^9.2.8",
16
- "webdriverio": "^9.2.8",
17
- "typescript": "^5.4.5"
21
+ "@types/node": "catalog:",
22
+ "typescript": "catalog:"
18
23
  },
19
24
  "type": "module",
20
- "license": "MIT"
25
+ "license": "SEE LICENSE IN LICENSE.md"
21
26
  }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * # PlatformDriverBridge Contract
4
+ *
5
+ * The unified abstract driver contract consumed by `@testspectra/matchers` element proxies,
6
+ * fluent matchers, and the `Spectra` automation object. Every platform-specific driver
7
+ * (`WebCdpDriverBridge`, `AndroidTcpDriverBridge`) implements this interface so that the
8
+ * DSL layer contains zero platform branching.
9
+ */
10
+
11
+ import type {
12
+ CDPNetworkEntry,
13
+ MockInterceptHandle,
14
+ MockRule,
15
+ ScrollOptions,
16
+ SpectraBrowserBridge,
17
+ SwipeOptions,
18
+ } from './types.js';
19
+
20
+ /**
21
+ * Runtime configuration injected by the Rust orchestrator via `globalThis.__TESTSPECTRA_CONFIG__`.
22
+ */
23
+ export interface RuntimeWorkerConfig {
24
+ workerId?: number;
25
+ rootDir: string;
26
+ testFilePath?: string;
27
+ testFiles?: Array<{ id: string; title: string; filePath: string; suite: string }>;
28
+ activePlatform: string;
29
+ configuredBaseUrl: string;
30
+ cdpWsUrl: string;
31
+ driverServerUrl: string;
32
+ manifest?: Record<string, any>;
33
+ /** Target app package (Android). Paired with androidSerial/adbPath for on-demand adb actions. */
34
+ appPackage?: string;
35
+ /** Target adb device serial for this worker (Android only). */
36
+ androidSerial?: string;
37
+ /** Resolved `adb` binary path (Android only), paired with androidSerial above. */
38
+ adbPath?: string;
39
+ /** Host port this worker's own MobileMockProxyServer should listen on (Android only) — derived
40
+ * per-device the same way androidSerial/the driver-server port already are, so each device in
41
+ * a multi-device run gets its own proxy instead of every worker racing for one shared port. */
42
+ mockProxyPort?: number;
43
+ implicitWaitMs?: number;
44
+ timeoutMs?: number;
45
+ stepDelayMs?: number;
46
+ }
47
+
48
+ /**
49
+ * Cross-cutting shared runtime state injected into the assembled worker script.
50
+ *
51
+ * The worker runtime is emitted as a single self-contained TypeScript module (concatenated
52
+ * by the Rust orchestrator). This object is created once in the harness prelude and mutated
53
+ * in place (`activeDriver` is bound after the platform bridge is instantiated), so fragments
54
+ * access it lazily at call-time through `globalThis.__TS_RUNTIME__`.
55
+ */
56
+ export interface RuntimeContext {
57
+ config: RuntimeWorkerConfig;
58
+ activeDriver: PlatformDriverBridge | null;
59
+ mobileMockRules: MockRule[];
60
+ lastFocusedSelector: string | null;
61
+ currentTargetItem?: any;
62
+
63
+ emitEvent(tag: string, payload: string): void;
64
+ trackStep<T>(
65
+ category: 'action' | 'assertion' | 'browser',
66
+ payloadObj: Record<string, any>,
67
+ fn: () => Promise<T>,
68
+ ): Promise<T>;
69
+ pollCondition(fn: () => Promise<boolean> | boolean, timeoutMs?: number, intervalMs?: number): Promise<boolean>;
70
+ getImplicitWaitMs(): number;
71
+ getAssertionTimeoutMs(): number;
72
+ matchesUrlPattern(pattern: string, url: string): boolean;
73
+ createMockHandle(rule: MockRule): MockInterceptHandle;
74
+ parseMockRule(patternOrOptions?: any, maybeMethodOrHandler?: any, maybeFixture?: any, maybeOptions?: any): MockRule;
75
+
76
+ // Opt-in duration logging (see core/orchestrator/src/worker/prelude.ts). Present at runtime only
77
+ // when TESTSPECTRA_DURATION_LOG is set; the wrappers are pass-through no-ops otherwise.
78
+ recordDuration?: (label: string, category: string, durationMs: number, extra?: Record<string, unknown>) => void;
79
+ withDuration?: <T>(
80
+ label: string,
81
+ category: string,
82
+ fn: () => Promise<T>,
83
+ extra?: Record<string, unknown>,
84
+ ) => Promise<T>;
85
+ durationLogPath?: string | null;
86
+
87
+ // Matchers runtime factories — registered onto the context by the `tools/matchers` fragments
88
+ // at load time, then consumed by sibling fragments (concatenated single-scope assembly).
89
+ createElementActions?: (selector: string, index: number | null) => Record<string, any>;
90
+ createElementState?: (selector: string, index: number | null) => Record<string, any>;
91
+ createElementAssertions?: (selector: string, index: number | null, state: Record<string, any>) => Record<string, any>;
92
+ createElementProxy?: (selector: string, index?: number | null) => any;
93
+ createCollectionProxy?: (selector: string) => any;
94
+ resolveTargetProxy?: (target: any) => any;
95
+ buildSpectra?: () => any;
96
+
97
+ // Platform driver classes — registered by the driver bridge fragments at load time.
98
+ cdpBridgeClass?: any;
99
+ androidBridgeClass?: any;
100
+ mobileMockProxyClass?: any;
101
+ mobileMockProxy?: any;
102
+
103
+ // BDD harness lifecycle hooks & entrypoints — `bdd_runner.ts` owns the hook slots and
104
+ // `runSuite`; `auto_import.ts` owns `bootstrapEnvironment`. Routed through this shared context
105
+ // (rather than plain module-scoped bindings) because the harness fragments are concatenated
106
+ // into one script by the Rust orchestrator but remain separate ES modules for unit testing.
107
+ beforeHook?: (() => Promise<void> | void) | null;
108
+ afterHook?: (() => Promise<void> | void) | null;
109
+ beforeEachHook?: (() => Promise<void> | void) | null;
110
+ afterEachHook?: (() => Promise<void> | void) | null;
111
+ bootstrapEnvironment?: () => Promise<void>;
112
+ runSuite?: () => Promise<void>;
113
+ }
114
+
115
+ /**
116
+ * The unified platform driver contract. It extends the browser surface documented in
117
+ * `SpectraBrowserBridge` (navigation, script execution, network interception, browser-level
118
+ * assertions) with the element interaction and state-inspection methods needed by the DSL,
119
+ * so the `tools/matchers` layer never branches on `activePlatform`.
120
+ */
121
+ export interface PlatformDriverBridge extends SpectraBrowserBridge {
122
+ /** Establishes connection to the underlying runtime endpoint (WebSocket / TCP Socket). */
123
+ connect(): Promise<void>;
124
+
125
+ /** Cleans up open connections, servers, and listeners. */
126
+ close(): Promise<void>;
127
+
128
+ /** Navigates to target URL (Web) or Activity / Deep Link (Android). */
129
+ navigate(targetUrl: string): Promise<void>;
130
+
131
+ // --- Element Actions ---
132
+ click(selector: string, index?: number | null): Promise<void>;
133
+ doubleClick(selector: string, index?: number | null): Promise<void>;
134
+ rightClick(selector: string, index?: number | null): Promise<void>;
135
+ setValue(selector: string, value: unknown, index?: number | null): Promise<void>;
136
+ clearValue(selector: string, index?: number | null): Promise<void>;
137
+ select(selector: string, option: string, index?: number | null): Promise<void>;
138
+ hover(selector: string, index?: number | null): Promise<void>;
139
+ focus(selector: string, index?: number | null): Promise<void>;
140
+ dragDrop(sourceSelector: string, targetSelector: string, sourceIndex?: number | null): Promise<void>;
141
+ longPress(selector: string, duration: number, index?: number | null): Promise<void>;
142
+ scrollIntoView(selector: string, index?: number | null): Promise<void>;
143
+
144
+ // --- Element State Inspection ---
145
+ getText(selector: string, index?: number | null): Promise<string>;
146
+ getValue(selector: string, index?: number | null): Promise<string>;
147
+ isDisplayed(selector: string, index?: number | null): Promise<boolean>;
148
+ isExisting(selector: string, index?: number | null): Promise<boolean>;
149
+ isEnabled(selector: string, index?: number | null): Promise<boolean>;
150
+ isSelected(selector: string, index?: number | null): Promise<boolean>;
151
+ isFocused(selector: string, index?: number | null): Promise<boolean>;
152
+ isClickable(selector: string, index?: number | null): Promise<boolean>;
153
+ hasClass(selector: string, className: string, index?: number | null): Promise<boolean>;
154
+ getAttribute(selector: string, name: string, index?: number | null): Promise<string | null>;
155
+ getCSSProperty(selector: string, name: string, index?: number | null): Promise<{ value: string }>;
156
+ count(selector: string): Promise<number>;
157
+
158
+ // --- Gestures & Keys ---
159
+ pressKey(key: string | number): Promise<void>;
160
+ scroll(options?: ScrollOptions): Promise<void>;
161
+ swipe(options: SwipeOptions): Promise<void>;
162
+
163
+ /**
164
+ * Grants an Android runtime permission on demand (e.g. right after confirming an in-app
165
+ * rationale dialog), via `adb shell pm grant` on the host. No-op on platforms without an
166
+ * OS-level runtime permission model (e.g. web).
167
+ */
168
+ grantPermission(name: string): Promise<void>;
169
+
170
+ /** Clears all active network interception rules. */
171
+ clearMocks(): void;
172
+
173
+ // --- State accessed by the harness & tests ---
174
+ mockRules: MockRule[];
175
+ consoleErrors: string[];
176
+ recordedNetwork: CDPNetworkEntry[];
177
+ }
178
+
179
+ declare global {
180
+ // eslint-disable-next-line no-var
181
+ var __TS_RUNTIME__: RuntimeContext;
182
+ }
package/src/index.ts CHANGED
@@ -2,27 +2,9 @@
2
2
  * @packageDocumentation
3
3
  * # @testspectra/matchers
4
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
- * ```
5
+ * Canonical TypeScript contracts, action/assertion types, and ambient type definitions for TestSpectra.
20
6
  */
21
7
 
22
- export * from "./types.js";
23
- export * from "./matchers.js";
24
- export * from "./runner/single.js";
25
- export * from "./runner/collection.js";
26
- export * from "./spectra.js";
27
- export * from "./proto.js";
28
-
8
+ export * from './types.js';
9
+ export * from './contract.js';
10
+ export * from './proto.js';