@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/cli.cjs CHANGED
@@ -7109,6 +7109,11 @@ function normalizeSetupAction(input, index) {
7109
7109
  if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
7110
7110
  const type = normalizeSetupActionType(stringValue2(input.type), index);
7111
7111
  const selector = stringValue2(input.selector);
7112
+ const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
7113
+ const frameIndex = numberValue(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
7114
+ if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
7115
+ throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
7116
+ }
7112
7117
  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) {
7113
7118
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
7114
7119
  }
@@ -7161,6 +7166,8 @@ function normalizeSetupAction(input, index) {
7161
7166
  return {
7162
7167
  type,
7163
7168
  selector,
7169
+ frame_selector: frameSelector,
7170
+ frame_index: frameIndex,
7164
7171
  force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
7165
7172
  key,
7166
7173
  value,
@@ -8047,6 +8054,8 @@ function assessSetupActionsFromEvidence(profile, evidence) {
8047
8054
  viewport: viewport.name,
8048
8055
  action: result.action ?? result.type ?? null,
8049
8056
  selector: result.selector ?? null,
8057
+ frame_selector: result.frame_selector ?? null,
8058
+ frame_index: result.frame_index ?? null,
8050
8059
  reason: result.reason ?? result.error ?? null
8051
8060
  });
8052
8061
  }
@@ -8543,10 +8552,12 @@ function assessProfile(profile, evidence) {
8543
8552
  if (result && result.ok === false) {
8544
8553
  failed.push({
8545
8554
  viewport: viewport.name,
8546
- action: result.action || result.type || null,
8547
- selector: result.selector || null,
8548
- reason: result.reason || result.error || null,
8549
- });
8555
+ action: result.action || result.type || null,
8556
+ selector: result.selector || null,
8557
+ frame_selector: result.frame_selector || null,
8558
+ frame_index: result.frame_index ?? null,
8559
+ reason: result.reason || result.error || null,
8560
+ });
8550
8561
  }
8551
8562
  }
8552
8563
  if (results.length < actionCount && results.every((result) => !result || result.ok !== false)) {
@@ -9009,8 +9020,8 @@ function setupJsonValue(value) {
9009
9020
  function setupValuesEqual(left, right) {
9010
9021
  return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
9011
9022
  }
9012
- async function setupReadWindowValue(path) {
9013
- return await page.evaluate(({ path }) => {
9023
+ async function setupReadWindowValue(context, path) {
9024
+ return await context.evaluate(({ path }) => {
9014
9025
  const toJsonValue = (value) => {
9015
9026
  if (value === null || value === undefined) return null;
9016
9027
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -9032,6 +9043,80 @@ async function setupReadWindowValue(path) {
9032
9043
  return { ok: true, value: toJsonValue(current) };
9033
9044
  }, { path });
9034
9045
  }
9046
+ function setupFrameSelector(action) {
9047
+ return String(action?.frame_selector || action?.frameSelector || action?.iframe_selector || action?.iframeSelector || "").trim();
9048
+ }
9049
+ function setupFrameIndex(action) {
9050
+ const raw = action?.frame_index ?? action?.frameIndex ?? action?.iframe_index ?? action?.iframeIndex ?? 0;
9051
+ const number = Number(raw);
9052
+ return Number.isInteger(number) && number >= 0 ? number : 0;
9053
+ }
9054
+ function setupScopeEvidence(scope) {
9055
+ if (!scope || !scope.frame_selector) return {};
9056
+ return {
9057
+ frame_selector: scope.frame_selector,
9058
+ frame_index: scope.frame_index,
9059
+ frame_count: scope.frame_count,
9060
+ };
9061
+ }
9062
+ function setupScopeFailure(base, scope) {
9063
+ return {
9064
+ ...base,
9065
+ ...setupScopeEvidence(scope),
9066
+ reason: scope?.reason || "frame_scope_unavailable",
9067
+ error: scope?.error || undefined,
9068
+ };
9069
+ }
9070
+ async function setupActionScope(action, timeout) {
9071
+ const frameSelector = setupFrameSelector(action);
9072
+ if (!frameSelector) return { ok: true, context: page };
9073
+ const frameIndex = setupFrameIndex(action);
9074
+ let frameCount = 0;
9075
+ let locator = null;
9076
+ try {
9077
+ await page.waitForSelector(frameSelector, { state: "attached", timeout });
9078
+ locator = page.locator(frameSelector);
9079
+ frameCount = await locator.count();
9080
+ } catch (error) {
9081
+ return {
9082
+ ok: false,
9083
+ reason: "frame_selector_not_found",
9084
+ frame_selector: frameSelector,
9085
+ frame_index: frameIndex,
9086
+ frame_count: frameCount,
9087
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
9088
+ };
9089
+ }
9090
+ if (!frameCount) {
9091
+ return { ok: false, reason: "frame_selector_not_found", frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
9092
+ }
9093
+ if (frameIndex >= frameCount) {
9094
+ return { ok: false, reason: "frame_index_out_of_range", frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
9095
+ }
9096
+ const handle = await locator.nth(frameIndex).elementHandle({ timeout }).catch((error) => ({ __riddle_error: error }));
9097
+ if (!handle || handle.__riddle_error) {
9098
+ return {
9099
+ ok: false,
9100
+ reason: "frame_element_unavailable",
9101
+ frame_selector: frameSelector,
9102
+ frame_index: frameIndex,
9103
+ frame_count: frameCount,
9104
+ error: handle?.__riddle_error ? String(handle.__riddle_error && handle.__riddle_error.message ? handle.__riddle_error.message : handle.__riddle_error).slice(0, 1000) : undefined,
9105
+ };
9106
+ }
9107
+ const frame = typeof handle.contentFrame === "function" ? await handle.contentFrame().catch((error) => ({ __riddle_error: error })) : null;
9108
+ if (!frame || frame.__riddle_error) {
9109
+ return {
9110
+ ok: false,
9111
+ reason: "content_frame_unavailable",
9112
+ frame_selector: frameSelector,
9113
+ frame_index: frameIndex,
9114
+ frame_count: frameCount,
9115
+ error: frame?.__riddle_error ? String(frame.__riddle_error && frame.__riddle_error.message ? frame.__riddle_error.message : frame.__riddle_error).slice(0, 1000) : undefined,
9116
+ };
9117
+ }
9118
+ return { ok: true, context: frame, frame_selector: frameSelector, frame_index: frameIndex, frame_count: frameCount };
9119
+ }
9035
9120
  async function setupLocatorText(locator, index) {
9036
9121
  return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
9037
9122
  }
@@ -9193,7 +9278,8 @@ async function registerNetworkMocks(mocks) {
9193
9278
  }
9194
9279
  async function executeSetupAction(action, ordinal) {
9195
9280
  const type = setupActionType(action);
9196
- const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
9281
+ const frameSelector = setupFrameSelector(action);
9282
+ const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null, frame_selector: frameSelector || null };
9197
9283
  const timeout = setupNumber(action.timeout_ms, 5000);
9198
9284
  try {
9199
9285
  if (type === "wait") {
@@ -9202,51 +9288,65 @@ async function executeSetupAction(action, ordinal) {
9202
9288
  return { ...base, ok: true, ms };
9203
9289
  }
9204
9290
  if (type === "wait_for_selector") {
9205
- await page.waitForSelector(action.selector, { state: "visible", timeout });
9206
- return { ...base, ok: true, timeout_ms: timeout };
9291
+ const scope = await setupActionScope(action, timeout);
9292
+ if (!scope.ok) return setupScopeFailure(base, scope);
9293
+ await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
9294
+ return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
9207
9295
  }
9208
9296
  if (type === "press") {
9209
9297
  const key = String(action.key || "").trim();
9210
9298
  if (!key) return { ...base, reason: "missing_key" };
9299
+ const scope = await setupActionScope(action, timeout);
9300
+ if (!scope.ok) return setupScopeFailure(base, scope);
9211
9301
  if (!action.selector) {
9212
- await page.keyboard.press(key);
9213
- return { ...base, ok: true, key };
9302
+ if (scope.frame_selector) {
9303
+ await scope.context.locator("body").press(key, { timeout });
9304
+ } else {
9305
+ await page.keyboard.press(key);
9306
+ }
9307
+ return { ...base, ...setupScopeEvidence(scope), ok: true, key };
9214
9308
  }
9215
- const locator = page.locator(action.selector);
9309
+ const locator = scope.context.locator(action.selector);
9216
9310
  const count = await locator.count();
9217
9311
  if (!count) return { ...base, reason: "selector_not_found", count, key };
9218
9312
  const targetIndex = Number.isInteger(action.index) ? action.index : 0;
9219
9313
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex, key };
9220
9314
  await locator.nth(targetIndex).press(key, { timeout });
9221
- return { ...base, ok: true, count, target_index: targetIndex, key };
9315
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, key };
9222
9316
  }
9223
9317
  if (type === "local_storage" || type === "session_storage") {
9224
9318
  const value = setupActionValue(action);
9225
- await page.evaluate(({ type, key, value }) => {
9319
+ const scope = await setupActionScope(action, timeout);
9320
+ if (!scope.ok) return setupScopeFailure(base, scope);
9321
+ await scope.context.evaluate(({ type, key, value }) => {
9226
9322
  const storage = type === "session_storage" ? window.sessionStorage : window.localStorage;
9227
9323
  storage.setItem(key, value);
9228
9324
  }, { type, key: action.key, value });
9229
9325
  if (action.reload === true) {
9230
9326
  await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
9231
9327
  }
9232
- return { ...base, ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
9328
+ return { ...base, ...setupScopeEvidence(scope), ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
9233
9329
  }
9234
9330
  if (type === "clear_storage") {
9235
9331
  const storage = action.storage || "both";
9236
- await page.evaluate(({ storage }) => {
9332
+ const scope = await setupActionScope(action, timeout);
9333
+ if (!scope.ok) return setupScopeFailure(base, scope);
9334
+ await scope.context.evaluate(({ storage }) => {
9237
9335
  if (storage === "local" || storage === "both") window.localStorage.clear();
9238
9336
  if (storage === "session" || storage === "both") window.sessionStorage.clear();
9239
9337
  }, { storage });
9240
9338
  if (action.reload === true) {
9241
9339
  await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
9242
9340
  }
9243
- return { ...base, ok: true, storage, reload: action.reload === true };
9341
+ return { ...base, ...setupScopeEvidence(scope), ok: true, storage, reload: action.reload === true };
9244
9342
  }
9245
9343
  if (type === "window_call") {
9246
9344
  const path = String(action.path || action.function_path || action.functionPath || "");
9247
9345
  const args = Array.isArray(action.args) ? action.args : [];
9248
9346
  if (!path) return { ...base, path, reason: "missing_path" };
9249
- const result = await page.evaluate(async ({ path, args }) => {
9347
+ const scope = await setupActionScope(action, timeout);
9348
+ if (!scope.ok) return setupScopeFailure(base, scope);
9349
+ const result = await scope.context.evaluate(async ({ path, args }) => {
9250
9350
  const toJsonValue = (value) => {
9251
9351
  if (value === null || value === undefined) return null;
9252
9352
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -9286,6 +9386,7 @@ async function executeSetupAction(action, ordinal) {
9286
9386
  const expectationMet = !hasExpectation || setupValuesEqual(result.returned, expected);
9287
9387
  return {
9288
9388
  ...base,
9389
+ ...setupScopeEvidence(scope),
9289
9390
  ok: Boolean(result.ok && expectationMet),
9290
9391
  path,
9291
9392
  arg_count: args.length,
@@ -9316,13 +9417,16 @@ async function executeSetupAction(action, ordinal) {
9316
9417
  : action.expect;
9317
9418
  if (!path) return { ...base, path, reason: "missing_path" };
9318
9419
  if (!hasExpected) return { ...base, path, reason: "missing_expected_value" };
9420
+ const scope = await setupActionScope(action, timeout);
9421
+ if (!scope.ok) return setupScopeFailure(base, scope);
9319
9422
  const startedAt = Date.now();
9320
9423
  let result = null;
9321
9424
  while (Date.now() - startedAt <= timeout) {
9322
- result = await setupReadWindowValue(path);
9425
+ result = await setupReadWindowValue(scope.context, path);
9323
9426
  if (result.ok && setupValuesEqual(result.value, expected)) {
9324
9427
  return {
9325
9428
  ...base,
9429
+ ...setupScopeEvidence(scope),
9326
9430
  ok: true,
9327
9431
  path,
9328
9432
  value: setupJsonValue(result.value),
@@ -9334,6 +9438,7 @@ async function executeSetupAction(action, ordinal) {
9334
9438
  }
9335
9439
  return {
9336
9440
  ...base,
9441
+ ...setupScopeEvidence(scope),
9337
9442
  path,
9338
9443
  reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
9339
9444
  missing_part: result?.missing_part || undefined,
@@ -9350,11 +9455,13 @@ async function executeSetupAction(action, ordinal) {
9350
9455
  const hasExpected = expected !== undefined;
9351
9456
  if (!path) return { ...base, path, reason: "missing_path" };
9352
9457
  if (!hasExpected && minValue === undefined && maxValue === undefined) return { ...base, path, reason: "missing_number_expectation" };
9458
+ const scope = await setupActionScope(action, timeout);
9459
+ if (!scope.ok) return setupScopeFailure(base, scope);
9353
9460
  const startedAt = Date.now();
9354
9461
  let result = null;
9355
9462
  let lastReason = "path_not_found";
9356
9463
  while (Date.now() - startedAt <= timeout) {
9357
- result = await setupReadWindowValue(path);
9464
+ result = await setupReadWindowValue(scope.context, path);
9358
9465
  if (result.ok) {
9359
9466
  const actual = setupFiniteNumber(result.value);
9360
9467
  if (actual === undefined) {
@@ -9368,6 +9475,7 @@ async function executeSetupAction(action, ordinal) {
9368
9475
  } else {
9369
9476
  return {
9370
9477
  ...base,
9478
+ ...setupScopeEvidence(scope),
9371
9479
  ok: true,
9372
9480
  path,
9373
9481
  value: actual,
@@ -9384,6 +9492,7 @@ async function executeSetupAction(action, ordinal) {
9384
9492
  }
9385
9493
  return {
9386
9494
  ...base,
9495
+ ...setupScopeEvidence(scope),
9387
9496
  path,
9388
9497
  reason: lastReason,
9389
9498
  missing_part: result?.missing_part || undefined,
@@ -9395,7 +9504,9 @@ async function executeSetupAction(action, ordinal) {
9395
9504
  };
9396
9505
  }
9397
9506
  if (type === "click") {
9398
- const locator = page.locator(action.selector);
9507
+ const scope = await setupActionScope(action, timeout);
9508
+ if (!scope.ok) return setupScopeFailure(base, scope);
9509
+ const locator = scope.context.locator(action.selector);
9399
9510
  const count = await locator.count();
9400
9511
  if (!count) return { ...base, reason: "selector_not_found", count };
9401
9512
  let targetIndex = Number.isInteger(action.index) ? action.index : 0;
@@ -9427,33 +9538,39 @@ async function executeSetupAction(action, ordinal) {
9427
9538
  ? { timeout, noWaitAfter: true, force: true }
9428
9539
  : { timeout, noWaitAfter: true };
9429
9540
  await locator.nth(targetIndex).click(clickOptions);
9430
- return { ...base, ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined };
9541
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined };
9431
9542
  }
9432
9543
  if (type === "fill" || type === "set_input_value") {
9433
- const locator = page.locator(action.selector);
9544
+ const scope = await setupActionScope(action, timeout);
9545
+ if (!scope.ok) return setupScopeFailure(base, scope);
9546
+ const locator = scope.context.locator(action.selector);
9434
9547
  const count = await locator.count();
9435
9548
  if (!count) return { ...base, reason: "selector_not_found", count };
9436
9549
  const targetIndex = Number.isInteger(action.index) ? action.index : 0;
9437
9550
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
9438
9551
  const value = setupActionValue(action);
9439
9552
  await locator.nth(targetIndex).fill(value, { timeout });
9440
- return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
9553
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, value_length: value.length };
9441
9554
  }
9442
9555
  if (type === "assert_selector_count") {
9443
- const locator = page.locator(action.selector);
9556
+ const scope = await setupActionScope(action, timeout);
9557
+ if (!scope.ok) return setupScopeFailure(base, scope);
9558
+ const locator = scope.context.locator(action.selector);
9444
9559
  const expectedCount = setupNumber(action.expected_count, -1);
9445
9560
  if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
9446
9561
  const startedAt = Date.now();
9447
9562
  let count = 0;
9448
9563
  while (Date.now() - startedAt <= timeout) {
9449
9564
  count = await locator.count().catch(() => 0);
9450
- if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
9565
+ if (count === expectedCount) return { ...base, ...setupScopeEvidence(scope), ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
9451
9566
  await page.waitForTimeout(100);
9452
9567
  }
9453
- return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
9568
+ return { ...base, ...setupScopeEvidence(scope), reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
9454
9569
  }
9455
9570
  if (type === "wait_for_text") {
9456
- const locator = page.locator(action.selector);
9571
+ const scope = await setupActionScope(action, timeout);
9572
+ if (!scope.ok) return setupScopeFailure(base, scope);
9573
+ const locator = scope.context.locator(action.selector);
9457
9574
  const startedAt = Date.now();
9458
9575
  let lastText = "";
9459
9576
  while (Date.now() - startedAt <= timeout) {
@@ -9462,15 +9579,17 @@ async function executeSetupAction(action, ordinal) {
9462
9579
  const text = await setupLocatorText(locator, index);
9463
9580
  lastText = text || lastText;
9464
9581
  if (setupTextMatches(text, action)) {
9465
- return { ...base, ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
9582
+ return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
9466
9583
  }
9467
9584
  }
9468
9585
  await page.waitForTimeout(100);
9469
9586
  }
9470
- return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9587
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9471
9588
  }
9472
9589
  if (type === "assert_text_visible" || type === "assert_text_absent") {
9473
- const locator = page.locator(action.selector);
9590
+ const scope = await setupActionScope(action, timeout);
9591
+ if (!scope.ok) return setupScopeFailure(base, scope);
9592
+ const locator = scope.context.locator(action.selector);
9474
9593
  const startedAt = Date.now();
9475
9594
  let lastText = "";
9476
9595
  let matchedText = "";
@@ -9489,7 +9608,7 @@ async function executeSetupAction(action, ordinal) {
9489
9608
  if (type === "assert_text_visible") {
9490
9609
  const visible = await setupLocatorVisible(locator, index);
9491
9610
  if (visible) {
9492
- return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
9611
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
9493
9612
  }
9494
9613
  hiddenMatch = true;
9495
9614
  break;
@@ -9498,17 +9617,17 @@ async function executeSetupAction(action, ordinal) {
9498
9617
  }
9499
9618
  }
9500
9619
  if (type === "assert_text_absent" && !matched) {
9501
- return { ...base, ok: true, count, timeout_ms: timeout };
9620
+ return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
9502
9621
  }
9503
9622
  await page.waitForTimeout(100);
9504
9623
  }
9505
9624
  if (type === "assert_text_visible") {
9506
9625
  if (hiddenMatch) {
9507
- return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
9626
+ return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
9508
9627
  }
9509
- return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9628
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9510
9629
  }
9511
- return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
9630
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
9512
9631
  }
9513
9632
  return { ...base, reason: "unsupported_action" };
9514
9633
  } catch (error) {
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-7ZBK2GQX.js";
13
+ } from "./chunk-Q5VW6MAP.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport