@riddledc/riddle-proof 0.7.51 → 0.7.52
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 +14 -12
- package/dist/{chunk-ZC4C52ZC.js → chunk-4S6RC5IJ.js} +78 -2
- package/dist/cli.cjs +78 -2
- package/dist/cli.js +1 -1
- package/dist/index.cjs +78 -2
- package/dist/index.js +1 -1
- package/dist/profile.cjs +78 -2
- package/dist/profile.d.cts +2 -1
- package/dist/profile.d.ts +2 -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,19 +238,21 @@ 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,
|
|
@@ -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",
|
|
@@ -248,11 +249,15 @@ function normalizeSetupAction(input, index) {
|
|
|
248
249
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
249
250
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
250
251
|
}
|
|
251
|
-
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
252
|
-
if (type === "window_call" && !path) {
|
|
252
|
+
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
253
|
+
if ((type === "window_call" || type === "assert_window_value") && !path) {
|
|
253
254
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
254
255
|
}
|
|
255
256
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
257
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
258
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
259
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
260
|
+
}
|
|
256
261
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
257
262
|
return {
|
|
258
263
|
type,
|
|
@@ -264,6 +269,7 @@ function normalizeSetupAction(input, index) {
|
|
|
264
269
|
path,
|
|
265
270
|
args,
|
|
266
271
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
272
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
267
273
|
text: stringValue(input.text),
|
|
268
274
|
pattern: stringValue(input.pattern),
|
|
269
275
|
flags: stringValue(input.flags),
|
|
@@ -1977,6 +1983,29 @@ function setupJsonValue(value) {
|
|
|
1977
1983
|
function setupValuesEqual(left, right) {
|
|
1978
1984
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
1979
1985
|
}
|
|
1986
|
+
async function setupReadWindowValue(path) {
|
|
1987
|
+
return await page.evaluate(({ path }) => {
|
|
1988
|
+
const toJsonValue = (value) => {
|
|
1989
|
+
if (value === null || value === undefined) return null;
|
|
1990
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
1991
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
1992
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
1993
|
+
if (typeof value === "object") {
|
|
1994
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
1995
|
+
}
|
|
1996
|
+
return String(value);
|
|
1997
|
+
};
|
|
1998
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
1999
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
2000
|
+
let current = window;
|
|
2001
|
+
for (const part of pathParts) {
|
|
2002
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2003
|
+
current = current[part];
|
|
2004
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2005
|
+
}
|
|
2006
|
+
return { ok: true, value: toJsonValue(current) };
|
|
2007
|
+
}, { path });
|
|
2008
|
+
}
|
|
1980
2009
|
async function setupLocatorText(locator, index) {
|
|
1981
2010
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
1982
2011
|
}
|
|
@@ -2225,6 +2254,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2225
2254
|
error: result.error || undefined,
|
|
2226
2255
|
};
|
|
2227
2256
|
}
|
|
2257
|
+
if (type === "assert_window_value") {
|
|
2258
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
2259
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
2260
|
+
|| setupHasOwn(action, "expectedValue")
|
|
2261
|
+
|| setupHasOwn(action, "expected")
|
|
2262
|
+
|| setupHasOwn(action, "expect_value")
|
|
2263
|
+
|| setupHasOwn(action, "expectValue")
|
|
2264
|
+
|| setupHasOwn(action, "expect");
|
|
2265
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
2266
|
+
? action.expected_value
|
|
2267
|
+
: setupHasOwn(action, "expectedValue")
|
|
2268
|
+
? action.expectedValue
|
|
2269
|
+
: setupHasOwn(action, "expected")
|
|
2270
|
+
? action.expected
|
|
2271
|
+
: setupHasOwn(action, "expect_value")
|
|
2272
|
+
? action.expect_value
|
|
2273
|
+
: setupHasOwn(action, "expectValue")
|
|
2274
|
+
? action.expectValue
|
|
2275
|
+
: action.expect;
|
|
2276
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
2277
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
2278
|
+
const startedAt = Date.now();
|
|
2279
|
+
let result = null;
|
|
2280
|
+
while (Date.now() - startedAt <= timeout) {
|
|
2281
|
+
result = await setupReadWindowValue(path);
|
|
2282
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
2283
|
+
return {
|
|
2284
|
+
...base,
|
|
2285
|
+
ok: true,
|
|
2286
|
+
path,
|
|
2287
|
+
value: setupJsonValue(result.value),
|
|
2288
|
+
expected_value: setupJsonValue(expected),
|
|
2289
|
+
timeout_ms: timeout,
|
|
2290
|
+
};
|
|
2291
|
+
}
|
|
2292
|
+
await page.waitForTimeout(100);
|
|
2293
|
+
}
|
|
2294
|
+
return {
|
|
2295
|
+
...base,
|
|
2296
|
+
path,
|
|
2297
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
2298
|
+
missing_part: result?.missing_part || undefined,
|
|
2299
|
+
value: setupJsonValue(result?.value),
|
|
2300
|
+
expected_value: setupJsonValue(expected),
|
|
2301
|
+
timeout_ms: timeout,
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2228
2304
|
if (type === "click") {
|
|
2229
2305
|
const locator = page.locator(action.selector);
|
|
2230
2306
|
const count = await locator.count();
|
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",
|
|
@@ -7121,11 +7122,15 @@ function normalizeSetupAction(input, index) {
|
|
|
7121
7122
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
7122
7123
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
7123
7124
|
}
|
|
7124
|
-
const path7 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
7125
|
-
if (type === "window_call" && !path7) {
|
|
7125
|
+
const path7 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
7126
|
+
if ((type === "window_call" || type === "assert_window_value") && !path7) {
|
|
7126
7127
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
7127
7128
|
}
|
|
7128
7129
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
7130
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
7131
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
7132
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
7133
|
+
}
|
|
7129
7134
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
7130
7135
|
return {
|
|
7131
7136
|
type,
|
|
@@ -7137,6 +7142,7 @@ function normalizeSetupAction(input, index) {
|
|
|
7137
7142
|
path: path7,
|
|
7138
7143
|
args,
|
|
7139
7144
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
7145
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
7140
7146
|
text: stringValue2(input.text),
|
|
7141
7147
|
pattern: stringValue2(input.pattern),
|
|
7142
7148
|
flags: stringValue2(input.flags),
|
|
@@ -8834,6 +8840,29 @@ function setupJsonValue(value) {
|
|
|
8834
8840
|
function setupValuesEqual(left, right) {
|
|
8835
8841
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
8836
8842
|
}
|
|
8843
|
+
async function setupReadWindowValue(path) {
|
|
8844
|
+
return await page.evaluate(({ path }) => {
|
|
8845
|
+
const toJsonValue = (value) => {
|
|
8846
|
+
if (value === null || value === undefined) return null;
|
|
8847
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
8848
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
8849
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
8850
|
+
if (typeof value === "object") {
|
|
8851
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
8852
|
+
}
|
|
8853
|
+
return String(value);
|
|
8854
|
+
};
|
|
8855
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
8856
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
8857
|
+
let current = window;
|
|
8858
|
+
for (const part of pathParts) {
|
|
8859
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
8860
|
+
current = current[part];
|
|
8861
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
8862
|
+
}
|
|
8863
|
+
return { ok: true, value: toJsonValue(current) };
|
|
8864
|
+
}, { path });
|
|
8865
|
+
}
|
|
8837
8866
|
async function setupLocatorText(locator, index) {
|
|
8838
8867
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
8839
8868
|
}
|
|
@@ -9082,6 +9111,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9082
9111
|
error: result.error || undefined,
|
|
9083
9112
|
};
|
|
9084
9113
|
}
|
|
9114
|
+
if (type === "assert_window_value") {
|
|
9115
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
9116
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
9117
|
+
|| setupHasOwn(action, "expectedValue")
|
|
9118
|
+
|| setupHasOwn(action, "expected")
|
|
9119
|
+
|| setupHasOwn(action, "expect_value")
|
|
9120
|
+
|| setupHasOwn(action, "expectValue")
|
|
9121
|
+
|| setupHasOwn(action, "expect");
|
|
9122
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
9123
|
+
? action.expected_value
|
|
9124
|
+
: setupHasOwn(action, "expectedValue")
|
|
9125
|
+
? action.expectedValue
|
|
9126
|
+
: setupHasOwn(action, "expected")
|
|
9127
|
+
? action.expected
|
|
9128
|
+
: setupHasOwn(action, "expect_value")
|
|
9129
|
+
? action.expect_value
|
|
9130
|
+
: setupHasOwn(action, "expectValue")
|
|
9131
|
+
? action.expectValue
|
|
9132
|
+
: action.expect;
|
|
9133
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
9134
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
9135
|
+
const startedAt = Date.now();
|
|
9136
|
+
let result = null;
|
|
9137
|
+
while (Date.now() - startedAt <= timeout) {
|
|
9138
|
+
result = await setupReadWindowValue(path);
|
|
9139
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
9140
|
+
return {
|
|
9141
|
+
...base,
|
|
9142
|
+
ok: true,
|
|
9143
|
+
path,
|
|
9144
|
+
value: setupJsonValue(result.value),
|
|
9145
|
+
expected_value: setupJsonValue(expected),
|
|
9146
|
+
timeout_ms: timeout,
|
|
9147
|
+
};
|
|
9148
|
+
}
|
|
9149
|
+
await page.waitForTimeout(100);
|
|
9150
|
+
}
|
|
9151
|
+
return {
|
|
9152
|
+
...base,
|
|
9153
|
+
path,
|
|
9154
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
9155
|
+
missing_part: result?.missing_part || undefined,
|
|
9156
|
+
value: setupJsonValue(result?.value),
|
|
9157
|
+
expected_value: setupJsonValue(expected),
|
|
9158
|
+
timeout_ms: timeout,
|
|
9159
|
+
};
|
|
9160
|
+
}
|
|
9085
9161
|
if (type === "click") {
|
|
9086
9162
|
const locator = page.locator(action.selector);
|
|
9087
9163
|
const count = await locator.count();
|
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",
|
|
@@ -8962,11 +8963,15 @@ function normalizeSetupAction(input, index) {
|
|
|
8962
8963
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
8963
8964
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
8964
8965
|
}
|
|
8965
|
-
const path6 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
8966
|
-
if (type === "window_call" && !path6) {
|
|
8966
|
+
const path6 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
8967
|
+
if ((type === "window_call" || type === "assert_window_value") && !path6) {
|
|
8967
8968
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
8968
8969
|
}
|
|
8969
8970
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
8971
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
8972
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
8973
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
8974
|
+
}
|
|
8970
8975
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
8971
8976
|
return {
|
|
8972
8977
|
type,
|
|
@@ -8978,6 +8983,7 @@ function normalizeSetupAction(input, index) {
|
|
|
8978
8983
|
path: path6,
|
|
8979
8984
|
args,
|
|
8980
8985
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
8986
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
8981
8987
|
text: stringValue5(input.text),
|
|
8982
8988
|
pattern: stringValue5(input.pattern),
|
|
8983
8989
|
flags: stringValue5(input.flags),
|
|
@@ -10691,6 +10697,29 @@ function setupJsonValue(value) {
|
|
|
10691
10697
|
function setupValuesEqual(left, right) {
|
|
10692
10698
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
10693
10699
|
}
|
|
10700
|
+
async function setupReadWindowValue(path) {
|
|
10701
|
+
return await page.evaluate(({ path }) => {
|
|
10702
|
+
const toJsonValue = (value) => {
|
|
10703
|
+
if (value === null || value === undefined) return null;
|
|
10704
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
10705
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
10706
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
10707
|
+
if (typeof value === "object") {
|
|
10708
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
10709
|
+
}
|
|
10710
|
+
return String(value);
|
|
10711
|
+
};
|
|
10712
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
10713
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
10714
|
+
let current = window;
|
|
10715
|
+
for (const part of pathParts) {
|
|
10716
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
10717
|
+
current = current[part];
|
|
10718
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
10719
|
+
}
|
|
10720
|
+
return { ok: true, value: toJsonValue(current) };
|
|
10721
|
+
}, { path });
|
|
10722
|
+
}
|
|
10694
10723
|
async function setupLocatorText(locator, index) {
|
|
10695
10724
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
10696
10725
|
}
|
|
@@ -10939,6 +10968,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
10939
10968
|
error: result.error || undefined,
|
|
10940
10969
|
};
|
|
10941
10970
|
}
|
|
10971
|
+
if (type === "assert_window_value") {
|
|
10972
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
10973
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
10974
|
+
|| setupHasOwn(action, "expectedValue")
|
|
10975
|
+
|| setupHasOwn(action, "expected")
|
|
10976
|
+
|| setupHasOwn(action, "expect_value")
|
|
10977
|
+
|| setupHasOwn(action, "expectValue")
|
|
10978
|
+
|| setupHasOwn(action, "expect");
|
|
10979
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
10980
|
+
? action.expected_value
|
|
10981
|
+
: setupHasOwn(action, "expectedValue")
|
|
10982
|
+
? action.expectedValue
|
|
10983
|
+
: setupHasOwn(action, "expected")
|
|
10984
|
+
? action.expected
|
|
10985
|
+
: setupHasOwn(action, "expect_value")
|
|
10986
|
+
? action.expect_value
|
|
10987
|
+
: setupHasOwn(action, "expectValue")
|
|
10988
|
+
? action.expectValue
|
|
10989
|
+
: action.expect;
|
|
10990
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
10991
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
10992
|
+
const startedAt = Date.now();
|
|
10993
|
+
let result = null;
|
|
10994
|
+
while (Date.now() - startedAt <= timeout) {
|
|
10995
|
+
result = await setupReadWindowValue(path);
|
|
10996
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
10997
|
+
return {
|
|
10998
|
+
...base,
|
|
10999
|
+
ok: true,
|
|
11000
|
+
path,
|
|
11001
|
+
value: setupJsonValue(result.value),
|
|
11002
|
+
expected_value: setupJsonValue(expected),
|
|
11003
|
+
timeout_ms: timeout,
|
|
11004
|
+
};
|
|
11005
|
+
}
|
|
11006
|
+
await page.waitForTimeout(100);
|
|
11007
|
+
}
|
|
11008
|
+
return {
|
|
11009
|
+
...base,
|
|
11010
|
+
path,
|
|
11011
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
11012
|
+
missing_part: result?.missing_part || undefined,
|
|
11013
|
+
value: setupJsonValue(result?.value),
|
|
11014
|
+
expected_value: setupJsonValue(expected),
|
|
11015
|
+
timeout_ms: timeout,
|
|
11016
|
+
};
|
|
11017
|
+
}
|
|
10942
11018
|
if (type === "click") {
|
|
10943
11019
|
const locator = page.locator(action.selector);
|
|
10944
11020
|
const count = await locator.count();
|
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-4S6RC5IJ.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",
|
|
@@ -291,11 +292,15 @@ function normalizeSetupAction(input, index) {
|
|
|
291
292
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
292
293
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
293
294
|
}
|
|
294
|
-
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath");
|
|
295
|
-
if (type === "window_call" && !path) {
|
|
295
|
+
const path = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
296
|
+
if ((type === "window_call" || type === "assert_window_value") && !path) {
|
|
296
297
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
297
298
|
}
|
|
298
299
|
const args = type === "window_call" ? normalizeSetupActionArgs(input, index) : void 0;
|
|
300
|
+
const hasExpectedValue = hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected") || hasOwn(input, "expect_value") || hasOwn(input, "expectValue") || hasOwn(input, "expect");
|
|
301
|
+
if (type === "assert_window_value" && !hasExpectedValue) {
|
|
302
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires expected_value.`);
|
|
303
|
+
}
|
|
299
304
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
300
305
|
return {
|
|
301
306
|
type,
|
|
@@ -307,6 +312,7 @@ function normalizeSetupAction(input, index) {
|
|
|
307
312
|
path,
|
|
308
313
|
args,
|
|
309
314
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
315
|
+
expected_value: hasExpectedValue ? toJsonValue(valueFromOwn(input, "expected_value", "expectedValue", "expected", "expect_value", "expectValue", "expect")) : void 0,
|
|
310
316
|
text: stringValue(input.text),
|
|
311
317
|
pattern: stringValue(input.pattern),
|
|
312
318
|
flags: stringValue(input.flags),
|
|
@@ -2020,6 +2026,29 @@ function setupJsonValue(value) {
|
|
|
2020
2026
|
function setupValuesEqual(left, right) {
|
|
2021
2027
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
2022
2028
|
}
|
|
2029
|
+
async function setupReadWindowValue(path) {
|
|
2030
|
+
return await page.evaluate(({ path }) => {
|
|
2031
|
+
const toJsonValue = (value) => {
|
|
2032
|
+
if (value === null || value === undefined) return null;
|
|
2033
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
2034
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
2035
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
2036
|
+
if (typeof value === "object") {
|
|
2037
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
2038
|
+
}
|
|
2039
|
+
return String(value);
|
|
2040
|
+
};
|
|
2041
|
+
const pathParts = String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
|
|
2042
|
+
if (!pathParts.length) return { ok: false, reason: "missing_path" };
|
|
2043
|
+
let current = window;
|
|
2044
|
+
for (const part of pathParts) {
|
|
2045
|
+
if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2046
|
+
current = current[part];
|
|
2047
|
+
if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
|
|
2048
|
+
}
|
|
2049
|
+
return { ok: true, value: toJsonValue(current) };
|
|
2050
|
+
}, { path });
|
|
2051
|
+
}
|
|
2023
2052
|
async function setupLocatorText(locator, index) {
|
|
2024
2053
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
2025
2054
|
}
|
|
@@ -2268,6 +2297,53 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2268
2297
|
error: result.error || undefined,
|
|
2269
2298
|
};
|
|
2270
2299
|
}
|
|
2300
|
+
if (type === "assert_window_value") {
|
|
2301
|
+
const path = String(action.path || action.window_path || action.windowPath || "");
|
|
2302
|
+
const hasExpected = setupHasOwn(action, "expected_value")
|
|
2303
|
+
|| setupHasOwn(action, "expectedValue")
|
|
2304
|
+
|| setupHasOwn(action, "expected")
|
|
2305
|
+
|| setupHasOwn(action, "expect_value")
|
|
2306
|
+
|| setupHasOwn(action, "expectValue")
|
|
2307
|
+
|| setupHasOwn(action, "expect");
|
|
2308
|
+
const expected = setupHasOwn(action, "expected_value")
|
|
2309
|
+
? action.expected_value
|
|
2310
|
+
: setupHasOwn(action, "expectedValue")
|
|
2311
|
+
? action.expectedValue
|
|
2312
|
+
: setupHasOwn(action, "expected")
|
|
2313
|
+
? action.expected
|
|
2314
|
+
: setupHasOwn(action, "expect_value")
|
|
2315
|
+
? action.expect_value
|
|
2316
|
+
: setupHasOwn(action, "expectValue")
|
|
2317
|
+
? action.expectValue
|
|
2318
|
+
: action.expect;
|
|
2319
|
+
if (!path) return { ...base, path, reason: "missing_path" };
|
|
2320
|
+
if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
|
|
2321
|
+
const startedAt = Date.now();
|
|
2322
|
+
let result = null;
|
|
2323
|
+
while (Date.now() - startedAt <= timeout) {
|
|
2324
|
+
result = await setupReadWindowValue(path);
|
|
2325
|
+
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
2326
|
+
return {
|
|
2327
|
+
...base,
|
|
2328
|
+
ok: true,
|
|
2329
|
+
path,
|
|
2330
|
+
value: setupJsonValue(result.value),
|
|
2331
|
+
expected_value: setupJsonValue(expected),
|
|
2332
|
+
timeout_ms: timeout,
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
await page.waitForTimeout(100);
|
|
2336
|
+
}
|
|
2337
|
+
return {
|
|
2338
|
+
...base,
|
|
2339
|
+
path,
|
|
2340
|
+
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
2341
|
+
missing_part: result?.missing_part || undefined,
|
|
2342
|
+
value: setupJsonValue(result?.value),
|
|
2343
|
+
expected_value: setupJsonValue(expected),
|
|
2344
|
+
timeout_ms: timeout,
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
2271
2347
|
if (type === "click") {
|
|
2272
2348
|
const locator = page.locator(action.selector);
|
|
2273
2349
|
const count = await locator.count();
|
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;
|
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;
|
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-4S6RC5IJ.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;
|