@testspectra/react 1.3.1 → 1.3.3

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/index.js CHANGED
@@ -1,6 +1,138 @@
1
1
  // src/dom_driver_bridge.ts
2
2
  import { userEvent } from "@testing-library/user-event";
3
3
 
4
+ // ../../core/worker-runtime/src/harness/config.ts
5
+ var DEFAULT_WORKER_CONFIG = {
6
+ activePlatform: "web",
7
+ configuredBaseUrl: "http://localhost:3000",
8
+ driverServerUrl: "tcp://127.0.0.1:8200",
9
+ defaultElementWaitMs: 5e3,
10
+ defaultNavigationWaitMs: 1e4,
11
+ defaultPollIntervalMs: 20,
12
+ defaultReadyPollIntervalMs: 50
13
+ };
14
+ var currentConfig = null;
15
+ function getWorkerConfig() {
16
+ if (currentConfig) {
17
+ return currentConfig;
18
+ }
19
+ if (globalThis.__TESTSPECTRA_CONFIG__) {
20
+ currentConfig = globalThis.__TESTSPECTRA_CONFIG__;
21
+ return currentConfig;
22
+ }
23
+ if (typeof process !== "undefined" && process.env?.TESTSPECTRA_CONFIG) {
24
+ try {
25
+ currentConfig = JSON.parse(process.env.TESTSPECTRA_CONFIG);
26
+ return currentConfig;
27
+ } catch {
28
+ }
29
+ }
30
+ currentConfig = {
31
+ rootDir: typeof process !== "undefined" ? process.cwd() : "",
32
+ testFilePath: "",
33
+ activePlatform: DEFAULT_WORKER_CONFIG.activePlatform,
34
+ configuredBaseUrl: DEFAULT_WORKER_CONFIG.configuredBaseUrl,
35
+ cdpWsUrl: "",
36
+ driverServerUrl: DEFAULT_WORKER_CONFIG.driverServerUrl,
37
+ manifest: {
38
+ page_objects: [],
39
+ fixtures: [],
40
+ steps: [],
41
+ actions: [],
42
+ global_hooks: [],
43
+ suite_hooks: {}
44
+ }
45
+ };
46
+ return currentConfig;
47
+ }
48
+
49
+ // ../../core/worker-runtime/src/harness/reporter.ts
50
+ var activeDurationSink = null;
51
+ function recordDuration(label, category, durationMs, extra) {
52
+ if (activeDurationSink) {
53
+ activeDurationSink(label, category, durationMs, extra);
54
+ }
55
+ }
56
+ function getImplicitWaitMs() {
57
+ const config = getWorkerConfig();
58
+ return config.implicitWaitMs ?? DEFAULT_WORKER_CONFIG.defaultElementWaitMs;
59
+ }
60
+ function getAssertionTimeoutMs() {
61
+ return Math.min(getImplicitWaitMs(), 2e3);
62
+ }
63
+ function emitEvent(tag, payload) {
64
+ console.log(`[${tag}] ${payload}`);
65
+ }
66
+ var stepContext = { index: 0, label: "" };
67
+ var lastResolved;
68
+ function describeTarget(target) {
69
+ if (target === void 0 || target === null) return "";
70
+ if (typeof target === "string") return target;
71
+ const scoped = target;
72
+ return scoped.parent ? `${scoped.selector} within ${describeTarget(scoped.parent)}` : String(scoped.selector ?? "");
73
+ }
74
+ function delayApplies(index) {
75
+ const ranges = typeof process !== "undefined" ? process.env?.TESTSPECTRA_DELAY_STEPS : void 0;
76
+ if (!ranges) return true;
77
+ return ranges.split(",").some((range) => {
78
+ const [from, to = from] = range.split("-").map((n) => Number(n.trim()));
79
+ return Number.isFinite(from) && index >= from && index <= to;
80
+ });
81
+ }
82
+ async function trackStep(category, payloadObj, fn) {
83
+ const config = getWorkerConfig();
84
+ const currentTest = globalThis.__CURRENT_TEST_TITLE__ || globalThis.__CURRENT_TEST_ID__ || "";
85
+ const workerId = globalThis.__TESTSPECTRA_WORKER_ID__;
86
+ if (currentTest && !payloadObj.test) payloadObj.test = currentTest;
87
+ if (workerId !== void 0 && payloadObj.workerId === void 0) payloadObj.workerId = workerId;
88
+ stepContext = { index: stepContext.index + 1, label: `${payloadObj.key} ${describeTarget(payloadObj.target)}`.trim() };
89
+ payloadObj.step = stepContext.index;
90
+ lastResolved = void 0;
91
+ emitEvent("TESTSPECTRA_STEP_START", JSON.stringify(payloadObj));
92
+ const start = Date.now();
93
+ const withResolved = () => {
94
+ if (lastResolved) payloadObj.resolved = lastResolved;
95
+ return JSON.stringify(payloadObj);
96
+ };
97
+ try {
98
+ const res = await fn();
99
+ const duration = Date.now() - start;
100
+ emitEvent("TESTSPECTRA_STEP_PASS", `${withResolved()} (${duration}ms)`);
101
+ recordDuration(`step:${payloadObj.key}`, category, duration, { test: currentTest, target: payloadObj.target });
102
+ const delay = config.stepDelayMs || 0;
103
+ if (delay > 0 && delayApplies(stepContext.index)) {
104
+ await new Promise((r) => setTimeout(r, delay));
105
+ }
106
+ return res;
107
+ } catch (err) {
108
+ const duration = Date.now() - start;
109
+ emitEvent("TESTSPECTRA_STEP_FAIL", `${withResolved()} (${duration}ms)`);
110
+ recordDuration(`step:${payloadObj.key}`, category, duration, {
111
+ test: currentTest,
112
+ target: payloadObj.target,
113
+ failed: true
114
+ });
115
+ emitEvent("TESTSPECTRA_TEST_ERROR", err?.message || String(err));
116
+ throw err;
117
+ }
118
+ }
119
+ async function pollCondition(fn, timeoutMs, intervalMs = 15) {
120
+ const effectiveTimeout = timeoutMs ?? getImplicitWaitMs();
121
+ const start = Date.now();
122
+ while (Date.now() - start < effectiveTimeout) {
123
+ try {
124
+ if (await fn()) return true;
125
+ } catch {
126
+ }
127
+ await new Promise((r) => setTimeout(r, intervalMs));
128
+ }
129
+ try {
130
+ return await fn();
131
+ } catch {
132
+ return false;
133
+ }
134
+ }
135
+
4
136
  // ../../core/worker-runtime/src/dsl/element_scope.ts
5
137
  var ELEMENT_SCOPE = /* @__PURE__ */ Symbol("testspectra.elementScope");
6
138
  function getElementScope(value) {
@@ -76,8 +208,8 @@ function createMockHandle(rule, release) {
76
208
  respondWith: async (newFixture, newOptions = {}) => {
77
209
  const newObj = newFixture;
78
210
  rule.response = newObj && newObj.body !== void 0 ? newObj.body : newFixture;
79
- if (newOptions.statusCode || newObj && newObj.statusCode) {
80
- rule.statusCode = newOptions.statusCode || newObj?.statusCode || 200;
211
+ if (newOptions.statusCode || newObj && (newObj.statusCode || newObj.status)) {
212
+ rule.statusCode = newOptions.statusCode || newObj?.statusCode || newObj?.status || 200;
81
213
  }
82
214
  if (newOptions.headers || newObj && newObj.headers) {
83
215
  rule.headers = newOptions.headers || newObj?.headers;
@@ -90,7 +222,7 @@ function createMockHandle(rule, release) {
90
222
  respondOnce: async (newFixture, newOptions = {}) => {
91
223
  const newObj = newFixture;
92
224
  const resp = newObj && newObj.body !== void 0 ? newObj.body : newFixture;
93
- const statusCode = newOptions.statusCode || newObj && newObj.statusCode || rule.statusCode || 200;
225
+ const statusCode = newOptions.statusCode || newObj && (newObj.statusCode || newObj.status) || rule.statusCode || 200;
94
226
  const headers = newOptions.headers || newObj && newObj.headers || rule.headers;
95
227
  const delayMs = newOptions.delayMs ?? (newObj && newObj.delayMs) ?? rule.delayMs;
96
228
  rule.respondOnceQueue.push({ response: resp, statusCode, headers, delayMs });
@@ -126,6 +258,19 @@ function createMockHandle(rule, release) {
126
258
  });
127
259
  }
128
260
  };
261
+ handle.shouldHaveCallCount = (count, options = {}) => trackStep(
262
+ "assertion",
263
+ { type: "assertion", key: "have.callCount", target: `intercept ${rule.method} ${rule.pattern}`, args: [count] },
264
+ async () => {
265
+ const ok = await pollCondition(() => rule.callCount === count, options.timeout ?? getAssertionTimeoutMs());
266
+ if (!ok) {
267
+ const seen = rule.calls.map((call) => `${call.method} ${call.url}`).join(", ");
268
+ throw new Error(
269
+ `Expected intercept '${rule.pattern}' (${rule.method}) to have answered ${count} request(s), but it answered ${rule.callCount}${seen ? `: ${seen}` : ""}`
270
+ );
271
+ }
272
+ }
273
+ );
129
274
  const getCount = () => rule.callCount;
130
275
  handle.callCount = Object.assign(getCount, {
131
276
  valueOf: () => rule.callCount,