@riddledc/riddle-proof 0.7.57 → 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/README.md +13 -3
- package/dist/{chunk-H5LDZKGN.js → chunk-Q5VW6MAP.js} +171 -33
- package/dist/cli.cjs +171 -33
- package/dist/cli.js +1 -1
- package/dist/index.cjs +171 -33
- package/dist/index.js +1 -1
- package/dist/profile.cjs +171 -33
- package/dist/profile.d.cts +3 -1
- package/dist/profile.d.ts +3 -1
- package/dist/profile.js +1 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6905,6 +6905,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
6905
6905
|
];
|
|
6906
6906
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
6907
6907
|
"click",
|
|
6908
|
+
"press",
|
|
6908
6909
|
"fill",
|
|
6909
6910
|
"set_input_value",
|
|
6910
6911
|
"assert_text_visible",
|
|
@@ -7074,7 +7075,7 @@ function isSupportedCheckType(value) {
|
|
|
7074
7075
|
}
|
|
7075
7076
|
function normalizeSetupActionType(value, index) {
|
|
7076
7077
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
7077
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput;
|
|
7078
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
7078
7079
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
7079
7080
|
return normalized;
|
|
7080
7081
|
}
|
|
@@ -7108,6 +7109,11 @@ function normalizeSetupAction(input, index) {
|
|
|
7108
7109
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
7109
7110
|
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
7110
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
|
+
}
|
|
7111
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) {
|
|
7112
7118
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
7113
7119
|
}
|
|
@@ -7127,6 +7133,9 @@ function normalizeSetupAction(input, index) {
|
|
|
7127
7133
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
7128
7134
|
}
|
|
7129
7135
|
const key = stringValue2(input.key);
|
|
7136
|
+
if (type === "press" && !key) {
|
|
7137
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
7138
|
+
}
|
|
7130
7139
|
if ((type === "local_storage" || type === "session_storage") && !key) {
|
|
7131
7140
|
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
7132
7141
|
}
|
|
@@ -7157,6 +7166,8 @@ function normalizeSetupAction(input, index) {
|
|
|
7157
7166
|
return {
|
|
7158
7167
|
type,
|
|
7159
7168
|
selector,
|
|
7169
|
+
frame_selector: frameSelector,
|
|
7170
|
+
frame_index: frameIndex,
|
|
7160
7171
|
force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
|
|
7161
7172
|
key,
|
|
7162
7173
|
value,
|
|
@@ -8043,6 +8054,8 @@ function assessSetupActionsFromEvidence(profile, evidence) {
|
|
|
8043
8054
|
viewport: viewport.name,
|
|
8044
8055
|
action: result.action ?? result.type ?? null,
|
|
8045
8056
|
selector: result.selector ?? null,
|
|
8057
|
+
frame_selector: result.frame_selector ?? null,
|
|
8058
|
+
frame_index: result.frame_index ?? null,
|
|
8046
8059
|
reason: result.reason ?? result.error ?? null
|
|
8047
8060
|
});
|
|
8048
8061
|
}
|
|
@@ -8539,10 +8552,12 @@ function assessProfile(profile, evidence) {
|
|
|
8539
8552
|
if (result && result.ok === false) {
|
|
8540
8553
|
failed.push({
|
|
8541
8554
|
viewport: viewport.name,
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
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
|
+
});
|
|
8546
8561
|
}
|
|
8547
8562
|
}
|
|
8548
8563
|
if (results.length < actionCount && results.every((result) => !result || result.ok !== false)) {
|
|
@@ -9005,8 +9020,8 @@ function setupJsonValue(value) {
|
|
|
9005
9020
|
function setupValuesEqual(left, right) {
|
|
9006
9021
|
return JSON.stringify(setupJsonValue(left)) === JSON.stringify(setupJsonValue(right));
|
|
9007
9022
|
}
|
|
9008
|
-
async function setupReadWindowValue(path) {
|
|
9009
|
-
return await
|
|
9023
|
+
async function setupReadWindowValue(context, path) {
|
|
9024
|
+
return await context.evaluate(({ path }) => {
|
|
9010
9025
|
const toJsonValue = (value) => {
|
|
9011
9026
|
if (value === null || value === undefined) return null;
|
|
9012
9027
|
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
@@ -9028,6 +9043,80 @@ async function setupReadWindowValue(path) {
|
|
|
9028
9043
|
return { ok: true, value: toJsonValue(current) };
|
|
9029
9044
|
}, { path });
|
|
9030
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
|
+
}
|
|
9031
9120
|
async function setupLocatorText(locator, index) {
|
|
9032
9121
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
9033
9122
|
}
|
|
@@ -9189,7 +9278,8 @@ async function registerNetworkMocks(mocks) {
|
|
|
9189
9278
|
}
|
|
9190
9279
|
async function executeSetupAction(action, ordinal) {
|
|
9191
9280
|
const type = setupActionType(action);
|
|
9192
|
-
const
|
|
9281
|
+
const frameSelector = setupFrameSelector(action);
|
|
9282
|
+
const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null, frame_selector: frameSelector || null };
|
|
9193
9283
|
const timeout = setupNumber(action.timeout_ms, 5000);
|
|
9194
9284
|
try {
|
|
9195
9285
|
if (type === "wait") {
|
|
@@ -9198,36 +9288,65 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9198
9288
|
return { ...base, ok: true, ms };
|
|
9199
9289
|
}
|
|
9200
9290
|
if (type === "wait_for_selector") {
|
|
9201
|
-
await
|
|
9202
|
-
return
|
|
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 };
|
|
9295
|
+
}
|
|
9296
|
+
if (type === "press") {
|
|
9297
|
+
const key = String(action.key || "").trim();
|
|
9298
|
+
if (!key) return { ...base, reason: "missing_key" };
|
|
9299
|
+
const scope = await setupActionScope(action, timeout);
|
|
9300
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9301
|
+
if (!action.selector) {
|
|
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 };
|
|
9308
|
+
}
|
|
9309
|
+
const locator = scope.context.locator(action.selector);
|
|
9310
|
+
const count = await locator.count();
|
|
9311
|
+
if (!count) return { ...base, reason: "selector_not_found", count, key };
|
|
9312
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
9313
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex, key };
|
|
9314
|
+
await locator.nth(targetIndex).press(key, { timeout });
|
|
9315
|
+
return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, key };
|
|
9203
9316
|
}
|
|
9204
9317
|
if (type === "local_storage" || type === "session_storage") {
|
|
9205
9318
|
const value = setupActionValue(action);
|
|
9206
|
-
await
|
|
9319
|
+
const scope = await setupActionScope(action, timeout);
|
|
9320
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9321
|
+
await scope.context.evaluate(({ type, key, value }) => {
|
|
9207
9322
|
const storage = type === "session_storage" ? window.sessionStorage : window.localStorage;
|
|
9208
9323
|
storage.setItem(key, value);
|
|
9209
9324
|
}, { type, key: action.key, value });
|
|
9210
9325
|
if (action.reload === true) {
|
|
9211
9326
|
await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
|
|
9212
9327
|
}
|
|
9213
|
-
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 };
|
|
9214
9329
|
}
|
|
9215
9330
|
if (type === "clear_storage") {
|
|
9216
9331
|
const storage = action.storage || "both";
|
|
9217
|
-
await
|
|
9332
|
+
const scope = await setupActionScope(action, timeout);
|
|
9333
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9334
|
+
await scope.context.evaluate(({ storage }) => {
|
|
9218
9335
|
if (storage === "local" || storage === "both") window.localStorage.clear();
|
|
9219
9336
|
if (storage === "session" || storage === "both") window.sessionStorage.clear();
|
|
9220
9337
|
}, { storage });
|
|
9221
9338
|
if (action.reload === true) {
|
|
9222
9339
|
await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
|
|
9223
9340
|
}
|
|
9224
|
-
return { ...base, ok: true, storage, reload: action.reload === true };
|
|
9341
|
+
return { ...base, ...setupScopeEvidence(scope), ok: true, storage, reload: action.reload === true };
|
|
9225
9342
|
}
|
|
9226
9343
|
if (type === "window_call") {
|
|
9227
9344
|
const path = String(action.path || action.function_path || action.functionPath || "");
|
|
9228
9345
|
const args = Array.isArray(action.args) ? action.args : [];
|
|
9229
9346
|
if (!path) return { ...base, path, reason: "missing_path" };
|
|
9230
|
-
const
|
|
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 }) => {
|
|
9231
9350
|
const toJsonValue = (value) => {
|
|
9232
9351
|
if (value === null || value === undefined) return null;
|
|
9233
9352
|
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
@@ -9267,6 +9386,7 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9267
9386
|
const expectationMet = !hasExpectation || setupValuesEqual(result.returned, expected);
|
|
9268
9387
|
return {
|
|
9269
9388
|
...base,
|
|
9389
|
+
...setupScopeEvidence(scope),
|
|
9270
9390
|
ok: Boolean(result.ok && expectationMet),
|
|
9271
9391
|
path,
|
|
9272
9392
|
arg_count: args.length,
|
|
@@ -9297,13 +9417,16 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9297
9417
|
: action.expect;
|
|
9298
9418
|
if (!path) return { ...base, path, reason: "missing_path" };
|
|
9299
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);
|
|
9300
9422
|
const startedAt = Date.now();
|
|
9301
9423
|
let result = null;
|
|
9302
9424
|
while (Date.now() - startedAt <= timeout) {
|
|
9303
|
-
result = await setupReadWindowValue(path);
|
|
9425
|
+
result = await setupReadWindowValue(scope.context, path);
|
|
9304
9426
|
if (result.ok && setupValuesEqual(result.value, expected)) {
|
|
9305
9427
|
return {
|
|
9306
9428
|
...base,
|
|
9429
|
+
...setupScopeEvidence(scope),
|
|
9307
9430
|
ok: true,
|
|
9308
9431
|
path,
|
|
9309
9432
|
value: setupJsonValue(result.value),
|
|
@@ -9315,6 +9438,7 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9315
9438
|
}
|
|
9316
9439
|
return {
|
|
9317
9440
|
...base,
|
|
9441
|
+
...setupScopeEvidence(scope),
|
|
9318
9442
|
path,
|
|
9319
9443
|
reason: result?.ok ? "unexpected_value" : result?.reason || "path_not_found",
|
|
9320
9444
|
missing_part: result?.missing_part || undefined,
|
|
@@ -9331,11 +9455,13 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9331
9455
|
const hasExpected = expected !== undefined;
|
|
9332
9456
|
if (!path) return { ...base, path, reason: "missing_path" };
|
|
9333
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);
|
|
9334
9460
|
const startedAt = Date.now();
|
|
9335
9461
|
let result = null;
|
|
9336
9462
|
let lastReason = "path_not_found";
|
|
9337
9463
|
while (Date.now() - startedAt <= timeout) {
|
|
9338
|
-
result = await setupReadWindowValue(path);
|
|
9464
|
+
result = await setupReadWindowValue(scope.context, path);
|
|
9339
9465
|
if (result.ok) {
|
|
9340
9466
|
const actual = setupFiniteNumber(result.value);
|
|
9341
9467
|
if (actual === undefined) {
|
|
@@ -9349,6 +9475,7 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9349
9475
|
} else {
|
|
9350
9476
|
return {
|
|
9351
9477
|
...base,
|
|
9478
|
+
...setupScopeEvidence(scope),
|
|
9352
9479
|
ok: true,
|
|
9353
9480
|
path,
|
|
9354
9481
|
value: actual,
|
|
@@ -9365,6 +9492,7 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9365
9492
|
}
|
|
9366
9493
|
return {
|
|
9367
9494
|
...base,
|
|
9495
|
+
...setupScopeEvidence(scope),
|
|
9368
9496
|
path,
|
|
9369
9497
|
reason: lastReason,
|
|
9370
9498
|
missing_part: result?.missing_part || undefined,
|
|
@@ -9376,7 +9504,9 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9376
9504
|
};
|
|
9377
9505
|
}
|
|
9378
9506
|
if (type === "click") {
|
|
9379
|
-
const
|
|
9507
|
+
const scope = await setupActionScope(action, timeout);
|
|
9508
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9509
|
+
const locator = scope.context.locator(action.selector);
|
|
9380
9510
|
const count = await locator.count();
|
|
9381
9511
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
9382
9512
|
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
@@ -9408,33 +9538,39 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9408
9538
|
? { timeout, noWaitAfter: true, force: true }
|
|
9409
9539
|
: { timeout, noWaitAfter: true };
|
|
9410
9540
|
await locator.nth(targetIndex).click(clickOptions);
|
|
9411
|
-
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 };
|
|
9412
9542
|
}
|
|
9413
9543
|
if (type === "fill" || type === "set_input_value") {
|
|
9414
|
-
const
|
|
9544
|
+
const scope = await setupActionScope(action, timeout);
|
|
9545
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9546
|
+
const locator = scope.context.locator(action.selector);
|
|
9415
9547
|
const count = await locator.count();
|
|
9416
9548
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
9417
9549
|
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
9418
9550
|
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
9419
9551
|
const value = setupActionValue(action);
|
|
9420
9552
|
await locator.nth(targetIndex).fill(value, { timeout });
|
|
9421
|
-
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 };
|
|
9422
9554
|
}
|
|
9423
9555
|
if (type === "assert_selector_count") {
|
|
9424
|
-
const
|
|
9556
|
+
const scope = await setupActionScope(action, timeout);
|
|
9557
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9558
|
+
const locator = scope.context.locator(action.selector);
|
|
9425
9559
|
const expectedCount = setupNumber(action.expected_count, -1);
|
|
9426
9560
|
if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
|
|
9427
9561
|
const startedAt = Date.now();
|
|
9428
9562
|
let count = 0;
|
|
9429
9563
|
while (Date.now() - startedAt <= timeout) {
|
|
9430
9564
|
count = await locator.count().catch(() => 0);
|
|
9431
|
-
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 };
|
|
9432
9566
|
await page.waitForTimeout(100);
|
|
9433
9567
|
}
|
|
9434
|
-
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 };
|
|
9435
9569
|
}
|
|
9436
9570
|
if (type === "wait_for_text") {
|
|
9437
|
-
const
|
|
9571
|
+
const scope = await setupActionScope(action, timeout);
|
|
9572
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9573
|
+
const locator = scope.context.locator(action.selector);
|
|
9438
9574
|
const startedAt = Date.now();
|
|
9439
9575
|
let lastText = "";
|
|
9440
9576
|
while (Date.now() - startedAt <= timeout) {
|
|
@@ -9443,15 +9579,17 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9443
9579
|
const text = await setupLocatorText(locator, index);
|
|
9444
9580
|
lastText = text || lastText;
|
|
9445
9581
|
if (setupTextMatches(text, action)) {
|
|
9446
|
-
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 };
|
|
9447
9583
|
}
|
|
9448
9584
|
}
|
|
9449
9585
|
await page.waitForTimeout(100);
|
|
9450
9586
|
}
|
|
9451
|
-
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 };
|
|
9452
9588
|
}
|
|
9453
9589
|
if (type === "assert_text_visible" || type === "assert_text_absent") {
|
|
9454
|
-
const
|
|
9590
|
+
const scope = await setupActionScope(action, timeout);
|
|
9591
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9592
|
+
const locator = scope.context.locator(action.selector);
|
|
9455
9593
|
const startedAt = Date.now();
|
|
9456
9594
|
let lastText = "";
|
|
9457
9595
|
let matchedText = "";
|
|
@@ -9470,7 +9608,7 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9470
9608
|
if (type === "assert_text_visible") {
|
|
9471
9609
|
const visible = await setupLocatorVisible(locator, index);
|
|
9472
9610
|
if (visible) {
|
|
9473
|
-
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 };
|
|
9474
9612
|
}
|
|
9475
9613
|
hiddenMatch = true;
|
|
9476
9614
|
break;
|
|
@@ -9479,17 +9617,17 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9479
9617
|
}
|
|
9480
9618
|
}
|
|
9481
9619
|
if (type === "assert_text_absent" && !matched) {
|
|
9482
|
-
return { ...base, ok: true, count, timeout_ms: timeout };
|
|
9620
|
+
return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
|
|
9483
9621
|
}
|
|
9484
9622
|
await page.waitForTimeout(100);
|
|
9485
9623
|
}
|
|
9486
9624
|
if (type === "assert_text_visible") {
|
|
9487
9625
|
if (hiddenMatch) {
|
|
9488
|
-
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 };
|
|
9489
9627
|
}
|
|
9490
|
-
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 };
|
|
9491
9629
|
}
|
|
9492
|
-
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 };
|
|
9493
9631
|
}
|
|
9494
9632
|
return { ...base, reason: "unsupported_action" };
|
|
9495
9633
|
} catch (error) {
|
package/dist/cli.js
CHANGED