@riddledc/riddle-proof 0.7.51 → 0.7.53
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/README.md +19 -13
- package/dist/{chunk-ZC4C52ZC.js → chunk-IKT7AKZN.js} +103 -7
- package/dist/cli.cjs +103 -7
- package/dist/cli.js +1 -1
- package/dist/index.cjs +103 -7
- package/dist/index.js +1 -1
- package/dist/profile.cjs +103 -7
- package/dist/profile.d.cts +3 -1
- package/dist/profile.d.ts +3 -1
- package/dist/profile.js +1 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -238,23 +238,29 @@ where the second request must carry newer state.
|
|
|
238
238
|
appears only after a picker, tab, login stub, storage seed, form fill,
|
|
239
239
|
transport control, or other bounded interaction. Supported setup actions are
|
|
240
240
|
`click`, `fill`, `set_input_value`, `assert_text_visible`,
|
|
241
|
-
`assert_text_absent`, `assert_selector_count`, `
|
|
242
|
-
`session_storage`, `clear_storage`, `wait`,
|
|
243
|
-
`wait_for_text`, and `window_call`; a failed setup action
|
|
244
|
-
`setup_actions_succeeded` check so the profile cannot
|
|
245
|
-
the intended state. Text-matched `click` actions prefer
|
|
246
|
-
elements, which keeps responsive layouts from selecting hidden
|
|
247
|
-
mobile-only links. Add `force: true` to a click action only when the
|
|
248
|
-
visible element is intentionally animated or otherwise never becomes
|
|
249
|
-
enough for Playwright's default click actionability checks. Use setup
|
|
241
|
+
`assert_text_absent`, `assert_selector_count`, `assert_window_value`,
|
|
242
|
+
`local_storage`, `session_storage`, `clear_storage`, `wait`,
|
|
243
|
+
`wait_for_selector`, `wait_for_text`, and `window_call`; a failed setup action
|
|
244
|
+
is recorded as a failed `setup_actions_succeeded` check so the profile cannot
|
|
245
|
+
pass without reaching the intended state. Text-matched `click` actions prefer
|
|
246
|
+
visible matching elements, which keeps responsive layouts from selecting hidden
|
|
247
|
+
desktop or mobile-only links. Add `force: true` to a click action only when the
|
|
248
|
+
matched visible element is intentionally animated or otherwise never becomes
|
|
249
|
+
stable enough for Playwright's default click actionability checks. Use setup
|
|
250
250
|
assertions when the pre-click or pre-navigation state is part of the contract,
|
|
251
|
-
for example a fresh row must be present, stale copy must be absent,
|
|
252
|
-
|
|
253
|
-
`assert_selector_count` accepts
|
|
251
|
+
for example a fresh row must be present, stale copy must be absent, exactly one
|
|
252
|
+
source link must exist before clicking into the final route, or a canvas app's
|
|
253
|
+
proof state must expose a terminal flag. `assert_selector_count` accepts
|
|
254
|
+
`expected_count`; `assert_window_value` accepts `path` / `state_path` plus
|
|
255
|
+
`expected_value` / `expected` and compares JSON-safe values exactly.
|
|
254
256
|
`local_storage` and `session_storage` accept a `key` plus string `value` or
|
|
255
257
|
JSON `json` / `value_json`, and can reload the page with `reload: true`.
|
|
256
258
|
`clear_storage` clears `local`, `session`, or `both` browser storage scopes,
|
|
257
|
-
defaults to `both`, and can also reload with `reload: true`.
|
|
259
|
+
defaults to `both`, and can also reload with `reload: true`. Any setup action
|
|
260
|
+
can include `repeat` / `repeat_count` / `times` from 1 to 100; each repetition
|
|
261
|
+
is recorded with `repeat_index` and `repeat_count`, and `after_ms` runs after
|
|
262
|
+
each repetition. Use it for bounded game proof helpers, retry controls, or other
|
|
263
|
+
workflows where one declarative action needs to advance the app several times.
|
|
258
264
|
|
|
259
265
|
`target.timeout_sec` is optional. Use it for known-heavy profile targets so the
|
|
260
266
|
profile carries its own hosted Riddle worker budget; an explicit CLI `--timeout`
|
|
@@ -35,6 +35,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
35
35
|
"assert_text_visible",
|
|
36
36
|
"assert_text_absent",
|
|
37
37
|
"assert_selector_count",
|
|
38
|
+
"assert_window_value",
|
|
38
39
|
"local_storage",
|
|
39
40
|
"session_storage",
|
|
40
41
|
"clear_storage",
|
|
@@ -219,6 +220,14 @@ function normalizeSetupActionArgs(input, index) {
|
|
|
219
220
|
}
|
|
220
221
|
return argsInput.map(toJsonValue);
|
|
221
222
|
}
|
|
223
|
+
function normalizeSetupActionRepeat(input, index) {
|
|
224
|
+
const repeat = numberValue(valueFromOwn(input, "repeat", "repeat_count", "repeatCount", "times"));
|
|
225
|
+
if (repeat === void 0) return void 0;
|
|
226
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) {
|
|
227
|
+
throw new Error(`target.setup_actions[${index}].repeat must be an integer from 1 to 100.`);
|
|
228
|
+
}
|
|
229
|
+
return repeat;
|
|
230
|
+
}
|
|
222
231
|
function normalizeSetupAction(input, index) {
|
|
223
232
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
224
233
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
@@ -248,11 +257,15 @@ function normalizeSetupAction(input, index) {
|
|
|
248
257
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
249
258
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
250
259
|
}
|
|
251
|
-
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
252
|
-
if (type === "window_call" && !path) {
|
|
260
|
+
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
261
|
+
if ((type === "window_call" || type === "assert_window_value") && !path) {
|
|
253
262
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
254
263
|
}
|
|
255
264
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
265
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
266
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
267
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
268
|
+
}
|
|
256
269
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
257
270
|
return {
|
|
258
271
|
type,
|
|
@@ -264,6 +277,7 @@ function normalizeSetupAction(input, index) {
|
|
|
264
277
|
path,
|
|
265
278
|
args,
|
|
266
279
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
280
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
267
281
|
text: stringValue(input.text),
|
|
268
282
|
pattern: stringValue(input.pattern),
|
|
269
283
|
flags: stringValue(input.flags),
|
|
@@ -272,6 +286,7 @@ function normalizeSetupAction(input, index) {
|
|
|
272
286
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
273
287
|
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
274
288
|
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
289
|
+
repeat: normalizeSetupActionRepeat(input, index),
|
|
275
290
|
reload: input.reload === true,
|
|
276
291
|
storage: normalizeSetupActionStorage(input.storage, index),
|
|
277
292
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
@@ -1977,6 +1992,29 @@ function setupJsonValue(value) {
|
|
|
1977
1992
|
function setupValuesEqual(left, right) {
|
|
1978
1993
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
1979
1994
|
}
|
|
1995
|
+
async function setupReadWindowValue(path) {
|
|
1996
|
+
return await page.evaluate(({ path }) => {
|
|
1997
|
+
const toJsonValue = (value) => {
|
|
1998
|
+
if (value === null || value === undefined) return null;
|
|
1999
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
2000
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
2001
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
2002
|
+
if (typeof value === "object") {
|
|
2003
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
2004
|
+
}
|
|
2005
|
+
return String(value);
|
|
2006
|
+
};
|
|
2007
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
2008
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
2009
|
+
let current = window;
|
|
2010
|
+
for (const part of pathParts) {
|
|
2011
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2012
|
+
current = current[part];
|
|
2013
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2014
|
+
}
|
|
2015
|
+
return { ok: true, value: toJsonValue(current) };
|
|
2016
|
+
}, { path });
|
|
2017
|
+
}
|
|
1980
2018
|
async function setupLocatorText(locator, index) {
|
|
1981
2019
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
1982
2020
|
}
|
|
@@ -2225,6 +2263,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2225
2263
|
error: result.error || undefined,
|
|
2226
2264
|
};
|
|
2227
2265
|
}
|
|
2266
|
+
if (type === "assert_window_value") {
|
|
2267
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
2268
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
2269
|
+
|| setupHasOwn(action, "expectedValue")
|
|
2270
|
+
|| setupHasOwn(action, "expected")
|
|
2271
|
+
|| setupHasOwn(action, "expect_value")
|
|
2272
|
+
|| setupHasOwn(action, "expectValue")
|
|
2273
|
+
|| setupHasOwn(action, "expect");
|
|
2274
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
2275
|
+
? action.expected_value
|
|
2276
|
+
: setupHasOwn(action, "expectedValue")
|
|
2277
|
+
? action.expectedValue
|
|
2278
|
+
: setupHasOwn(action, "expected")
|
|
2279
|
+
? action.expected
|
|
2280
|
+
: setupHasOwn(action, "expect_value")
|
|
2281
|
+
? action.expect_value
|
|
2282
|
+
: setupHasOwn(action, "expectValue")
|
|
2283
|
+
? action.expectValue
|
|
2284
|
+
: action.expect;
|
|
2285
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
2286
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
2287
|
+
const startedAt = Date.now();
|
|
2288
|
+
let result = null;
|
|
2289
|
+
while (Date.now() - startedAt <= timeout) {
|
|
2290
|
+
result = await setupReadWindowValue(path);
|
|
2291
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
2292
|
+
return {
|
|
2293
|
+
...base,
|
|
2294
|
+
ok: true,
|
|
2295
|
+
path,
|
|
2296
|
+
value: setupJsonValue(result.value),
|
|
2297
|
+
expected_value: setupJsonValue(expected),
|
|
2298
|
+
timeout_ms: timeout,
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
await page.waitForTimeout(100);
|
|
2302
|
+
}
|
|
2303
|
+
return {
|
|
2304
|
+
...base,
|
|
2305
|
+
path,
|
|
2306
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
2307
|
+
missing_part: result?.missing_part || undefined,
|
|
2308
|
+
value: setupJsonValue(result?.value),
|
|
2309
|
+
expected_value: setupJsonValue(expected),
|
|
2310
|
+
timeout_ms: timeout,
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2228
2313
|
if (type === "click") {
|
|
2229
2314
|
const locator = page.locator(action.selector);
|
|
2230
2315
|
const count = await locator.count();
|
|
@@ -2350,11 +2435,22 @@ async function executeSetupActions(actions) {
|
|
|
2350
2435
|
const results = [];
|
|
2351
2436
|
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
2352
2437
|
const action = actions[index] || {};
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2438
|
+
const requestedRepeat = setupNumber(action.repeat, 1);
|
|
2439
|
+
const repeatCount = Math.min(100, Math.max(1, Math.floor(requestedRepeat || 1)));
|
|
2440
|
+
let shouldStop = false;
|
|
2441
|
+
for (let repeatIndex = 0; repeatIndex < repeatCount; repeatIndex += 1) {
|
|
2442
|
+
const result = await executeSetupAction(action, index);
|
|
2443
|
+
results.push(repeatCount > 1
|
|
2444
|
+
? { ...result, repeat_index: repeatIndex, repeat_count: repeatCount }
|
|
2445
|
+
: result);
|
|
2446
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
2447
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
2448
|
+
if (result.ok === false && action.continue_on_failure !== true) {
|
|
2449
|
+
shouldStop = true;
|
|
2450
|
+
break;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
if (shouldStop) break;
|
|
2358
2454
|
}
|
|
2359
2455
|
return results;
|
|
2360
2456
|
}
|
package/dist/cli.cjs
CHANGED
|
@@ -6908,6 +6908,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
6908
6908
|
"assert_text_visible",
|
|
6909
6909
|
"assert_text_absent",
|
|
6910
6910
|
"assert_selector_count",
|
|
6911
|
+
"assert_window_value",
|
|
6911
6912
|
"local_storage",
|
|
6912
6913
|
"session_storage",
|
|
6913
6914
|
"clear_storage",
|
|
@@ -7092,6 +7093,14 @@ function normalizeSetupActionArgs(input, index) {
|
|
|
7092
7093
|
}
|
|
7093
7094
|
return argsInput.map(toJsonValue);
|
|
7094
7095
|
}
|
|
7096
|
+
function normalizeSetupActionRepeat(input, index) {
|
|
7097
|
+
const repeat = numberValue(valueFromOwn(input, "repeat", "repeat_count", "repeatCount", "times"));
|
|
7098
|
+
if (repeat === void 0) return void 0;
|
|
7099
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) {
|
|
7100
|
+
throw new Error(`target.setup_actions[${index}].repeat must be an integer from 1 to 100.`);
|
|
7101
|
+
}
|
|
7102
|
+
return repeat;
|
|
7103
|
+
}
|
|
7095
7104
|
function normalizeSetupAction(input, index) {
|
|
7096
7105
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
7097
7106
|
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
@@ -7121,11 +7130,15 @@ function normalizeSetupAction(input, index) {
|
|
|
7121
7130
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
7122
7131
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
7123
7132
|
}
|
|
7124
|
-
const path7 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
7125
|
-
if (type === "window_call" && !path7) {
|
|
7133
|
+
const path7 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
7134
|
+
if ((type === "window_call" || type === "assert_window_value") && !path7) {
|
|
7126
7135
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
7127
7136
|
}
|
|
7128
7137
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
7138
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
7139
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
7140
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
7141
|
+
}
|
|
7129
7142
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
7130
7143
|
return {
|
|
7131
7144
|
type,
|
|
@@ -7137,6 +7150,7 @@ function normalizeSetupAction(input, index) {
|
|
|
7137
7150
|
path: path7,
|
|
7138
7151
|
args,
|
|
7139
7152
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
7153
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
7140
7154
|
text: stringValue2(input.text),
|
|
7141
7155
|
pattern: stringValue2(input.pattern),
|
|
7142
7156
|
flags: stringValue2(input.flags),
|
|
@@ -7145,6 +7159,7 @@ function normalizeSetupAction(input, index) {
|
|
|
7145
7159
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
7146
7160
|
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
7147
7161
|
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
7162
|
+
repeat: normalizeSetupActionRepeat(input, index),
|
|
7148
7163
|
reload: input.reload === true,
|
|
7149
7164
|
storage: normalizeSetupActionStorage(input.storage, index),
|
|
7150
7165
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
@@ -8834,6 +8849,29 @@ function setupJsonValue(value) {
|
|
|
8834
8849
|
function setupValuesEqual(left, right) {
|
|
8835
8850
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
8836
8851
|
}
|
|
8852
|
+
async function setupReadWindowValue(path) {
|
|
8853
|
+
return await page.evaluate(({ path }) => {
|
|
8854
|
+
const toJsonValue = (value) => {
|
|
8855
|
+
if (value === null || value === undefined) return null;
|
|
8856
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
8857
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
8858
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
8859
|
+
if (typeof value === "object") {
|
|
8860
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
8861
|
+
}
|
|
8862
|
+
return String(value);
|
|
8863
|
+
};
|
|
8864
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
8865
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
8866
|
+
let current = window;
|
|
8867
|
+
for (const part of pathParts) {
|
|
8868
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
8869
|
+
current = current[part];
|
|
8870
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
8871
|
+
}
|
|
8872
|
+
return { ok: true, value: toJsonValue(current) };
|
|
8873
|
+
}, { path });
|
|
8874
|
+
}
|
|
8837
8875
|
async function setupLocatorText(locator, index) {
|
|
8838
8876
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
8839
8877
|
}
|
|
@@ -9082,6 +9120,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9082
9120
|
error: result.error || undefined,
|
|
9083
9121
|
};
|
|
9084
9122
|
}
|
|
9123
|
+
if (type === "assert_window_value") {
|
|
9124
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
9125
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
9126
|
+
|| setupHasOwn(action, "expectedValue")
|
|
9127
|
+
|| setupHasOwn(action, "expected")
|
|
9128
|
+
|| setupHasOwn(action, "expect_value")
|
|
9129
|
+
|| setupHasOwn(action, "expectValue")
|
|
9130
|
+
|| setupHasOwn(action, "expect");
|
|
9131
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
9132
|
+
? action.expected_value
|
|
9133
|
+
: setupHasOwn(action, "expectedValue")
|
|
9134
|
+
? action.expectedValue
|
|
9135
|
+
: setupHasOwn(action, "expected")
|
|
9136
|
+
? action.expected
|
|
9137
|
+
: setupHasOwn(action, "expect_value")
|
|
9138
|
+
? action.expect_value
|
|
9139
|
+
: setupHasOwn(action, "expectValue")
|
|
9140
|
+
? action.expectValue
|
|
9141
|
+
: action.expect;
|
|
9142
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
9143
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
9144
|
+
const startedAt = Date.now();
|
|
9145
|
+
let result = null;
|
|
9146
|
+
while (Date.now() - startedAt <= timeout) {
|
|
9147
|
+
result = await setupReadWindowValue(path);
|
|
9148
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
9149
|
+
return {
|
|
9150
|
+
...base,
|
|
9151
|
+
ok: true,
|
|
9152
|
+
path,
|
|
9153
|
+
value: setupJsonValue(result.value),
|
|
9154
|
+
expected_value: setupJsonValue(expected),
|
|
9155
|
+
timeout_ms: timeout,
|
|
9156
|
+
};
|
|
9157
|
+
}
|
|
9158
|
+
await page.waitForTimeout(100);
|
|
9159
|
+
}
|
|
9160
|
+
return {
|
|
9161
|
+
...base,
|
|
9162
|
+
path,
|
|
9163
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
9164
|
+
missing_part: result?.missing_part || undefined,
|
|
9165
|
+
value: setupJsonValue(result?.value),
|
|
9166
|
+
expected_value: setupJsonValue(expected),
|
|
9167
|
+
timeout_ms: timeout,
|
|
9168
|
+
};
|
|
9169
|
+
}
|
|
9085
9170
|
if (type === "click") {
|
|
9086
9171
|
const locator = page.locator(action.selector);
|
|
9087
9172
|
const count = await locator.count();
|
|
@@ -9207,11 +9292,22 @@ async function executeSetupActions(actions) {
|
|
|
9207
9292
|
const results = [];
|
|
9208
9293
|
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
9209
9294
|
const action = actions[index] || {};
|
|
9210
|
-
const
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
|
|
9295
|
+
const requestedRepeat = setupNumber(action.repeat, 1);
|
|
9296
|
+
const repeatCount = Math.min(100, Math.max(1, Math.floor(requestedRepeat || 1)));
|
|
9297
|
+
let shouldStop = false;
|
|
9298
|
+
for (let repeatIndex = 0; repeatIndex < repeatCount; repeatIndex += 1) {
|
|
9299
|
+
const result = await executeSetupAction(action, index);
|
|
9300
|
+
results.push(repeatCount > 1
|
|
9301
|
+
? { ...result, repeat_index: repeatIndex, repeat_count: repeatCount }
|
|
9302
|
+
: result);
|
|
9303
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
9304
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
9305
|
+
if (result.ok === false && action.continue_on_failure !== true) {
|
|
9306
|
+
shouldStop = true;
|
|
9307
|
+
break;
|
|
9308
|
+
}
|
|
9309
|
+
}
|
|
9310
|
+
if (shouldStop) break;
|
|
9215
9311
|
}
|
|
9216
9312
|
return results;
|
|
9217
9313
|
}
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -8749,6 +8749,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
8749
8749
|
"assert_text_visible",
|
|
8750
8750
|
"assert_text_absent",
|
|
8751
8751
|
"assert_selector_count",
|
|
8752
|
+
"assert_window_value",
|
|
8752
8753
|
"local_storage",
|
|
8753
8754
|
"session_storage",
|
|
8754
8755
|
"clear_storage",
|
|
@@ -8933,6 +8934,14 @@ function normalizeSetupActionArgs(input, index) {
|
|
|
8933
8934
|
}
|
|
8934
8935
|
return argsInput.map(toJsonValue);
|
|
8935
8936
|
}
|
|
8937
|
+
function normalizeSetupActionRepeat(input, index) {
|
|
8938
|
+
const repeat = numberValue3(valueFromOwn(input, "repeat", "repeat_count", "repeatCount", "times"));
|
|
8939
|
+
if (repeat === void 0) return void 0;
|
|
8940
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) {
|
|
8941
|
+
throw new Error(`target.setup_actions[${index}].repeat must be an integer from 1 to 100.`);
|
|
8942
|
+
}
|
|
8943
|
+
return repeat;
|
|
8944
|
+
}
|
|
8936
8945
|
function normalizeSetupAction(input, index) {
|
|
8937
8946
|
if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
8938
8947
|
const type = normalizeSetupActionType(stringValue5(input.type), index);
|
|
@@ -8962,11 +8971,15 @@ function normalizeSetupAction(input, index) {
|
|
|
8962
8971
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
8963
8972
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
8964
8973
|
}
|
|
8965
|
-
const path6 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
8966
|
-
if (type === "window_call" && !path6) {
|
|
8974
|
+
const path6 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
8975
|
+
if ((type === "window_call" || type === "assert_window_value") && !path6) {
|
|
8967
8976
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
8968
8977
|
}
|
|
8969
8978
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
8979
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
8980
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
8981
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
8982
|
+
}
|
|
8970
8983
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
8971
8984
|
return {
|
|
8972
8985
|
type,
|
|
@@ -8978,6 +8991,7 @@ function normalizeSetupAction(input, index) {
|
|
|
8978
8991
|
path: path6,
|
|
8979
8992
|
args,
|
|
8980
8993
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
8994
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
8981
8995
|
text: stringValue5(input.text),
|
|
8982
8996
|
pattern: stringValue5(input.pattern),
|
|
8983
8997
|
flags: stringValue5(input.flags),
|
|
@@ -8986,6 +9000,7 @@ function normalizeSetupAction(input, index) {
|
|
|
8986
9000
|
ms: numberValue3(input.ms) ?? numberValue3(input.wait_ms) ?? numberValue3(input.waitMs),
|
|
8987
9001
|
timeout_ms: numberValue3(input.timeout_ms) ?? numberValue3(input.timeoutMs),
|
|
8988
9002
|
after_ms: numberValue3(input.after_ms) ?? numberValue3(input.afterMs),
|
|
9003
|
+
repeat: normalizeSetupActionRepeat(input, index),
|
|
8989
9004
|
reload: input.reload === true,
|
|
8990
9005
|
storage: normalizeSetupActionStorage(input.storage, index),
|
|
8991
9006
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
@@ -10691,6 +10706,29 @@ function setupJsonValue(value) {
|
|
|
10691
10706
|
function setupValuesEqual(left, right) {
|
|
10692
10707
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
10693
10708
|
}
|
|
10709
|
+
async function setupReadWindowValue(path) {
|
|
10710
|
+
return await page.evaluate(({ path }) => {
|
|
10711
|
+
const toJsonValue = (value) => {
|
|
10712
|
+
if (value === null || value === undefined) return null;
|
|
10713
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
10714
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
10715
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
10716
|
+
if (typeof value === "object") {
|
|
10717
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
10718
|
+
}
|
|
10719
|
+
return String(value);
|
|
10720
|
+
};
|
|
10721
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
10722
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
10723
|
+
let current = window;
|
|
10724
|
+
for (const part of pathParts) {
|
|
10725
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
10726
|
+
current = current[part];
|
|
10727
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
10728
|
+
}
|
|
10729
|
+
return { ok: true, value: toJsonValue(current) };
|
|
10730
|
+
}, { path });
|
|
10731
|
+
}
|
|
10694
10732
|
async function setupLocatorText(locator, index) {
|
|
10695
10733
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
10696
10734
|
}
|
|
@@ -10939,6 +10977,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
10939
10977
|
error: result.error || undefined,
|
|
10940
10978
|
};
|
|
10941
10979
|
}
|
|
10980
|
+
if (type === "assert_window_value") {
|
|
10981
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
10982
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
10983
|
+
|| setupHasOwn(action, "expectedValue")
|
|
10984
|
+
|| setupHasOwn(action, "expected")
|
|
10985
|
+
|| setupHasOwn(action, "expect_value")
|
|
10986
|
+
|| setupHasOwn(action, "expectValue")
|
|
10987
|
+
|| setupHasOwn(action, "expect");
|
|
10988
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
10989
|
+
? action.expected_value
|
|
10990
|
+
: setupHasOwn(action, "expectedValue")
|
|
10991
|
+
? action.expectedValue
|
|
10992
|
+
: setupHasOwn(action, "expected")
|
|
10993
|
+
? action.expected
|
|
10994
|
+
: setupHasOwn(action, "expect_value")
|
|
10995
|
+
? action.expect_value
|
|
10996
|
+
: setupHasOwn(action, "expectValue")
|
|
10997
|
+
? action.expectValue
|
|
10998
|
+
: action.expect;
|
|
10999
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
11000
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
11001
|
+
const startedAt = Date.now();
|
|
11002
|
+
let result = null;
|
|
11003
|
+
while (Date.now() - startedAt <= timeout) {
|
|
11004
|
+
result = await setupReadWindowValue(path);
|
|
11005
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
11006
|
+
return {
|
|
11007
|
+
...base,
|
|
11008
|
+
ok: true,
|
|
11009
|
+
path,
|
|
11010
|
+
value: setupJsonValue(result.value),
|
|
11011
|
+
expected_value: setupJsonValue(expected),
|
|
11012
|
+
timeout_ms: timeout,
|
|
11013
|
+
};
|
|
11014
|
+
}
|
|
11015
|
+
await page.waitForTimeout(100);
|
|
11016
|
+
}
|
|
11017
|
+
return {
|
|
11018
|
+
...base,
|
|
11019
|
+
path,
|
|
11020
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
11021
|
+
missing_part: result?.missing_part || undefined,
|
|
11022
|
+
value: setupJsonValue(result?.value),
|
|
11023
|
+
expected_value: setupJsonValue(expected),
|
|
11024
|
+
timeout_ms: timeout,
|
|
11025
|
+
};
|
|
11026
|
+
}
|
|
10942
11027
|
if (type === "click") {
|
|
10943
11028
|
const locator = page.locator(action.selector);
|
|
10944
11029
|
const count = await locator.count();
|
|
@@ -11064,11 +11149,22 @@ async function executeSetupActions(actions) {
|
|
|
11064
11149
|
const results = [];
|
|
11065
11150
|
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
11066
11151
|
const action = actions[index] || {};
|
|
11067
|
-
const
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
|
|
11152
|
+
const requestedRepeat = setupNumber(action.repeat, 1);
|
|
11153
|
+
const repeatCount = Math.min(100, Math.max(1, Math.floor(requestedRepeat || 1)));
|
|
11154
|
+
let shouldStop = false;
|
|
11155
|
+
for (let repeatIndex = 0; repeatIndex < repeatCount; repeatIndex += 1) {
|
|
11156
|
+
const result = await executeSetupAction(action, index);
|
|
11157
|
+
results.push(repeatCount > 1
|
|
11158
|
+
? { ...result, repeat_index: repeatIndex, repeat_count: repeatCount }
|
|
11159
|
+
: result);
|
|
11160
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
11161
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
11162
|
+
if (result.ok === false && action.continue_on_failure !== true) {
|
|
11163
|
+
shouldStop = true;
|
|
11164
|
+
break;
|
|
11165
|
+
}
|
|
11166
|
+
}
|
|
11167
|
+
if (shouldStop) break;
|
|
11072
11168
|
}
|
|
11073
11169
|
return results;
|
|
11074
11170
|
}
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
resolveRiddleProofProfileTimeoutSec,
|
|
59
59
|
slugifyRiddleProofProfileName,
|
|
60
60
|
summarizeRiddleProofProfileResult
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-IKT7AKZN.js";
|
|
62
62
|
import {
|
|
63
63
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
64
64
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -78,6 +78,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
78
78
|
"assert_text_visible",
|
|
79
79
|
"assert_text_absent",
|
|
80
80
|
"assert_selector_count",
|
|
81
|
+
"assert_window_value",
|
|
81
82
|
"local_storage",
|
|
82
83
|
"session_storage",
|
|
83
84
|
"clear_storage",
|
|
@@ -262,6 +263,14 @@ function normalizeSetupActionArgs(input, index) {
|
|
|
262
263
|
}
|
|
263
264
|
return argsInput.map(toJsonValue);
|
|
264
265
|
}
|
|
266
|
+
function normalizeSetupActionRepeat(input, index) {
|
|
267
|
+
const repeat = numberValue(valueFromOwn(input, "repeat", "repeat_count", "repeatCount", "times"));
|
|
268
|
+
if (repeat === void 0) return void 0;
|
|
269
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) {
|
|
270
|
+
throw new Error(`target.setup_actions[${index}].repeat must be an integer from 1 to 100.`);
|
|
271
|
+
}
|
|
272
|
+
return repeat;
|
|
273
|
+
}
|
|
265
274
|
function normalizeSetupAction(input, index) {
|
|
266
275
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
267
276
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
@@ -291,11 +300,15 @@ function normalizeSetupAction(input, index) {
|
|
|
291
300
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
292
301
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
293
302
|
}
|
|
294
|
-
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
295
|
-
if (type === "window_call" && !path) {
|
|
303
|
+
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
304
|
+
if ((type === "window_call" || type === "assert_window_value") && !path) {
|
|
296
305
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
297
306
|
}
|
|
298
307
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
308
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
309
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
310
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
311
|
+
}
|
|
299
312
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
300
313
|
return {
|
|
301
314
|
type,
|
|
@@ -307,6 +320,7 @@ function normalizeSetupAction(input, index) {
|
|
|
307
320
|
path,
|
|
308
321
|
args,
|
|
309
322
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
323
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
310
324
|
text: stringValue(input.text),
|
|
311
325
|
pattern: stringValue(input.pattern),
|
|
312
326
|
flags: stringValue(input.flags),
|
|
@@ -315,6 +329,7 @@ function normalizeSetupAction(input, index) {
|
|
|
315
329
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
316
330
|
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
317
331
|
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
332
|
+
repeat: normalizeSetupActionRepeat(input, index),
|
|
318
333
|
reload: input.reload === true,
|
|
319
334
|
storage: normalizeSetupActionStorage(input.storage, index),
|
|
320
335
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
@@ -2020,6 +2035,29 @@ function setupJsonValue(value) {
|
|
|
2020
2035
|
function setupValuesEqual(left, right) {
|
|
2021
2036
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
2022
2037
|
}
|
|
2038
|
+
async function setupReadWindowValue(path) {
|
|
2039
|
+
return await page.evaluate(({ path }) => {
|
|
2040
|
+
const toJsonValue = (value) => {
|
|
2041
|
+
if (value === null || value === undefined) return null;
|
|
2042
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
2043
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
2044
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
2045
|
+
if (typeof value === "object") {
|
|
2046
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
2047
|
+
}
|
|
2048
|
+
return String(value);
|
|
2049
|
+
};
|
|
2050
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
2051
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
2052
|
+
let current = window;
|
|
2053
|
+
for (const part of pathParts) {
|
|
2054
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2055
|
+
current = current[part];
|
|
2056
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2057
|
+
}
|
|
2058
|
+
return { ok: true, value: toJsonValue(current) };
|
|
2059
|
+
}, { path });
|
|
2060
|
+
}
|
|
2023
2061
|
async function setupLocatorText(locator, index) {
|
|
2024
2062
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
2025
2063
|
}
|
|
@@ -2268,6 +2306,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2268
2306
|
error: result.error || undefined,
|
|
2269
2307
|
};
|
|
2270
2308
|
}
|
|
2309
|
+
if (type === "assert_window_value") {
|
|
2310
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
2311
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
2312
|
+
|| setupHasOwn(action, "expectedValue")
|
|
2313
|
+
|| setupHasOwn(action, "expected")
|
|
2314
|
+
|| setupHasOwn(action, "expect_value")
|
|
2315
|
+
|| setupHasOwn(action, "expectValue")
|
|
2316
|
+
|| setupHasOwn(action, "expect");
|
|
2317
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
2318
|
+
? action.expected_value
|
|
2319
|
+
: setupHasOwn(action, "expectedValue")
|
|
2320
|
+
? action.expectedValue
|
|
2321
|
+
: setupHasOwn(action, "expected")
|
|
2322
|
+
? action.expected
|
|
2323
|
+
: setupHasOwn(action, "expect_value")
|
|
2324
|
+
? action.expect_value
|
|
2325
|
+
: setupHasOwn(action, "expectValue")
|
|
2326
|
+
? action.expectValue
|
|
2327
|
+
: action.expect;
|
|
2328
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
2329
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
2330
|
+
const startedAt = Date.now();
|
|
2331
|
+
let result = null;
|
|
2332
|
+
while (Date.now() - startedAt <= timeout) {
|
|
2333
|
+
result = await setupReadWindowValue(path);
|
|
2334
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
2335
|
+
return {
|
|
2336
|
+
...base,
|
|
2337
|
+
ok: true,
|
|
2338
|
+
path,
|
|
2339
|
+
value: setupJsonValue(result.value),
|
|
2340
|
+
expected_value: setupJsonValue(expected),
|
|
2341
|
+
timeout_ms: timeout,
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
await page.waitForTimeout(100);
|
|
2345
|
+
}
|
|
2346
|
+
return {
|
|
2347
|
+
...base,
|
|
2348
|
+
path,
|
|
2349
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
2350
|
+
missing_part: result?.missing_part || undefined,
|
|
2351
|
+
value: setupJsonValue(result?.value),
|
|
2352
|
+
expected_value: setupJsonValue(expected),
|
|
2353
|
+
timeout_ms: timeout,
|
|
2354
|
+
};
|
|
2355
|
+
}
|
|
2271
2356
|
if (type === "click") {
|
|
2272
2357
|
const locator = page.locator(action.selector);
|
|
2273
2358
|
const count = await locator.count();
|
|
@@ -2393,11 +2478,22 @@ async function executeSetupActions(actions) {
|
|
|
2393
2478
|
const results = [];
|
|
2394
2479
|
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
2395
2480
|
const action = actions[index] || {};
|
|
2396
|
-
const
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2481
|
+
const requestedRepeat = setupNumber(action.repeat, 1);
|
|
2482
|
+
const repeatCount = Math.min(100, Math.max(1, Math.floor(requestedRepeat || 1)));
|
|
2483
|
+
let shouldStop = false;
|
|
2484
|
+
for (let repeatIndex = 0; repeatIndex < repeatCount; repeatIndex += 1) {
|
|
2485
|
+
const result = await executeSetupAction(action, index);
|
|
2486
|
+
results.push(repeatCount > 1
|
|
2487
|
+
? { ...result, repeat_index: repeatIndex, repeat_count: repeatCount }
|
|
2488
|
+
: result);
|
|
2489
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
2490
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
2491
|
+
if (result.ok === false && action.continue_on_failure !== true) {
|
|
2492
|
+
shouldStop = true;
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
if (shouldStop) break;
|
|
2401
2497
|
}
|
|
2402
2498
|
return results;
|
|
2403
2499
|
}
|
package/dist/profile.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
-
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -27,6 +27,7 @@ interface RiddleProofProfileSetupAction {
|
|
|
27
27
|
path?: string;
|
|
28
28
|
args?: JsonValue[];
|
|
29
29
|
expect_return?: JsonValue;
|
|
30
|
+
expected_value?: JsonValue;
|
|
30
31
|
text?: string;
|
|
31
32
|
pattern?: string;
|
|
32
33
|
flags?: string;
|
|
@@ -35,6 +36,7 @@ interface RiddleProofProfileSetupAction {
|
|
|
35
36
|
ms?: number;
|
|
36
37
|
timeout_ms?: number;
|
|
37
38
|
after_ms?: number;
|
|
39
|
+
repeat?: number;
|
|
38
40
|
reload?: boolean;
|
|
39
41
|
storage?: "local" | "session" | "both";
|
|
40
42
|
continue_on_failure?: boolean;
|
package/dist/profile.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
-
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -27,6 +27,7 @@ interface RiddleProofProfileSetupAction {
|
|
|
27
27
|
path?: string;
|
|
28
28
|
args?: JsonValue[];
|
|
29
29
|
expect_return?: JsonValue;
|
|
30
|
+
expected_value?: JsonValue;
|
|
30
31
|
text?: string;
|
|
31
32
|
pattern?: string;
|
|
32
33
|
flags?: string;
|
|
@@ -35,6 +36,7 @@ interface RiddleProofProfileSetupAction {
|
|
|
35
36
|
ms?: number;
|
|
36
37
|
timeout_ms?: number;
|
|
37
38
|
after_ms?: number;
|
|
39
|
+
repeat?: number;
|
|
38
40
|
reload?: boolean;
|
|
39
41
|
storage?: "local" | "session" | "both";
|
|
40
42
|
continue_on_failure?: boolean;
|
package/dist/profile.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
resolveRiddleProofProfileTimeoutSec,
|
|
20
20
|
slugifyRiddleProofProfileName,
|
|
21
21
|
summarizeRiddleProofProfileResult
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IKT7AKZN.js";
|
|
23
23
|
export {
|
|
24
24
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
25
25
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|