@riddledc/riddle-proof 0.7.58 → 0.7.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -8950,6 +8950,11 @@ function normalizeSetupAction(input, index) {
8950
8950
  if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
8951
8951
  const type = normalizeSetupActionType(stringValue5(input.type), index);
8952
8952
  const selector = stringValue5(input.selector);
8953
+ const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
8954
+ const frameIndex = numberValue3(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
8955
+ if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
8956
+ throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
8957
+ }
8953
8958
  if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
8954
8959
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
8955
8960
  }
@@ -9002,6 +9007,8 @@ function normalizeSetupAction(input, index) {
9002
9007
  return {
9003
9008
  type,
9004
9009
  selector,
9010
+ frame_selector: frameSelector,
9011
+ frame_index: frameIndex,
9005
9012
  force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
9006
9013
  key,
9007
9014
  value,
@@ -9888,6 +9895,8 @@ function assessSetupActionsFromEvidence(profile, evidence) {
9888
9895
  viewport: viewport.name,
9889
9896
  action: result.action ?? result.type ?? null,
9890
9897
  selector: result.selector ?? null,
9898
+ frame_selector: result.frame_selector ?? null,
9899
+ frame_index: result.frame_index ?? null,
9891
9900
  reason: result.reason ?? result.error ?? null
9892
9901
  });
9893
9902
  }
@@ -10400,10 +10409,12 @@ function assessProfile(profile, evidence) {
10400
10409
  if (result && result.ok === false) {
10401
10410
  failed.push({
10402
10411
  viewport: viewport.name,
10403
- action: result.action || result.type || null,
10404
- selector: result.selector || null,
10405
- reason: result.reason || result.error || null,
10406
- });
10412
+ action: result.action || result.type || null,
10413
+ selector: result.selector || null,
10414
+ frame_selector: result.frame_selector || null,
10415
+ frame_index: result.frame_index ?? null,
10416
+ reason: result.reason || result.error || null,
10417
+ });
10407
10418
  }
10408
10419
  }
10409
10420
  if (results.length < actionCount && results.every((result) => !result || result.ok !== false)) {
@@ -10866,8 +10877,8 @@ function setupJsonValue(value) {
10866
10877
  function setupValuesEqual(left, right) {
10867
10878
  return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
10868
10879
  }
10869
- async function setupReadWindowValue(path) {
10870
- return await page.evaluate(({ path }) => {
10880
+ async function setupReadWindowValue(context, path) {
10881
+ return await context.evaluate(({ path }) => {
10871
10882
  const toJsonValue = (value) => {
10872
10883
  if (value === null || value === undefined) return null;
10873
10884
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -10889,6 +10900,80 @@ async function setupReadWindowValue(path) {
10889
10900
  return { ok: true, value: toJsonValue(current) };
10890
10901
  }, { path });
10891
10902
  }
10903
+ function setupFrameSelector(action) {
10904
+ return String(action?.frame_selector || action?.frameSelector || action?.iframe_selector || action?.iframeSelector || "").trim();
10905
+ }
10906
+ function setupFrameIndex(action) {
10907
+ const raw = action?.frame_index ?? action?.frameIndex ?? action?.iframe_index ?? action?.iframeIndex ?? 0;
10908
+ const number = Number(raw);
10909
+ return Number.isInteger(number) && number >= 0 ? number : 0;
10910
+ }
10911
+ function setupScopeEvidence(scope) {
10912
+ if (!scope || !scope.frame_selector) return {};
10913
+ return {
10914
+ frame_selector: scope.frame_selector,
10915
+ frame_index: scope.frame_index,
10916
+ frame_count: scope.frame_count,
10917
+ };
10918
+ }
10919
+ function setupScopeFailure(base, scope) {
10920
+ return {
10921
+ ...base,
10922
+ ...setupScopeEvidence(scope),
10923
+ reason: scope?.reason || "frame_scope_unavailable",
10924
+ error: scope?.error || undefined,
10925
+ };
10926
+ }
10927
+ async function setupActionScope(action, timeout) {
10928
+ const frameSelector = setupFrameSelector(action);
10929
+ if (!frameSelector) return { ok: true, context: page };
10930
+ const frameIndex = setupFrameIndex(action);
10931
+ let frameCount = 0;
10932
+ let locator = null;
10933
+ try {
10934
+ await page.waitForSelector(frameSelector, { state: "attached", timeout });
10935
+ locator = page.locator(frameSelector);
10936
+ frameCount = await locator.count();
10937
+ } catch (error) {
10938
+ return {
10939
+ ok: false,
10940
+ reason: "frame_selector_not_found",
10941
+ frame_selector: frameSelector,
10942
+ frame_index: frameIndex,
10943
+ frame_count: frameCount,
10944
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
10945
+ };
10946
+ }
10947
+ if (!frameCount) {
10948
+ return { ok: false, reason: "frame_selector_not_found", frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
10949
+ }
10950
+ if (frameIndex >= frameCount) {
10951
+ return { ok: false, reason: "frame_index_out_of_range", frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
10952
+ }
10953
+ const handle = await locator.nth(frameIndex).elementHandle({ timeout }).catch((error) => ({ __riddle_error: error }));
10954
+ if (!handle || handle.__riddle_error) {
10955
+ return {
10956
+ ok: false,
10957
+ reason: "frame_element_unavailable",
10958
+ frame_selector: frameSelector,
10959
+ frame_index: frameIndex,
10960
+ frame_count: frameCount,
10961
+ error: handle?.__riddle_error ? String(handle.__riddle_error && handle.__riddle_error.message ? handle.__riddle_error.message : handle.__riddle_error).slice(0, 1000) : undefined,
10962
+ };
10963
+ }
10964
+ const frame = typeof handle.contentFrame === "function" ? await handle.contentFrame().catch((error) => ({ __riddle_error: error })) : null;
10965
+ if (!frame || frame.__riddle_error) {
10966
+ return {
10967
+ ok: false,
10968
+ reason: "content_frame_unavailable",
10969
+ frame_selector: frameSelector,
10970
+ frame_index: frameIndex,
10971
+ frame_count: frameCount,
10972
+ error: frame?.__riddle_error ? String(frame.__riddle_error && frame.__riddle_error.message ? frame.__riddle_error.message : frame.__riddle_error).slice(0, 1000) : undefined,
10973
+ };
10974
+ }
10975
+ return { ok: true, context: frame, frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
10976
+ }
10892
10977
  async function setupLocatorText(locator, index) {
10893
10978
  return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
10894
10979
  }
@@ -11050,7 +11135,8 @@ async function registerNetworkMocks(mocks) {
11050
11135
  }
11051
11136
  async function executeSetupAction(action, ordinal) {
11052
11137
  const type = setupActionType(action);
11053
- const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
11138
+ const frameSelector = setupFrameSelector(action);
11139
+ const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null, frame_selector: frameSelector || null };
11054
11140
  const timeout = setupNumber(action.timeout_ms, 5000);
11055
11141
  try {
11056
11142
  if (type === "wait") {
@@ -11059,51 +11145,65 @@ async function executeSetupAction(action, ordinal) {
11059
11145
  return { ...base, ok: true, ms };
11060
11146
  }
11061
11147
  if (type === "wait_for_selector") {
11062
- await page.waitForSelector(action.selector, { state: "visible", timeout });
11063
- return { ...base, ok: true, timeout_ms: timeout };
11148
+ const scope = await setupActionScope(action, timeout);
11149
+ if (!scope.ok) return setupScopeFailure(base, scope);
11150
+ await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
11151
+ return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
11064
11152
  }
11065
11153
  if (type === "press") {
11066
11154
  const key = String(action.key || "").trim();
11067
11155
  if (!key) return { ...base, reason: "missing_key" };
11156
+ const scope = await setupActionScope(action, timeout);
11157
+ if (!scope.ok) return setupScopeFailure(base, scope);
11068
11158
  if (!action.selector) {
11069
- await page.keyboard.press(key);
11070
- return { ...base, ok: true, key };
11159
+ if (scope.frame_selector) {
11160
+ await scope.context.locator("body").press(key, { timeout });
11161
+ } else {
11162
+ await page.keyboard.press(key);
11163
+ }
11164
+ return { ...base, ...setupScopeEvidence(scope), ok: true, key };
11071
11165
  }
11072
- const locator = page.locator(action.selector);
11166
+ const locator = scope.context.locator(action.selector);
11073
11167
  const count = await locator.count();
11074
11168
  if (!count) return { ...base, reason: "selector_not_found", count, key };
11075
11169
  const targetIndex = Number.isInteger(action.index) ? action.index : 0;
11076
11170
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex, key };
11077
11171
  await locator.nth(targetIndex).press(key, { timeout });
11078
- return { ...base, ok: true, count, target_index: targetIndex, key };
11172
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, key };
11079
11173
  }
11080
11174
  if (type === "local_storage" || type === "session_storage") {
11081
11175
  const value = setupActionValue(action);
11082
- await page.evaluate(({ type, key, value }) => {
11176
+ const scope = await setupActionScope(action, timeout);
11177
+ if (!scope.ok) return setupScopeFailure(base, scope);
11178
+ await scope.context.evaluate(({ type, key, value }) => {
11083
11179
  const storage = type === "session_storage" ? window.sessionStorage : window.localStorage;
11084
11180
  storage.setItem(key, value);
11085
11181
  }, { type, key: action.key, value });
11086
11182
  if (action.reload === true) {
11087
11183
  await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
11088
11184
  }
11089
- return { ...base, ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
11185
+ return { ...base, ...setupScopeEvidence(scope), ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
11090
11186
  }
11091
11187
  if (type === "clear_storage") {
11092
11188
  const storage = action.storage || "both";
11093
- await page.evaluate(({ storage }) => {
11189
+ const scope = await setupActionScope(action, timeout);
11190
+ if (!scope.ok) return setupScopeFailure(base, scope);
11191
+ await scope.context.evaluate(({ storage }) => {
11094
11192
  if (storage === "local" || storage === "both") window.localStorage.clear();
11095
11193
  if (storage === "session" || storage === "both") window.sessionStorage.clear();
11096
11194
  }, { storage });
11097
11195
  if (action.reload === true) {
11098
11196
  await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
11099
11197
  }
11100
- return { ...base, ok: true, storage, reload: action.reload === true };
11198
+ return { ...base, ...setupScopeEvidence(scope), ok: true, storage, reload: action.reload === true };
11101
11199
  }
11102
11200
  if (type === "window_call") {
11103
11201
  const path = String(action.path || action.function_path || action.functionPath || "");
11104
11202
  const args = Array.isArray(action.args) ? action.args : [];
11105
11203
  if (!path) return { ...base, path, reason: "missing_path" };
11106
- const result = await page.evaluate(async ({ path, args }) => {
11204
+ const scope = await setupActionScope(action, timeout);
11205
+ if (!scope.ok) return setupScopeFailure(base, scope);
11206
+ const result = await scope.context.evaluate(async ({ path, args }) => {
11107
11207
  const toJsonValue = (value) => {
11108
11208
  if (value === null || value === undefined) return null;
11109
11209
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -11143,6 +11243,7 @@ async function executeSetupAction(action, ordinal) {
11143
11243
  const expectationMet = !hasExpectation || setupValuesEqual(result.returned, expected);
11144
11244
  return {
11145
11245
  ...base,
11246
+ ...setupScopeEvidence(scope),
11146
11247
  ok: Boolean(result.ok && expectationMet),
11147
11248
  path,
11148
11249
  arg_count: args.length,
@@ -11173,13 +11274,16 @@ async function executeSetupAction(action, ordinal) {
11173
11274
  : action.expect;
11174
11275
  if (!path) return { ...base, path, reason: "missing_path" };
11175
11276
  if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
11277
+ const scope = await setupActionScope(action, timeout);
11278
+ if (!scope.ok) return setupScopeFailure(base, scope);
11176
11279
  const startedAt = Date.now();
11177
11280
  let result = null;
11178
11281
  while (Date.now() - startedAt <= timeout) {
11179
- result = await setupReadWindowValue(path);
11282
+ result = await setupReadWindowValue(scope.context, path);
11180
11283
  if (result.ok && setupValuesEqual(result.value, expected)) {
11181
11284
  return {
11182
11285
  ...base,
11286
+ ...setupScopeEvidence(scope),
11183
11287
  ok: true,
11184
11288
  path,
11185
11289
  value: setupJsonValue(result.value),
@@ -11191,6 +11295,7 @@ async function executeSetupAction(action, ordinal) {
11191
11295
  }
11192
11296
  return {
11193
11297
  ...base,
11298
+ ...setupScopeEvidence(scope),
11194
11299
  path,
11195
11300
  reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
11196
11301
  missing_part: result?.missing_part || undefined,
@@ -11207,11 +11312,13 @@ async function executeSetupAction(action, ordinal) {
11207
11312
  const hasExpected = expected !== undefined;
11208
11313
  if (!path) return { ...base, path, reason: "missing_path" };
11209
11314
  if (!hasExpected && minValue === undefined && maxValue === undefined) return { ...base, path, reason: "missing_number_expectation" };
11315
+ const scope = await setupActionScope(action, timeout);
11316
+ if (!scope.ok) return setupScopeFailure(base, scope);
11210
11317
  const startedAt = Date.now();
11211
11318
  let result = null;
11212
11319
  let lastReason = "path_not_found";
11213
11320
  while (Date.now() - startedAt <= timeout) {
11214
- result = await setupReadWindowValue(path);
11321
+ result = await setupReadWindowValue(scope.context, path);
11215
11322
  if (result.ok) {
11216
11323
  const actual = setupFiniteNumber(result.value);
11217
11324
  if (actual === undefined) {
@@ -11225,6 +11332,7 @@ async function executeSetupAction(action, ordinal) {
11225
11332
  } else {
11226
11333
  return {
11227
11334
  ...base,
11335
+ ...setupScopeEvidence(scope),
11228
11336
  ok: true,
11229
11337
  path,
11230
11338
  value: actual,
@@ -11241,6 +11349,7 @@ async function executeSetupAction(action, ordinal) {
11241
11349
  }
11242
11350
  return {
11243
11351
  ...base,
11352
+ ...setupScopeEvidence(scope),
11244
11353
  path,
11245
11354
  reason: lastReason,
11246
11355
  missing_part: result?.missing_part || undefined,
@@ -11252,7 +11361,9 @@ async function executeSetupAction(action, ordinal) {
11252
11361
  };
11253
11362
  }
11254
11363
  if (type === "click") {
11255
- const locator = page.locator(action.selector);
11364
+ const scope = await setupActionScope(action, timeout);
11365
+ if (!scope.ok) return setupScopeFailure(base, scope);
11366
+ const locator = scope.context.locator(action.selector);
11256
11367
  const count = await locator.count();
11257
11368
  if (!count) return { ...base, reason: "selector_not_found", count };
11258
11369
  let targetIndex = Number.isInteger(action.index) ? action.index : 0;
@@ -11284,33 +11395,39 @@ async function executeSetupAction(action, ordinal) {
11284
11395
  ? { timeout, noWaitAfter: true, force: true }
11285
11396
  : { timeout, noWaitAfter: true };
11286
11397
  await locator.nth(targetIndex).click(clickOptions);
11287
- return { ...base, ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined };
11398
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined };
11288
11399
  }
11289
11400
  if (type === "fill" || type === "set_input_value") {
11290
- const locator = page.locator(action.selector);
11401
+ const scope = await setupActionScope(action, timeout);
11402
+ if (!scope.ok) return setupScopeFailure(base, scope);
11403
+ const locator = scope.context.locator(action.selector);
11291
11404
  const count = await locator.count();
11292
11405
  if (!count) return { ...base, reason: "selector_not_found", count };
11293
11406
  const targetIndex = Number.isInteger(action.index) ? action.index : 0;
11294
11407
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
11295
11408
  const value = setupActionValue(action);
11296
11409
  await locator.nth(targetIndex).fill(value, { timeout });
11297
- return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
11410
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, value_length: value.length };
11298
11411
  }
11299
11412
  if (type === "assert_selector_count") {
11300
- const locator = page.locator(action.selector);
11413
+ const scope = await setupActionScope(action, timeout);
11414
+ if (!scope.ok) return setupScopeFailure(base, scope);
11415
+ const locator = scope.context.locator(action.selector);
11301
11416
  const expectedCount = setupNumber(action.expected_count, -1);
11302
11417
  if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
11303
11418
  const startedAt = Date.now();
11304
11419
  let count = 0;
11305
11420
  while (Date.now() - startedAt <= timeout) {
11306
11421
  count = await locator.count().catch(() => 0);
11307
- if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
11422
+ if (count === expectedCount) return { ...base, ...setupScopeEvidence(scope), ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
11308
11423
  await page.waitForTimeout(100);
11309
11424
  }
11310
- return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
11425
+ return { ...base, ...setupScopeEvidence(scope), reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
11311
11426
  }
11312
11427
  if (type === "wait_for_text") {
11313
- const locator = page.locator(action.selector);
11428
+ const scope = await setupActionScope(action, timeout);
11429
+ if (!scope.ok) return setupScopeFailure(base, scope);
11430
+ const locator = scope.context.locator(action.selector);
11314
11431
  const startedAt = Date.now();
11315
11432
  let lastText = "";
11316
11433
  while (Date.now() - startedAt <= timeout) {
@@ -11319,15 +11436,17 @@ async function executeSetupAction(action, ordinal) {
11319
11436
  const text = await setupLocatorText(locator, index);
11320
11437
  lastText = text || lastText;
11321
11438
  if (setupTextMatches(text, action)) {
11322
- return { ...base, ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
11439
+ return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
11323
11440
  }
11324
11441
  }
11325
11442
  await page.waitForTimeout(100);
11326
11443
  }
11327
- return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
11444
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
11328
11445
  }
11329
11446
  if (type === "assert_text_visible" || type === "assert_text_absent") {
11330
- const locator = page.locator(action.selector);
11447
+ const scope = await setupActionScope(action, timeout);
11448
+ if (!scope.ok) return setupScopeFailure(base, scope);
11449
+ const locator = scope.context.locator(action.selector);
11331
11450
  const startedAt = Date.now();
11332
11451
  let lastText = "";
11333
11452
  let matchedText = "";
@@ -11346,7 +11465,7 @@ async function executeSetupAction(action, ordinal) {
11346
11465
  if (type === "assert_text_visible") {
11347
11466
  const visible = await setupLocatorVisible(locator, index);
11348
11467
  if (visible) {
11349
- return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
11468
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
11350
11469
  }
11351
11470
  hiddenMatch = true;
11352
11471
  break;
@@ -11355,17 +11474,17 @@ async function executeSetupAction(action, ordinal) {
11355
11474
  }
11356
11475
  }
11357
11476
  if (type === "assert_text_absent" && !matched) {
11358
- return { ...base, ok: true, count, timeout_ms: timeout };
11477
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
11359
11478
  }
11360
11479
  await page.waitForTimeout(100);
11361
11480
  }
11362
11481
  if (type === "assert_text_visible") {
11363
11482
  if (hiddenMatch) {
11364
- return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
11483
+ return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
11365
11484
  }
11366
- return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
11485
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
11367
11486
  }
11368
- return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
11487
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
11369
11488
  }
11370
11489
  return { ...base, reason: "unsupported_action" };
11371
11490
  } catch (error) {
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-7ZBK2GQX.js";
61
+ } from "./chunk-Q5VW6MAP.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,