@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 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`, `local_storage`,
242
- `session_storage`, `clear_storage`, `wait`, `wait_for_selector`,
243
- `wait_for_text`, and `window_call`; a failed setup action is recorded as a failed
244
- `setup_actions_succeeded` check so the profile cannot pass without reaching
245
- the intended state. Text-matched `click` actions prefer visible matching
246
- elements, which keeps responsive layouts from selecting hidden desktop or
247
- mobile-only links. Add `force: true` to a click action only when the matched
248
- visible element is intentionally animated or otherwise never becomes stable
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, or exactly
252
- one source link must exist before clicking into the final route.
253
- `assert_selector_count` accepts `expected_count`.
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
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-ZC4C52ZC.js";
13
+ } from "./chunk-4S6RC5IJ.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
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-ZC4C52ZC.js";
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();
@@ -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-ZC4C52ZC.js";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.51",
3
+ "version": "0.7.52",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",