@validate.qa/runner 1.0.87 → 1.0.89
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.js +3754 -45
- package/dist/cli.mjs +3754 -45
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1798,7 +1798,11 @@ var init_constants = __esm({
|
|
|
1798
1798
|
"home",
|
|
1799
1799
|
"waitForElement",
|
|
1800
1800
|
"assertVisible",
|
|
1801
|
-
"assertText"
|
|
1801
|
+
"assertText",
|
|
1802
|
+
/** Capture list labels / badge counts into run-local state bag (Phase 1 oracles). */
|
|
1803
|
+
"captureState",
|
|
1804
|
+
/** Assert a prior captureState delta (removed id, count change, etc.). */
|
|
1805
|
+
"assertStateDelta"
|
|
1802
1806
|
];
|
|
1803
1807
|
BLOCKED_ENV_VARS = /* @__PURE__ */ new Set([
|
|
1804
1808
|
// Execution / code-injection vectors
|
|
@@ -2233,7 +2237,10 @@ function readMobileMetadata(value) {
|
|
|
2233
2237
|
webCss: typeof value.webCss === "string" && value.webCss.trim() ? value.webCss.trim() : void 0,
|
|
2234
2238
|
webviewContext: typeof value.webviewContext === "string" && /^WEBVIEW/i.test(value.webviewContext.trim()) ? value.webviewContext.trim() : void 0,
|
|
2235
2239
|
matchIndex: hasValidMatchPair ? rawMatchIndex : void 0,
|
|
2236
|
-
expectedMatchCount: hasValidMatchPair ? rawExpectedMatchCount : void 0
|
|
2240
|
+
expectedMatchCount: hasValidMatchPair ? rawExpectedMatchCount : void 0,
|
|
2241
|
+
stateKey: typeof value.stateKey === "string" && value.stateKey.trim() ? value.stateKey.trim() : void 0,
|
|
2242
|
+
stateKind: typeof value.stateKind === "string" && value.stateKind.trim() ? value.stateKind.trim() : void 0,
|
|
2243
|
+
expect: typeof value.expect === "string" && value.expect.trim() ? value.expect.trim() : void 0
|
|
2237
2244
|
};
|
|
2238
2245
|
}
|
|
2239
2246
|
function nonEmpty(value) {
|
|
@@ -2316,6 +2323,10 @@ function descriptionForStep(action, stepAction, metadata) {
|
|
|
2316
2323
|
return `Assert ${label} is visible`;
|
|
2317
2324
|
case "assertText":
|
|
2318
2325
|
return `Assert ${label} shows "${action.value ?? action.innerText ?? ""}"`;
|
|
2326
|
+
case "captureState":
|
|
2327
|
+
return `Capture UI state "${metadata.stateKey ?? label}" (${metadata.stateKind ?? "list_ids"})`;
|
|
2328
|
+
case "assertStateDelta":
|
|
2329
|
+
return `Assert state delta "${metadata.stateKey ?? label}" expect=${metadata.expect ?? action.value ?? "changed"}`;
|
|
2319
2330
|
default:
|
|
2320
2331
|
return `Execute ${stepAction}`;
|
|
2321
2332
|
}
|
|
@@ -2361,6 +2372,8 @@ function buildMobileStep(action, order) {
|
|
|
2361
2372
|
step.assertion = `${labelForAction(action, metadata)} should be visible`;
|
|
2362
2373
|
} else if (stepAction === "assertText") {
|
|
2363
2374
|
step.assertion = action.value ?? action.innerText ?? void 0;
|
|
2375
|
+
} else if (stepAction === "assertStateDelta") {
|
|
2376
|
+
step.assertion = metadata.expect ?? action.value ?? "changed";
|
|
2364
2377
|
}
|
|
2365
2378
|
if ((stepAction === "swipe" || stepAction === "scroll") && (metadata.direction || metadata.distance)) {
|
|
2366
2379
|
const stepMetadata = ensureMetadata(step);
|
|
@@ -2369,6 +2382,24 @@ function buildMobileStep(action, order) {
|
|
|
2369
2382
|
if (metadata.distance)
|
|
2370
2383
|
stepMetadata.distance = metadata.distance;
|
|
2371
2384
|
}
|
|
2385
|
+
if (stepAction === "captureState" || stepAction === "assertStateDelta") {
|
|
2386
|
+
const stepMetadata = ensureMetadata(step);
|
|
2387
|
+
const stateKey = nonEmpty(metadata.stateKey) ?? nonEmpty(action.selector) ?? nonEmpty(metadata.targetLabel) ?? `state-${order}`;
|
|
2388
|
+
stepMetadata.stateKey = stateKey;
|
|
2389
|
+
if (stepAction === "captureState") {
|
|
2390
|
+
stepMetadata.stateKind = nonEmpty(metadata.stateKind) ?? "list_ids";
|
|
2391
|
+
}
|
|
2392
|
+
if (stepAction === "assertStateDelta") {
|
|
2393
|
+
stepMetadata.expect = nonEmpty(metadata.expect) ?? nonEmpty(action.value) ?? "changed";
|
|
2394
|
+
}
|
|
2395
|
+
if (!step.target) {
|
|
2396
|
+
step.target = {
|
|
2397
|
+
primary: stateKey,
|
|
2398
|
+
fallbacks: [],
|
|
2399
|
+
screenName: metadata.screenName || "UnknownScreen"
|
|
2400
|
+
};
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2372
2403
|
return step;
|
|
2373
2404
|
}
|
|
2374
2405
|
function buildLaunchStep(target, medium, appResetOnLaunch = false) {
|
|
@@ -2580,6 +2611,9 @@ function buildAppiumCode(testName, target, steps) {
|
|
|
2580
2611
|
used.find = true;
|
|
2581
2612
|
}
|
|
2582
2613
|
break;
|
|
2614
|
+
case "captureState":
|
|
2615
|
+
case "assertStateDelta":
|
|
2616
|
+
break;
|
|
2583
2617
|
default:
|
|
2584
2618
|
break;
|
|
2585
2619
|
}
|
|
@@ -2698,6 +2732,8 @@ function buildAppiumCode(testName, target, steps) {
|
|
|
2698
2732
|
const expectedLiteral = toJsStringLiteral(step.assertion ?? "");
|
|
2699
2733
|
const replayExpected = step.assertion?.includes("{{") ? `resolveValue(${expectedLiteral})` : expectedLiteral;
|
|
2700
2734
|
pushAction(`await expectText(driver, ${sel}, ${replayExpected});`);
|
|
2735
|
+
} else if (step.action === "captureState" || step.action === "assertStateDelta") {
|
|
2736
|
+
lines.push(` // ${step.action}: ${step.description.replace(/\n/g, " ").slice(0, 120)}`);
|
|
2701
2737
|
} else if (step.action === "back") {
|
|
2702
2738
|
lines.push(` await driver.back();`);
|
|
2703
2739
|
} else if (step.action === "home") {
|
|
@@ -3040,7 +3076,9 @@ var init_mobile_test_generation = __esm({
|
|
|
3040
3076
|
HOME: "home",
|
|
3041
3077
|
WAIT_FOR_ELEMENT: "waitForElement",
|
|
3042
3078
|
ASSERT_VISIBLE: "assertVisible",
|
|
3043
|
-
ASSERT_TEXT: "assertText"
|
|
3079
|
+
ASSERT_TEXT: "assertText",
|
|
3080
|
+
CAPTURE_STATE: "captureState",
|
|
3081
|
+
ASSERT_STATE_DELTA: "assertStateDelta"
|
|
3044
3082
|
};
|
|
3045
3083
|
MOBILE_VALUE_PLACEHOLDER_RE = /\{\{([A-Za-z0-9_]+)\}\}/g;
|
|
3046
3084
|
}
|
|
@@ -3271,7 +3309,9 @@ var init_mobile_step_healer = __esm({
|
|
|
3271
3309
|
"home",
|
|
3272
3310
|
"waitForElement",
|
|
3273
3311
|
"assertVisible",
|
|
3274
|
-
"assertText"
|
|
3312
|
+
"assertText",
|
|
3313
|
+
"captureState",
|
|
3314
|
+
"assertStateDelta"
|
|
3275
3315
|
]);
|
|
3276
3316
|
FOREIGN_PACKAGE_RE = /\b[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*){2,}\b/gi;
|
|
3277
3317
|
ANDROID_RESOURCE_OWNER_RE = /([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+):id\//gi;
|
|
@@ -80310,6 +80350,306 @@ ${JSON.stringify(gatePlan)}`;
|
|
|
80310
80350
|
}
|
|
80311
80351
|
});
|
|
80312
80352
|
|
|
80353
|
+
// ../runner-core/dist/services/mobile/scenario-taxonomy.js
|
|
80354
|
+
var require_scenario_taxonomy = __commonJS({
|
|
80355
|
+
"../runner-core/dist/services/mobile/scenario-taxonomy.js"(exports) {
|
|
80356
|
+
"use strict";
|
|
80357
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
80358
|
+
exports.ALL_SCENARIO_KINDS = void 0;
|
|
80359
|
+
exports.extractUiSignals = extractUiSignals;
|
|
80360
|
+
exports.requiredScenarioKinds = requiredScenarioKinds;
|
|
80361
|
+
exports.coverageGaps = coverageGaps;
|
|
80362
|
+
exports.inferScenarioKind = inferScenarioKind;
|
|
80363
|
+
exports.inferScenarioKinds = inferScenarioKinds;
|
|
80364
|
+
exports.isStrongOracleKind = isStrongOracleKind;
|
|
80365
|
+
exports.formatRequiredScenarioKindsPrompt = formatRequiredScenarioKindsPrompt;
|
|
80366
|
+
exports.formatCoverageGapLog = formatCoverageGapLog;
|
|
80367
|
+
exports.ALL_SCENARIO_KINDS = [
|
|
80368
|
+
"smoke_nav",
|
|
80369
|
+
"happy_submit",
|
|
80370
|
+
"negative_validation",
|
|
80371
|
+
"crud_identity",
|
|
80372
|
+
"count_delta",
|
|
80373
|
+
"persistence_roundtrip",
|
|
80374
|
+
"auth_session",
|
|
80375
|
+
"navigation_integrity",
|
|
80376
|
+
"permission_system",
|
|
80377
|
+
"double_submit"
|
|
80378
|
+
];
|
|
80379
|
+
var DELETE_RE = /\b(delete|remove|archive|trash)\b/i;
|
|
80380
|
+
var EMAIL_RE = /\b(e-?mail|email address)\b/i;
|
|
80381
|
+
var PASSWORD_RE = /\b(password|passcode|pin)\b/i;
|
|
80382
|
+
var SIGN_OUT_RE = /\b(sign\s*out|log\s*out|logout)\b/i;
|
|
80383
|
+
var TOGGLE_RE = /\b(toggle|switch|enable|disable|on\/off)\b/i;
|
|
80384
|
+
var SUBMIT_RE = /\b(submit|save|send|create|confirm|apply|done|update|post)\b/i;
|
|
80385
|
+
var BADGE_OR_COUNT_RE = /\b(\d+)\s*(item|items|open|unread|invoice|message|result|pending|new)\b/i;
|
|
80386
|
+
var BADGE_LABEL_RE = /\b(badge|count|open invoices|unread|notifications?)\b/i;
|
|
80387
|
+
var PERMISSION_RE = /\b(camera|microphone|location|photos?|permission|allow access|not now)\b/i;
|
|
80388
|
+
var SETTINGS_RE = /\b(settings|preferences|profile|account)\b/i;
|
|
80389
|
+
var TAB_RE = /\b(tab|home|catalog|forms|edges|inbox|feed|dashboard)\b/i;
|
|
80390
|
+
function elementText(el) {
|
|
80391
|
+
return [
|
|
80392
|
+
el.label ?? "",
|
|
80393
|
+
el.text ?? "",
|
|
80394
|
+
el.accessibilityId ?? "",
|
|
80395
|
+
el.resourceId ?? "",
|
|
80396
|
+
el.role ?? ""
|
|
80397
|
+
].join(" ");
|
|
80398
|
+
}
|
|
80399
|
+
function isEditable(el) {
|
|
80400
|
+
const role = el.role ?? "";
|
|
80401
|
+
return /EditText|TextField|SecureTextField|SearchField|AutoComplete|textbox|searchbox/i.test(role) || el.role === "textbox" || el.role === "searchbox";
|
|
80402
|
+
}
|
|
80403
|
+
function isToggle(el) {
|
|
80404
|
+
const role = el.role ?? "";
|
|
80405
|
+
return /Switch|CheckBox|Toggle|RadioButton/i.test(role) || TOGGLE_RE.test(elementText(el));
|
|
80406
|
+
}
|
|
80407
|
+
function isRowAction(el) {
|
|
80408
|
+
const t = elementText(el);
|
|
80409
|
+
return DELETE_RE.test(t) && el.actionable !== false;
|
|
80410
|
+
}
|
|
80411
|
+
function extractUiSignals(graph, appId) {
|
|
80412
|
+
const screens = [...graph.screens.values()].filter((s) => {
|
|
80413
|
+
if (!appId)
|
|
80414
|
+
return true;
|
|
80415
|
+
return s.screenId === appId || s.screenId.startsWith(`${appId}#`) || s.screenId.startsWith(`${appId}.`);
|
|
80416
|
+
});
|
|
80417
|
+
let hasListWithRowActions = false;
|
|
80418
|
+
let hasFormFields = false;
|
|
80419
|
+
let hasEmailField = false;
|
|
80420
|
+
let hasNumericBadge = false;
|
|
80421
|
+
let hasSettingsToggles = false;
|
|
80422
|
+
let hasSignOut = false;
|
|
80423
|
+
let hasDestructiveConfirm = false;
|
|
80424
|
+
let hasPrimarySubmit = false;
|
|
80425
|
+
let hasTabOrDrawerNav = false;
|
|
80426
|
+
let hasPermissionCopy = false;
|
|
80427
|
+
for (const state2 of screens) {
|
|
80428
|
+
const labels = state2.elements.map(elementText);
|
|
80429
|
+
const blob = [state2.screenName ?? "", state2.screenType ?? "", ...state2.observations ?? [], ...labels].join(" ");
|
|
80430
|
+
if (PASSWORD_RE.test(blob) || state2.elements.some(isEditable))
|
|
80431
|
+
hasFormFields = true;
|
|
80432
|
+
if (labels.some((t) => EMAIL_RE.test(t)) || state2.elements.some((el) => isEditable(el) && EMAIL_RE.test(elementText(el)))) {
|
|
80433
|
+
hasEmailField = true;
|
|
80434
|
+
hasFormFields = true;
|
|
80435
|
+
}
|
|
80436
|
+
if (state2.elements.some(isRowAction))
|
|
80437
|
+
hasListWithRowActions = true;
|
|
80438
|
+
if (!hasListWithRowActions && state2.elements.filter((el) => el.actionable).length >= 6 && DELETE_RE.test(blob)) {
|
|
80439
|
+
hasListWithRowActions = true;
|
|
80440
|
+
}
|
|
80441
|
+
if (BADGE_OR_COUNT_RE.test(blob) || BADGE_LABEL_RE.test(blob))
|
|
80442
|
+
hasNumericBadge = true;
|
|
80443
|
+
if (state2.elements.some(isToggle) || SETTINGS_RE.test(blob) && TOGGLE_RE.test(blob)) {
|
|
80444
|
+
hasSettingsToggles = true;
|
|
80445
|
+
}
|
|
80446
|
+
if (SIGN_OUT_RE.test(blob))
|
|
80447
|
+
hasSignOut = true;
|
|
80448
|
+
if (DELETE_RE.test(blob) && /\b(confirm|are you sure|permanently)\b/i.test(blob)) {
|
|
80449
|
+
hasDestructiveConfirm = true;
|
|
80450
|
+
}
|
|
80451
|
+
if (labels.some((t) => SUBMIT_RE.test(t)))
|
|
80452
|
+
hasPrimarySubmit = true;
|
|
80453
|
+
if (TAB_RE.test(blob) || state2.screenType === "TAB" || /\btab\b/i.test(state2.screenName ?? "")) {
|
|
80454
|
+
hasTabOrDrawerNav = true;
|
|
80455
|
+
}
|
|
80456
|
+
if (PERMISSION_RE.test(blob) || state2.screenType === "PERMISSION")
|
|
80457
|
+
hasPermissionCopy = true;
|
|
80458
|
+
}
|
|
80459
|
+
return {
|
|
80460
|
+
hasListWithRowActions,
|
|
80461
|
+
hasFormFields,
|
|
80462
|
+
hasEmailField,
|
|
80463
|
+
hasNumericBadge,
|
|
80464
|
+
hasSettingsToggles,
|
|
80465
|
+
hasSignOut,
|
|
80466
|
+
hasDestructiveConfirm,
|
|
80467
|
+
hasPrimarySubmit,
|
|
80468
|
+
hasTabOrDrawerNav,
|
|
80469
|
+
hasPermissionCopy
|
|
80470
|
+
};
|
|
80471
|
+
}
|
|
80472
|
+
function requiredScenarioKinds(signals) {
|
|
80473
|
+
const kinds = /* @__PURE__ */ new Set(["smoke_nav"]);
|
|
80474
|
+
if (signals.hasFormFields || signals.hasPrimarySubmit) {
|
|
80475
|
+
kinds.add("happy_submit");
|
|
80476
|
+
}
|
|
80477
|
+
if (signals.hasFormFields || signals.hasEmailField) {
|
|
80478
|
+
kinds.add("negative_validation");
|
|
80479
|
+
}
|
|
80480
|
+
if (signals.hasListWithRowActions) {
|
|
80481
|
+
kinds.add("crud_identity");
|
|
80482
|
+
}
|
|
80483
|
+
if (signals.hasNumericBadge) {
|
|
80484
|
+
kinds.add("count_delta");
|
|
80485
|
+
}
|
|
80486
|
+
if (signals.hasSettingsToggles) {
|
|
80487
|
+
kinds.add("persistence_roundtrip");
|
|
80488
|
+
}
|
|
80489
|
+
if (signals.hasSignOut) {
|
|
80490
|
+
kinds.add("auth_session");
|
|
80491
|
+
}
|
|
80492
|
+
if (signals.hasTabOrDrawerNav) {
|
|
80493
|
+
kinds.add("navigation_integrity");
|
|
80494
|
+
}
|
|
80495
|
+
if (signals.hasPermissionCopy) {
|
|
80496
|
+
kinds.add("permission_system");
|
|
80497
|
+
}
|
|
80498
|
+
if (signals.hasPrimarySubmit && signals.hasFormFields) {
|
|
80499
|
+
kinds.add("double_submit");
|
|
80500
|
+
}
|
|
80501
|
+
return exports.ALL_SCENARIO_KINDS.filter((k) => kinds.has(k));
|
|
80502
|
+
}
|
|
80503
|
+
function coverageGaps(signals, plannedKinds) {
|
|
80504
|
+
const planned = new Set(plannedKinds);
|
|
80505
|
+
return requiredScenarioKinds(signals).filter((k) => !planned.has(k));
|
|
80506
|
+
}
|
|
80507
|
+
function inferScenarioKind(scenario) {
|
|
80508
|
+
const text = `${scenario.name} ${scenario.goal} ${scenario.variant ?? ""} ${scenario.type}`.toLowerCase();
|
|
80509
|
+
if (/\b(invalid|empty|required|validation|too short|malformed|reject|error message)\b/.test(text) || scenario.variant === "validation" || scenario.type === "EDGE_CASE" && /\b(empty|invalid|required)\b/.test(text)) {
|
|
80510
|
+
return "negative_validation";
|
|
80511
|
+
}
|
|
80512
|
+
if (/\b(delete|remove|wrong row|entity|archive)\b/.test(text) && /\b(list|row|item|record)\b/.test(text)) {
|
|
80513
|
+
return "crud_identity";
|
|
80514
|
+
}
|
|
80515
|
+
if (/\b(badge|count|unread|open invoices|\+\d|increment|decrement)\b/.test(text)) {
|
|
80516
|
+
return "count_delta";
|
|
80517
|
+
}
|
|
80518
|
+
if (/\b(persist|revisit|return|leave|settings|toggle|favorite|remember)\b/.test(text)) {
|
|
80519
|
+
return "persistence_roundtrip";
|
|
80520
|
+
}
|
|
80521
|
+
if (/\b(sign\s*out|log\s*out|session|sign\s*in|remember me|auth)\b/.test(text) || scenario.type === "HAPPY_PATH" && /\b(login|sign in)\b/.test(text)) {
|
|
80522
|
+
return "auth_session";
|
|
80523
|
+
}
|
|
80524
|
+
if (/\b(tab|navigate|navigation|back|deep link|empty.?state)\b/.test(text)) {
|
|
80525
|
+
return "navigation_integrity";
|
|
80526
|
+
}
|
|
80527
|
+
if (/\b(permission|camera|microphone|location|allow)\b/.test(text)) {
|
|
80528
|
+
return "permission_system";
|
|
80529
|
+
}
|
|
80530
|
+
if (/\b(double|twice|duplicate submit|double.?tap)\b/.test(text)) {
|
|
80531
|
+
return "double_submit";
|
|
80532
|
+
}
|
|
80533
|
+
if (scenario.type === "HAPPY_PATH" || scenario.variant === "happy") {
|
|
80534
|
+
return "happy_submit";
|
|
80535
|
+
}
|
|
80536
|
+
if (scenario.type === "USER_JOURNEY" || scenario.type === "REGRESSION") {
|
|
80537
|
+
return "navigation_integrity";
|
|
80538
|
+
}
|
|
80539
|
+
return "smoke_nav";
|
|
80540
|
+
}
|
|
80541
|
+
function inferScenarioKinds(scenarios) {
|
|
80542
|
+
return [...new Set(scenarios.map(inferScenarioKind))];
|
|
80543
|
+
}
|
|
80544
|
+
function isStrongOracleKind(kind) {
|
|
80545
|
+
return kind !== "smoke_nav" && kind !== "navigation_integrity";
|
|
80546
|
+
}
|
|
80547
|
+
function formatRequiredScenarioKindsPrompt(signals) {
|
|
80548
|
+
const required = requiredScenarioKinds(signals);
|
|
80549
|
+
if (required.length === 0)
|
|
80550
|
+
return "";
|
|
80551
|
+
const lines = required.map((kind) => {
|
|
80552
|
+
switch (kind) {
|
|
80553
|
+
case "smoke_nav":
|
|
80554
|
+
return '- smoke_nav: reach a primary destination and prove it with a durable product signal (not only "tab visible")';
|
|
80555
|
+
case "happy_submit":
|
|
80556
|
+
return "- happy_submit: complete a form/primary action and assert the durable result (new row, saved state, success that outlives a toast)";
|
|
80557
|
+
case "negative_validation":
|
|
80558
|
+
return "- negative_validation: submit empty/invalid input (e.g. empty required, malformed email-like field) and assert error OR blocked submit \u2014 never invent success copy";
|
|
80559
|
+
case "crud_identity":
|
|
80560
|
+
return '- crud_identity: create or note an entity id/label, perform delete/edit on THAT entity, assert identity set changed correctly (not "list still visible")';
|
|
80561
|
+
case "count_delta":
|
|
80562
|
+
return "- count_delta: capture a numeric badge/count, perform an action, assert the number changed as expected";
|
|
80563
|
+
case "persistence_roundtrip":
|
|
80564
|
+
return "- persistence_roundtrip: change a setting/toggle, leave the screen (or relaunch if policy allows), return, assert value persisted";
|
|
80565
|
+
case "auth_session":
|
|
80566
|
+
return "- auth_session: prove sign-in session (profile/sign-out) and/or sign-out leaves only logged-out chrome";
|
|
80567
|
+
case "navigation_integrity":
|
|
80568
|
+
return "- navigation_integrity: tab/drawer/back reaches the intended screen family";
|
|
80569
|
+
case "permission_system":
|
|
80570
|
+
return "- permission_system: permission prompt or settings path behaves honestly (allow/deny/settings)";
|
|
80571
|
+
case "double_submit":
|
|
80572
|
+
return "- double_submit: single user intent must not double-create (assert count +1 not +2, or single confirmation)";
|
|
80573
|
+
default:
|
|
80574
|
+
return `- ${kind}`;
|
|
80575
|
+
}
|
|
80576
|
+
});
|
|
80577
|
+
return "## Required scenario kinds (from observed UI \u2014 fill each or explain impossibility in reasoning)\nThese kinds are derived ONLY from controls/screens the explorer saw. Plan at least one scenario per kind when evidence supports it.\n" + lines.join("\n");
|
|
80578
|
+
}
|
|
80579
|
+
function formatCoverageGapLog(gaps) {
|
|
80580
|
+
if (gaps.length === 0)
|
|
80581
|
+
return "Scenario taxonomy: all required kinds covered by plan";
|
|
80582
|
+
return `Scenario taxonomy coverage gaps (required but not planned): ${gaps.join(", ")}`;
|
|
80583
|
+
}
|
|
80584
|
+
}
|
|
80585
|
+
});
|
|
80586
|
+
|
|
80587
|
+
// ../runner-core/dist/services/mobile/coverage-map.js
|
|
80588
|
+
var require_coverage_map = __commonJS({
|
|
80589
|
+
"../runner-core/dist/services/mobile/coverage-map.js"(exports) {
|
|
80590
|
+
"use strict";
|
|
80591
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
80592
|
+
exports.buildMobileCoverageMap = buildMobileCoverageMap;
|
|
80593
|
+
var scenario_taxonomy_js_1 = require_scenario_taxonomy();
|
|
80594
|
+
function strongLookup(name, map2) {
|
|
80595
|
+
if (!map2)
|
|
80596
|
+
return false;
|
|
80597
|
+
if (map2 instanceof Map)
|
|
80598
|
+
return map2.get(name) === true;
|
|
80599
|
+
return Object.prototype.hasOwnProperty.call(map2, name) && map2[name] === true;
|
|
80600
|
+
}
|
|
80601
|
+
function buildMobileCoverageMap(input) {
|
|
80602
|
+
const signals = (0, scenario_taxonomy_js_1.extractUiSignals)(input.graph, input.appId);
|
|
80603
|
+
const required = (0, scenario_taxonomy_js_1.requiredScenarioKinds)(signals);
|
|
80604
|
+
const planned = input.plannedScenarios ?? [];
|
|
80605
|
+
const plannedKinds = planned.map(scenario_taxonomy_js_1.inferScenarioKind);
|
|
80606
|
+
const plannedSet = new Set(plannedKinds);
|
|
80607
|
+
const gaps = (0, scenario_taxonomy_js_1.coverageGaps)(signals, plannedKinds);
|
|
80608
|
+
const kindsWithStrong = /* @__PURE__ */ new Set();
|
|
80609
|
+
for (const s of planned) {
|
|
80610
|
+
const kind = (0, scenario_taxonomy_js_1.inferScenarioKind)(s);
|
|
80611
|
+
const isStrong = (0, scenario_taxonomy_js_1.isStrongOracleKind)(kind) || strongLookup(s.name, input.strongByScenarioName);
|
|
80612
|
+
if (isStrong)
|
|
80613
|
+
kindsWithStrong.add(kind);
|
|
80614
|
+
}
|
|
80615
|
+
const warnings = [];
|
|
80616
|
+
const entries = required.map((kind) => {
|
|
80617
|
+
const isPlanned = plannedSet.has(kind);
|
|
80618
|
+
const strongPlanned = kindsWithStrong.has(kind);
|
|
80619
|
+
let warning;
|
|
80620
|
+
if (!isPlanned) {
|
|
80621
|
+
warning = `Required kind "${kind}" has no planned scenario`;
|
|
80622
|
+
warnings.push(warning);
|
|
80623
|
+
} else if (!strongPlanned && (0, scenario_taxonomy_js_1.isStrongOracleKind)(kind)) {
|
|
80624
|
+
warning = `Kind "${kind}" is planned but has no strong-oracle scenario (smoke-only coverage)`;
|
|
80625
|
+
warnings.push(warning);
|
|
80626
|
+
}
|
|
80627
|
+
return {
|
|
80628
|
+
kind,
|
|
80629
|
+
required: true,
|
|
80630
|
+
planned: isPlanned,
|
|
80631
|
+
strongPlanned,
|
|
80632
|
+
warning
|
|
80633
|
+
};
|
|
80634
|
+
});
|
|
80635
|
+
if (planned.length > 0 && plannedKinds.every((k) => k === "smoke_nav" || k === "navigation_integrity")) {
|
|
80636
|
+
const w = "All planned scenarios are smoke/nav \u2014 no strong product oracles";
|
|
80637
|
+
if (!warnings.includes(w))
|
|
80638
|
+
warnings.push(w);
|
|
80639
|
+
}
|
|
80640
|
+
const summary = warnings.length === 0 ? `Coverage map: ${required.length} required kinds, all covered with strong scenarios where needed` : `Coverage map: ${warnings.length} warning(s); ${(0, scenario_taxonomy_js_1.formatCoverageGapLog)(gaps)}`;
|
|
80641
|
+
return {
|
|
80642
|
+
signals,
|
|
80643
|
+
requiredKinds: required,
|
|
80644
|
+
gaps,
|
|
80645
|
+
entries,
|
|
80646
|
+
warnings,
|
|
80647
|
+
summary
|
|
80648
|
+
};
|
|
80649
|
+
}
|
|
80650
|
+
}
|
|
80651
|
+
});
|
|
80652
|
+
|
|
80313
80653
|
// ../runner-core/dist/services/mobile/mobile-discovery-prompts.js
|
|
80314
80654
|
var require_mobile_discovery_prompts = __commonJS({
|
|
80315
80655
|
"../runner-core/dist/services/mobile/mobile-discovery-prompts.js"(exports) {
|
|
@@ -80327,6 +80667,8 @@ var require_mobile_discovery_prompts = __commonJS({
|
|
|
80327
80667
|
var ai_provider_js_1 = require_ai_provider();
|
|
80328
80668
|
var discover_ai_planner_js_1 = require_discover_ai_planner();
|
|
80329
80669
|
var mobile_observation_js_1 = require_mobile_observation();
|
|
80670
|
+
var scenario_taxonomy_js_1 = require_scenario_taxonomy();
|
|
80671
|
+
var coverage_map_js_1 = require_coverage_map();
|
|
80330
80672
|
function isTargetAppScreenId(screenId, appId) {
|
|
80331
80673
|
if (!appId)
|
|
80332
80674
|
return true;
|
|
@@ -80408,7 +80750,7 @@ Return ONLY one valid JSON object matching the schema below. Do NOT include <thi
|
|
|
80408
80750
|
9. **No duplicates** - check existing test names before adding
|
|
80409
80751
|
10. **All tests start from the app launch entry** - every generated test starts by launching the target app. The runner clears app data when the device/reset policy safely supports it; otherwise it performs a terminate + activate relaunch, which can preserve app session data. Therefore scenarios MUST navigate through the app's own UI from whatever launch state is valid, and MUST NOT rely on mutable data from a prior scenario disappearing. Steps must reflect this: say "Launch the app and tap Sign In" not "deep-link to the login screen". Do NOT navigate by deep-link; the app's launch + tab/drawer navigation is the only entry path. \`targetPages\` lists the screen-ids involved in the flow.
|
|
80410
80752
|
11. **targetPages must be copied CHARACTER-FOR-CHARACTER from the screen-ids in the evidence** (they look like \`com.example.app.MainActivity#ab12cd34\`). NEVER invent, prettify, or abbreviate them \u2014 no "Landing", "AUTH", "Home Screen", or any name that is not literally in the provided screens. A scenario whose targetPages contains even ONE id not present in the evidence is REJECTED WHOLESALE by the validator, so a single made-up route silently destroys the entire scenario. If you are unsure which screen-id a step touches, use the screen-id of the screen where the flow STARTS.
|
|
80411
|
-
12. **Happy paths must verify the DURABLE OUTCOME, not just the trigger.** A HAPPY_PATH is NOT complete until it verifies the feature's real output. "Button tapped" / "Sheet opened" / "Spinner appeared" / "Settings screen opened" is NOT a happy path - that is a UI interaction test. Form-mutation happy paths (change password, create/edit/save a record, send a message, checkout, etc.) MUST include typing into the relevant fields AND committing the form (submit/save/send or keyboard Enter/Done) \u2014 navigating to the form screen alone is insufficient. Apply this to any feature where an action produces a result the user then sees or uses: CRUD creates, photo/file uploads, searches that return results, imports, exports, payments, messages sent, AI/ML outputs, generated documents, sync runs, analysis runs, conversion, data processing. The scenario MUST include:
|
|
80753
|
+
12. **Happy paths must verify the DURABLE OUTCOME, not just the trigger.** A HAPPY_PATH is NOT complete until it verifies the feature's real output. "Button tapped" / "Sheet opened" / "Spinner appeared" / "Settings screen opened" is NOT a happy path - that is a UI interaction test. When the explorer observed list rows with delete/remove, plan at least one scenario that captures entity identity before the action and asserts that identity is gone or changed afterward (not merely that the list screen is still visible). When numeric badges/counts were observed, plan a before/after count check. Form-mutation happy paths (change password, create/edit/save a record, send a message, checkout, etc.) MUST include typing into the relevant fields AND committing the form (submit/save/send or keyboard Enter/Done) \u2014 navigating to the form screen alone is insufficient. Apply this to any feature where an action produces a result the user then sees or uses: CRUD creates, photo/file uploads, searches that return results, imports, exports, payments, messages sent, AI/ML outputs, generated documents, sync runs, analysis runs, conversion, data processing. The scenario MUST include:
|
|
80412
80754
|
- The trigger step (Tap Submit / Generate / Send / Upload / Run / Analyze / Save / Pay / etc.)
|
|
80413
80755
|
- A wait step for the operation to complete. Phrase it by SIGNAL, not wall-clock ("Wait for the result to appear - up to 60 seconds"). Prefer signals the app actually uses: spinner disappears, status badge flips to a success state, a new row appears, an item count increments, a success toast/snackbar shows, the screen transitions to a result screen.
|
|
80414
80756
|
- A verification step on the DURABLE RESULT - the thing that outlives the transient UI: a new list row, a persisted record, a received message, a committed state change, visible output text. Do NOT assert on the spinner disappearing alone; assert on what replaced it.
|
|
@@ -80808,6 +81150,14 @@ SCOPE: this is a feature-focused deep run. Plan scenarios ONLY for the "${contex
|
|
|
80808
81150
|
sections.push(`## Operator notes
|
|
80809
81151
|
${context.userNotes.trim()}`);
|
|
80810
81152
|
}
|
|
81153
|
+
if (context.mode === "deep" || context.mode === "full") {
|
|
81154
|
+
const signals = (0, scenario_taxonomy_js_1.extractUiSignals)(graph, context.appId);
|
|
81155
|
+
const requiredBlock = (0, scenario_taxonomy_js_1.formatRequiredScenarioKindsPrompt)(signals);
|
|
81156
|
+
if (requiredBlock) {
|
|
81157
|
+
sections.push(requiredBlock);
|
|
81158
|
+
sections.push('## Scenario kind coverage rules\n1. Prefer scenarios whose expectedOutcomes prove durable product results (state deltas, validation errors, persistence), not only "control X is visible".\n2. For negative_validation: empty required field and/or malformed email-like input when an email field was observed.\n3. For crud_identity: assert the specific entity identity is gone/changed \u2014 never only that the list screen is still visible.\n4. For count_delta: mention the before/after numeric expectation in expectedOutcomes.\n5. If a required kind is impossible given evidence, say so in "reasoning" \u2014 do not invent unobserved screens.');
|
|
81159
|
+
}
|
|
81160
|
+
}
|
|
80811
81161
|
const orderedScreens = plannableTargetAppScreens(graph, context.appId).sort((a, b) => a.firstSeenIteration - b.firstSeenIteration || a.screenId.localeCompare(b.screenId));
|
|
80812
81162
|
const includedScreenIds = new Set(orderedScreens.map((state2) => state2.screenId));
|
|
80813
81163
|
const maxElementsPerScreen = context.mode === "survey" ? SURVEY_MAX_ELEMENTS_PER_SCREEN : MAX_ELEMENTS_PER_SCREEN;
|
|
@@ -81531,6 +81881,43 @@ ${constraints.join("\n")}`);
|
|
|
81531
81881
|
mobileAdaptationLogs.push(`Dropped ${guestWallFilter.dropped} guest-wall scenario(s) \u2014 explore session was authenticated; re-exec would not see sign-in gates`);
|
|
81532
81882
|
}
|
|
81533
81883
|
const plannedScenarios = guestWallFilter.scenarios;
|
|
81884
|
+
let taxonomyGapLogs = [];
|
|
81885
|
+
let taxonomyCoverageGaps = result.coverageGaps ?? [];
|
|
81886
|
+
if (input.mode !== "survey" && plannedScenarios.length > 0) {
|
|
81887
|
+
const signals = (0, scenario_taxonomy_js_1.extractUiSignals)(input.graph, input.appId);
|
|
81888
|
+
const plannedKinds = (0, scenario_taxonomy_js_1.inferScenarioKinds)(plannedScenarios);
|
|
81889
|
+
const gaps = (0, scenario_taxonomy_js_1.coverageGaps)(signals, plannedKinds);
|
|
81890
|
+
const coverageMap = (0, coverage_map_js_1.buildMobileCoverageMap)({
|
|
81891
|
+
graph: input.graph,
|
|
81892
|
+
appId: input.appId,
|
|
81893
|
+
plannedScenarios
|
|
81894
|
+
});
|
|
81895
|
+
taxonomyGapLogs = [(0, scenario_taxonomy_js_1.formatCoverageGapLog)(gaps), coverageMap.summary];
|
|
81896
|
+
if (coverageMap.warnings.length > 0) {
|
|
81897
|
+
taxonomyGapLogs.push(...coverageMap.warnings.slice(0, 12));
|
|
81898
|
+
}
|
|
81899
|
+
if (gaps.length > 0) {
|
|
81900
|
+
taxonomyGapLogs.push(`UI signals: listRowActions=${signals.hasListWithRowActions} forms=${signals.hasFormFields} email=${signals.hasEmailField} badge=${signals.hasNumericBadge} toggles=${signals.hasSettingsToggles} signOut=${signals.hasSignOut} tabs=${signals.hasTabOrDrawerNav}`);
|
|
81901
|
+
const detectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
81902
|
+
taxonomyCoverageGaps = [
|
|
81903
|
+
...taxonomyCoverageGaps,
|
|
81904
|
+
...gaps.map((kind) => ({
|
|
81905
|
+
scenarioName: `[taxonomy] ${kind}`,
|
|
81906
|
+
reason: `Required scenario kind "${kind}" not represented in the planned set`,
|
|
81907
|
+
suggestion: `Add a ${kind} scenario backed by observed controls, or document impossibility`,
|
|
81908
|
+
unmetPrerequisites: [],
|
|
81909
|
+
detectedAt
|
|
81910
|
+
})),
|
|
81911
|
+
...coverageMap.warnings.filter((w) => /smoke-only|no strong-oracle/i.test(w)).map((w) => ({
|
|
81912
|
+
scenarioName: "[coverage-map] strong-oracle gap",
|
|
81913
|
+
reason: w,
|
|
81914
|
+
suggestion: "Author durable assertStateDelta/assertText outcomes for this kind",
|
|
81915
|
+
unmetPrerequisites: [],
|
|
81916
|
+
detectedAt
|
|
81917
|
+
}))
|
|
81918
|
+
];
|
|
81919
|
+
}
|
|
81920
|
+
}
|
|
81534
81921
|
if (input.mode !== "survey" && plannedScenarios.length === 0 && input.graph.screens.size > 0) {
|
|
81535
81922
|
const fallbackScenarios = buildMobileFallbackScenarios(input);
|
|
81536
81923
|
if (fallbackScenarios.length > 0) {
|
|
@@ -81589,7 +81976,8 @@ ${constraints.join("\n")}`);
|
|
|
81589
81976
|
...result,
|
|
81590
81977
|
scenarios: plannedScenarios,
|
|
81591
81978
|
featureGroups: mobileFeatureGroups,
|
|
81592
|
-
|
|
81979
|
+
coverageGaps: taxonomyCoverageGaps.length > 0 ? taxonomyCoverageGaps : result.coverageGaps,
|
|
81980
|
+
logs: [...result.logs, ...mobileAdaptationLogs, ...taxonomyGapLogs]
|
|
81593
81981
|
};
|
|
81594
81982
|
}
|
|
81595
81983
|
}
|
|
@@ -81668,6 +82056,7 @@ var require_mobile_generator = __commonJS({
|
|
|
81668
82056
|
var ai_retry_js_1 = require_ai_retry();
|
|
81669
82057
|
var mobile_session_keepalive_js_1 = require_mobile_session_keepalive();
|
|
81670
82058
|
var discovery_lint_flags_js_1 = require_discovery_lint_flags();
|
|
82059
|
+
var scenario_taxonomy_js_1 = require_scenario_taxonomy();
|
|
81671
82060
|
var mobile_source_parser_js_1 = require_mobile_source_parser();
|
|
81672
82061
|
var mobile_source_parser_js_2 = require_mobile_source_parser();
|
|
81673
82062
|
var mobile_observation_js_1 = require_mobile_observation();
|
|
@@ -81809,6 +82198,50 @@ var require_mobile_generator = __commonJS({
|
|
|
81809
82198
|
}
|
|
81810
82199
|
}
|
|
81811
82200
|
};
|
|
82201
|
+
var MOBILE_CAPTURE_STATE_TOOL = {
|
|
82202
|
+
type: "function",
|
|
82203
|
+
function: {
|
|
82204
|
+
name: "mobile_capture_state",
|
|
82205
|
+
description: 'Capture list labels or numeric badge counts into a named state key BEFORE a mutating action (delete/create/toggle). Pair with mobile_assert_state_delta afterward to prove durable identity/count outcomes \u2014 stronger than "list still visible".',
|
|
82206
|
+
parameters: {
|
|
82207
|
+
type: "object",
|
|
82208
|
+
properties: {
|
|
82209
|
+
stateKey: {
|
|
82210
|
+
type: "string",
|
|
82211
|
+
description: 'Short key for this bag entry (e.g. "invoice_list", "open_count"). Reuse the same key in mobile_assert_state_delta.'
|
|
82212
|
+
},
|
|
82213
|
+
kind: {
|
|
82214
|
+
type: "string",
|
|
82215
|
+
enum: ["list_ids", "badge_count"],
|
|
82216
|
+
description: "list_ids = unique visible labels; badge_count = numeric count tokens. Default list_ids."
|
|
82217
|
+
}
|
|
82218
|
+
},
|
|
82219
|
+
required: ["stateKey"]
|
|
82220
|
+
}
|
|
82221
|
+
}
|
|
82222
|
+
};
|
|
82223
|
+
var MOBILE_ASSERT_STATE_DELTA_TOOL = {
|
|
82224
|
+
type: "function",
|
|
82225
|
+
function: {
|
|
82226
|
+
name: "mobile_assert_state_delta",
|
|
82227
|
+
description: "Compare the current screen to a prior mobile_capture_state. Verifies LIVE then records assertStateDelta. Use after delete/create/count-changing actions. expect: changed | entity_removed | count_decreased | count_increased | unchanged | persisted.",
|
|
82228
|
+
parameters: {
|
|
82229
|
+
type: "object",
|
|
82230
|
+
properties: {
|
|
82231
|
+
stateKey: {
|
|
82232
|
+
type: "string",
|
|
82233
|
+
description: "Must match a prior mobile_capture_state stateKey in this scenario."
|
|
82234
|
+
},
|
|
82235
|
+
expect: {
|
|
82236
|
+
type: "string",
|
|
82237
|
+
enum: ["changed", "entity_removed", "count_decreased", "count_increased", "unchanged", "persisted"],
|
|
82238
|
+
description: "What must differ (or persist) vs the prior capture. Default: changed."
|
|
82239
|
+
}
|
|
82240
|
+
},
|
|
82241
|
+
required: ["stateKey"]
|
|
82242
|
+
}
|
|
82243
|
+
}
|
|
82244
|
+
};
|
|
81812
82245
|
var MOBILE_FILL_CREDENTIAL_TOOL = {
|
|
81813
82246
|
type: "function",
|
|
81814
82247
|
function: {
|
|
@@ -81831,7 +82264,7 @@ var require_mobile_generator = __commonJS({
|
|
|
81831
82264
|
type: "function",
|
|
81832
82265
|
function: {
|
|
81833
82266
|
name: "finish_generate",
|
|
81834
|
-
description: "Call when the scenario is fully exercised and its outcome is asserted. verified:true requires you to have called at least one assert tool (mobile_assert_visible / mobile_assert_text) \u2014 claiming verified without any assert is auto-downgraded.",
|
|
82267
|
+
description: "Call when the scenario is fully exercised and its outcome is asserted. verified:true requires you to have called at least one assert tool (mobile_assert_visible / mobile_assert_text / mobile_assert_state_delta) \u2014 claiming verified without any assert is auto-downgraded.",
|
|
81835
82268
|
parameters: {
|
|
81836
82269
|
type: "object",
|
|
81837
82270
|
properties: {
|
|
@@ -81863,6 +82296,8 @@ var require_mobile_generator = __commonJS({
|
|
|
81863
82296
|
MOBILE_RELAUNCH_TOOL,
|
|
81864
82297
|
MOBILE_ASSERT_VISIBLE_TOOL,
|
|
81865
82298
|
MOBILE_ASSERT_TEXT_TOOL,
|
|
82299
|
+
MOBILE_CAPTURE_STATE_TOOL,
|
|
82300
|
+
MOBILE_ASSERT_STATE_DELTA_TOOL,
|
|
81866
82301
|
FINISH_GENERATE_TOOL
|
|
81867
82302
|
];
|
|
81868
82303
|
var STRUCTURAL_KEY_MAX_ELEMENTS = 16;
|
|
@@ -82129,6 +82564,7 @@ The scenario name + goal + steps describe ONE product behavior from survey/disco
|
|
|
82129
82564
|
- Navigation scenarios: you MUST land on the destination and assert something unique to it.
|
|
82130
82565
|
4. PROVE the outcome with an assert tool that matches the scenario \u2014 not ambient chrome:
|
|
82131
82566
|
- mobile_assert_visible({ref}) / mobile_assert_text({ref, expected})
|
|
82567
|
+
- For list delete/create or count changes: mobile_capture_state({stateKey, kind}) BEFORE the mutation, then mobile_assert_state_delta({stateKey, expect}) AFTER \u2014 proves identity/count change, not only "list screen still visible".
|
|
82132
82568
|
- After sign-in \u2192 signed-in product signal; after like \u2192 liked/unlike control or durable like state; after open Settings \u2192 a settings-specific control.
|
|
82133
82569
|
- Do NOT assert bottom-nav tab labels alone, notification badge counts ("N unread"), or one-time empty-state CTAs as the scenario outcome.
|
|
82134
82570
|
5. Call finish_generate with verified:true ONLY if you completed the goal AND asserted a matching durable outcome. If the app cannot complete the goal, finish with verified:false and explain \u2014 never invent a green path from unrelated screens.
|
|
@@ -82242,6 +82678,7 @@ Start by calling mobile_snapshot, then execute ONLY the steps needed for this go
|
|
|
82242
82678
|
const { scenario, driver, platform: platform3, maxIterations, agentModel, provider, aiClient, auditGroupId, onAICall, onScreenshot, targetAppId, credentials, redactionCredentials, log: emitLog, allowRelaunch } = args;
|
|
82243
82679
|
const log2 = (line) => emitLog(redactCredentialValues(line, redactionCredentials));
|
|
82244
82680
|
const actions = [];
|
|
82681
|
+
const stateBag = /* @__PURE__ */ new Map();
|
|
82245
82682
|
let assertCount = 0;
|
|
82246
82683
|
let finish = null;
|
|
82247
82684
|
let finishIntentRejections = 0;
|
|
@@ -82711,7 +83148,9 @@ ${statePacket}`, redactionCredentials) },
|
|
|
82711
83148
|
const screenDependentTools = /* @__PURE__ */ new Set([
|
|
82712
83149
|
...screenMutatingTools,
|
|
82713
83150
|
"mobile_assert_visible",
|
|
82714
|
-
"mobile_assert_text"
|
|
83151
|
+
"mobile_assert_text",
|
|
83152
|
+
"mobile_capture_state",
|
|
83153
|
+
"mobile_assert_state_delta"
|
|
82715
83154
|
]);
|
|
82716
83155
|
for (const toolCall of assistantMessage.tool_calls) {
|
|
82717
83156
|
const toolName = toolCall.function.name;
|
|
@@ -82755,7 +83194,7 @@ ${statePacket}`, redactionCredentials) },
|
|
|
82755
83194
|
if (intentReason)
|
|
82756
83195
|
reasons.push(intentReason);
|
|
82757
83196
|
if (verifiedWithoutAssert) {
|
|
82758
|
-
reasons.push("claimed verified:true but never called mobile_assert_visible / mobile_assert_text");
|
|
83197
|
+
reasons.push("claimed verified:true but never called mobile_assert_visible / mobile_assert_text / mobile_assert_state_delta");
|
|
82759
83198
|
}
|
|
82760
83199
|
if (strengthRejectReason !== null) {
|
|
82761
83200
|
reasons.push(`assertion strength: ${strengthRejectReason} \u2014 your only live proof re-checks a control you already used. Assert the scenario OUTCOME instead: an element on the resulting screen, the created/updated row, or the success/error message.`);
|
|
@@ -82826,10 +83265,12 @@ ${statePacket}`, redactionCredentials) },
|
|
|
82826
83265
|
}
|
|
82827
83266
|
} : action;
|
|
82828
83267
|
actions.push((0, shared_1.placeholderizeRecordedMobileAction)(finalizeAction(stamped), credentials));
|
|
82829
|
-
if (action.type === "ASSERT_VISIBLE" || action.type === "ASSERT_TEXT")
|
|
83268
|
+
if (action.type === "ASSERT_VISIBLE" || action.type === "ASSERT_TEXT" || action.type === "ASSERT_STATE_DELTA") {
|
|
82830
83269
|
assertCount++;
|
|
83270
|
+
}
|
|
82831
83271
|
},
|
|
82832
83272
|
recordedActions: actions,
|
|
83273
|
+
stateBag,
|
|
82833
83274
|
log: log2
|
|
82834
83275
|
});
|
|
82835
83276
|
if (screenMutatingTools.has(toolName))
|
|
@@ -82848,7 +83289,7 @@ ${statePacket}`, redactionCredentials) },
|
|
|
82848
83289
|
return { actions, assertCount, finish, lastSnapshot: lastTargetSnapshot, lastScreenName: lastTargetScreenName };
|
|
82849
83290
|
}
|
|
82850
83291
|
async function dispatchGenerateTool(args) {
|
|
82851
|
-
const { toolName, toolArgs, driver, platform: platform3, targetAppId, latest, absorbObservation, resolveRef, resolveHybridRef, maybeEnrichHybridWeb, setLatest, credentials, screenName, allowRelaunch, recordAction, recordedActions, log: log2 } = args;
|
|
83292
|
+
const { toolName, toolArgs, driver, platform: platform3, targetAppId, latest, absorbObservation, resolveRef, resolveHybridRef, maybeEnrichHybridWeb, setLatest, credentials, screenName, allowRelaunch, recordAction, recordedActions, stateBag, log: log2 } = args;
|
|
82852
83293
|
const unknownRef = (ref) => ({
|
|
82853
83294
|
ok: false,
|
|
82854
83295
|
error: `Unknown element ref "${String(ref)}". Call mobile_snapshot first; refs are only valid for the latest snapshot.`
|
|
@@ -83393,10 +83834,170 @@ ${statePacket}`, redactionCredentials) },
|
|
|
83393
83834
|
target: metadata.targetLabel
|
|
83394
83835
|
};
|
|
83395
83836
|
}
|
|
83837
|
+
case "mobile_capture_state": {
|
|
83838
|
+
const stateKey = nonEmpty3(typeof toolArgs.stateKey === "string" ? toolArgs.stateKey : "");
|
|
83839
|
+
if (!stateKey) {
|
|
83840
|
+
return { ok: false, error: "mobile_capture_state requires a non-empty stateKey." };
|
|
83841
|
+
}
|
|
83842
|
+
const kindRaw = typeof toolArgs.kind === "string" ? toolArgs.kind.trim() : "list_ids";
|
|
83843
|
+
const kind = kindRaw === "badge_count" ? "badge_count" : "list_ids";
|
|
83844
|
+
const snap = latest();
|
|
83845
|
+
if (!snap) {
|
|
83846
|
+
return { ok: false, error: "No snapshot yet \u2014 call mobile_snapshot before mobile_capture_state." };
|
|
83847
|
+
}
|
|
83848
|
+
const values = captureValuesFromElements(snap.screen.elements, kind);
|
|
83849
|
+
stateBag.set(stateKey, { kind, values });
|
|
83850
|
+
recordAction({
|
|
83851
|
+
type: "CAPTURE_STATE",
|
|
83852
|
+
selector: stateKey,
|
|
83853
|
+
metadata: {
|
|
83854
|
+
screenName: screenName(),
|
|
83855
|
+
targetLabel: stateKey,
|
|
83856
|
+
stateKey,
|
|
83857
|
+
stateKind: kind
|
|
83858
|
+
}
|
|
83859
|
+
});
|
|
83860
|
+
log2(` capture_state: key=${stateKey} kind=${kind} n=${values.length}`);
|
|
83861
|
+
return {
|
|
83862
|
+
ok: true,
|
|
83863
|
+
captured: true,
|
|
83864
|
+
stateKey,
|
|
83865
|
+
kind,
|
|
83866
|
+
sample: values.slice(0, 8),
|
|
83867
|
+
count: values.length
|
|
83868
|
+
};
|
|
83869
|
+
}
|
|
83870
|
+
case "mobile_assert_state_delta": {
|
|
83871
|
+
const stateKey = nonEmpty3(typeof toolArgs.stateKey === "string" ? toolArgs.stateKey : "");
|
|
83872
|
+
if (!stateKey) {
|
|
83873
|
+
return { ok: false, error: "mobile_assert_state_delta requires a non-empty stateKey." };
|
|
83874
|
+
}
|
|
83875
|
+
const prior = stateBag.get(stateKey);
|
|
83876
|
+
if (!prior) {
|
|
83877
|
+
return {
|
|
83878
|
+
ok: false,
|
|
83879
|
+
error: `No prior mobile_capture_state for key "${stateKey}". Capture before the mutating action, then assert.`
|
|
83880
|
+
};
|
|
83881
|
+
}
|
|
83882
|
+
const expectRaw = typeof toolArgs.expect === "string" ? toolArgs.expect.trim() : "changed";
|
|
83883
|
+
const expect = expectRaw || "changed";
|
|
83884
|
+
const snap = latest();
|
|
83885
|
+
if (!snap) {
|
|
83886
|
+
return { ok: false, error: "No snapshot yet \u2014 call mobile_snapshot after the action, then assert_state_delta." };
|
|
83887
|
+
}
|
|
83888
|
+
const current = captureValuesFromElements(snap.screen.elements, prior.kind);
|
|
83889
|
+
const liveError = liveAssertStateDelta(prior.values, current, expect, stateKey);
|
|
83890
|
+
if (liveError) {
|
|
83891
|
+
return {
|
|
83892
|
+
ok: false,
|
|
83893
|
+
error: liveError,
|
|
83894
|
+
beforeSample: prior.values.slice(0, 8),
|
|
83895
|
+
afterSample: current.slice(0, 8)
|
|
83896
|
+
};
|
|
83897
|
+
}
|
|
83898
|
+
recordAction({
|
|
83899
|
+
type: "ASSERT_STATE_DELTA",
|
|
83900
|
+
value: expect,
|
|
83901
|
+
selector: stateKey,
|
|
83902
|
+
metadata: {
|
|
83903
|
+
screenName: screenName(),
|
|
83904
|
+
targetLabel: stateKey,
|
|
83905
|
+
stateKey,
|
|
83906
|
+
stateKind: prior.kind,
|
|
83907
|
+
expect
|
|
83908
|
+
}
|
|
83909
|
+
});
|
|
83910
|
+
log2(` assert_state_delta: key=${stateKey} expect=${expect}`);
|
|
83911
|
+
return {
|
|
83912
|
+
ok: true,
|
|
83913
|
+
asserted: "state_delta",
|
|
83914
|
+
stateKey,
|
|
83915
|
+
expect,
|
|
83916
|
+
beforeCount: prior.values.length,
|
|
83917
|
+
afterCount: current.length
|
|
83918
|
+
};
|
|
83919
|
+
}
|
|
83396
83920
|
default:
|
|
83397
83921
|
return { ok: false, error: `Unknown tool: ${toolName}` };
|
|
83398
83922
|
}
|
|
83399
83923
|
}
|
|
83924
|
+
function captureValuesFromElements(elements, kind) {
|
|
83925
|
+
if (kind === "badge_count") {
|
|
83926
|
+
const nums = /* @__PURE__ */ new Set();
|
|
83927
|
+
const preferred = /* @__PURE__ */ new Set();
|
|
83928
|
+
for (const el of elements) {
|
|
83929
|
+
const t = [el.label, el.text, el.accessibilityId].filter(Boolean).join(" ");
|
|
83930
|
+
for (const m of t.matchAll(/\b(\d{1,6})\b/g))
|
|
83931
|
+
nums.add(m[1]);
|
|
83932
|
+
if (/(?:count|badge|open|unread|item|invoice|result|pending)/i.test(t)) {
|
|
83933
|
+
for (const m of t.matchAll(/\b(\d{1,6})\b/g))
|
|
83934
|
+
preferred.add(m[1]);
|
|
83935
|
+
}
|
|
83936
|
+
}
|
|
83937
|
+
return preferred.size > 0 ? [...preferred] : [...nums].slice(0, 20);
|
|
83938
|
+
}
|
|
83939
|
+
const labels = /* @__PURE__ */ new Set();
|
|
83940
|
+
for (const el of elements) {
|
|
83941
|
+
for (const raw of [el.label, el.text, el.accessibilityId]) {
|
|
83942
|
+
const t = raw?.trim() ?? "";
|
|
83943
|
+
if (t.length < 2 || t.length > 80)
|
|
83944
|
+
continue;
|
|
83945
|
+
if (/^(true|false|null|OK|Cancel)$/i.test(t))
|
|
83946
|
+
continue;
|
|
83947
|
+
labels.add(t);
|
|
83948
|
+
}
|
|
83949
|
+
}
|
|
83950
|
+
return [...labels].slice(0, 80);
|
|
83951
|
+
}
|
|
83952
|
+
function liveAssertStateDelta(before, after, expect, key) {
|
|
83953
|
+
const beforeSet = new Set(before);
|
|
83954
|
+
const afterSet = new Set(after);
|
|
83955
|
+
const removed = before.filter((v) => !afterSet.has(v));
|
|
83956
|
+
const added = after.filter((v) => !beforeSet.has(v));
|
|
83957
|
+
const exp = expect.toLowerCase().trim();
|
|
83958
|
+
if (exp === "changed" || exp === "any_change") {
|
|
83959
|
+
if (removed.length === 0 && added.length === 0) {
|
|
83960
|
+
return `assertStateDelta(${key}): expected change, captures identical (${before.length} values)`;
|
|
83961
|
+
}
|
|
83962
|
+
return null;
|
|
83963
|
+
}
|
|
83964
|
+
if (exp === "removed" || exp === "entity_removed" || exp.startsWith("removed:")) {
|
|
83965
|
+
if (removed.length === 0) {
|
|
83966
|
+
return `assertStateDelta(${key}): expected at least one entity removed`;
|
|
83967
|
+
}
|
|
83968
|
+
return null;
|
|
83969
|
+
}
|
|
83970
|
+
if (exp === "count_decreased" || exp === "count-1") {
|
|
83971
|
+
const b = before.map(Number).filter((n) => Number.isFinite(n));
|
|
83972
|
+
const a = after.map(Number).filter((n) => Number.isFinite(n));
|
|
83973
|
+
const bMax = b.length ? Math.max(...b) : NaN;
|
|
83974
|
+
const aMax = a.length ? Math.max(...a) : NaN;
|
|
83975
|
+
if (!Number.isFinite(bMax) || !Number.isFinite(aMax) || aMax >= bMax) {
|
|
83976
|
+
return `assertStateDelta(${key}): expected count decrease (before max=${bMax}, after max=${aMax})`;
|
|
83977
|
+
}
|
|
83978
|
+
return null;
|
|
83979
|
+
}
|
|
83980
|
+
if (exp === "count_increased" || exp === "count+1") {
|
|
83981
|
+
const b = before.map(Number).filter((n) => Number.isFinite(n));
|
|
83982
|
+
const a = after.map(Number).filter((n) => Number.isFinite(n));
|
|
83983
|
+
const bMax = b.length ? Math.max(...b) : NaN;
|
|
83984
|
+
const aMax = a.length ? Math.max(...a) : NaN;
|
|
83985
|
+
if (!Number.isFinite(bMax) || !Number.isFinite(aMax) || aMax <= bMax) {
|
|
83986
|
+
return `assertStateDelta(${key}): expected count increase (before max=${bMax}, after max=${aMax})`;
|
|
83987
|
+
}
|
|
83988
|
+
return null;
|
|
83989
|
+
}
|
|
83990
|
+
if (exp === "unchanged" || exp === "persisted") {
|
|
83991
|
+
if (removed.length > 0 || added.length > 0) {
|
|
83992
|
+
return `assertStateDelta(${key}): expected persistence/unchanged but set changed`;
|
|
83993
|
+
}
|
|
83994
|
+
return null;
|
|
83995
|
+
}
|
|
83996
|
+
if (removed.length === 0 && added.length === 0) {
|
|
83997
|
+
return `assertStateDelta(${key}): expected change (expect=${expect}), state identical`;
|
|
83998
|
+
}
|
|
83999
|
+
return null;
|
|
84000
|
+
}
|
|
83400
84001
|
function recordAssertVisible(toolArgs, ctx) {
|
|
83401
84002
|
const { resolveRef, latest, screenName, platform: platform3, recordAction } = ctx;
|
|
83402
84003
|
const element = resolveRef(toolArgs.ref);
|
|
@@ -84376,6 +84977,14 @@ ${statePacket}`, redactionCredentials) },
|
|
|
84376
84977
|
lines.push(` await expect(page.getByText('${expected}')).toBeVisible();`);
|
|
84377
84978
|
break;
|
|
84378
84979
|
}
|
|
84980
|
+
case "CAPTURE_STATE":
|
|
84981
|
+
lines.push(` // captureState ${escape((action.metadata.stateKey ?? label).slice(0, 40))}`);
|
|
84982
|
+
break;
|
|
84983
|
+
case "ASSERT_STATE_DELTA": {
|
|
84984
|
+
const expect = escape((action.metadata.expect ?? action.value ?? "changed").slice(0, 40));
|
|
84985
|
+
lines.push(` await expect(page.getByText('state:${expect}')).toBeVisible();`);
|
|
84986
|
+
break;
|
|
84987
|
+
}
|
|
84379
84988
|
case "CLEAR":
|
|
84380
84989
|
lines.push(` await page.getByLabel('${label}').fill('');`);
|
|
84381
84990
|
break;
|
|
@@ -84419,6 +85028,22 @@ ${statePacket}`, redactionCredentials) },
|
|
|
84419
85028
|
return [action.selector, action.value, action.innerText, action.metadata?.targetLabel].filter((v) => typeof v === "string" && v.trim().length > 0).join(" ");
|
|
84420
85029
|
}
|
|
84421
85030
|
function evaluateMobileAssertionStrength(actions) {
|
|
85031
|
+
if (actions.some((a) => a.type === "ASSERT_STATE_DELTA")) {
|
|
85032
|
+
return {
|
|
85033
|
+
ok: true,
|
|
85034
|
+
severity: "none",
|
|
85035
|
+
reason: "state-delta oracle proves a durable product change (identity/count/persistence)",
|
|
85036
|
+
signals: {
|
|
85037
|
+
apiTest: false,
|
|
85038
|
+
interacted: actions.some((a) => a.type === "TAP" || a.type === "TYPE" || a.type === "CLEAR"),
|
|
85039
|
+
mutated: actions.some((a) => a.type === "TYPE" || a.type === "CLEAR" || a.type === "TAP"),
|
|
85040
|
+
navOnly: false,
|
|
85041
|
+
hasOutcomeProof: true,
|
|
85042
|
+
errorBanner: false,
|
|
85043
|
+
terminal: null
|
|
85044
|
+
}
|
|
85045
|
+
};
|
|
85046
|
+
}
|
|
84422
85047
|
const modelAsserts = actions.filter((a) => a.type === "ASSERT_VISIBLE" || a.type === "ASSERT_TEXT");
|
|
84423
85048
|
if (modelAsserts.length === 0) {
|
|
84424
85049
|
return {
|
|
@@ -84588,6 +85213,16 @@ ${statePacket}`, redactionCredentials) },
|
|
|
84588
85213
|
if (coldResetUnavailable)
|
|
84589
85214
|
tags.push("@warm-state");
|
|
84590
85215
|
const strengthBlocked = !strengthVerdict.ok || strengthVerdict.severity === "block" || strengthVerdict.severity === "route-bug" || !verified || coldResetUnavailable;
|
|
85216
|
+
{
|
|
85217
|
+
const kind = (0, scenario_taxonomy_js_1.inferScenarioKind)(scenario);
|
|
85218
|
+
const hasStateOracle = compiled.steps.some((s) => s.action === "assertStateDelta" || s.action === "assertText" || s.action === "captureState");
|
|
85219
|
+
const strong = verified && !strengthBlocked && strengthVerdict.severity === "none" && ((0, scenario_taxonomy_js_1.isStrongOracleKind)(kind) || hasStateOracle);
|
|
85220
|
+
if (strong)
|
|
85221
|
+
tags.push("@strong-oracle");
|
|
85222
|
+
else if (!tags.includes("@smoke") && (kind === "smoke_nav" || kind === "navigation_integrity")) {
|
|
85223
|
+
tags.push("@smoke");
|
|
85224
|
+
}
|
|
85225
|
+
}
|
|
84591
85226
|
const strengthReason = coldResetUnavailable ? `Cold app-data reset unavailable${coldResetReason ? ` (${coldResetReason})` : ""} \u2014 generation may not match cold-boot replay. ${strengthVerdict.reason}` : !verified && recording.assertCount === 0 ? "Mobile scenario finished unverified \u2014 the agent never proved the scenario outcome live, so the recording may not demonstrate the goal (e.g. a happy path that never completed). Review before promotion." : strengthVerdict.reason;
|
|
84592
85227
|
const test = {
|
|
84593
85228
|
name: compiled.name,
|
|
@@ -84835,6 +85470,344 @@ Mobile generate phase complete: ${tests.length}/${scenarios.length} test(s) gene
|
|
|
84835
85470
|
}
|
|
84836
85471
|
});
|
|
84837
85472
|
|
|
85473
|
+
// ../runner-core/dist/services/mobile/failure-triage.js
|
|
85474
|
+
var require_failure_triage = __commonJS({
|
|
85475
|
+
"../runner-core/dist/services/mobile/failure-triage.js"(exports) {
|
|
85476
|
+
"use strict";
|
|
85477
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
85478
|
+
exports.hasStrongMobileOracle = hasStrongMobileOracle;
|
|
85479
|
+
exports.isStrongOracleStep = isStrongOracleStep;
|
|
85480
|
+
exports.listStrongOracleKinds = listStrongOracleKinds;
|
|
85481
|
+
exports.triageMobileFailure = triageMobileFailure;
|
|
85482
|
+
exports.triageToHealTerminal = triageToHealTerminal;
|
|
85483
|
+
var STRONG_ACTIONS = /* @__PURE__ */ new Set(["assertStateDelta", "assertText", "captureState"]);
|
|
85484
|
+
var CHROME_VISIBLE_RE = /\b(tab|home|settings|back|menu|navigation|nav bar|bottom nav|status bar)\b/i;
|
|
85485
|
+
function hasStrongMobileOracle(steps) {
|
|
85486
|
+
return steps.some(isStrongOracleStep);
|
|
85487
|
+
}
|
|
85488
|
+
function isStrongOracleStep(step) {
|
|
85489
|
+
if (STRONG_ACTIONS.has(step.action))
|
|
85490
|
+
return true;
|
|
85491
|
+
if (step.action !== "assertVisible")
|
|
85492
|
+
return false;
|
|
85493
|
+
const blob = [
|
|
85494
|
+
step.assertion ?? "",
|
|
85495
|
+
step.description ?? "",
|
|
85496
|
+
step.target?.primary ?? "",
|
|
85497
|
+
...step.target?.fallbacks ?? []
|
|
85498
|
+
].join(" ");
|
|
85499
|
+
if (/\b(error|invalid|required|must|cannot|failed|denied|blocked|empty|missing|deleted|removed|saved|success|created|updated)\b/i.test(blob)) {
|
|
85500
|
+
return true;
|
|
85501
|
+
}
|
|
85502
|
+
if (CHROME_VISIBLE_RE.test(blob) && blob.length < 80)
|
|
85503
|
+
return false;
|
|
85504
|
+
return false;
|
|
85505
|
+
}
|
|
85506
|
+
function listStrongOracleKinds(steps) {
|
|
85507
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
85508
|
+
for (const step of steps) {
|
|
85509
|
+
if (step.action === "assertStateDelta")
|
|
85510
|
+
kinds.add("assertStateDelta");
|
|
85511
|
+
else if (step.action === "assertText")
|
|
85512
|
+
kinds.add("assertText");
|
|
85513
|
+
else if (step.action === "captureState")
|
|
85514
|
+
kinds.add("captureState");
|
|
85515
|
+
else if (isStrongOracleStep(step))
|
|
85516
|
+
kinds.add(step.action);
|
|
85517
|
+
}
|
|
85518
|
+
return [...kinds];
|
|
85519
|
+
}
|
|
85520
|
+
function errorText(error2, logs2) {
|
|
85521
|
+
return `${error2 ?? ""}
|
|
85522
|
+
${logs2 ?? ""}`.trim();
|
|
85523
|
+
}
|
|
85524
|
+
function leadingPrefix(error2) {
|
|
85525
|
+
if (!error2)
|
|
85526
|
+
return null;
|
|
85527
|
+
const m = error2.match(/^(CONFIG_ISSUE|APP_BUG|RATE_LIMIT_BLOCKED|PREREQ_UNMET|HEAL_SECRET_LEAK)\s*:/i);
|
|
85528
|
+
return m ? m[1].toUpperCase() : null;
|
|
85529
|
+
}
|
|
85530
|
+
function looksLikeConfig(text) {
|
|
85531
|
+
if (/CONFIG_ISSUE\s*:/i.test(text))
|
|
85532
|
+
return true;
|
|
85533
|
+
if (/RATE_LIMIT_BLOCKED\s*:/i.test(text))
|
|
85534
|
+
return true;
|
|
85535
|
+
if (/Missing mobile test variable/i.test(text))
|
|
85536
|
+
return true;
|
|
85537
|
+
if (/\b(quota|rate.?limit|429|lockout)\b/i.test(text))
|
|
85538
|
+
return true;
|
|
85539
|
+
if (/\b(device (?:offline|disconnected|not found)|session (?:not started|terminated|deleted))\b/i.test(text)) {
|
|
85540
|
+
return true;
|
|
85541
|
+
}
|
|
85542
|
+
if (/\b(Appium|adbExec|UiAutomator2|XCUITest)\b/i.test(text) && /\b(ECONNREFUSED|timeout|not available|could not start|driver)\b/i.test(text)) {
|
|
85543
|
+
return true;
|
|
85544
|
+
}
|
|
85545
|
+
return false;
|
|
85546
|
+
}
|
|
85547
|
+
function looksLikePrereq(text) {
|
|
85548
|
+
return /PREREQ_UNMET\s*:/i.test(text) || /\b(prerequisite|fixture missing|no test data|account (?:missing|not provisioned)|required entity)\b/i.test(text);
|
|
85549
|
+
}
|
|
85550
|
+
function looksLikeFlake(text) {
|
|
85551
|
+
return /\b(stale element|animation|transition|intermittent|flaky|race condition)\b/i.test(text) || /\b(element (?:is )?not interactable|obscured|covered by)\b/i.test(text);
|
|
85552
|
+
}
|
|
85553
|
+
function looksLikeLocatorMiss(text) {
|
|
85554
|
+
return /not found|no such element|No identity locator|unable to locate/i.test(text);
|
|
85555
|
+
}
|
|
85556
|
+
function looksLikeOracleFailure(text) {
|
|
85557
|
+
return /assertStateDelta/i.test(text) || /expected state/i.test(text) || /expected (?:["'].+["'] )?(?:to be |text|visible|removed|count)/i.test(text) || /assertion failed|Assert .+ (?:visible|shows|contains)/i.test(text);
|
|
85558
|
+
}
|
|
85559
|
+
function triageMobileFailure(input) {
|
|
85560
|
+
const failureCount = Math.max(1, input.failureCount ?? 1);
|
|
85561
|
+
const tags = input.tags ?? [];
|
|
85562
|
+
const text = errorText(input.error, input.logs);
|
|
85563
|
+
const prefix = leadingPrefix(input.error);
|
|
85564
|
+
const strongKinds = listStrongOracleKinds(input.steps);
|
|
85565
|
+
const hasStrong = strongKinds.length > 0 || tags.some((t) => t === "@strong-oracle" || t === "strong-oracle");
|
|
85566
|
+
const evidence = {
|
|
85567
|
+
hasStrongOracle: hasStrong,
|
|
85568
|
+
strongOracleKinds: strongKinds,
|
|
85569
|
+
failureCount,
|
|
85570
|
+
errorPrefix: prefix
|
|
85571
|
+
};
|
|
85572
|
+
if (prefix === "CONFIG_ISSUE" || prefix === "RATE_LIMIT_BLOCKED") {
|
|
85573
|
+
return {
|
|
85574
|
+
verdict: "config_issue",
|
|
85575
|
+
reason: `Environment/config prefix on error (${prefix})`,
|
|
85576
|
+
shouldHeal: false,
|
|
85577
|
+
healVerdict: "config_issue",
|
|
85578
|
+
evidence
|
|
85579
|
+
};
|
|
85580
|
+
}
|
|
85581
|
+
if (prefix === "APP_BUG") {
|
|
85582
|
+
return {
|
|
85583
|
+
verdict: "app_bug_candidate",
|
|
85584
|
+
reason: "Error already classified APP_BUG",
|
|
85585
|
+
shouldHeal: false,
|
|
85586
|
+
healVerdict: "app_bug",
|
|
85587
|
+
evidence
|
|
85588
|
+
};
|
|
85589
|
+
}
|
|
85590
|
+
if (prefix === "PREREQ_UNMET") {
|
|
85591
|
+
return {
|
|
85592
|
+
verdict: "prereq_unmet",
|
|
85593
|
+
reason: "Error already classified PREREQ_UNMET",
|
|
85594
|
+
shouldHeal: false,
|
|
85595
|
+
healVerdict: "prereq_unmet",
|
|
85596
|
+
evidence
|
|
85597
|
+
};
|
|
85598
|
+
}
|
|
85599
|
+
if (looksLikeConfig(text)) {
|
|
85600
|
+
return {
|
|
85601
|
+
verdict: "config_issue",
|
|
85602
|
+
reason: "Failure matches environment/config/device patterns",
|
|
85603
|
+
shouldHeal: false,
|
|
85604
|
+
healVerdict: "config_issue",
|
|
85605
|
+
evidence
|
|
85606
|
+
};
|
|
85607
|
+
}
|
|
85608
|
+
if (looksLikePrereq(text)) {
|
|
85609
|
+
return {
|
|
85610
|
+
verdict: "prereq_unmet",
|
|
85611
|
+
reason: "Failure matches missing prerequisite / fixture patterns",
|
|
85612
|
+
shouldHeal: false,
|
|
85613
|
+
healVerdict: "prereq_unmet",
|
|
85614
|
+
evidence
|
|
85615
|
+
};
|
|
85616
|
+
}
|
|
85617
|
+
if (input.uiSuccessWithFailedWriteApi && hasStrong) {
|
|
85618
|
+
return {
|
|
85619
|
+
verdict: "app_bug_candidate",
|
|
85620
|
+
reason: "UI path completed but a write API failed (network secondary oracle)",
|
|
85621
|
+
shouldHeal: false,
|
|
85622
|
+
healVerdict: "app_bug",
|
|
85623
|
+
evidence
|
|
85624
|
+
};
|
|
85625
|
+
}
|
|
85626
|
+
if (hasStrong && failureCount >= 2 && (looksLikeOracleFailure(text) || !looksLikeLocatorMiss(text))) {
|
|
85627
|
+
if (looksLikeLocatorMiss(text) && failureCount < 3) {
|
|
85628
|
+
return {
|
|
85629
|
+
verdict: "needs_heal",
|
|
85630
|
+
reason: "Strong oracle present but error looks like a locator miss \u2014 attempt heal",
|
|
85631
|
+
shouldHeal: true,
|
|
85632
|
+
evidence
|
|
85633
|
+
};
|
|
85634
|
+
}
|
|
85635
|
+
return {
|
|
85636
|
+
verdict: "app_bug_candidate",
|
|
85637
|
+
reason: `Strong oracle (${strongKinds.join(", ") || "tagged"}) failed ${failureCount}\xD7 with product-shaped error`,
|
|
85638
|
+
shouldHeal: false,
|
|
85639
|
+
healVerdict: "app_bug",
|
|
85640
|
+
evidence
|
|
85641
|
+
};
|
|
85642
|
+
}
|
|
85643
|
+
if (looksLikeFlake(text) && failureCount === 1 && !hasStrong) {
|
|
85644
|
+
return {
|
|
85645
|
+
verdict: "flake_candidate",
|
|
85646
|
+
reason: "Transient interactability / race signals on a weak-oracle test",
|
|
85647
|
+
shouldHeal: true,
|
|
85648
|
+
// still allow heal, but tag flaky path
|
|
85649
|
+
extraTags: ["@flaky"],
|
|
85650
|
+
evidence
|
|
85651
|
+
};
|
|
85652
|
+
}
|
|
85653
|
+
if (tags.includes("@smoke") && !hasStrong && looksLikeLocatorMiss(text)) {
|
|
85654
|
+
return {
|
|
85655
|
+
verdict: "needs_heal",
|
|
85656
|
+
reason: "Smoke/nav locator failure \u2014 heal allowed",
|
|
85657
|
+
shouldHeal: true,
|
|
85658
|
+
evidence
|
|
85659
|
+
};
|
|
85660
|
+
}
|
|
85661
|
+
return {
|
|
85662
|
+
verdict: "needs_heal",
|
|
85663
|
+
reason: hasStrong ? "Strong oracle first failure \u2014 allow heal once before APP_BUG escalation" : "Default: attempt script/live heal",
|
|
85664
|
+
shouldHeal: true,
|
|
85665
|
+
evidence
|
|
85666
|
+
};
|
|
85667
|
+
}
|
|
85668
|
+
function triageToHealTerminal(triage) {
|
|
85669
|
+
if (triage.shouldHeal || !triage.healVerdict)
|
|
85670
|
+
return null;
|
|
85671
|
+
return {
|
|
85672
|
+
verdict: triage.healVerdict,
|
|
85673
|
+
healReason: triage.reason,
|
|
85674
|
+
extraTags: triage.extraTags
|
|
85675
|
+
};
|
|
85676
|
+
}
|
|
85677
|
+
}
|
|
85678
|
+
});
|
|
85679
|
+
|
|
85680
|
+
// ../runner-core/dist/services/mobile/oracle-protection.js
|
|
85681
|
+
var require_oracle_protection = __commonJS({
|
|
85682
|
+
"../runner-core/dist/services/mobile/oracle-protection.js"(exports) {
|
|
85683
|
+
"use strict";
|
|
85684
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
85685
|
+
exports.fingerprintOracles = fingerprintOracles;
|
|
85686
|
+
exports.rejectOracleWeakeningPatch = rejectOracleWeakeningPatch;
|
|
85687
|
+
exports.oraclesPreserved = oraclesPreserved;
|
|
85688
|
+
var failure_triage_js_1 = require_failure_triage();
|
|
85689
|
+
var EXPECT_STRENGTH = {
|
|
85690
|
+
entity_removed: 5,
|
|
85691
|
+
removed: 5,
|
|
85692
|
+
count_decreased: 4,
|
|
85693
|
+
"count-1": 4,
|
|
85694
|
+
count_increased: 4,
|
|
85695
|
+
"count+1": 4,
|
|
85696
|
+
persisted: 3,
|
|
85697
|
+
unchanged: 3,
|
|
85698
|
+
changed: 2,
|
|
85699
|
+
any_change: 2
|
|
85700
|
+
};
|
|
85701
|
+
function normalizeText(value) {
|
|
85702
|
+
return (value ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
85703
|
+
}
|
|
85704
|
+
function stateKeyOf(step) {
|
|
85705
|
+
const meta = step.metadata;
|
|
85706
|
+
const key = typeof meta?.stateKey === "string" ? meta.stateKey.trim() : "";
|
|
85707
|
+
return key || normalizeText(step.target?.primary) || normalizeText(step.description) || `order-${step.order}`;
|
|
85708
|
+
}
|
|
85709
|
+
function expectOf(step) {
|
|
85710
|
+
const meta = step.metadata;
|
|
85711
|
+
const fromMeta = typeof meta?.expect === "string" ? meta.expect : "";
|
|
85712
|
+
return normalizeText(fromMeta || step.assertion || step.value || "changed");
|
|
85713
|
+
}
|
|
85714
|
+
function fingerprintOracles(steps) {
|
|
85715
|
+
const assertTexts = [];
|
|
85716
|
+
const stateExpects = {};
|
|
85717
|
+
let stateDeltas = 0;
|
|
85718
|
+
let captures = 0;
|
|
85719
|
+
let strongVisible = 0;
|
|
85720
|
+
for (const step of steps) {
|
|
85721
|
+
if (step.action === "assertStateDelta") {
|
|
85722
|
+
stateDeltas += 1;
|
|
85723
|
+
stateExpects[stateKeyOf(step)] = expectOf(step);
|
|
85724
|
+
} else if (step.action === "captureState")
|
|
85725
|
+
captures += 1;
|
|
85726
|
+
else if (step.action === "assertText") {
|
|
85727
|
+
const t = normalizeText(step.assertion ?? step.value ?? step.description);
|
|
85728
|
+
if (t)
|
|
85729
|
+
assertTexts.push(t);
|
|
85730
|
+
} else if (step.action === "assertVisible" && (0, failure_triage_js_1.isStrongOracleStep)(step)) {
|
|
85731
|
+
strongVisible += 1;
|
|
85732
|
+
}
|
|
85733
|
+
}
|
|
85734
|
+
return {
|
|
85735
|
+
stateDeltas,
|
|
85736
|
+
captures,
|
|
85737
|
+
assertTexts,
|
|
85738
|
+
stateExpects,
|
|
85739
|
+
strongVisible,
|
|
85740
|
+
strongTotal: stateDeltas + captures + assertTexts.length + strongVisible
|
|
85741
|
+
};
|
|
85742
|
+
}
|
|
85743
|
+
function expectStrength(expect) {
|
|
85744
|
+
const e = expect.toLowerCase().trim();
|
|
85745
|
+
if (e.startsWith("removed:"))
|
|
85746
|
+
return 5;
|
|
85747
|
+
return EXPECT_STRENGTH[e] ?? 1;
|
|
85748
|
+
}
|
|
85749
|
+
function rejectOracleWeakeningPatch(original, patched) {
|
|
85750
|
+
if (!Array.isArray(patched) || patched.length === 0) {
|
|
85751
|
+
return "healed steps missing \u2014 refusing empty patch that would drop oracles";
|
|
85752
|
+
}
|
|
85753
|
+
const before = fingerprintOracles(original);
|
|
85754
|
+
const after = fingerprintOracles(patched);
|
|
85755
|
+
if (before.stateDeltas > 0 && after.stateDeltas < before.stateDeltas) {
|
|
85756
|
+
return `heal patch removed assertStateDelta oracle(s) (${before.stateDeltas} \u2192 ${after.stateDeltas}) \u2014 refusing to go green by dropping state proof`;
|
|
85757
|
+
}
|
|
85758
|
+
for (const [key, beforeExpect] of Object.entries(before.stateExpects)) {
|
|
85759
|
+
const afterExpect = after.stateExpects[key];
|
|
85760
|
+
if (!afterExpect) {
|
|
85761
|
+
return `heal patch removed assertStateDelta for key "${key}" (expect was ${beforeExpect})`;
|
|
85762
|
+
}
|
|
85763
|
+
if (expectStrength(afterExpect) < expectStrength(beforeExpect)) {
|
|
85764
|
+
return `heal patch softened assertStateDelta expect for "${key}" (${beforeExpect} \u2192 ${afterExpect})`;
|
|
85765
|
+
}
|
|
85766
|
+
}
|
|
85767
|
+
if (before.captures > 0 && after.captures < before.captures && after.stateDeltas === 0) {
|
|
85768
|
+
return `heal patch removed captureState without keeping assertStateDelta (${before.captures} \u2192 ${after.captures})`;
|
|
85769
|
+
}
|
|
85770
|
+
if (before.assertTexts.length > 0) {
|
|
85771
|
+
const afterSet = new Set(after.assertTexts);
|
|
85772
|
+
const lost = before.assertTexts.filter((t) => !afterSet.has(t));
|
|
85773
|
+
if (after.assertTexts.length < before.assertTexts.length) {
|
|
85774
|
+
return `heal patch dropped assertText outcome proof (${before.assertTexts.length} \u2192 ${after.assertTexts.length})`;
|
|
85775
|
+
}
|
|
85776
|
+
if (lost.length > 0) {
|
|
85777
|
+
const softKept = lost.every((t) => after.assertTexts.some((a) => a.includes(t) || t.includes(a)));
|
|
85778
|
+
if (!softKept) {
|
|
85779
|
+
return `heal patch replaced assertText expectations (${lost.slice(0, 2).join("; ")}) \u2014 outcome must stay`;
|
|
85780
|
+
}
|
|
85781
|
+
}
|
|
85782
|
+
}
|
|
85783
|
+
if (before.strongVisible > 0 && after.strongVisible + after.assertTexts.length + after.stateDeltas < before.strongVisible) {
|
|
85784
|
+
return `heal patch weakened strong assertVisible validation oracles (${before.strongVisible} \u2192 ${after.strongVisible})`;
|
|
85785
|
+
}
|
|
85786
|
+
if (before.strongTotal > 0 && after.strongTotal === 0) {
|
|
85787
|
+
return "heal patch removed all strong oracles \u2014 refusing visibility-only green path";
|
|
85788
|
+
}
|
|
85789
|
+
for (const orig of original) {
|
|
85790
|
+
if (orig.action !== "assertStateDelta" && orig.action !== "assertText")
|
|
85791
|
+
continue;
|
|
85792
|
+
const key = normalizeText(orig.description ?? orig.assertion ?? "");
|
|
85793
|
+
if (!key)
|
|
85794
|
+
continue;
|
|
85795
|
+
const stillStrong = patched.some((p) => (p.action === "assertStateDelta" || p.action === "assertText") && normalizeText(p.description ?? p.assertion ?? "") === key);
|
|
85796
|
+
if (stillStrong)
|
|
85797
|
+
continue;
|
|
85798
|
+
const onlyVisible = patched.some((p) => p.action === "assertVisible" && normalizeText(p.description ?? p.assertion ?? "") === key);
|
|
85799
|
+
if (onlyVisible) {
|
|
85800
|
+
return `heal patch downgraded strong oracle "${key.slice(0, 60)}" to assertVisible`;
|
|
85801
|
+
}
|
|
85802
|
+
}
|
|
85803
|
+
return null;
|
|
85804
|
+
}
|
|
85805
|
+
function oraclesPreserved(original, patched) {
|
|
85806
|
+
return rejectOracleWeakeningPatch(original, patched) === null;
|
|
85807
|
+
}
|
|
85808
|
+
}
|
|
85809
|
+
});
|
|
85810
|
+
|
|
84838
85811
|
// ../runner-core/dist/services/mobile/mobile-heal-postprocess.js
|
|
84839
85812
|
var require_mobile_heal_postprocess = __commonJS({
|
|
84840
85813
|
"../runner-core/dist/services/mobile/mobile-heal-postprocess.js"(exports) {
|
|
@@ -84843,6 +85816,7 @@ var require_mobile_heal_postprocess = __commonJS({
|
|
|
84843
85816
|
exports.redactMobileSecretsFromText = redactMobileSecretsFromText;
|
|
84844
85817
|
exports.detectMobileStepSecretLeak = detectMobileStepSecretLeak;
|
|
84845
85818
|
exports.computeMobileHealOutcome = computeMobileHealOutcome2;
|
|
85819
|
+
var oracle_protection_js_1 = require_oracle_protection();
|
|
84846
85820
|
var REDACT_KEY_RE = /email|username|user|phone|password|secret|token|api[_-]?key|access[_-]?key|\bpass\b|credential|bearer|\bpat\b|session|cookie|jwt|otp|pin/i;
|
|
84847
85821
|
var DETECT_KEY_RE = /password|secret|token|api[_]?key|\bpass\b|credential|bearer|\bpat\b/i;
|
|
84848
85822
|
var MIN_REDACT_LEN = 4;
|
|
@@ -84908,18 +85882,27 @@ var require_mobile_heal_postprocess = __commonJS({
|
|
|
84908
85882
|
function computeMobileHealOutcome2(args) {
|
|
84909
85883
|
const { heal } = args;
|
|
84910
85884
|
const hasFix = Array.isArray(heal.healedSteps) && heal.healedSteps.length > 0;
|
|
84911
|
-
|
|
85885
|
+
let isVerifiedFix = heal.passed === true && heal.verdict === "fix" && hasFix;
|
|
84912
85886
|
const secretLeak = isVerifiedFix ? detectMobileStepSecretLeak(heal.healedSteps, args.testVariables) : null;
|
|
85887
|
+
const oracleWeakening = isVerifiedFix && args.originalSteps ? (0, oracle_protection_js_1.rejectOracleWeakeningPatch)(args.originalSteps, heal.healedSteps ?? []) : null;
|
|
85888
|
+
if (oracleWeakening)
|
|
85889
|
+
isVerifiedFix = false;
|
|
84913
85890
|
const isConfigIssue = heal.verdict === "config_issue";
|
|
84914
|
-
const isAppBug = heal.verdict === "app_bug";
|
|
85891
|
+
const isAppBug = heal.verdict === "app_bug" || Boolean(oracleWeakening && heal.passed);
|
|
84915
85892
|
const extraTags = new Set((heal.extraTags ?? []).filter((t) => typeof t === "string" && t.length > 0));
|
|
84916
85893
|
if (secretLeak)
|
|
84917
85894
|
extraTags.add("@needs-review");
|
|
85895
|
+
if (oracleWeakening) {
|
|
85896
|
+
extraTags.add("@needs-review");
|
|
85897
|
+
extraTags.add("@bug-found");
|
|
85898
|
+
}
|
|
84918
85899
|
if (!heal.passed && NEEDS_REVIEW_VERDICTS.has(heal.verdict))
|
|
84919
85900
|
extraTags.add("@needs-review");
|
|
84920
85901
|
let status;
|
|
84921
85902
|
if (secretLeak)
|
|
84922
85903
|
status = "FAILED";
|
|
85904
|
+
else if (oracleWeakening)
|
|
85905
|
+
status = "FAILED";
|
|
84923
85906
|
else if (isVerifiedFix)
|
|
84924
85907
|
status = "PASSED";
|
|
84925
85908
|
else if (isConfigIssue)
|
|
@@ -84931,6 +85914,8 @@ var require_mobile_heal_postprocess = __commonJS({
|
|
|
84931
85914
|
error2 = void 0;
|
|
84932
85915
|
} else if (secretLeak) {
|
|
84933
85916
|
error2 = `HEAL_SECRET_LEAK: healed steps contained a literal secret (${secretLeak}); patch dropped, tagged @needs-review`;
|
|
85917
|
+
} else if (oracleWeakening) {
|
|
85918
|
+
error2 = `APP_BUG: heal attempted to drop strong oracle (${oracleWeakening}); patch refused`;
|
|
84934
85919
|
} else if (isConfigIssue) {
|
|
84935
85920
|
error2 = `CONFIG_ISSUE: ${heal.healReason ?? args.finalError ?? args.reproduceError ?? "environment/rate-limit blocker"}`;
|
|
84936
85921
|
} else if (isAppBug) {
|
|
@@ -84947,13 +85932,64 @@ var require_mobile_heal_postprocess = __commonJS({
|
|
|
84947
85932
|
error: error2,
|
|
84948
85933
|
extraTags: extraTags.size > 0 ? [...extraTags] : void 0,
|
|
84949
85934
|
removeTags: heal.removeTags,
|
|
84950
|
-
shouldPatch: isVerifiedFix && !secretLeak,
|
|
85935
|
+
shouldPatch: isVerifiedFix && !secretLeak && !oracleWeakening,
|
|
84951
85936
|
secretLeak
|
|
84952
85937
|
};
|
|
84953
85938
|
}
|
|
84954
85939
|
}
|
|
84955
85940
|
});
|
|
84956
85941
|
|
|
85942
|
+
// ../runner-core/dist/services/mobile/network-oracle.js
|
|
85943
|
+
var require_network_oracle = __commonJS({
|
|
85944
|
+
"../runner-core/dist/services/mobile/network-oracle.js"(exports) {
|
|
85945
|
+
"use strict";
|
|
85946
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
85947
|
+
exports.evaluateNetworkSecondaryOracle = evaluateNetworkSecondaryOracle;
|
|
85948
|
+
exports.uiSuccessWithFailedWriteApi = uiSuccessWithFailedWriteApi;
|
|
85949
|
+
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
85950
|
+
function isWrite(method) {
|
|
85951
|
+
return WRITE_METHODS.has(method.toUpperCase());
|
|
85952
|
+
}
|
|
85953
|
+
function isServerOrClientError(status) {
|
|
85954
|
+
return status >= 400 && status < 600;
|
|
85955
|
+
}
|
|
85956
|
+
function isNoiseUrl(url) {
|
|
85957
|
+
return /\b(analytics|telemetry|sentry|bugsnag|crashlytics|facebook\.com\/tr|google-analytics|doubleclick|hotjar|segment\.io|amplitude|mixpanel)\b/i.test(url);
|
|
85958
|
+
}
|
|
85959
|
+
function evaluateNetworkSecondaryOracle(input) {
|
|
85960
|
+
const calls = input.apiCalls;
|
|
85961
|
+
if (!calls || calls.length === 0)
|
|
85962
|
+
return null;
|
|
85963
|
+
if (input.uiPathSucceeded === false)
|
|
85964
|
+
return null;
|
|
85965
|
+
for (const call of calls) {
|
|
85966
|
+
const method = String(call.method ?? "GET");
|
|
85967
|
+
const url = String(call.url ?? "");
|
|
85968
|
+
const status = typeof call.status === "number" ? call.status : 0;
|
|
85969
|
+
if (!isWrite(method))
|
|
85970
|
+
continue;
|
|
85971
|
+
if (!isServerOrClientError(status))
|
|
85972
|
+
continue;
|
|
85973
|
+
if (!url || isNoiseUrl(url))
|
|
85974
|
+
continue;
|
|
85975
|
+
if (status === 401 || status === 403)
|
|
85976
|
+
continue;
|
|
85977
|
+
return {
|
|
85978
|
+
kind: "write_api_failed",
|
|
85979
|
+
method: method.toUpperCase(),
|
|
85980
|
+
url: url.slice(0, 200),
|
|
85981
|
+
status,
|
|
85982
|
+
reason: `Write API ${method.toUpperCase()} ${url.slice(0, 120)} returned ${status} while UI path appeared successful`
|
|
85983
|
+
};
|
|
85984
|
+
}
|
|
85985
|
+
return null;
|
|
85986
|
+
}
|
|
85987
|
+
function uiSuccessWithFailedWriteApi(input) {
|
|
85988
|
+
return evaluateNetworkSecondaryOracle(input) !== null;
|
|
85989
|
+
}
|
|
85990
|
+
}
|
|
85991
|
+
});
|
|
85992
|
+
|
|
84957
85993
|
// ../runner-core/dist/services/selector-registry-context.js
|
|
84958
85994
|
var require_selector_registry_context = __commonJS({
|
|
84959
85995
|
"../runner-core/dist/services/selector-registry-context.js"(exports) {
|
|
@@ -85321,6 +86357,9 @@ var require_mobile_heal_loop = __commonJS({
|
|
|
85321
86357
|
var ai_retry_js_1 = require_ai_retry();
|
|
85322
86358
|
var mobile_source_parser_js_1 = require_mobile_source_parser();
|
|
85323
86359
|
var mobile_heal_postprocess_js_1 = require_mobile_heal_postprocess();
|
|
86360
|
+
var failure_triage_js_1 = require_failure_triage();
|
|
86361
|
+
var oracle_protection_js_1 = require_oracle_protection();
|
|
86362
|
+
var network_oracle_js_1 = require_network_oracle();
|
|
85324
86363
|
var mobile_observation_js_1 = require_mobile_observation();
|
|
85325
86364
|
var selector_registry_context_js_1 = require_selector_registry_context();
|
|
85326
86365
|
var mobile_session_keepalive_js_1 = require_mobile_session_keepalive();
|
|
@@ -85343,7 +86382,12 @@ Reason over steps + error + tree + registry and return working healed steps. Do
|
|
|
85343
86382
|
{"verdict":"state_stale","reason":"leftover data blocks a baseline assertion"}
|
|
85344
86383
|
{"verdict":"test_invalid","reason":"scenario cannot be made to pass"}
|
|
85345
86384
|
{"verdict":"unhealable_dynamic","reason":"asserted value is inherently volatile (timestamps, counters, feeds) \u2014 no durable locator can exist; needs human review"}
|
|
85346
|
-
For a fix, return the COMPLETE steps array (not a diff)
|
|
86385
|
+
For a fix, return the COMPLETE steps array (not a diff).
|
|
86386
|
+
## Strong oracle protection (non-negotiable)
|
|
86387
|
+
- NEVER remove or downgrade assertStateDelta, captureState, or assertText outcome proof to go green.
|
|
86388
|
+
- NEVER replace a durable outcome assert with mere assertVisible of a tab/header.
|
|
86389
|
+
- You MAY fix locators, waits, and navigation around those oracles.
|
|
86390
|
+
- If the app truly violates the oracle, return verdict "app_bug" instead of stripping the assert.`;
|
|
85347
86391
|
var DEFAULT_SCRIPT_MAX_ATTEMPTS = 6;
|
|
85348
86392
|
var RECOVERABLE_MAX = 3;
|
|
85349
86393
|
var MAX_CONSECUTIVE_INVALID_VERDICTS = 3;
|
|
@@ -85373,7 +86417,9 @@ For a fix, return the COMPLETE steps array (not a diff).`;
|
|
|
85373
86417
|
"home",
|
|
85374
86418
|
"waitForElement",
|
|
85375
86419
|
"assertVisible",
|
|
85376
|
-
"assertText"
|
|
86420
|
+
"assertText",
|
|
86421
|
+
"captureState",
|
|
86422
|
+
"assertStateDelta"
|
|
85377
86423
|
]);
|
|
85378
86424
|
var MAX_HEALED_STEPS = 300;
|
|
85379
86425
|
var TERMINAL_VERDICTS = /* @__PURE__ */ new Set([
|
|
@@ -85400,6 +86446,28 @@ For a fix, return the COMPLETE steps array (not a diff).`;
|
|
|
85400
86446
|
function isMobileHealVerdict(value) {
|
|
85401
86447
|
return MOBILE_HEAL_VERDICTS.includes(value);
|
|
85402
86448
|
}
|
|
86449
|
+
function normalizeMobileHealVerdict(raw) {
|
|
86450
|
+
const v = raw.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
86451
|
+
if (isMobileHealVerdict(v))
|
|
86452
|
+
return v;
|
|
86453
|
+
if (v === "appbug" || v === "application_bug" || v === "bug_found")
|
|
86454
|
+
return "app_bug";
|
|
86455
|
+
if (v === "config" || v === "configuration_issue" || v === "env" || v === "environment")
|
|
86456
|
+
return "config_issue";
|
|
86457
|
+
if (v === "prereq" || v === "prerequisite" || v === "prereq_missing")
|
|
86458
|
+
return "prereq_unmet";
|
|
86459
|
+
if (v === "stale" || v === "stale_state")
|
|
86460
|
+
return "state_stale";
|
|
86461
|
+
if (v === "invalid_test" || v === "bad_test")
|
|
86462
|
+
return "test_invalid";
|
|
86463
|
+
if (v === "unhealable" || v === "dynamic")
|
|
86464
|
+
return "unhealable_dynamic";
|
|
86465
|
+
if (v === "need_device" || v === "needs_appium" || v === "needs_live")
|
|
86466
|
+
return "needs_device";
|
|
86467
|
+
if (v === "healed" || v === "ok" || v === "pass" || v === "passed")
|
|
86468
|
+
return "fix";
|
|
86469
|
+
return null;
|
|
86470
|
+
}
|
|
85403
86471
|
function isLocatorNotFound(error2) {
|
|
85404
86472
|
return /not found|no such element/i.test(error2 ?? "");
|
|
85405
86473
|
}
|
|
@@ -85681,15 +86749,43 @@ For a fix, return the COMPLETE steps array (not a diff).`;
|
|
|
85681
86749
|
const sub = extractBracesSubstring(cleaned);
|
|
85682
86750
|
obj = sub ? safeJsonParse(sub) : void 0;
|
|
85683
86751
|
}
|
|
85684
|
-
if (!isRecord(obj))
|
|
86752
|
+
if (!isRecord(obj)) {
|
|
86753
|
+
const line = cleaned.match(/\bverdict\s*[:=]\s*["']?([a-zA-Z_ -]+)["']?/i);
|
|
86754
|
+
if (line) {
|
|
86755
|
+
const verdict2 = normalizeMobileHealVerdict(line[1]);
|
|
86756
|
+
if (verdict2) {
|
|
86757
|
+
return {
|
|
86758
|
+
verdict: verdict2,
|
|
86759
|
+
reason: cleaned.slice(0, 2e3)
|
|
86760
|
+
};
|
|
86761
|
+
}
|
|
86762
|
+
}
|
|
86763
|
+
const prefix = cleaned.match(/^\s*(APP_BUG|CONFIG_ISSUE|PREREQ_UNMET|TEST_INVALID|STATE_STALE)\s*:\s*(.*)$/im);
|
|
86764
|
+
if (prefix) {
|
|
86765
|
+
const map2 = {
|
|
86766
|
+
APP_BUG: "app_bug",
|
|
86767
|
+
CONFIG_ISSUE: "config_issue",
|
|
86768
|
+
PREREQ_UNMET: "prereq_unmet",
|
|
86769
|
+
TEST_INVALID: "test_invalid",
|
|
86770
|
+
STATE_STALE: "state_stale"
|
|
86771
|
+
};
|
|
86772
|
+
const verdict2 = map2[prefix[1].toUpperCase()];
|
|
86773
|
+
if (verdict2) {
|
|
86774
|
+
return { verdict: verdict2, reason: (prefix[2] || cleaned).slice(0, 2e3) };
|
|
86775
|
+
}
|
|
86776
|
+
}
|
|
86777
|
+
return null;
|
|
86778
|
+
}
|
|
86779
|
+
const rawVerdict = obj.verdict ?? obj.Verdict ?? obj.status;
|
|
86780
|
+
if (typeof rawVerdict !== "string")
|
|
85685
86781
|
return null;
|
|
85686
|
-
const
|
|
85687
|
-
if (
|
|
86782
|
+
const verdict = normalizeMobileHealVerdict(rawVerdict);
|
|
86783
|
+
if (!verdict)
|
|
85688
86784
|
return null;
|
|
85689
86785
|
return {
|
|
85690
|
-
verdict
|
|
86786
|
+
verdict,
|
|
85691
86787
|
steps: coerceSteps(obj.steps),
|
|
85692
|
-
reason: typeof obj.reason === "string" ? obj.reason : void 0,
|
|
86788
|
+
reason: typeof obj.reason === "string" ? obj.reason : typeof obj.rationale === "string" ? obj.rationale : typeof obj.message === "string" ? obj.message : void 0,
|
|
85693
86789
|
confidence: typeof obj.confidence === "number" ? obj.confidence : void 0
|
|
85694
86790
|
};
|
|
85695
86791
|
}
|
|
@@ -86038,7 +87134,7 @@ ${args.directive}`);
|
|
|
86038
87134
|
};
|
|
86039
87135
|
}
|
|
86040
87136
|
markRecoverableTurn();
|
|
86041
|
-
pendingDirective =
|
|
87137
|
+
pendingDirective = 'SCHEMA REPAIR: Your last response was not a valid heal verdict. Reply with ONLY one JSON object (no markdown fences, no prose) of the form:\n{"verdict":"<one of: fix|app_bug|config_issue|needs_device|prereq_unmet|state_stale|test_invalid|unhealable_dynamic>","reason":"<short string>","steps":[/* optional MobileTestStep[] when verdict is fix */],"confidence":0.0}\nUse lowercase snake_case for verdict. Do not invent other verdict values.';
|
|
86042
87138
|
continue;
|
|
86043
87139
|
}
|
|
86044
87140
|
consecutiveInvalidVerdicts = 0;
|
|
@@ -86067,6 +87163,13 @@ ${args.directive}`);
|
|
|
86067
87163
|
pendingDirective = 'You returned verdict "fix" but no usable steps array. Return the COMPLETE healed MobileTestStep array.';
|
|
86068
87164
|
continue;
|
|
86069
87165
|
}
|
|
87166
|
+
const oracleRejection = (0, oracle_protection_js_1.rejectOracleWeakeningPatch)(steps, healedSteps);
|
|
87167
|
+
if (oracleRejection) {
|
|
87168
|
+
markRecoverableTurn();
|
|
87169
|
+
lastVerdict = "fix";
|
|
87170
|
+
pendingDirective = `ORACLE PROTECTION: ${oracleRejection}. Keep all assertStateDelta/assertText/captureState outcome proof; fix locators/navigation only. If the app violates the oracle, return verdict "app_bug".`;
|
|
87171
|
+
continue;
|
|
87172
|
+
}
|
|
86070
87173
|
if (activeFailingSource && isLocatorNotFound(activeError) && !isDrift(activeError)) {
|
|
86071
87174
|
const failingSourceSnapshot = activeFailingSource;
|
|
86072
87175
|
const missing = timedSync("device-op", `phase1-attempt-${attempt}-static-verify`, options.onProgress, () => {
|
|
@@ -86210,6 +87313,28 @@ ${args.directive}`);
|
|
|
86210
87313
|
if (invalidAuthSetup) {
|
|
86211
87314
|
return { passed: false, verdict: "test_invalid", healReason: invalidAuthSetup };
|
|
86212
87315
|
}
|
|
87316
|
+
const networkBug = (0, network_oracle_js_1.uiSuccessWithFailedWriteApi)({
|
|
87317
|
+
apiCalls: ctx.apiCalls,
|
|
87318
|
+
uiPathSucceeded: ctx.uiPathSucceeded
|
|
87319
|
+
});
|
|
87320
|
+
const triage = (0, failure_triage_js_1.triageMobileFailure)({
|
|
87321
|
+
steps,
|
|
87322
|
+
error: ctx.error,
|
|
87323
|
+
logs: ctx.logs,
|
|
87324
|
+
tags: ctx.tags,
|
|
87325
|
+
failureCount: ctx.failureCount,
|
|
87326
|
+
uiSuccessWithFailedWriteApi: networkBug
|
|
87327
|
+
});
|
|
87328
|
+
options.onProgress?.(`Pre-heal triage: ${triage.verdict} \u2014 ${triage.reason}`);
|
|
87329
|
+
const terminal = (0, failure_triage_js_1.triageToHealTerminal)(triage);
|
|
87330
|
+
if (terminal) {
|
|
87331
|
+
return {
|
|
87332
|
+
passed: false,
|
|
87333
|
+
verdict: terminal.verdict,
|
|
87334
|
+
healReason: terminal.healReason,
|
|
87335
|
+
extraTags: terminal.extraTags
|
|
87336
|
+
};
|
|
87337
|
+
}
|
|
86213
87338
|
const preflight = await tryRegistryPreflight(steps, target, ctx, options);
|
|
86214
87339
|
if (preflight)
|
|
86215
87340
|
return preflight;
|
|
@@ -86459,6 +87584,11 @@ For a fix, return the COMPLETE steps array (not a diff). Use "observe" only to r
|
|
|
86459
87584
|
if (parsed.verdict !== "fix" || !parsed.steps)
|
|
86460
87585
|
continue;
|
|
86461
87586
|
const healedSteps = parsed.steps;
|
|
87587
|
+
const liveOracleRejection = (0, oracle_protection_js_1.rejectOracleWeakeningPatch)(args.steps, healedSteps);
|
|
87588
|
+
if (liveOracleRejection) {
|
|
87589
|
+
options.onProgress?.(`ORACLE PROTECTION (live): ${liveOracleRejection}`);
|
|
87590
|
+
continue;
|
|
87591
|
+
}
|
|
86462
87592
|
let verify;
|
|
86463
87593
|
try {
|
|
86464
87594
|
verify = await timed("reexec", `phase2-pass-${pass}-verify`, options.onProgress, () => runNativeTest({ steps: healedSteps, target, testVariables }));
|
|
@@ -87749,6 +88879,7 @@ var require_auth_recipe = __commonJS({
|
|
|
87749
88879
|
var START_MARKER = `// >>> VALIDATE_QA_AUTH ${exports.AUTH_MARKER_VERSION} \u2014 generated, do not edit >>>`;
|
|
87750
88880
|
var END_MARKER = `// <<< VALIDATE_QA_AUTH ${exports.AUTH_MARKER_VERSION} <<<`;
|
|
87751
88881
|
var SHARED_AUTH_RUNTIME_ENABLED = `!/^false$/i.test((process.env.SHARED_AUTH_INJECT ?? '').trim())`;
|
|
88882
|
+
var WARM_PROOF_SETTLE_MS = 8e3;
|
|
87752
88883
|
var AUTH_REGION_RE = /\/\/ >>> VALIDATE_QA_AUTH[^\n]*\r?\n[\s\S]*?\/\/ <<< VALIDATE_QA_AUTH[^\n]*\r?\n?/g;
|
|
87753
88884
|
function computeRecipeHash(input) {
|
|
87754
88885
|
const canonical = JSON.stringify({
|
|
@@ -87884,12 +89015,20 @@ ${tabs}`);
|
|
|
87884
89015
|
const pred = urlProofPredicateExpr(recipe.authProof.route, recipe.authProof.exact);
|
|
87885
89016
|
lines.push(` await page.waitForURL((u) => !(${pred})(u), { timeout: 2000 }).catch(() => {});`);
|
|
87886
89017
|
lines.push(` if ((${pred})(new URL(page.url())) && !(await page.locator('input[type="password"]').first().isVisible().catch(() => false))) return;`);
|
|
87887
|
-
} else if (loginRoute) {
|
|
87888
|
-
lines.push(` if (await ${authProofLocator(recipe.authProof)}.isVisible().catch(() => false) && new URL(page.url()).pathname !== new URL(${JSON.stringify(loginRoute)}, page.url()).pathname) return;`);
|
|
87889
89018
|
} else {
|
|
87890
|
-
|
|
89019
|
+
const proofSettle = `await ${authProofLocator(recipe.authProof)}.waitFor({ state: 'visible', timeout: ${WARM_PROOF_SETTLE_MS} }).then(() => true).catch(() => false)`;
|
|
89020
|
+
if (loginRoute) {
|
|
89021
|
+
lines.push(` if (new URL(page.url()).pathname !== new URL(${JSON.stringify(loginRoute)}, page.url()).pathname && ${proofSettle}) return;`);
|
|
89022
|
+
} else {
|
|
89023
|
+
lines.push(` if (${proofSettle}) return;`);
|
|
89024
|
+
}
|
|
87891
89025
|
}
|
|
87892
89026
|
lines.push(` }`);
|
|
89027
|
+
lines.push(` if (${SHARED_AUTH_RUNTIME_ENABLED}) {`);
|
|
89028
|
+
lines.push(` await page.context().clearCookies().catch(() => {});`);
|
|
89029
|
+
lines.push(` await page.goto(${JSON.stringify(recipe.preNavRoute)}, { waitUntil: 'domcontentloaded' }).catch(() => {});`);
|
|
89030
|
+
lines.push(` await page.evaluate(() => { try { localStorage.clear(); sessionStorage.clear(); } catch {} }).catch(() => {});`);
|
|
89031
|
+
lines.push(` }`);
|
|
87893
89032
|
}
|
|
87894
89033
|
lines.push(` await page.goto(${JSON.stringify(recipe.preNavRoute)}, { waitUntil: 'domcontentloaded' });`);
|
|
87895
89034
|
for (const cmd of recipe.preNavCmds)
|
|
@@ -95842,6 +96981,32 @@ var require_agentic_discovery_prompts = __commonJS({
|
|
|
95842
96981
|
lines.push("For a pure navigation or page-load scenario (no in-page mutation), URL + one");
|
|
95843
96982
|
lines.push("structural heading is sufficient.");
|
|
95844
96983
|
lines.push("");
|
|
96984
|
+
lines.push("**Stop at the gate for expensive or irreversible actions.** Some controls");
|
|
96985
|
+
lines.push("start work that costs the account real money (an AI generation, a paid");
|
|
96986
|
+
lines.push("third-party call, a checkout), takes minutes to finish, or cannot be undone");
|
|
96987
|
+
lines.push("(delete, publish, cancel a subscription). Do NOT press them. The regression");
|
|
96988
|
+
lines.push("risk lives in the wiring, and the wiring is fully provable for free:");
|
|
96989
|
+
lines.push("- Assert the control is present and correctly ENABLED/DISABLED by its inputs.");
|
|
96990
|
+
lines.push("- If it opens a dialog, assert the dialog, its fields and its confirm button,");
|
|
96991
|
+
lines.push(" then press Cancel and assert nothing changed.");
|
|
96992
|
+
lines.push("- Assert the auth / quota wall fires for a caller who should be refused.");
|
|
96993
|
+
lines.push("A test that waits minutes for generated output cannot finish inside the run");
|
|
96994
|
+
lines.push("budget, bills the account on every run, and leaves permanent rows behind. If");
|
|
96995
|
+
lines.push("the ONLY way to prove a scenario is to trigger such an action, drop it as a");
|
|
96996
|
+
lines.push("gap rather than emitting a test that does.");
|
|
96997
|
+
lines.push("");
|
|
96998
|
+
lines.push("**Never sign up a new account.** Use the injected credentials. Registering a");
|
|
96999
|
+
lines.push("`testuser-<timestamp>` account to get past a login wall leaves a permanent,");
|
|
97000
|
+
lines.push("unowned user in the target database on every single run. Registration is in");
|
|
97001
|
+
lines.push("scope ONLY when the scenario under test IS registration, in which case use");
|
|
97002
|
+
lines.push("the provided inbox helper so the account is tracked and reaped.");
|
|
97003
|
+
lines.push("");
|
|
97004
|
+
lines.push("**Write the assertion so the BUG fails it.** When a scenario documents broken");
|
|
97005
|
+
lines.push("behaviour, still assert the CORRECT outcome. A test that passes because the");
|
|
97006
|
+
lines.push("error message / console error / not-found page is present inverts the suite:");
|
|
97007
|
+
lines.push("fixing the bug turns the test red and the fix is reported as a regression.");
|
|
97008
|
+
lines.push("State the intended behaviour, let it fail, and flag it as a bug.");
|
|
97009
|
+
lines.push("");
|
|
95845
97010
|
lines.push("## Tools");
|
|
95846
97011
|
lines.push("");
|
|
95847
97012
|
lines.push("Browser MCP: `browser_navigate`, `browser_snapshot`, `browser_click`,");
|
|
@@ -96651,7 +97816,7 @@ var require_discover_generator = __commonJS({
|
|
|
96651
97816
|
"../runner-core/dist/services/discover-generator.js"(exports) {
|
|
96652
97817
|
"use strict";
|
|
96653
97818
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
96654
|
-
exports.MIN_BUG_DESCRIPTION_LENGTH = exports.VALID_PLAYWRIGHT_GETBY_METHODS = exports.BLOCKED_MCP_TOOLS_SCENARIO_GEN = void 0;
|
|
97819
|
+
exports.MIN_BUG_DESCRIPTION_LENGTH = exports.NAME_PROHIBITED_ROLES = exports.VALID_PLAYWRIGHT_GETBY_METHODS = exports.BLOCKED_MCP_TOOLS_SCENARIO_GEN = void 0;
|
|
96655
97820
|
exports.scenarioLooksLikeRegistration = scenarioLooksLikeRegistration;
|
|
96656
97821
|
exports.signupFeatureTestingAllowed = signupFeatureTestingAllowed;
|
|
96657
97822
|
exports.scenarioTouchesSignupAuthSurface = scenarioTouchesSignupAuthSurface;
|
|
@@ -96681,6 +97846,7 @@ var require_discover_generator = __commonJS({
|
|
|
96681
97846
|
exports.scanFragileStructuralLocators = scanFragileStructuralLocators;
|
|
96682
97847
|
exports.bannedRoleTokensInSelector = bannedRoleTokensInSelector;
|
|
96683
97848
|
exports.scanInvalidRoleTagLocators = scanInvalidRoleTagLocators;
|
|
97849
|
+
exports.scanNameProhibitedRoleLocators = scanNameProhibitedRoleLocators;
|
|
96684
97850
|
exports.scanHealedRoleTagLocators = scanHealedRoleTagLocators;
|
|
96685
97851
|
exports.validateFinalActionFidelity = validateFinalActionFidelity;
|
|
96686
97852
|
exports.resolveSuspectedBugVerdict = resolveSuspectedBugVerdict;
|
|
@@ -99748,10 +100914,55 @@ ${testOpen}`;
|
|
|
99748
100914
|
}
|
|
99749
100915
|
return findings;
|
|
99750
100916
|
}
|
|
100917
|
+
exports.NAME_PROHIBITED_ROLES = /* @__PURE__ */ new Set([
|
|
100918
|
+
"caption",
|
|
100919
|
+
"code",
|
|
100920
|
+
"deletion",
|
|
100921
|
+
"emphasis",
|
|
100922
|
+
"generic",
|
|
100923
|
+
"insertion",
|
|
100924
|
+
"mark",
|
|
100925
|
+
"none",
|
|
100926
|
+
"paragraph",
|
|
100927
|
+
"presentation",
|
|
100928
|
+
"strong",
|
|
100929
|
+
"subscript",
|
|
100930
|
+
"superscript",
|
|
100931
|
+
"term",
|
|
100932
|
+
"time"
|
|
100933
|
+
]);
|
|
100934
|
+
function scanNameProhibitedRoleLocators(code) {
|
|
100935
|
+
const findings = [];
|
|
100936
|
+
const seen = /* @__PURE__ */ new Set();
|
|
100937
|
+
const scanCode = code.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, " "));
|
|
100938
|
+
const RE = /getByRole\(\s*(['"`])([a-zA-Z]+)\1\s*,\s*\{[^}]*\bname\s*:/g;
|
|
100939
|
+
for (const rawLine of scanCode.split("\n")) {
|
|
100940
|
+
const line = rawLine.replace(/\/\/.*$/, "");
|
|
100941
|
+
if (line.indexOf("getByRole(") === -1)
|
|
100942
|
+
continue;
|
|
100943
|
+
RE.lastIndex = 0;
|
|
100944
|
+
let m;
|
|
100945
|
+
while ((m = RE.exec(line)) !== null) {
|
|
100946
|
+
const role = m[2].toLowerCase();
|
|
100947
|
+
if (!exports.NAME_PROHIBITED_ROLES.has(role))
|
|
100948
|
+
continue;
|
|
100949
|
+
const key = `${rawLine.trim()} ${role}`;
|
|
100950
|
+
if (seen.has(key))
|
|
100951
|
+
continue;
|
|
100952
|
+
seen.add(key);
|
|
100953
|
+
findings.push({
|
|
100954
|
+
line: rawLine.trim().slice(0, 200),
|
|
100955
|
+
role,
|
|
100956
|
+
reason: `ARIA prohibits an accessible name on role "${role}", so no element ever exposes one \u2014 getByRole('${role}', { name: \u2026 }) matches ZERO nodes and the assertion hangs to its timeout. Match the text instead: page.getByText('\u2026', { exact: true }), optionally scoped (e.g. page.getByRole('main').getByText('\u2026')). If you need the element itself, select a nameable ancestor (region/listitem/link/button) and assert its text.`
|
|
100957
|
+
});
|
|
100958
|
+
}
|
|
100959
|
+
}
|
|
100960
|
+
return findings;
|
|
100961
|
+
}
|
|
99751
100962
|
function scanHealedRoleTagLocators(code, opts) {
|
|
99752
100963
|
const inboxStripped = (0, inbox_stamp_js_1.stripInboxRegions)(code);
|
|
99753
100964
|
const scanned = opts?.stripAuth === false ? inboxStripped : (0, auth_recipe_js_1.stripAuthRegions)(inboxStripped);
|
|
99754
|
-
return scanInvalidRoleTagLocators(scanned);
|
|
100965
|
+
return [...scanInvalidRoleTagLocators(scanned), ...scanNameProhibitedRoleLocators(scanned)];
|
|
99755
100966
|
}
|
|
99756
100967
|
function validateFinalActionFidelity(playwrightCode, actionLedger, credentials, opts) {
|
|
99757
100968
|
const ledgerSigs = [];
|
|
@@ -100472,7 +101683,7 @@ Do NOT add steps you did not execute. Do NOT skip steps from the recording.${led
|
|
|
100472
101683
|
continue;
|
|
100473
101684
|
}
|
|
100474
101685
|
const roleTagMode = (0, discovery_lint_flags_js_1.roleTagLocatorLintMode)();
|
|
100475
|
-
const roleTagFindings = roleTagMode !== "off" ?
|
|
101686
|
+
const roleTagFindings = roleTagMode !== "off" ? scanHealedRoleTagLocators(validated[0].playwrightCode) : [];
|
|
100476
101687
|
if (roleTagMode === "warn" && roleTagFindings.length > 0) {
|
|
100477
101688
|
logs2.push(` Role-tag locator gate [warn]: ${roleTagFindings.length} role-as-CSS-tag locator(s) \u2014 ${roleTagFindings.map((f) => sanitizeLedgerText(f.line)).join(" | ").slice(0, 300)}`);
|
|
100478
101689
|
}
|
|
@@ -100485,12 +101696,10 @@ Do NOT add steps you did not execute. Do NOT skip steps from the recording.${led
|
|
|
100485
101696
|
valid: false,
|
|
100486
101697
|
revisionRequired: true,
|
|
100487
101698
|
reason: "invalid_role_tag_locator",
|
|
100488
|
-
instruction: targeted ? `
|
|
100489
|
-
|
|
100490
|
-
|
|
100491
|
-
|
|
100492
|
-
3. For a verification-code field, prefer the injected helper: await __vqaEnterVerificationCode(page, code).
|
|
100493
|
-
Keep every other line exactly as-is. Submit the COMPLETE corrected test and call finish_generate again.` : `Your resubmission STILL contains a locator that uses an ARIA role as a CSS tag selector (page.locator('<role>[\u2026]')). This can only ever match nothing. Replace EVERY such locator with page.getByRole('<role>', { name: '\u2026' }) / getByLabel / input[type="\u2026"], or use await __vqaEnterVerificationCode(page, code) for the code field, and resubmit the COMPLETE test.`,
|
|
101699
|
+
instruction: targeted ? `Every locator listed below matches ZERO nodes, so the step hangs until the test times out. Read the \`reason\` on each one \u2014 there are two distinct mistakes:
|
|
101700
|
+
(a) An ARIA ROLE used as a CSS tag selector, e.g. page.locator('textbox[name^="code"]'). There is no <textbox>/<checkbox>/<heading> element. Rewrite as page.getByRole('<role>', { name: '<accessible name>' }), or page.getByLabel('<label>'), or a type-scoped CSS like page.locator('input[type="email"]'). For a verification-code field prefer the injected helper: await __vqaEnterVerificationCode(page, code).
|
|
101701
|
+
(b) A { name: \u2026 } filter on a role whose accessible name ARIA PROHIBITS (paragraph, generic, code, emphasis, strong, term, time, mark, caption, presentation/none, insertion, deletion, sub/superscript). No element with those roles ever exposes a name. Match the text instead: page.getByText('\u2026', { exact: true }), scoped if needed (page.getByRole('main').getByText('\u2026')), or target a nameable ancestor such as region/listitem/link/button.
|
|
101702
|
+
Fix EVERY flagged locator, keep every other line exactly as-is, then submit the COMPLETE corrected test and call finish_generate again.` : `Your resubmission STILL contains a locator that can only ever match nothing \u2014 either an ARIA role used as a CSS tag selector (page.locator('<role>[\u2026]')) or a { name: \u2026 } filter on a name-prohibited role (paragraph/generic/code/emphasis/strong/term/time/\u2026). Replace EVERY one: use getByRole('<role>', { name: '\u2026' }) / getByLabel / input[type="\u2026"] for the first, and getByText('\u2026', { exact: true }) for the second. Resubmit the COMPLETE test.`,
|
|
100494
101703
|
offendingLocators: roleTagFindings.map((f) => ({
|
|
100495
101704
|
line: sanitizeLedgerText(f.line),
|
|
100496
101705
|
reason: f.reason
|
|
@@ -101536,6 +102745,2285 @@ var require_rate_limit_detector = __commonJS({
|
|
|
101536
102745
|
}
|
|
101537
102746
|
});
|
|
101538
102747
|
|
|
102748
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/base64.js
|
|
102749
|
+
var require_base64 = __commonJS({
|
|
102750
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/base64.js"(exports) {
|
|
102751
|
+
"use strict";
|
|
102752
|
+
var intToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
|
|
102753
|
+
exports.encode = function(number) {
|
|
102754
|
+
if (0 <= number && number < intToCharMap.length) {
|
|
102755
|
+
return intToCharMap[number];
|
|
102756
|
+
}
|
|
102757
|
+
throw new TypeError("Must be between 0 and 63: " + number);
|
|
102758
|
+
};
|
|
102759
|
+
exports.decode = function(charCode) {
|
|
102760
|
+
var bigA = 65;
|
|
102761
|
+
var bigZ = 90;
|
|
102762
|
+
var littleA = 97;
|
|
102763
|
+
var littleZ = 122;
|
|
102764
|
+
var zero = 48;
|
|
102765
|
+
var nine = 57;
|
|
102766
|
+
var plus = 43;
|
|
102767
|
+
var slash = 47;
|
|
102768
|
+
var littleOffset = 26;
|
|
102769
|
+
var numberOffset = 52;
|
|
102770
|
+
if (bigA <= charCode && charCode <= bigZ) {
|
|
102771
|
+
return charCode - bigA;
|
|
102772
|
+
}
|
|
102773
|
+
if (littleA <= charCode && charCode <= littleZ) {
|
|
102774
|
+
return charCode - littleA + littleOffset;
|
|
102775
|
+
}
|
|
102776
|
+
if (zero <= charCode && charCode <= nine) {
|
|
102777
|
+
return charCode - zero + numberOffset;
|
|
102778
|
+
}
|
|
102779
|
+
if (charCode == plus) {
|
|
102780
|
+
return 62;
|
|
102781
|
+
}
|
|
102782
|
+
if (charCode == slash) {
|
|
102783
|
+
return 63;
|
|
102784
|
+
}
|
|
102785
|
+
return -1;
|
|
102786
|
+
};
|
|
102787
|
+
}
|
|
102788
|
+
});
|
|
102789
|
+
|
|
102790
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/base64-vlq.js
|
|
102791
|
+
var require_base64_vlq = __commonJS({
|
|
102792
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/base64-vlq.js"(exports) {
|
|
102793
|
+
"use strict";
|
|
102794
|
+
var base64 = require_base64();
|
|
102795
|
+
var VLQ_BASE_SHIFT = 5;
|
|
102796
|
+
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
|
102797
|
+
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
|
102798
|
+
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
|
102799
|
+
function toVLQSigned(aValue) {
|
|
102800
|
+
return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0;
|
|
102801
|
+
}
|
|
102802
|
+
function fromVLQSigned(aValue) {
|
|
102803
|
+
var isNegative = (aValue & 1) === 1;
|
|
102804
|
+
var shifted = aValue >> 1;
|
|
102805
|
+
return isNegative ? -shifted : shifted;
|
|
102806
|
+
}
|
|
102807
|
+
exports.encode = function base64VLQ_encode(aValue) {
|
|
102808
|
+
var encoded = "";
|
|
102809
|
+
var digit;
|
|
102810
|
+
var vlq = toVLQSigned(aValue);
|
|
102811
|
+
do {
|
|
102812
|
+
digit = vlq & VLQ_BASE_MASK;
|
|
102813
|
+
vlq >>>= VLQ_BASE_SHIFT;
|
|
102814
|
+
if (vlq > 0) {
|
|
102815
|
+
digit |= VLQ_CONTINUATION_BIT;
|
|
102816
|
+
}
|
|
102817
|
+
encoded += base64.encode(digit);
|
|
102818
|
+
} while (vlq > 0);
|
|
102819
|
+
return encoded;
|
|
102820
|
+
};
|
|
102821
|
+
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
|
|
102822
|
+
var strLen = aStr.length;
|
|
102823
|
+
var result = 0;
|
|
102824
|
+
var shift = 0;
|
|
102825
|
+
var continuation, digit;
|
|
102826
|
+
do {
|
|
102827
|
+
if (aIndex >= strLen) {
|
|
102828
|
+
throw new Error("Expected more digits in base 64 VLQ value.");
|
|
102829
|
+
}
|
|
102830
|
+
digit = base64.decode(aStr.charCodeAt(aIndex++));
|
|
102831
|
+
if (digit === -1) {
|
|
102832
|
+
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
|
|
102833
|
+
}
|
|
102834
|
+
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
|
102835
|
+
digit &= VLQ_BASE_MASK;
|
|
102836
|
+
result = result + (digit << shift);
|
|
102837
|
+
shift += VLQ_BASE_SHIFT;
|
|
102838
|
+
} while (continuation);
|
|
102839
|
+
aOutParam.value = fromVLQSigned(result);
|
|
102840
|
+
aOutParam.rest = aIndex;
|
|
102841
|
+
};
|
|
102842
|
+
}
|
|
102843
|
+
});
|
|
102844
|
+
|
|
102845
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/util.js
|
|
102846
|
+
var require_util4 = __commonJS({
|
|
102847
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/util.js"(exports) {
|
|
102848
|
+
"use strict";
|
|
102849
|
+
function getArg(aArgs, aName, aDefaultValue) {
|
|
102850
|
+
if (aName in aArgs) {
|
|
102851
|
+
return aArgs[aName];
|
|
102852
|
+
} else if (arguments.length === 3) {
|
|
102853
|
+
return aDefaultValue;
|
|
102854
|
+
} else {
|
|
102855
|
+
throw new Error('"' + aName + '" is a required argument.');
|
|
102856
|
+
}
|
|
102857
|
+
}
|
|
102858
|
+
exports.getArg = getArg;
|
|
102859
|
+
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
|
|
102860
|
+
var dataUrlRegexp = /^data:.+\,.+$/;
|
|
102861
|
+
function urlParse(aUrl) {
|
|
102862
|
+
var match = aUrl.match(urlRegexp);
|
|
102863
|
+
if (!match) {
|
|
102864
|
+
return null;
|
|
102865
|
+
}
|
|
102866
|
+
return {
|
|
102867
|
+
scheme: match[1],
|
|
102868
|
+
auth: match[2],
|
|
102869
|
+
host: match[3],
|
|
102870
|
+
port: match[4],
|
|
102871
|
+
path: match[5]
|
|
102872
|
+
};
|
|
102873
|
+
}
|
|
102874
|
+
exports.urlParse = urlParse;
|
|
102875
|
+
function urlGenerate(aParsedUrl) {
|
|
102876
|
+
var url = "";
|
|
102877
|
+
if (aParsedUrl.scheme) {
|
|
102878
|
+
url += aParsedUrl.scheme + ":";
|
|
102879
|
+
}
|
|
102880
|
+
url += "//";
|
|
102881
|
+
if (aParsedUrl.auth) {
|
|
102882
|
+
url += aParsedUrl.auth + "@";
|
|
102883
|
+
}
|
|
102884
|
+
if (aParsedUrl.host) {
|
|
102885
|
+
url += aParsedUrl.host;
|
|
102886
|
+
}
|
|
102887
|
+
if (aParsedUrl.port) {
|
|
102888
|
+
url += ":" + aParsedUrl.port;
|
|
102889
|
+
}
|
|
102890
|
+
if (aParsedUrl.path) {
|
|
102891
|
+
url += aParsedUrl.path;
|
|
102892
|
+
}
|
|
102893
|
+
return url;
|
|
102894
|
+
}
|
|
102895
|
+
exports.urlGenerate = urlGenerate;
|
|
102896
|
+
function normalize(aPath) {
|
|
102897
|
+
var path = aPath;
|
|
102898
|
+
var url = urlParse(aPath);
|
|
102899
|
+
if (url) {
|
|
102900
|
+
if (!url.path) {
|
|
102901
|
+
return aPath;
|
|
102902
|
+
}
|
|
102903
|
+
path = url.path;
|
|
102904
|
+
}
|
|
102905
|
+
var isAbsolute2 = exports.isAbsolute(path);
|
|
102906
|
+
var parts = path.split(/\/+/);
|
|
102907
|
+
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
102908
|
+
part = parts[i];
|
|
102909
|
+
if (part === ".") {
|
|
102910
|
+
parts.splice(i, 1);
|
|
102911
|
+
} else if (part === "..") {
|
|
102912
|
+
up++;
|
|
102913
|
+
} else if (up > 0) {
|
|
102914
|
+
if (part === "") {
|
|
102915
|
+
parts.splice(i + 1, up);
|
|
102916
|
+
up = 0;
|
|
102917
|
+
} else {
|
|
102918
|
+
parts.splice(i, 2);
|
|
102919
|
+
up--;
|
|
102920
|
+
}
|
|
102921
|
+
}
|
|
102922
|
+
}
|
|
102923
|
+
path = parts.join("/");
|
|
102924
|
+
if (path === "") {
|
|
102925
|
+
path = isAbsolute2 ? "/" : ".";
|
|
102926
|
+
}
|
|
102927
|
+
if (url) {
|
|
102928
|
+
url.path = path;
|
|
102929
|
+
return urlGenerate(url);
|
|
102930
|
+
}
|
|
102931
|
+
return path;
|
|
102932
|
+
}
|
|
102933
|
+
exports.normalize = normalize;
|
|
102934
|
+
function join8(aRoot, aPath) {
|
|
102935
|
+
if (aRoot === "") {
|
|
102936
|
+
aRoot = ".";
|
|
102937
|
+
}
|
|
102938
|
+
if (aPath === "") {
|
|
102939
|
+
aPath = ".";
|
|
102940
|
+
}
|
|
102941
|
+
var aPathUrl = urlParse(aPath);
|
|
102942
|
+
var aRootUrl = urlParse(aRoot);
|
|
102943
|
+
if (aRootUrl) {
|
|
102944
|
+
aRoot = aRootUrl.path || "/";
|
|
102945
|
+
}
|
|
102946
|
+
if (aPathUrl && !aPathUrl.scheme) {
|
|
102947
|
+
if (aRootUrl) {
|
|
102948
|
+
aPathUrl.scheme = aRootUrl.scheme;
|
|
102949
|
+
}
|
|
102950
|
+
return urlGenerate(aPathUrl);
|
|
102951
|
+
}
|
|
102952
|
+
if (aPathUrl || aPath.match(dataUrlRegexp)) {
|
|
102953
|
+
return aPath;
|
|
102954
|
+
}
|
|
102955
|
+
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
|
|
102956
|
+
aRootUrl.host = aPath;
|
|
102957
|
+
return urlGenerate(aRootUrl);
|
|
102958
|
+
}
|
|
102959
|
+
var joined = aPath.charAt(0) === "/" ? aPath : normalize(aRoot.replace(/\/+$/, "") + "/" + aPath);
|
|
102960
|
+
if (aRootUrl) {
|
|
102961
|
+
aRootUrl.path = joined;
|
|
102962
|
+
return urlGenerate(aRootUrl);
|
|
102963
|
+
}
|
|
102964
|
+
return joined;
|
|
102965
|
+
}
|
|
102966
|
+
exports.join = join8;
|
|
102967
|
+
exports.isAbsolute = function(aPath) {
|
|
102968
|
+
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
102969
|
+
};
|
|
102970
|
+
function relative(aRoot, aPath) {
|
|
102971
|
+
if (aRoot === "") {
|
|
102972
|
+
aRoot = ".";
|
|
102973
|
+
}
|
|
102974
|
+
aRoot = aRoot.replace(/\/$/, "");
|
|
102975
|
+
var level = 0;
|
|
102976
|
+
while (aPath.indexOf(aRoot + "/") !== 0) {
|
|
102977
|
+
var index = aRoot.lastIndexOf("/");
|
|
102978
|
+
if (index < 0) {
|
|
102979
|
+
return aPath;
|
|
102980
|
+
}
|
|
102981
|
+
aRoot = aRoot.slice(0, index);
|
|
102982
|
+
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
|
|
102983
|
+
return aPath;
|
|
102984
|
+
}
|
|
102985
|
+
++level;
|
|
102986
|
+
}
|
|
102987
|
+
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
102988
|
+
}
|
|
102989
|
+
exports.relative = relative;
|
|
102990
|
+
var supportsNullProto = (function() {
|
|
102991
|
+
var obj = /* @__PURE__ */ Object.create(null);
|
|
102992
|
+
return !("__proto__" in obj);
|
|
102993
|
+
})();
|
|
102994
|
+
function identity(s) {
|
|
102995
|
+
return s;
|
|
102996
|
+
}
|
|
102997
|
+
function toSetString(aStr) {
|
|
102998
|
+
if (isProtoString(aStr)) {
|
|
102999
|
+
return "$" + aStr;
|
|
103000
|
+
}
|
|
103001
|
+
return aStr;
|
|
103002
|
+
}
|
|
103003
|
+
exports.toSetString = supportsNullProto ? identity : toSetString;
|
|
103004
|
+
function fromSetString(aStr) {
|
|
103005
|
+
if (isProtoString(aStr)) {
|
|
103006
|
+
return aStr.slice(1);
|
|
103007
|
+
}
|
|
103008
|
+
return aStr;
|
|
103009
|
+
}
|
|
103010
|
+
exports.fromSetString = supportsNullProto ? identity : fromSetString;
|
|
103011
|
+
function isProtoString(s) {
|
|
103012
|
+
if (!s) {
|
|
103013
|
+
return false;
|
|
103014
|
+
}
|
|
103015
|
+
var length = s.length;
|
|
103016
|
+
if (length < 9) {
|
|
103017
|
+
return false;
|
|
103018
|
+
}
|
|
103019
|
+
if (s.charCodeAt(length - 1) !== 95 || s.charCodeAt(length - 2) !== 95 || s.charCodeAt(length - 3) !== 111 || s.charCodeAt(length - 4) !== 116 || s.charCodeAt(length - 5) !== 111 || s.charCodeAt(length - 6) !== 114 || s.charCodeAt(length - 7) !== 112 || s.charCodeAt(length - 8) !== 95 || s.charCodeAt(length - 9) !== 95) {
|
|
103020
|
+
return false;
|
|
103021
|
+
}
|
|
103022
|
+
for (var i = length - 10; i >= 0; i--) {
|
|
103023
|
+
if (s.charCodeAt(i) !== 36) {
|
|
103024
|
+
return false;
|
|
103025
|
+
}
|
|
103026
|
+
}
|
|
103027
|
+
return true;
|
|
103028
|
+
}
|
|
103029
|
+
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
|
|
103030
|
+
var cmp = strcmp(mappingA.source, mappingB.source);
|
|
103031
|
+
if (cmp !== 0) {
|
|
103032
|
+
return cmp;
|
|
103033
|
+
}
|
|
103034
|
+
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
103035
|
+
if (cmp !== 0) {
|
|
103036
|
+
return cmp;
|
|
103037
|
+
}
|
|
103038
|
+
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
103039
|
+
if (cmp !== 0 || onlyCompareOriginal) {
|
|
103040
|
+
return cmp;
|
|
103041
|
+
}
|
|
103042
|
+
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
103043
|
+
if (cmp !== 0) {
|
|
103044
|
+
return cmp;
|
|
103045
|
+
}
|
|
103046
|
+
cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
103047
|
+
if (cmp !== 0) {
|
|
103048
|
+
return cmp;
|
|
103049
|
+
}
|
|
103050
|
+
return strcmp(mappingA.name, mappingB.name);
|
|
103051
|
+
}
|
|
103052
|
+
exports.compareByOriginalPositions = compareByOriginalPositions;
|
|
103053
|
+
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
|
103054
|
+
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
103055
|
+
if (cmp !== 0) {
|
|
103056
|
+
return cmp;
|
|
103057
|
+
}
|
|
103058
|
+
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
103059
|
+
if (cmp !== 0 || onlyCompareGenerated) {
|
|
103060
|
+
return cmp;
|
|
103061
|
+
}
|
|
103062
|
+
cmp = strcmp(mappingA.source, mappingB.source);
|
|
103063
|
+
if (cmp !== 0) {
|
|
103064
|
+
return cmp;
|
|
103065
|
+
}
|
|
103066
|
+
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
103067
|
+
if (cmp !== 0) {
|
|
103068
|
+
return cmp;
|
|
103069
|
+
}
|
|
103070
|
+
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
103071
|
+
if (cmp !== 0) {
|
|
103072
|
+
return cmp;
|
|
103073
|
+
}
|
|
103074
|
+
return strcmp(mappingA.name, mappingB.name);
|
|
103075
|
+
}
|
|
103076
|
+
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
|
103077
|
+
function strcmp(aStr1, aStr2) {
|
|
103078
|
+
if (aStr1 === aStr2) {
|
|
103079
|
+
return 0;
|
|
103080
|
+
}
|
|
103081
|
+
if (aStr1 === null) {
|
|
103082
|
+
return 1;
|
|
103083
|
+
}
|
|
103084
|
+
if (aStr2 === null) {
|
|
103085
|
+
return -1;
|
|
103086
|
+
}
|
|
103087
|
+
if (aStr1 > aStr2) {
|
|
103088
|
+
return 1;
|
|
103089
|
+
}
|
|
103090
|
+
return -1;
|
|
103091
|
+
}
|
|
103092
|
+
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
|
103093
|
+
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
103094
|
+
if (cmp !== 0) {
|
|
103095
|
+
return cmp;
|
|
103096
|
+
}
|
|
103097
|
+
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
103098
|
+
if (cmp !== 0) {
|
|
103099
|
+
return cmp;
|
|
103100
|
+
}
|
|
103101
|
+
cmp = strcmp(mappingA.source, mappingB.source);
|
|
103102
|
+
if (cmp !== 0) {
|
|
103103
|
+
return cmp;
|
|
103104
|
+
}
|
|
103105
|
+
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
103106
|
+
if (cmp !== 0) {
|
|
103107
|
+
return cmp;
|
|
103108
|
+
}
|
|
103109
|
+
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
103110
|
+
if (cmp !== 0) {
|
|
103111
|
+
return cmp;
|
|
103112
|
+
}
|
|
103113
|
+
return strcmp(mappingA.name, mappingB.name);
|
|
103114
|
+
}
|
|
103115
|
+
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
|
103116
|
+
function parseSourceMapInput(str) {
|
|
103117
|
+
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ""));
|
|
103118
|
+
}
|
|
103119
|
+
exports.parseSourceMapInput = parseSourceMapInput;
|
|
103120
|
+
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
|
|
103121
|
+
sourceURL = sourceURL || "";
|
|
103122
|
+
if (sourceRoot) {
|
|
103123
|
+
if (sourceRoot[sourceRoot.length - 1] !== "/" && sourceURL[0] !== "/") {
|
|
103124
|
+
sourceRoot += "/";
|
|
103125
|
+
}
|
|
103126
|
+
sourceURL = sourceRoot + sourceURL;
|
|
103127
|
+
}
|
|
103128
|
+
if (sourceMapURL) {
|
|
103129
|
+
var parsed = urlParse(sourceMapURL);
|
|
103130
|
+
if (!parsed) {
|
|
103131
|
+
throw new Error("sourceMapURL could not be parsed");
|
|
103132
|
+
}
|
|
103133
|
+
if (parsed.path) {
|
|
103134
|
+
var index = parsed.path.lastIndexOf("/");
|
|
103135
|
+
if (index >= 0) {
|
|
103136
|
+
parsed.path = parsed.path.substring(0, index + 1);
|
|
103137
|
+
}
|
|
103138
|
+
}
|
|
103139
|
+
sourceURL = join8(urlGenerate(parsed), sourceURL);
|
|
103140
|
+
}
|
|
103141
|
+
return normalize(sourceURL);
|
|
103142
|
+
}
|
|
103143
|
+
exports.computeSourceURL = computeSourceURL;
|
|
103144
|
+
}
|
|
103145
|
+
});
|
|
103146
|
+
|
|
103147
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/array-set.js
|
|
103148
|
+
var require_array_set = __commonJS({
|
|
103149
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/array-set.js"(exports) {
|
|
103150
|
+
"use strict";
|
|
103151
|
+
var util = require_util4();
|
|
103152
|
+
var has = Object.prototype.hasOwnProperty;
|
|
103153
|
+
var hasNativeMap = typeof Map !== "undefined";
|
|
103154
|
+
function ArraySet() {
|
|
103155
|
+
this._array = [];
|
|
103156
|
+
this._set = hasNativeMap ? /* @__PURE__ */ new Map() : /* @__PURE__ */ Object.create(null);
|
|
103157
|
+
}
|
|
103158
|
+
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
|
103159
|
+
var set = new ArraySet();
|
|
103160
|
+
for (var i = 0, len = aArray.length; i < len; i++) {
|
|
103161
|
+
set.add(aArray[i], aAllowDuplicates);
|
|
103162
|
+
}
|
|
103163
|
+
return set;
|
|
103164
|
+
};
|
|
103165
|
+
ArraySet.prototype.size = function ArraySet_size() {
|
|
103166
|
+
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
|
|
103167
|
+
};
|
|
103168
|
+
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
|
103169
|
+
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
|
|
103170
|
+
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
|
|
103171
|
+
var idx = this._array.length;
|
|
103172
|
+
if (!isDuplicate || aAllowDuplicates) {
|
|
103173
|
+
this._array.push(aStr);
|
|
103174
|
+
}
|
|
103175
|
+
if (!isDuplicate) {
|
|
103176
|
+
if (hasNativeMap) {
|
|
103177
|
+
this._set.set(aStr, idx);
|
|
103178
|
+
} else {
|
|
103179
|
+
this._set[sStr] = idx;
|
|
103180
|
+
}
|
|
103181
|
+
}
|
|
103182
|
+
};
|
|
103183
|
+
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
|
103184
|
+
if (hasNativeMap) {
|
|
103185
|
+
return this._set.has(aStr);
|
|
103186
|
+
} else {
|
|
103187
|
+
var sStr = util.toSetString(aStr);
|
|
103188
|
+
return has.call(this._set, sStr);
|
|
103189
|
+
}
|
|
103190
|
+
};
|
|
103191
|
+
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
|
103192
|
+
if (hasNativeMap) {
|
|
103193
|
+
var idx = this._set.get(aStr);
|
|
103194
|
+
if (idx >= 0) {
|
|
103195
|
+
return idx;
|
|
103196
|
+
}
|
|
103197
|
+
} else {
|
|
103198
|
+
var sStr = util.toSetString(aStr);
|
|
103199
|
+
if (has.call(this._set, sStr)) {
|
|
103200
|
+
return this._set[sStr];
|
|
103201
|
+
}
|
|
103202
|
+
}
|
|
103203
|
+
throw new Error('"' + aStr + '" is not in the set.');
|
|
103204
|
+
};
|
|
103205
|
+
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
|
103206
|
+
if (aIdx >= 0 && aIdx < this._array.length) {
|
|
103207
|
+
return this._array[aIdx];
|
|
103208
|
+
}
|
|
103209
|
+
throw new Error("No element indexed by " + aIdx);
|
|
103210
|
+
};
|
|
103211
|
+
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
|
103212
|
+
return this._array.slice();
|
|
103213
|
+
};
|
|
103214
|
+
exports.ArraySet = ArraySet;
|
|
103215
|
+
}
|
|
103216
|
+
});
|
|
103217
|
+
|
|
103218
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/mapping-list.js
|
|
103219
|
+
var require_mapping_list = __commonJS({
|
|
103220
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/mapping-list.js"(exports) {
|
|
103221
|
+
"use strict";
|
|
103222
|
+
var util = require_util4();
|
|
103223
|
+
function generatedPositionAfter(mappingA, mappingB) {
|
|
103224
|
+
var lineA = mappingA.generatedLine;
|
|
103225
|
+
var lineB = mappingB.generatedLine;
|
|
103226
|
+
var columnA = mappingA.generatedColumn;
|
|
103227
|
+
var columnB = mappingB.generatedColumn;
|
|
103228
|
+
return lineB > lineA || lineB == lineA && columnB >= columnA || util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
|
103229
|
+
}
|
|
103230
|
+
function MappingList() {
|
|
103231
|
+
this._array = [];
|
|
103232
|
+
this._sorted = true;
|
|
103233
|
+
this._last = { generatedLine: -1, generatedColumn: 0 };
|
|
103234
|
+
}
|
|
103235
|
+
MappingList.prototype.unsortedForEach = function MappingList_forEach(aCallback, aThisArg) {
|
|
103236
|
+
this._array.forEach(aCallback, aThisArg);
|
|
103237
|
+
};
|
|
103238
|
+
MappingList.prototype.add = function MappingList_add(aMapping) {
|
|
103239
|
+
if (generatedPositionAfter(this._last, aMapping)) {
|
|
103240
|
+
this._last = aMapping;
|
|
103241
|
+
this._array.push(aMapping);
|
|
103242
|
+
} else {
|
|
103243
|
+
this._sorted = false;
|
|
103244
|
+
this._array.push(aMapping);
|
|
103245
|
+
}
|
|
103246
|
+
};
|
|
103247
|
+
MappingList.prototype.toArray = function MappingList_toArray() {
|
|
103248
|
+
if (!this._sorted) {
|
|
103249
|
+
this._array.sort(util.compareByGeneratedPositionsInflated);
|
|
103250
|
+
this._sorted = true;
|
|
103251
|
+
}
|
|
103252
|
+
return this._array;
|
|
103253
|
+
};
|
|
103254
|
+
exports.MappingList = MappingList;
|
|
103255
|
+
}
|
|
103256
|
+
});
|
|
103257
|
+
|
|
103258
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/source-map-generator.js
|
|
103259
|
+
var require_source_map_generator = __commonJS({
|
|
103260
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/source-map-generator.js"(exports) {
|
|
103261
|
+
"use strict";
|
|
103262
|
+
var base64VLQ = require_base64_vlq();
|
|
103263
|
+
var util = require_util4();
|
|
103264
|
+
var ArraySet = require_array_set().ArraySet;
|
|
103265
|
+
var MappingList = require_mapping_list().MappingList;
|
|
103266
|
+
function SourceMapGenerator(aArgs) {
|
|
103267
|
+
if (!aArgs) {
|
|
103268
|
+
aArgs = {};
|
|
103269
|
+
}
|
|
103270
|
+
this._file = util.getArg(aArgs, "file", null);
|
|
103271
|
+
this._sourceRoot = util.getArg(aArgs, "sourceRoot", null);
|
|
103272
|
+
this._skipValidation = util.getArg(aArgs, "skipValidation", false);
|
|
103273
|
+
this._sources = new ArraySet();
|
|
103274
|
+
this._names = new ArraySet();
|
|
103275
|
+
this._mappings = new MappingList();
|
|
103276
|
+
this._sourcesContents = null;
|
|
103277
|
+
}
|
|
103278
|
+
SourceMapGenerator.prototype._version = 3;
|
|
103279
|
+
SourceMapGenerator.fromSourceMap = function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
|
|
103280
|
+
var sourceRoot = aSourceMapConsumer.sourceRoot;
|
|
103281
|
+
var generator = new SourceMapGenerator({
|
|
103282
|
+
file: aSourceMapConsumer.file,
|
|
103283
|
+
sourceRoot
|
|
103284
|
+
});
|
|
103285
|
+
aSourceMapConsumer.eachMapping(function(mapping) {
|
|
103286
|
+
var newMapping = {
|
|
103287
|
+
generated: {
|
|
103288
|
+
line: mapping.generatedLine,
|
|
103289
|
+
column: mapping.generatedColumn
|
|
103290
|
+
}
|
|
103291
|
+
};
|
|
103292
|
+
if (mapping.source != null) {
|
|
103293
|
+
newMapping.source = mapping.source;
|
|
103294
|
+
if (sourceRoot != null) {
|
|
103295
|
+
newMapping.source = util.relative(sourceRoot, newMapping.source);
|
|
103296
|
+
}
|
|
103297
|
+
newMapping.original = {
|
|
103298
|
+
line: mapping.originalLine,
|
|
103299
|
+
column: mapping.originalColumn
|
|
103300
|
+
};
|
|
103301
|
+
if (mapping.name != null) {
|
|
103302
|
+
newMapping.name = mapping.name;
|
|
103303
|
+
}
|
|
103304
|
+
}
|
|
103305
|
+
generator.addMapping(newMapping);
|
|
103306
|
+
});
|
|
103307
|
+
aSourceMapConsumer.sources.forEach(function(sourceFile) {
|
|
103308
|
+
var sourceRelative = sourceFile;
|
|
103309
|
+
if (sourceRoot !== null) {
|
|
103310
|
+
sourceRelative = util.relative(sourceRoot, sourceFile);
|
|
103311
|
+
}
|
|
103312
|
+
if (!generator._sources.has(sourceRelative)) {
|
|
103313
|
+
generator._sources.add(sourceRelative);
|
|
103314
|
+
}
|
|
103315
|
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
|
103316
|
+
if (content != null) {
|
|
103317
|
+
generator.setSourceContent(sourceFile, content);
|
|
103318
|
+
}
|
|
103319
|
+
});
|
|
103320
|
+
return generator;
|
|
103321
|
+
};
|
|
103322
|
+
SourceMapGenerator.prototype.addMapping = function SourceMapGenerator_addMapping(aArgs) {
|
|
103323
|
+
var generated = util.getArg(aArgs, "generated");
|
|
103324
|
+
var original = util.getArg(aArgs, "original", null);
|
|
103325
|
+
var source = util.getArg(aArgs, "source", null);
|
|
103326
|
+
var name = util.getArg(aArgs, "name", null);
|
|
103327
|
+
if (!this._skipValidation) {
|
|
103328
|
+
this._validateMapping(generated, original, source, name);
|
|
103329
|
+
}
|
|
103330
|
+
if (source != null) {
|
|
103331
|
+
source = String(source);
|
|
103332
|
+
if (!this._sources.has(source)) {
|
|
103333
|
+
this._sources.add(source);
|
|
103334
|
+
}
|
|
103335
|
+
}
|
|
103336
|
+
if (name != null) {
|
|
103337
|
+
name = String(name);
|
|
103338
|
+
if (!this._names.has(name)) {
|
|
103339
|
+
this._names.add(name);
|
|
103340
|
+
}
|
|
103341
|
+
}
|
|
103342
|
+
this._mappings.add({
|
|
103343
|
+
generatedLine: generated.line,
|
|
103344
|
+
generatedColumn: generated.column,
|
|
103345
|
+
originalLine: original != null && original.line,
|
|
103346
|
+
originalColumn: original != null && original.column,
|
|
103347
|
+
source,
|
|
103348
|
+
name
|
|
103349
|
+
});
|
|
103350
|
+
};
|
|
103351
|
+
SourceMapGenerator.prototype.setSourceContent = function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
|
|
103352
|
+
var source = aSourceFile;
|
|
103353
|
+
if (this._sourceRoot != null) {
|
|
103354
|
+
source = util.relative(this._sourceRoot, source);
|
|
103355
|
+
}
|
|
103356
|
+
if (aSourceContent != null) {
|
|
103357
|
+
if (!this._sourcesContents) {
|
|
103358
|
+
this._sourcesContents = /* @__PURE__ */ Object.create(null);
|
|
103359
|
+
}
|
|
103360
|
+
this._sourcesContents[util.toSetString(source)] = aSourceContent;
|
|
103361
|
+
} else if (this._sourcesContents) {
|
|
103362
|
+
delete this._sourcesContents[util.toSetString(source)];
|
|
103363
|
+
if (Object.keys(this._sourcesContents).length === 0) {
|
|
103364
|
+
this._sourcesContents = null;
|
|
103365
|
+
}
|
|
103366
|
+
}
|
|
103367
|
+
};
|
|
103368
|
+
SourceMapGenerator.prototype.applySourceMap = function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
|
|
103369
|
+
var sourceFile = aSourceFile;
|
|
103370
|
+
if (aSourceFile == null) {
|
|
103371
|
+
if (aSourceMapConsumer.file == null) {
|
|
103372
|
+
throw new Error(
|
|
103373
|
+
`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`
|
|
103374
|
+
);
|
|
103375
|
+
}
|
|
103376
|
+
sourceFile = aSourceMapConsumer.file;
|
|
103377
|
+
}
|
|
103378
|
+
var sourceRoot = this._sourceRoot;
|
|
103379
|
+
if (sourceRoot != null) {
|
|
103380
|
+
sourceFile = util.relative(sourceRoot, sourceFile);
|
|
103381
|
+
}
|
|
103382
|
+
var newSources = new ArraySet();
|
|
103383
|
+
var newNames = new ArraySet();
|
|
103384
|
+
this._mappings.unsortedForEach(function(mapping) {
|
|
103385
|
+
if (mapping.source === sourceFile && mapping.originalLine != null) {
|
|
103386
|
+
var original = aSourceMapConsumer.originalPositionFor({
|
|
103387
|
+
line: mapping.originalLine,
|
|
103388
|
+
column: mapping.originalColumn
|
|
103389
|
+
});
|
|
103390
|
+
if (original.source != null) {
|
|
103391
|
+
mapping.source = original.source;
|
|
103392
|
+
if (aSourceMapPath != null) {
|
|
103393
|
+
mapping.source = util.join(aSourceMapPath, mapping.source);
|
|
103394
|
+
}
|
|
103395
|
+
if (sourceRoot != null) {
|
|
103396
|
+
mapping.source = util.relative(sourceRoot, mapping.source);
|
|
103397
|
+
}
|
|
103398
|
+
mapping.originalLine = original.line;
|
|
103399
|
+
mapping.originalColumn = original.column;
|
|
103400
|
+
if (original.name != null) {
|
|
103401
|
+
mapping.name = original.name;
|
|
103402
|
+
}
|
|
103403
|
+
}
|
|
103404
|
+
}
|
|
103405
|
+
var source = mapping.source;
|
|
103406
|
+
if (source != null && !newSources.has(source)) {
|
|
103407
|
+
newSources.add(source);
|
|
103408
|
+
}
|
|
103409
|
+
var name = mapping.name;
|
|
103410
|
+
if (name != null && !newNames.has(name)) {
|
|
103411
|
+
newNames.add(name);
|
|
103412
|
+
}
|
|
103413
|
+
}, this);
|
|
103414
|
+
this._sources = newSources;
|
|
103415
|
+
this._names = newNames;
|
|
103416
|
+
aSourceMapConsumer.sources.forEach(function(sourceFile2) {
|
|
103417
|
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile2);
|
|
103418
|
+
if (content != null) {
|
|
103419
|
+
if (aSourceMapPath != null) {
|
|
103420
|
+
sourceFile2 = util.join(aSourceMapPath, sourceFile2);
|
|
103421
|
+
}
|
|
103422
|
+
if (sourceRoot != null) {
|
|
103423
|
+
sourceFile2 = util.relative(sourceRoot, sourceFile2);
|
|
103424
|
+
}
|
|
103425
|
+
this.setSourceContent(sourceFile2, content);
|
|
103426
|
+
}
|
|
103427
|
+
}, this);
|
|
103428
|
+
};
|
|
103429
|
+
SourceMapGenerator.prototype._validateMapping = function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, aName) {
|
|
103430
|
+
if (aOriginal && typeof aOriginal.line !== "number" && typeof aOriginal.column !== "number") {
|
|
103431
|
+
throw new Error(
|
|
103432
|
+
"original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values."
|
|
103433
|
+
);
|
|
103434
|
+
}
|
|
103435
|
+
if (aGenerated && "line" in aGenerated && "column" in aGenerated && aGenerated.line > 0 && aGenerated.column >= 0 && !aOriginal && !aSource && !aName) {
|
|
103436
|
+
return;
|
|
103437
|
+
} else if (aGenerated && "line" in aGenerated && "column" in aGenerated && aOriginal && "line" in aOriginal && "column" in aOriginal && aGenerated.line > 0 && aGenerated.column >= 0 && aOriginal.line > 0 && aOriginal.column >= 0 && aSource) {
|
|
103438
|
+
return;
|
|
103439
|
+
} else {
|
|
103440
|
+
throw new Error("Invalid mapping: " + JSON.stringify({
|
|
103441
|
+
generated: aGenerated,
|
|
103442
|
+
source: aSource,
|
|
103443
|
+
original: aOriginal,
|
|
103444
|
+
name: aName
|
|
103445
|
+
}));
|
|
103446
|
+
}
|
|
103447
|
+
};
|
|
103448
|
+
SourceMapGenerator.prototype._serializeMappings = function SourceMapGenerator_serializeMappings() {
|
|
103449
|
+
var previousGeneratedColumn = 0;
|
|
103450
|
+
var previousGeneratedLine = 1;
|
|
103451
|
+
var previousOriginalColumn = 0;
|
|
103452
|
+
var previousOriginalLine = 0;
|
|
103453
|
+
var previousName = 0;
|
|
103454
|
+
var previousSource = 0;
|
|
103455
|
+
var result = "";
|
|
103456
|
+
var next;
|
|
103457
|
+
var mapping;
|
|
103458
|
+
var nameIdx;
|
|
103459
|
+
var sourceIdx;
|
|
103460
|
+
var mappings = this._mappings.toArray();
|
|
103461
|
+
for (var i = 0, len = mappings.length; i < len; i++) {
|
|
103462
|
+
mapping = mappings[i];
|
|
103463
|
+
next = "";
|
|
103464
|
+
if (mapping.generatedLine !== previousGeneratedLine) {
|
|
103465
|
+
previousGeneratedColumn = 0;
|
|
103466
|
+
while (mapping.generatedLine !== previousGeneratedLine) {
|
|
103467
|
+
next += ";";
|
|
103468
|
+
previousGeneratedLine++;
|
|
103469
|
+
}
|
|
103470
|
+
} else {
|
|
103471
|
+
if (i > 0) {
|
|
103472
|
+
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
|
|
103473
|
+
continue;
|
|
103474
|
+
}
|
|
103475
|
+
next += ",";
|
|
103476
|
+
}
|
|
103477
|
+
}
|
|
103478
|
+
next += base64VLQ.encode(mapping.generatedColumn - previousGeneratedColumn);
|
|
103479
|
+
previousGeneratedColumn = mapping.generatedColumn;
|
|
103480
|
+
if (mapping.source != null) {
|
|
103481
|
+
sourceIdx = this._sources.indexOf(mapping.source);
|
|
103482
|
+
next += base64VLQ.encode(sourceIdx - previousSource);
|
|
103483
|
+
previousSource = sourceIdx;
|
|
103484
|
+
next += base64VLQ.encode(mapping.originalLine - 1 - previousOriginalLine);
|
|
103485
|
+
previousOriginalLine = mapping.originalLine - 1;
|
|
103486
|
+
next += base64VLQ.encode(mapping.originalColumn - previousOriginalColumn);
|
|
103487
|
+
previousOriginalColumn = mapping.originalColumn;
|
|
103488
|
+
if (mapping.name != null) {
|
|
103489
|
+
nameIdx = this._names.indexOf(mapping.name);
|
|
103490
|
+
next += base64VLQ.encode(nameIdx - previousName);
|
|
103491
|
+
previousName = nameIdx;
|
|
103492
|
+
}
|
|
103493
|
+
}
|
|
103494
|
+
result += next;
|
|
103495
|
+
}
|
|
103496
|
+
return result;
|
|
103497
|
+
};
|
|
103498
|
+
SourceMapGenerator.prototype._generateSourcesContent = function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
|
|
103499
|
+
return aSources.map(function(source) {
|
|
103500
|
+
if (!this._sourcesContents) {
|
|
103501
|
+
return null;
|
|
103502
|
+
}
|
|
103503
|
+
if (aSourceRoot != null) {
|
|
103504
|
+
source = util.relative(aSourceRoot, source);
|
|
103505
|
+
}
|
|
103506
|
+
var key = util.toSetString(source);
|
|
103507
|
+
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) ? this._sourcesContents[key] : null;
|
|
103508
|
+
}, this);
|
|
103509
|
+
};
|
|
103510
|
+
SourceMapGenerator.prototype.toJSON = function SourceMapGenerator_toJSON() {
|
|
103511
|
+
var map2 = {
|
|
103512
|
+
version: this._version,
|
|
103513
|
+
sources: this._sources.toArray(),
|
|
103514
|
+
names: this._names.toArray(),
|
|
103515
|
+
mappings: this._serializeMappings()
|
|
103516
|
+
};
|
|
103517
|
+
if (this._file != null) {
|
|
103518
|
+
map2.file = this._file;
|
|
103519
|
+
}
|
|
103520
|
+
if (this._sourceRoot != null) {
|
|
103521
|
+
map2.sourceRoot = this._sourceRoot;
|
|
103522
|
+
}
|
|
103523
|
+
if (this._sourcesContents) {
|
|
103524
|
+
map2.sourcesContent = this._generateSourcesContent(map2.sources, map2.sourceRoot);
|
|
103525
|
+
}
|
|
103526
|
+
return map2;
|
|
103527
|
+
};
|
|
103528
|
+
SourceMapGenerator.prototype.toString = function SourceMapGenerator_toString() {
|
|
103529
|
+
return JSON.stringify(this.toJSON());
|
|
103530
|
+
};
|
|
103531
|
+
exports.SourceMapGenerator = SourceMapGenerator;
|
|
103532
|
+
}
|
|
103533
|
+
});
|
|
103534
|
+
|
|
103535
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/binary-search.js
|
|
103536
|
+
var require_binary_search = __commonJS({
|
|
103537
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/binary-search.js"(exports) {
|
|
103538
|
+
"use strict";
|
|
103539
|
+
exports.GREATEST_LOWER_BOUND = 1;
|
|
103540
|
+
exports.LEAST_UPPER_BOUND = 2;
|
|
103541
|
+
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
|
|
103542
|
+
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
|
103543
|
+
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
|
103544
|
+
if (cmp === 0) {
|
|
103545
|
+
return mid;
|
|
103546
|
+
} else if (cmp > 0) {
|
|
103547
|
+
if (aHigh - mid > 1) {
|
|
103548
|
+
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
|
|
103549
|
+
}
|
|
103550
|
+
if (aBias == exports.LEAST_UPPER_BOUND) {
|
|
103551
|
+
return aHigh < aHaystack.length ? aHigh : -1;
|
|
103552
|
+
} else {
|
|
103553
|
+
return mid;
|
|
103554
|
+
}
|
|
103555
|
+
} else {
|
|
103556
|
+
if (mid - aLow > 1) {
|
|
103557
|
+
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
|
|
103558
|
+
}
|
|
103559
|
+
if (aBias == exports.LEAST_UPPER_BOUND) {
|
|
103560
|
+
return mid;
|
|
103561
|
+
} else {
|
|
103562
|
+
return aLow < 0 ? -1 : aLow;
|
|
103563
|
+
}
|
|
103564
|
+
}
|
|
103565
|
+
}
|
|
103566
|
+
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
|
|
103567
|
+
if (aHaystack.length === 0) {
|
|
103568
|
+
return -1;
|
|
103569
|
+
}
|
|
103570
|
+
var index = recursiveSearch(
|
|
103571
|
+
-1,
|
|
103572
|
+
aHaystack.length,
|
|
103573
|
+
aNeedle,
|
|
103574
|
+
aHaystack,
|
|
103575
|
+
aCompare,
|
|
103576
|
+
aBias || exports.GREATEST_LOWER_BOUND
|
|
103577
|
+
);
|
|
103578
|
+
if (index < 0) {
|
|
103579
|
+
return -1;
|
|
103580
|
+
}
|
|
103581
|
+
while (index - 1 >= 0) {
|
|
103582
|
+
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
|
|
103583
|
+
break;
|
|
103584
|
+
}
|
|
103585
|
+
--index;
|
|
103586
|
+
}
|
|
103587
|
+
return index;
|
|
103588
|
+
};
|
|
103589
|
+
}
|
|
103590
|
+
});
|
|
103591
|
+
|
|
103592
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/quick-sort.js
|
|
103593
|
+
var require_quick_sort = __commonJS({
|
|
103594
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/quick-sort.js"(exports) {
|
|
103595
|
+
"use strict";
|
|
103596
|
+
function swap(ary, x, y) {
|
|
103597
|
+
var temp = ary[x];
|
|
103598
|
+
ary[x] = ary[y];
|
|
103599
|
+
ary[y] = temp;
|
|
103600
|
+
}
|
|
103601
|
+
function randomIntInRange(low, high) {
|
|
103602
|
+
return Math.round(low + Math.random() * (high - low));
|
|
103603
|
+
}
|
|
103604
|
+
function doQuickSort(ary, comparator, p, r) {
|
|
103605
|
+
if (p < r) {
|
|
103606
|
+
var pivotIndex = randomIntInRange(p, r);
|
|
103607
|
+
var i = p - 1;
|
|
103608
|
+
swap(ary, pivotIndex, r);
|
|
103609
|
+
var pivot = ary[r];
|
|
103610
|
+
for (var j = p; j < r; j++) {
|
|
103611
|
+
if (comparator(ary[j], pivot) <= 0) {
|
|
103612
|
+
i += 1;
|
|
103613
|
+
swap(ary, i, j);
|
|
103614
|
+
}
|
|
103615
|
+
}
|
|
103616
|
+
swap(ary, i + 1, j);
|
|
103617
|
+
var q = i + 1;
|
|
103618
|
+
doQuickSort(ary, comparator, p, q - 1);
|
|
103619
|
+
doQuickSort(ary, comparator, q + 1, r);
|
|
103620
|
+
}
|
|
103621
|
+
}
|
|
103622
|
+
exports.quickSort = function(ary, comparator) {
|
|
103623
|
+
doQuickSort(ary, comparator, 0, ary.length - 1);
|
|
103624
|
+
};
|
|
103625
|
+
}
|
|
103626
|
+
});
|
|
103627
|
+
|
|
103628
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/source-map-consumer.js
|
|
103629
|
+
var require_source_map_consumer = __commonJS({
|
|
103630
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/source-map-consumer.js"(exports) {
|
|
103631
|
+
"use strict";
|
|
103632
|
+
var util = require_util4();
|
|
103633
|
+
var binarySearch = require_binary_search();
|
|
103634
|
+
var ArraySet = require_array_set().ArraySet;
|
|
103635
|
+
var base64VLQ = require_base64_vlq();
|
|
103636
|
+
var quickSort = require_quick_sort().quickSort;
|
|
103637
|
+
function SourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
103638
|
+
var sourceMap = aSourceMap;
|
|
103639
|
+
if (typeof aSourceMap === "string") {
|
|
103640
|
+
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
103641
|
+
}
|
|
103642
|
+
return sourceMap.sections != null ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
|
|
103643
|
+
}
|
|
103644
|
+
SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {
|
|
103645
|
+
return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
|
|
103646
|
+
};
|
|
103647
|
+
SourceMapConsumer.prototype._version = 3;
|
|
103648
|
+
SourceMapConsumer.prototype.__generatedMappings = null;
|
|
103649
|
+
Object.defineProperty(SourceMapConsumer.prototype, "_generatedMappings", {
|
|
103650
|
+
configurable: true,
|
|
103651
|
+
enumerable: true,
|
|
103652
|
+
get: function() {
|
|
103653
|
+
if (!this.__generatedMappings) {
|
|
103654
|
+
this._parseMappings(this._mappings, this.sourceRoot);
|
|
103655
|
+
}
|
|
103656
|
+
return this.__generatedMappings;
|
|
103657
|
+
}
|
|
103658
|
+
});
|
|
103659
|
+
SourceMapConsumer.prototype.__originalMappings = null;
|
|
103660
|
+
Object.defineProperty(SourceMapConsumer.prototype, "_originalMappings", {
|
|
103661
|
+
configurable: true,
|
|
103662
|
+
enumerable: true,
|
|
103663
|
+
get: function() {
|
|
103664
|
+
if (!this.__originalMappings) {
|
|
103665
|
+
this._parseMappings(this._mappings, this.sourceRoot);
|
|
103666
|
+
}
|
|
103667
|
+
return this.__originalMappings;
|
|
103668
|
+
}
|
|
103669
|
+
});
|
|
103670
|
+
SourceMapConsumer.prototype._charIsMappingSeparator = function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
|
|
103671
|
+
var c = aStr.charAt(index);
|
|
103672
|
+
return c === ";" || c === ",";
|
|
103673
|
+
};
|
|
103674
|
+
SourceMapConsumer.prototype._parseMappings = function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
103675
|
+
throw new Error("Subclasses must implement _parseMappings");
|
|
103676
|
+
};
|
|
103677
|
+
SourceMapConsumer.GENERATED_ORDER = 1;
|
|
103678
|
+
SourceMapConsumer.ORIGINAL_ORDER = 2;
|
|
103679
|
+
SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
|
|
103680
|
+
SourceMapConsumer.LEAST_UPPER_BOUND = 2;
|
|
103681
|
+
SourceMapConsumer.prototype.eachMapping = function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
|
|
103682
|
+
var context = aContext || null;
|
|
103683
|
+
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
|
|
103684
|
+
var mappings;
|
|
103685
|
+
switch (order) {
|
|
103686
|
+
case SourceMapConsumer.GENERATED_ORDER:
|
|
103687
|
+
mappings = this._generatedMappings;
|
|
103688
|
+
break;
|
|
103689
|
+
case SourceMapConsumer.ORIGINAL_ORDER:
|
|
103690
|
+
mappings = this._originalMappings;
|
|
103691
|
+
break;
|
|
103692
|
+
default:
|
|
103693
|
+
throw new Error("Unknown order of iteration.");
|
|
103694
|
+
}
|
|
103695
|
+
var sourceRoot = this.sourceRoot;
|
|
103696
|
+
mappings.map(function(mapping) {
|
|
103697
|
+
var source = mapping.source === null ? null : this._sources.at(mapping.source);
|
|
103698
|
+
source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
|
|
103699
|
+
return {
|
|
103700
|
+
source,
|
|
103701
|
+
generatedLine: mapping.generatedLine,
|
|
103702
|
+
generatedColumn: mapping.generatedColumn,
|
|
103703
|
+
originalLine: mapping.originalLine,
|
|
103704
|
+
originalColumn: mapping.originalColumn,
|
|
103705
|
+
name: mapping.name === null ? null : this._names.at(mapping.name)
|
|
103706
|
+
};
|
|
103707
|
+
}, this).forEach(aCallback, context);
|
|
103708
|
+
};
|
|
103709
|
+
SourceMapConsumer.prototype.allGeneratedPositionsFor = function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
|
|
103710
|
+
var line = util.getArg(aArgs, "line");
|
|
103711
|
+
var needle = {
|
|
103712
|
+
source: util.getArg(aArgs, "source"),
|
|
103713
|
+
originalLine: line,
|
|
103714
|
+
originalColumn: util.getArg(aArgs, "column", 0)
|
|
103715
|
+
};
|
|
103716
|
+
needle.source = this._findSourceIndex(needle.source);
|
|
103717
|
+
if (needle.source < 0) {
|
|
103718
|
+
return [];
|
|
103719
|
+
}
|
|
103720
|
+
var mappings = [];
|
|
103721
|
+
var index = this._findMapping(
|
|
103722
|
+
needle,
|
|
103723
|
+
this._originalMappings,
|
|
103724
|
+
"originalLine",
|
|
103725
|
+
"originalColumn",
|
|
103726
|
+
util.compareByOriginalPositions,
|
|
103727
|
+
binarySearch.LEAST_UPPER_BOUND
|
|
103728
|
+
);
|
|
103729
|
+
if (index >= 0) {
|
|
103730
|
+
var mapping = this._originalMappings[index];
|
|
103731
|
+
if (aArgs.column === void 0) {
|
|
103732
|
+
var originalLine = mapping.originalLine;
|
|
103733
|
+
while (mapping && mapping.originalLine === originalLine) {
|
|
103734
|
+
mappings.push({
|
|
103735
|
+
line: util.getArg(mapping, "generatedLine", null),
|
|
103736
|
+
column: util.getArg(mapping, "generatedColumn", null),
|
|
103737
|
+
lastColumn: util.getArg(mapping, "lastGeneratedColumn", null)
|
|
103738
|
+
});
|
|
103739
|
+
mapping = this._originalMappings[++index];
|
|
103740
|
+
}
|
|
103741
|
+
} else {
|
|
103742
|
+
var originalColumn = mapping.originalColumn;
|
|
103743
|
+
while (mapping && mapping.originalLine === line && mapping.originalColumn == originalColumn) {
|
|
103744
|
+
mappings.push({
|
|
103745
|
+
line: util.getArg(mapping, "generatedLine", null),
|
|
103746
|
+
column: util.getArg(mapping, "generatedColumn", null),
|
|
103747
|
+
lastColumn: util.getArg(mapping, "lastGeneratedColumn", null)
|
|
103748
|
+
});
|
|
103749
|
+
mapping = this._originalMappings[++index];
|
|
103750
|
+
}
|
|
103751
|
+
}
|
|
103752
|
+
}
|
|
103753
|
+
return mappings;
|
|
103754
|
+
};
|
|
103755
|
+
exports.SourceMapConsumer = SourceMapConsumer;
|
|
103756
|
+
function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
103757
|
+
var sourceMap = aSourceMap;
|
|
103758
|
+
if (typeof aSourceMap === "string") {
|
|
103759
|
+
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
103760
|
+
}
|
|
103761
|
+
var version = util.getArg(sourceMap, "version");
|
|
103762
|
+
var sources = util.getArg(sourceMap, "sources");
|
|
103763
|
+
var names = util.getArg(sourceMap, "names", []);
|
|
103764
|
+
var sourceRoot = util.getArg(sourceMap, "sourceRoot", null);
|
|
103765
|
+
var sourcesContent = util.getArg(sourceMap, "sourcesContent", null);
|
|
103766
|
+
var mappings = util.getArg(sourceMap, "mappings");
|
|
103767
|
+
var file = util.getArg(sourceMap, "file", null);
|
|
103768
|
+
if (version != this._version) {
|
|
103769
|
+
throw new Error("Unsupported version: " + version);
|
|
103770
|
+
}
|
|
103771
|
+
if (sourceRoot) {
|
|
103772
|
+
sourceRoot = util.normalize(sourceRoot);
|
|
103773
|
+
}
|
|
103774
|
+
sources = sources.map(String).map(util.normalize).map(function(source) {
|
|
103775
|
+
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) ? util.relative(sourceRoot, source) : source;
|
|
103776
|
+
});
|
|
103777
|
+
this._names = ArraySet.fromArray(names.map(String), true);
|
|
103778
|
+
this._sources = ArraySet.fromArray(sources, true);
|
|
103779
|
+
this._absoluteSources = this._sources.toArray().map(function(s) {
|
|
103780
|
+
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
|
|
103781
|
+
});
|
|
103782
|
+
this.sourceRoot = sourceRoot;
|
|
103783
|
+
this.sourcesContent = sourcesContent;
|
|
103784
|
+
this._mappings = mappings;
|
|
103785
|
+
this._sourceMapURL = aSourceMapURL;
|
|
103786
|
+
this.file = file;
|
|
103787
|
+
}
|
|
103788
|
+
BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
|
103789
|
+
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
|
|
103790
|
+
BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {
|
|
103791
|
+
var relativeSource = aSource;
|
|
103792
|
+
if (this.sourceRoot != null) {
|
|
103793
|
+
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
|
103794
|
+
}
|
|
103795
|
+
if (this._sources.has(relativeSource)) {
|
|
103796
|
+
return this._sources.indexOf(relativeSource);
|
|
103797
|
+
}
|
|
103798
|
+
var i;
|
|
103799
|
+
for (i = 0; i < this._absoluteSources.length; ++i) {
|
|
103800
|
+
if (this._absoluteSources[i] == aSource) {
|
|
103801
|
+
return i;
|
|
103802
|
+
}
|
|
103803
|
+
}
|
|
103804
|
+
return -1;
|
|
103805
|
+
};
|
|
103806
|
+
BasicSourceMapConsumer.fromSourceMap = function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
|
|
103807
|
+
var smc = Object.create(BasicSourceMapConsumer.prototype);
|
|
103808
|
+
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
|
103809
|
+
var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
|
103810
|
+
smc.sourceRoot = aSourceMap._sourceRoot;
|
|
103811
|
+
smc.sourcesContent = aSourceMap._generateSourcesContent(
|
|
103812
|
+
smc._sources.toArray(),
|
|
103813
|
+
smc.sourceRoot
|
|
103814
|
+
);
|
|
103815
|
+
smc.file = aSourceMap._file;
|
|
103816
|
+
smc._sourceMapURL = aSourceMapURL;
|
|
103817
|
+
smc._absoluteSources = smc._sources.toArray().map(function(s) {
|
|
103818
|
+
return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);
|
|
103819
|
+
});
|
|
103820
|
+
var generatedMappings = aSourceMap._mappings.toArray().slice();
|
|
103821
|
+
var destGeneratedMappings = smc.__generatedMappings = [];
|
|
103822
|
+
var destOriginalMappings = smc.__originalMappings = [];
|
|
103823
|
+
for (var i = 0, length = generatedMappings.length; i < length; i++) {
|
|
103824
|
+
var srcMapping = generatedMappings[i];
|
|
103825
|
+
var destMapping = new Mapping();
|
|
103826
|
+
destMapping.generatedLine = srcMapping.generatedLine;
|
|
103827
|
+
destMapping.generatedColumn = srcMapping.generatedColumn;
|
|
103828
|
+
if (srcMapping.source) {
|
|
103829
|
+
destMapping.source = sources.indexOf(srcMapping.source);
|
|
103830
|
+
destMapping.originalLine = srcMapping.originalLine;
|
|
103831
|
+
destMapping.originalColumn = srcMapping.originalColumn;
|
|
103832
|
+
if (srcMapping.name) {
|
|
103833
|
+
destMapping.name = names.indexOf(srcMapping.name);
|
|
103834
|
+
}
|
|
103835
|
+
destOriginalMappings.push(destMapping);
|
|
103836
|
+
}
|
|
103837
|
+
destGeneratedMappings.push(destMapping);
|
|
103838
|
+
}
|
|
103839
|
+
quickSort(smc.__originalMappings, util.compareByOriginalPositions);
|
|
103840
|
+
return smc;
|
|
103841
|
+
};
|
|
103842
|
+
BasicSourceMapConsumer.prototype._version = 3;
|
|
103843
|
+
Object.defineProperty(BasicSourceMapConsumer.prototype, "sources", {
|
|
103844
|
+
get: function() {
|
|
103845
|
+
return this._absoluteSources.slice();
|
|
103846
|
+
}
|
|
103847
|
+
});
|
|
103848
|
+
function Mapping() {
|
|
103849
|
+
this.generatedLine = 0;
|
|
103850
|
+
this.generatedColumn = 0;
|
|
103851
|
+
this.source = null;
|
|
103852
|
+
this.originalLine = null;
|
|
103853
|
+
this.originalColumn = null;
|
|
103854
|
+
this.name = null;
|
|
103855
|
+
}
|
|
103856
|
+
BasicSourceMapConsumer.prototype._parseMappings = function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
103857
|
+
var generatedLine = 1;
|
|
103858
|
+
var previousGeneratedColumn = 0;
|
|
103859
|
+
var previousOriginalLine = 0;
|
|
103860
|
+
var previousOriginalColumn = 0;
|
|
103861
|
+
var previousSource = 0;
|
|
103862
|
+
var previousName = 0;
|
|
103863
|
+
var length = aStr.length;
|
|
103864
|
+
var index = 0;
|
|
103865
|
+
var cachedSegments = {};
|
|
103866
|
+
var temp = {};
|
|
103867
|
+
var originalMappings = [];
|
|
103868
|
+
var generatedMappings = [];
|
|
103869
|
+
var mapping, str, segment, end, value;
|
|
103870
|
+
while (index < length) {
|
|
103871
|
+
if (aStr.charAt(index) === ";") {
|
|
103872
|
+
generatedLine++;
|
|
103873
|
+
index++;
|
|
103874
|
+
previousGeneratedColumn = 0;
|
|
103875
|
+
} else if (aStr.charAt(index) === ",") {
|
|
103876
|
+
index++;
|
|
103877
|
+
} else {
|
|
103878
|
+
mapping = new Mapping();
|
|
103879
|
+
mapping.generatedLine = generatedLine;
|
|
103880
|
+
for (end = index; end < length; end++) {
|
|
103881
|
+
if (this._charIsMappingSeparator(aStr, end)) {
|
|
103882
|
+
break;
|
|
103883
|
+
}
|
|
103884
|
+
}
|
|
103885
|
+
str = aStr.slice(index, end);
|
|
103886
|
+
segment = cachedSegments[str];
|
|
103887
|
+
if (segment) {
|
|
103888
|
+
index += str.length;
|
|
103889
|
+
} else {
|
|
103890
|
+
segment = [];
|
|
103891
|
+
while (index < end) {
|
|
103892
|
+
base64VLQ.decode(aStr, index, temp);
|
|
103893
|
+
value = temp.value;
|
|
103894
|
+
index = temp.rest;
|
|
103895
|
+
segment.push(value);
|
|
103896
|
+
}
|
|
103897
|
+
if (segment.length === 2) {
|
|
103898
|
+
throw new Error("Found a source, but no line and column");
|
|
103899
|
+
}
|
|
103900
|
+
if (segment.length === 3) {
|
|
103901
|
+
throw new Error("Found a source and line, but no column");
|
|
103902
|
+
}
|
|
103903
|
+
cachedSegments[str] = segment;
|
|
103904
|
+
}
|
|
103905
|
+
mapping.generatedColumn = previousGeneratedColumn + segment[0];
|
|
103906
|
+
previousGeneratedColumn = mapping.generatedColumn;
|
|
103907
|
+
if (segment.length > 1) {
|
|
103908
|
+
mapping.source = previousSource + segment[1];
|
|
103909
|
+
previousSource += segment[1];
|
|
103910
|
+
mapping.originalLine = previousOriginalLine + segment[2];
|
|
103911
|
+
previousOriginalLine = mapping.originalLine;
|
|
103912
|
+
mapping.originalLine += 1;
|
|
103913
|
+
mapping.originalColumn = previousOriginalColumn + segment[3];
|
|
103914
|
+
previousOriginalColumn = mapping.originalColumn;
|
|
103915
|
+
if (segment.length > 4) {
|
|
103916
|
+
mapping.name = previousName + segment[4];
|
|
103917
|
+
previousName += segment[4];
|
|
103918
|
+
}
|
|
103919
|
+
}
|
|
103920
|
+
generatedMappings.push(mapping);
|
|
103921
|
+
if (typeof mapping.originalLine === "number") {
|
|
103922
|
+
originalMappings.push(mapping);
|
|
103923
|
+
}
|
|
103924
|
+
}
|
|
103925
|
+
}
|
|
103926
|
+
quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
|
|
103927
|
+
this.__generatedMappings = generatedMappings;
|
|
103928
|
+
quickSort(originalMappings, util.compareByOriginalPositions);
|
|
103929
|
+
this.__originalMappings = originalMappings;
|
|
103930
|
+
};
|
|
103931
|
+
BasicSourceMapConsumer.prototype._findMapping = function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, aColumnName, aComparator, aBias) {
|
|
103932
|
+
if (aNeedle[aLineName] <= 0) {
|
|
103933
|
+
throw new TypeError("Line must be greater than or equal to 1, got " + aNeedle[aLineName]);
|
|
103934
|
+
}
|
|
103935
|
+
if (aNeedle[aColumnName] < 0) {
|
|
103936
|
+
throw new TypeError("Column must be greater than or equal to 0, got " + aNeedle[aColumnName]);
|
|
103937
|
+
}
|
|
103938
|
+
return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
|
|
103939
|
+
};
|
|
103940
|
+
BasicSourceMapConsumer.prototype.computeColumnSpans = function SourceMapConsumer_computeColumnSpans() {
|
|
103941
|
+
for (var index = 0; index < this._generatedMappings.length; ++index) {
|
|
103942
|
+
var mapping = this._generatedMappings[index];
|
|
103943
|
+
if (index + 1 < this._generatedMappings.length) {
|
|
103944
|
+
var nextMapping = this._generatedMappings[index + 1];
|
|
103945
|
+
if (mapping.generatedLine === nextMapping.generatedLine) {
|
|
103946
|
+
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
|
|
103947
|
+
continue;
|
|
103948
|
+
}
|
|
103949
|
+
}
|
|
103950
|
+
mapping.lastGeneratedColumn = Infinity;
|
|
103951
|
+
}
|
|
103952
|
+
};
|
|
103953
|
+
BasicSourceMapConsumer.prototype.originalPositionFor = function SourceMapConsumer_originalPositionFor(aArgs) {
|
|
103954
|
+
var needle = {
|
|
103955
|
+
generatedLine: util.getArg(aArgs, "line"),
|
|
103956
|
+
generatedColumn: util.getArg(aArgs, "column")
|
|
103957
|
+
};
|
|
103958
|
+
var index = this._findMapping(
|
|
103959
|
+
needle,
|
|
103960
|
+
this._generatedMappings,
|
|
103961
|
+
"generatedLine",
|
|
103962
|
+
"generatedColumn",
|
|
103963
|
+
util.compareByGeneratedPositionsDeflated,
|
|
103964
|
+
util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND)
|
|
103965
|
+
);
|
|
103966
|
+
if (index >= 0) {
|
|
103967
|
+
var mapping = this._generatedMappings[index];
|
|
103968
|
+
if (mapping.generatedLine === needle.generatedLine) {
|
|
103969
|
+
var source = util.getArg(mapping, "source", null);
|
|
103970
|
+
if (source !== null) {
|
|
103971
|
+
source = this._sources.at(source);
|
|
103972
|
+
source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
|
|
103973
|
+
}
|
|
103974
|
+
var name = util.getArg(mapping, "name", null);
|
|
103975
|
+
if (name !== null) {
|
|
103976
|
+
name = this._names.at(name);
|
|
103977
|
+
}
|
|
103978
|
+
return {
|
|
103979
|
+
source,
|
|
103980
|
+
line: util.getArg(mapping, "originalLine", null),
|
|
103981
|
+
column: util.getArg(mapping, "originalColumn", null),
|
|
103982
|
+
name
|
|
103983
|
+
};
|
|
103984
|
+
}
|
|
103985
|
+
}
|
|
103986
|
+
return {
|
|
103987
|
+
source: null,
|
|
103988
|
+
line: null,
|
|
103989
|
+
column: null,
|
|
103990
|
+
name: null
|
|
103991
|
+
};
|
|
103992
|
+
};
|
|
103993
|
+
BasicSourceMapConsumer.prototype.hasContentsOfAllSources = function BasicSourceMapConsumer_hasContentsOfAllSources() {
|
|
103994
|
+
if (!this.sourcesContent) {
|
|
103995
|
+
return false;
|
|
103996
|
+
}
|
|
103997
|
+
return this.sourcesContent.length >= this._sources.size() && !this.sourcesContent.some(function(sc) {
|
|
103998
|
+
return sc == null;
|
|
103999
|
+
});
|
|
104000
|
+
};
|
|
104001
|
+
BasicSourceMapConsumer.prototype.sourceContentFor = function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
|
104002
|
+
if (!this.sourcesContent) {
|
|
104003
|
+
return null;
|
|
104004
|
+
}
|
|
104005
|
+
var index = this._findSourceIndex(aSource);
|
|
104006
|
+
if (index >= 0) {
|
|
104007
|
+
return this.sourcesContent[index];
|
|
104008
|
+
}
|
|
104009
|
+
var relativeSource = aSource;
|
|
104010
|
+
if (this.sourceRoot != null) {
|
|
104011
|
+
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
|
104012
|
+
}
|
|
104013
|
+
var url;
|
|
104014
|
+
if (this.sourceRoot != null && (url = util.urlParse(this.sourceRoot))) {
|
|
104015
|
+
var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
|
|
104016
|
+
if (url.scheme == "file" && this._sources.has(fileUriAbsPath)) {
|
|
104017
|
+
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];
|
|
104018
|
+
}
|
|
104019
|
+
if ((!url.path || url.path == "/") && this._sources.has("/" + relativeSource)) {
|
|
104020
|
+
return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
|
|
104021
|
+
}
|
|
104022
|
+
}
|
|
104023
|
+
if (nullOnMissing) {
|
|
104024
|
+
return null;
|
|
104025
|
+
} else {
|
|
104026
|
+
throw new Error('"' + relativeSource + '" is not in the SourceMap.');
|
|
104027
|
+
}
|
|
104028
|
+
};
|
|
104029
|
+
BasicSourceMapConsumer.prototype.generatedPositionFor = function SourceMapConsumer_generatedPositionFor(aArgs) {
|
|
104030
|
+
var source = util.getArg(aArgs, "source");
|
|
104031
|
+
source = this._findSourceIndex(source);
|
|
104032
|
+
if (source < 0) {
|
|
104033
|
+
return {
|
|
104034
|
+
line: null,
|
|
104035
|
+
column: null,
|
|
104036
|
+
lastColumn: null
|
|
104037
|
+
};
|
|
104038
|
+
}
|
|
104039
|
+
var needle = {
|
|
104040
|
+
source,
|
|
104041
|
+
originalLine: util.getArg(aArgs, "line"),
|
|
104042
|
+
originalColumn: util.getArg(aArgs, "column")
|
|
104043
|
+
};
|
|
104044
|
+
var index = this._findMapping(
|
|
104045
|
+
needle,
|
|
104046
|
+
this._originalMappings,
|
|
104047
|
+
"originalLine",
|
|
104048
|
+
"originalColumn",
|
|
104049
|
+
util.compareByOriginalPositions,
|
|
104050
|
+
util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND)
|
|
104051
|
+
);
|
|
104052
|
+
if (index >= 0) {
|
|
104053
|
+
var mapping = this._originalMappings[index];
|
|
104054
|
+
if (mapping.source === needle.source) {
|
|
104055
|
+
return {
|
|
104056
|
+
line: util.getArg(mapping, "generatedLine", null),
|
|
104057
|
+
column: util.getArg(mapping, "generatedColumn", null),
|
|
104058
|
+
lastColumn: util.getArg(mapping, "lastGeneratedColumn", null)
|
|
104059
|
+
};
|
|
104060
|
+
}
|
|
104061
|
+
}
|
|
104062
|
+
return {
|
|
104063
|
+
line: null,
|
|
104064
|
+
column: null,
|
|
104065
|
+
lastColumn: null
|
|
104066
|
+
};
|
|
104067
|
+
};
|
|
104068
|
+
exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
|
|
104069
|
+
function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
104070
|
+
var sourceMap = aSourceMap;
|
|
104071
|
+
if (typeof aSourceMap === "string") {
|
|
104072
|
+
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
104073
|
+
}
|
|
104074
|
+
var version = util.getArg(sourceMap, "version");
|
|
104075
|
+
var sections = util.getArg(sourceMap, "sections");
|
|
104076
|
+
if (version != this._version) {
|
|
104077
|
+
throw new Error("Unsupported version: " + version);
|
|
104078
|
+
}
|
|
104079
|
+
this._sources = new ArraySet();
|
|
104080
|
+
this._names = new ArraySet();
|
|
104081
|
+
var lastOffset = {
|
|
104082
|
+
line: -1,
|
|
104083
|
+
column: 0
|
|
104084
|
+
};
|
|
104085
|
+
this._sections = sections.map(function(s) {
|
|
104086
|
+
if (s.url) {
|
|
104087
|
+
throw new Error("Support for url field in sections not implemented.");
|
|
104088
|
+
}
|
|
104089
|
+
var offset = util.getArg(s, "offset");
|
|
104090
|
+
var offsetLine = util.getArg(offset, "line");
|
|
104091
|
+
var offsetColumn = util.getArg(offset, "column");
|
|
104092
|
+
if (offsetLine < lastOffset.line || offsetLine === lastOffset.line && offsetColumn < lastOffset.column) {
|
|
104093
|
+
throw new Error("Section offsets must be ordered and non-overlapping.");
|
|
104094
|
+
}
|
|
104095
|
+
lastOffset = offset;
|
|
104096
|
+
return {
|
|
104097
|
+
generatedOffset: {
|
|
104098
|
+
// The offset fields are 0-based, but we use 1-based indices when
|
|
104099
|
+
// encoding/decoding from VLQ.
|
|
104100
|
+
generatedLine: offsetLine + 1,
|
|
104101
|
+
generatedColumn: offsetColumn + 1
|
|
104102
|
+
},
|
|
104103
|
+
consumer: new SourceMapConsumer(util.getArg(s, "map"), aSourceMapURL)
|
|
104104
|
+
};
|
|
104105
|
+
});
|
|
104106
|
+
}
|
|
104107
|
+
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
|
104108
|
+
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
|
|
104109
|
+
IndexedSourceMapConsumer.prototype._version = 3;
|
|
104110
|
+
Object.defineProperty(IndexedSourceMapConsumer.prototype, "sources", {
|
|
104111
|
+
get: function() {
|
|
104112
|
+
var sources = [];
|
|
104113
|
+
for (var i = 0; i < this._sections.length; i++) {
|
|
104114
|
+
for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
|
|
104115
|
+
sources.push(this._sections[i].consumer.sources[j]);
|
|
104116
|
+
}
|
|
104117
|
+
}
|
|
104118
|
+
return sources;
|
|
104119
|
+
}
|
|
104120
|
+
});
|
|
104121
|
+
IndexedSourceMapConsumer.prototype.originalPositionFor = function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
|
|
104122
|
+
var needle = {
|
|
104123
|
+
generatedLine: util.getArg(aArgs, "line"),
|
|
104124
|
+
generatedColumn: util.getArg(aArgs, "column")
|
|
104125
|
+
};
|
|
104126
|
+
var sectionIndex = binarySearch.search(
|
|
104127
|
+
needle,
|
|
104128
|
+
this._sections,
|
|
104129
|
+
function(needle2, section2) {
|
|
104130
|
+
var cmp = needle2.generatedLine - section2.generatedOffset.generatedLine;
|
|
104131
|
+
if (cmp) {
|
|
104132
|
+
return cmp;
|
|
104133
|
+
}
|
|
104134
|
+
return needle2.generatedColumn - section2.generatedOffset.generatedColumn;
|
|
104135
|
+
}
|
|
104136
|
+
);
|
|
104137
|
+
var section = this._sections[sectionIndex];
|
|
104138
|
+
if (!section) {
|
|
104139
|
+
return {
|
|
104140
|
+
source: null,
|
|
104141
|
+
line: null,
|
|
104142
|
+
column: null,
|
|
104143
|
+
name: null
|
|
104144
|
+
};
|
|
104145
|
+
}
|
|
104146
|
+
return section.consumer.originalPositionFor({
|
|
104147
|
+
line: needle.generatedLine - (section.generatedOffset.generatedLine - 1),
|
|
104148
|
+
column: needle.generatedColumn - (section.generatedOffset.generatedLine === needle.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0),
|
|
104149
|
+
bias: aArgs.bias
|
|
104150
|
+
});
|
|
104151
|
+
};
|
|
104152
|
+
IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = function IndexedSourceMapConsumer_hasContentsOfAllSources() {
|
|
104153
|
+
return this._sections.every(function(s) {
|
|
104154
|
+
return s.consumer.hasContentsOfAllSources();
|
|
104155
|
+
});
|
|
104156
|
+
};
|
|
104157
|
+
IndexedSourceMapConsumer.prototype.sourceContentFor = function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
|
104158
|
+
for (var i = 0; i < this._sections.length; i++) {
|
|
104159
|
+
var section = this._sections[i];
|
|
104160
|
+
var content = section.consumer.sourceContentFor(aSource, true);
|
|
104161
|
+
if (content) {
|
|
104162
|
+
return content;
|
|
104163
|
+
}
|
|
104164
|
+
}
|
|
104165
|
+
if (nullOnMissing) {
|
|
104166
|
+
return null;
|
|
104167
|
+
} else {
|
|
104168
|
+
throw new Error('"' + aSource + '" is not in the SourceMap.');
|
|
104169
|
+
}
|
|
104170
|
+
};
|
|
104171
|
+
IndexedSourceMapConsumer.prototype.generatedPositionFor = function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
|
|
104172
|
+
for (var i = 0; i < this._sections.length; i++) {
|
|
104173
|
+
var section = this._sections[i];
|
|
104174
|
+
if (section.consumer._findSourceIndex(util.getArg(aArgs, "source")) === -1) {
|
|
104175
|
+
continue;
|
|
104176
|
+
}
|
|
104177
|
+
var generatedPosition = section.consumer.generatedPositionFor(aArgs);
|
|
104178
|
+
if (generatedPosition) {
|
|
104179
|
+
var ret = {
|
|
104180
|
+
line: generatedPosition.line + (section.generatedOffset.generatedLine - 1),
|
|
104181
|
+
column: generatedPosition.column + (section.generatedOffset.generatedLine === generatedPosition.line ? section.generatedOffset.generatedColumn - 1 : 0)
|
|
104182
|
+
};
|
|
104183
|
+
return ret;
|
|
104184
|
+
}
|
|
104185
|
+
}
|
|
104186
|
+
return {
|
|
104187
|
+
line: null,
|
|
104188
|
+
column: null
|
|
104189
|
+
};
|
|
104190
|
+
};
|
|
104191
|
+
IndexedSourceMapConsumer.prototype._parseMappings = function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
104192
|
+
this.__generatedMappings = [];
|
|
104193
|
+
this.__originalMappings = [];
|
|
104194
|
+
for (var i = 0; i < this._sections.length; i++) {
|
|
104195
|
+
var section = this._sections[i];
|
|
104196
|
+
var sectionMappings = section.consumer._generatedMappings;
|
|
104197
|
+
for (var j = 0; j < sectionMappings.length; j++) {
|
|
104198
|
+
var mapping = sectionMappings[j];
|
|
104199
|
+
var source = section.consumer._sources.at(mapping.source);
|
|
104200
|
+
source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
|
|
104201
|
+
this._sources.add(source);
|
|
104202
|
+
source = this._sources.indexOf(source);
|
|
104203
|
+
var name = null;
|
|
104204
|
+
if (mapping.name) {
|
|
104205
|
+
name = section.consumer._names.at(mapping.name);
|
|
104206
|
+
this._names.add(name);
|
|
104207
|
+
name = this._names.indexOf(name);
|
|
104208
|
+
}
|
|
104209
|
+
var adjustedMapping = {
|
|
104210
|
+
source,
|
|
104211
|
+
generatedLine: mapping.generatedLine + (section.generatedOffset.generatedLine - 1),
|
|
104212
|
+
generatedColumn: mapping.generatedColumn + (section.generatedOffset.generatedLine === mapping.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0),
|
|
104213
|
+
originalLine: mapping.originalLine,
|
|
104214
|
+
originalColumn: mapping.originalColumn,
|
|
104215
|
+
name
|
|
104216
|
+
};
|
|
104217
|
+
this.__generatedMappings.push(adjustedMapping);
|
|
104218
|
+
if (typeof adjustedMapping.originalLine === "number") {
|
|
104219
|
+
this.__originalMappings.push(adjustedMapping);
|
|
104220
|
+
}
|
|
104221
|
+
}
|
|
104222
|
+
}
|
|
104223
|
+
quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
|
|
104224
|
+
quickSort(this.__originalMappings, util.compareByOriginalPositions);
|
|
104225
|
+
};
|
|
104226
|
+
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
|
|
104227
|
+
}
|
|
104228
|
+
});
|
|
104229
|
+
|
|
104230
|
+
// ../../node_modules/source-map-support/node_modules/source-map/lib/source-node.js
|
|
104231
|
+
var require_source_node = __commonJS({
|
|
104232
|
+
"../../node_modules/source-map-support/node_modules/source-map/lib/source-node.js"(exports) {
|
|
104233
|
+
"use strict";
|
|
104234
|
+
var SourceMapGenerator = require_source_map_generator().SourceMapGenerator;
|
|
104235
|
+
var util = require_util4();
|
|
104236
|
+
var REGEX_NEWLINE = /(\r?\n)/;
|
|
104237
|
+
var NEWLINE_CODE = 10;
|
|
104238
|
+
var isSourceNode = "$$$isSourceNode$$$";
|
|
104239
|
+
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
|
|
104240
|
+
this.children = [];
|
|
104241
|
+
this.sourceContents = {};
|
|
104242
|
+
this.line = aLine == null ? null : aLine;
|
|
104243
|
+
this.column = aColumn == null ? null : aColumn;
|
|
104244
|
+
this.source = aSource == null ? null : aSource;
|
|
104245
|
+
this.name = aName == null ? null : aName;
|
|
104246
|
+
this[isSourceNode] = true;
|
|
104247
|
+
if (aChunks != null) this.add(aChunks);
|
|
104248
|
+
}
|
|
104249
|
+
SourceNode.fromStringWithSourceMap = function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
|
|
104250
|
+
var node = new SourceNode();
|
|
104251
|
+
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
|
|
104252
|
+
var remainingLinesIndex = 0;
|
|
104253
|
+
var shiftNextLine = function() {
|
|
104254
|
+
var lineContents = getNextLine();
|
|
104255
|
+
var newLine = getNextLine() || "";
|
|
104256
|
+
return lineContents + newLine;
|
|
104257
|
+
function getNextLine() {
|
|
104258
|
+
return remainingLinesIndex < remainingLines.length ? remainingLines[remainingLinesIndex++] : void 0;
|
|
104259
|
+
}
|
|
104260
|
+
};
|
|
104261
|
+
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
|
|
104262
|
+
var lastMapping = null;
|
|
104263
|
+
aSourceMapConsumer.eachMapping(function(mapping) {
|
|
104264
|
+
if (lastMapping !== null) {
|
|
104265
|
+
if (lastGeneratedLine < mapping.generatedLine) {
|
|
104266
|
+
addMappingWithCode(lastMapping, shiftNextLine());
|
|
104267
|
+
lastGeneratedLine++;
|
|
104268
|
+
lastGeneratedColumn = 0;
|
|
104269
|
+
} else {
|
|
104270
|
+
var nextLine = remainingLines[remainingLinesIndex] || "";
|
|
104271
|
+
var code = nextLine.substr(0, mapping.generatedColumn - lastGeneratedColumn);
|
|
104272
|
+
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - lastGeneratedColumn);
|
|
104273
|
+
lastGeneratedColumn = mapping.generatedColumn;
|
|
104274
|
+
addMappingWithCode(lastMapping, code);
|
|
104275
|
+
lastMapping = mapping;
|
|
104276
|
+
return;
|
|
104277
|
+
}
|
|
104278
|
+
}
|
|
104279
|
+
while (lastGeneratedLine < mapping.generatedLine) {
|
|
104280
|
+
node.add(shiftNextLine());
|
|
104281
|
+
lastGeneratedLine++;
|
|
104282
|
+
}
|
|
104283
|
+
if (lastGeneratedColumn < mapping.generatedColumn) {
|
|
104284
|
+
var nextLine = remainingLines[remainingLinesIndex] || "";
|
|
104285
|
+
node.add(nextLine.substr(0, mapping.generatedColumn));
|
|
104286
|
+
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
|
|
104287
|
+
lastGeneratedColumn = mapping.generatedColumn;
|
|
104288
|
+
}
|
|
104289
|
+
lastMapping = mapping;
|
|
104290
|
+
}, this);
|
|
104291
|
+
if (remainingLinesIndex < remainingLines.length) {
|
|
104292
|
+
if (lastMapping) {
|
|
104293
|
+
addMappingWithCode(lastMapping, shiftNextLine());
|
|
104294
|
+
}
|
|
104295
|
+
node.add(remainingLines.splice(remainingLinesIndex).join(""));
|
|
104296
|
+
}
|
|
104297
|
+
aSourceMapConsumer.sources.forEach(function(sourceFile) {
|
|
104298
|
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
|
104299
|
+
if (content != null) {
|
|
104300
|
+
if (aRelativePath != null) {
|
|
104301
|
+
sourceFile = util.join(aRelativePath, sourceFile);
|
|
104302
|
+
}
|
|
104303
|
+
node.setSourceContent(sourceFile, content);
|
|
104304
|
+
}
|
|
104305
|
+
});
|
|
104306
|
+
return node;
|
|
104307
|
+
function addMappingWithCode(mapping, code) {
|
|
104308
|
+
if (mapping === null || mapping.source === void 0) {
|
|
104309
|
+
node.add(code);
|
|
104310
|
+
} else {
|
|
104311
|
+
var source = aRelativePath ? util.join(aRelativePath, mapping.source) : mapping.source;
|
|
104312
|
+
node.add(new SourceNode(
|
|
104313
|
+
mapping.originalLine,
|
|
104314
|
+
mapping.originalColumn,
|
|
104315
|
+
source,
|
|
104316
|
+
code,
|
|
104317
|
+
mapping.name
|
|
104318
|
+
));
|
|
104319
|
+
}
|
|
104320
|
+
}
|
|
104321
|
+
};
|
|
104322
|
+
SourceNode.prototype.add = function SourceNode_add(aChunk) {
|
|
104323
|
+
if (Array.isArray(aChunk)) {
|
|
104324
|
+
aChunk.forEach(function(chunk) {
|
|
104325
|
+
this.add(chunk);
|
|
104326
|
+
}, this);
|
|
104327
|
+
} else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
|
104328
|
+
if (aChunk) {
|
|
104329
|
+
this.children.push(aChunk);
|
|
104330
|
+
}
|
|
104331
|
+
} else {
|
|
104332
|
+
throw new TypeError(
|
|
104333
|
+
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
|
104334
|
+
);
|
|
104335
|
+
}
|
|
104336
|
+
return this;
|
|
104337
|
+
};
|
|
104338
|
+
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
|
|
104339
|
+
if (Array.isArray(aChunk)) {
|
|
104340
|
+
for (var i = aChunk.length - 1; i >= 0; i--) {
|
|
104341
|
+
this.prepend(aChunk[i]);
|
|
104342
|
+
}
|
|
104343
|
+
} else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
|
104344
|
+
this.children.unshift(aChunk);
|
|
104345
|
+
} else {
|
|
104346
|
+
throw new TypeError(
|
|
104347
|
+
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
|
104348
|
+
);
|
|
104349
|
+
}
|
|
104350
|
+
return this;
|
|
104351
|
+
};
|
|
104352
|
+
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
|
|
104353
|
+
var chunk;
|
|
104354
|
+
for (var i = 0, len = this.children.length; i < len; i++) {
|
|
104355
|
+
chunk = this.children[i];
|
|
104356
|
+
if (chunk[isSourceNode]) {
|
|
104357
|
+
chunk.walk(aFn);
|
|
104358
|
+
} else {
|
|
104359
|
+
if (chunk !== "") {
|
|
104360
|
+
aFn(chunk, {
|
|
104361
|
+
source: this.source,
|
|
104362
|
+
line: this.line,
|
|
104363
|
+
column: this.column,
|
|
104364
|
+
name: this.name
|
|
104365
|
+
});
|
|
104366
|
+
}
|
|
104367
|
+
}
|
|
104368
|
+
}
|
|
104369
|
+
};
|
|
104370
|
+
SourceNode.prototype.join = function SourceNode_join(aSep) {
|
|
104371
|
+
var newChildren;
|
|
104372
|
+
var i;
|
|
104373
|
+
var len = this.children.length;
|
|
104374
|
+
if (len > 0) {
|
|
104375
|
+
newChildren = [];
|
|
104376
|
+
for (i = 0; i < len - 1; i++) {
|
|
104377
|
+
newChildren.push(this.children[i]);
|
|
104378
|
+
newChildren.push(aSep);
|
|
104379
|
+
}
|
|
104380
|
+
newChildren.push(this.children[i]);
|
|
104381
|
+
this.children = newChildren;
|
|
104382
|
+
}
|
|
104383
|
+
return this;
|
|
104384
|
+
};
|
|
104385
|
+
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
|
|
104386
|
+
var lastChild = this.children[this.children.length - 1];
|
|
104387
|
+
if (lastChild[isSourceNode]) {
|
|
104388
|
+
lastChild.replaceRight(aPattern, aReplacement);
|
|
104389
|
+
} else if (typeof lastChild === "string") {
|
|
104390
|
+
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
|
|
104391
|
+
} else {
|
|
104392
|
+
this.children.push("".replace(aPattern, aReplacement));
|
|
104393
|
+
}
|
|
104394
|
+
return this;
|
|
104395
|
+
};
|
|
104396
|
+
SourceNode.prototype.setSourceContent = function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
|
|
104397
|
+
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
|
|
104398
|
+
};
|
|
104399
|
+
SourceNode.prototype.walkSourceContents = function SourceNode_walkSourceContents(aFn) {
|
|
104400
|
+
for (var i = 0, len = this.children.length; i < len; i++) {
|
|
104401
|
+
if (this.children[i][isSourceNode]) {
|
|
104402
|
+
this.children[i].walkSourceContents(aFn);
|
|
104403
|
+
}
|
|
104404
|
+
}
|
|
104405
|
+
var sources = Object.keys(this.sourceContents);
|
|
104406
|
+
for (var i = 0, len = sources.length; i < len; i++) {
|
|
104407
|
+
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
|
|
104408
|
+
}
|
|
104409
|
+
};
|
|
104410
|
+
SourceNode.prototype.toString = function SourceNode_toString() {
|
|
104411
|
+
var str = "";
|
|
104412
|
+
this.walk(function(chunk) {
|
|
104413
|
+
str += chunk;
|
|
104414
|
+
});
|
|
104415
|
+
return str;
|
|
104416
|
+
};
|
|
104417
|
+
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
|
|
104418
|
+
var generated = {
|
|
104419
|
+
code: "",
|
|
104420
|
+
line: 1,
|
|
104421
|
+
column: 0
|
|
104422
|
+
};
|
|
104423
|
+
var map2 = new SourceMapGenerator(aArgs);
|
|
104424
|
+
var sourceMappingActive = false;
|
|
104425
|
+
var lastOriginalSource = null;
|
|
104426
|
+
var lastOriginalLine = null;
|
|
104427
|
+
var lastOriginalColumn = null;
|
|
104428
|
+
var lastOriginalName = null;
|
|
104429
|
+
this.walk(function(chunk, original) {
|
|
104430
|
+
generated.code += chunk;
|
|
104431
|
+
if (original.source !== null && original.line !== null && original.column !== null) {
|
|
104432
|
+
if (lastOriginalSource !== original.source || lastOriginalLine !== original.line || lastOriginalColumn !== original.column || lastOriginalName !== original.name) {
|
|
104433
|
+
map2.addMapping({
|
|
104434
|
+
source: original.source,
|
|
104435
|
+
original: {
|
|
104436
|
+
line: original.line,
|
|
104437
|
+
column: original.column
|
|
104438
|
+
},
|
|
104439
|
+
generated: {
|
|
104440
|
+
line: generated.line,
|
|
104441
|
+
column: generated.column
|
|
104442
|
+
},
|
|
104443
|
+
name: original.name
|
|
104444
|
+
});
|
|
104445
|
+
}
|
|
104446
|
+
lastOriginalSource = original.source;
|
|
104447
|
+
lastOriginalLine = original.line;
|
|
104448
|
+
lastOriginalColumn = original.column;
|
|
104449
|
+
lastOriginalName = original.name;
|
|
104450
|
+
sourceMappingActive = true;
|
|
104451
|
+
} else if (sourceMappingActive) {
|
|
104452
|
+
map2.addMapping({
|
|
104453
|
+
generated: {
|
|
104454
|
+
line: generated.line,
|
|
104455
|
+
column: generated.column
|
|
104456
|
+
}
|
|
104457
|
+
});
|
|
104458
|
+
lastOriginalSource = null;
|
|
104459
|
+
sourceMappingActive = false;
|
|
104460
|
+
}
|
|
104461
|
+
for (var idx = 0, length = chunk.length; idx < length; idx++) {
|
|
104462
|
+
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
|
|
104463
|
+
generated.line++;
|
|
104464
|
+
generated.column = 0;
|
|
104465
|
+
if (idx + 1 === length) {
|
|
104466
|
+
lastOriginalSource = null;
|
|
104467
|
+
sourceMappingActive = false;
|
|
104468
|
+
} else if (sourceMappingActive) {
|
|
104469
|
+
map2.addMapping({
|
|
104470
|
+
source: original.source,
|
|
104471
|
+
original: {
|
|
104472
|
+
line: original.line,
|
|
104473
|
+
column: original.column
|
|
104474
|
+
},
|
|
104475
|
+
generated: {
|
|
104476
|
+
line: generated.line,
|
|
104477
|
+
column: generated.column
|
|
104478
|
+
},
|
|
104479
|
+
name: original.name
|
|
104480
|
+
});
|
|
104481
|
+
}
|
|
104482
|
+
} else {
|
|
104483
|
+
generated.column++;
|
|
104484
|
+
}
|
|
104485
|
+
}
|
|
104486
|
+
});
|
|
104487
|
+
this.walkSourceContents(function(sourceFile, sourceContent) {
|
|
104488
|
+
map2.setSourceContent(sourceFile, sourceContent);
|
|
104489
|
+
});
|
|
104490
|
+
return { code: generated.code, map: map2 };
|
|
104491
|
+
};
|
|
104492
|
+
exports.SourceNode = SourceNode;
|
|
104493
|
+
}
|
|
104494
|
+
});
|
|
104495
|
+
|
|
104496
|
+
// ../../node_modules/source-map-support/node_modules/source-map/source-map.js
|
|
104497
|
+
var require_source_map = __commonJS({
|
|
104498
|
+
"../../node_modules/source-map-support/node_modules/source-map/source-map.js"(exports) {
|
|
104499
|
+
"use strict";
|
|
104500
|
+
exports.SourceMapGenerator = require_source_map_generator().SourceMapGenerator;
|
|
104501
|
+
exports.SourceMapConsumer = require_source_map_consumer().SourceMapConsumer;
|
|
104502
|
+
exports.SourceNode = require_source_node().SourceNode;
|
|
104503
|
+
}
|
|
104504
|
+
});
|
|
104505
|
+
|
|
104506
|
+
// ../../node_modules/buffer-from/index.js
|
|
104507
|
+
var require_buffer_from = __commonJS({
|
|
104508
|
+
"../../node_modules/buffer-from/index.js"(exports, module) {
|
|
104509
|
+
"use strict";
|
|
104510
|
+
var toString = Object.prototype.toString;
|
|
104511
|
+
var isModern = typeof Buffer !== "undefined" && typeof Buffer.alloc === "function" && typeof Buffer.allocUnsafe === "function" && typeof Buffer.from === "function";
|
|
104512
|
+
function isArrayBuffer(input) {
|
|
104513
|
+
return toString.call(input).slice(8, -1) === "ArrayBuffer";
|
|
104514
|
+
}
|
|
104515
|
+
function fromArrayBuffer(obj, byteOffset, length) {
|
|
104516
|
+
byteOffset >>>= 0;
|
|
104517
|
+
var maxLength = obj.byteLength - byteOffset;
|
|
104518
|
+
if (maxLength < 0) {
|
|
104519
|
+
throw new RangeError("'offset' is out of bounds");
|
|
104520
|
+
}
|
|
104521
|
+
if (length === void 0) {
|
|
104522
|
+
length = maxLength;
|
|
104523
|
+
} else {
|
|
104524
|
+
length >>>= 0;
|
|
104525
|
+
if (length > maxLength) {
|
|
104526
|
+
throw new RangeError("'length' is out of bounds");
|
|
104527
|
+
}
|
|
104528
|
+
}
|
|
104529
|
+
return isModern ? Buffer.from(obj.slice(byteOffset, byteOffset + length)) : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)));
|
|
104530
|
+
}
|
|
104531
|
+
function fromString(string, encoding) {
|
|
104532
|
+
if (typeof encoding !== "string" || encoding === "") {
|
|
104533
|
+
encoding = "utf8";
|
|
104534
|
+
}
|
|
104535
|
+
if (!Buffer.isEncoding(encoding)) {
|
|
104536
|
+
throw new TypeError('"encoding" must be a valid string encoding');
|
|
104537
|
+
}
|
|
104538
|
+
return isModern ? Buffer.from(string, encoding) : new Buffer(string, encoding);
|
|
104539
|
+
}
|
|
104540
|
+
function bufferFrom(value, encodingOrOffset, length) {
|
|
104541
|
+
if (typeof value === "number") {
|
|
104542
|
+
throw new TypeError('"value" argument must not be a number');
|
|
104543
|
+
}
|
|
104544
|
+
if (isArrayBuffer(value)) {
|
|
104545
|
+
return fromArrayBuffer(value, encodingOrOffset, length);
|
|
104546
|
+
}
|
|
104547
|
+
if (typeof value === "string") {
|
|
104548
|
+
return fromString(value, encodingOrOffset);
|
|
104549
|
+
}
|
|
104550
|
+
return isModern ? Buffer.from(value) : new Buffer(value);
|
|
104551
|
+
}
|
|
104552
|
+
module.exports = bufferFrom;
|
|
104553
|
+
}
|
|
104554
|
+
});
|
|
104555
|
+
|
|
104556
|
+
// ../../node_modules/source-map-support/source-map-support.js
|
|
104557
|
+
var require_source_map_support = __commonJS({
|
|
104558
|
+
"../../node_modules/source-map-support/source-map-support.js"(exports, module) {
|
|
104559
|
+
"use strict";
|
|
104560
|
+
var SourceMapConsumer = require_source_map().SourceMapConsumer;
|
|
104561
|
+
var path = __require("path");
|
|
104562
|
+
var fs;
|
|
104563
|
+
try {
|
|
104564
|
+
fs = __require("fs");
|
|
104565
|
+
if (!fs.existsSync || !fs.readFileSync) {
|
|
104566
|
+
fs = null;
|
|
104567
|
+
}
|
|
104568
|
+
} catch (err) {
|
|
104569
|
+
}
|
|
104570
|
+
var bufferFrom = require_buffer_from();
|
|
104571
|
+
function dynamicRequire(mod, request) {
|
|
104572
|
+
return mod.require(request);
|
|
104573
|
+
}
|
|
104574
|
+
var errorFormatterInstalled = false;
|
|
104575
|
+
var uncaughtShimInstalled = false;
|
|
104576
|
+
var emptyCacheBetweenOperations = false;
|
|
104577
|
+
var environment = "auto";
|
|
104578
|
+
var fileContentsCache = {};
|
|
104579
|
+
var sourceMapCache = {};
|
|
104580
|
+
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
|
104581
|
+
var retrieveFileHandlers = [];
|
|
104582
|
+
var retrieveMapHandlers = [];
|
|
104583
|
+
function isInBrowser() {
|
|
104584
|
+
if (environment === "browser")
|
|
104585
|
+
return true;
|
|
104586
|
+
if (environment === "node")
|
|
104587
|
+
return false;
|
|
104588
|
+
return typeof window !== "undefined" && typeof XMLHttpRequest === "function" && !(window.require && window.module && window.process && window.process.type === "renderer");
|
|
104589
|
+
}
|
|
104590
|
+
function hasGlobalProcessEventEmitter() {
|
|
104591
|
+
return typeof process === "object" && process !== null && typeof process.on === "function";
|
|
104592
|
+
}
|
|
104593
|
+
function globalProcessVersion() {
|
|
104594
|
+
if (typeof process === "object" && process !== null) {
|
|
104595
|
+
return process.version;
|
|
104596
|
+
} else {
|
|
104597
|
+
return "";
|
|
104598
|
+
}
|
|
104599
|
+
}
|
|
104600
|
+
function globalProcessStderr() {
|
|
104601
|
+
if (typeof process === "object" && process !== null) {
|
|
104602
|
+
return process.stderr;
|
|
104603
|
+
}
|
|
104604
|
+
}
|
|
104605
|
+
function globalProcessExit(code) {
|
|
104606
|
+
if (typeof process === "object" && process !== null && typeof process.exit === "function") {
|
|
104607
|
+
return process.exit(code);
|
|
104608
|
+
}
|
|
104609
|
+
}
|
|
104610
|
+
function handlerExec(list) {
|
|
104611
|
+
return function(arg) {
|
|
104612
|
+
for (var i = 0; i < list.length; i++) {
|
|
104613
|
+
var ret = list[i](arg);
|
|
104614
|
+
if (ret) {
|
|
104615
|
+
return ret;
|
|
104616
|
+
}
|
|
104617
|
+
}
|
|
104618
|
+
return null;
|
|
104619
|
+
};
|
|
104620
|
+
}
|
|
104621
|
+
var retrieveFile = handlerExec(retrieveFileHandlers);
|
|
104622
|
+
retrieveFileHandlers.push(function(path2) {
|
|
104623
|
+
path2 = path2.trim();
|
|
104624
|
+
if (/^file:/.test(path2)) {
|
|
104625
|
+
path2 = path2.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
|
|
104626
|
+
return drive ? "" : (
|
|
104627
|
+
// file:///C:/dir/file -> C:/dir/file
|
|
104628
|
+
"/"
|
|
104629
|
+
);
|
|
104630
|
+
});
|
|
104631
|
+
}
|
|
104632
|
+
if (path2 in fileContentsCache) {
|
|
104633
|
+
return fileContentsCache[path2];
|
|
104634
|
+
}
|
|
104635
|
+
var contents = "";
|
|
104636
|
+
try {
|
|
104637
|
+
if (!fs) {
|
|
104638
|
+
var xhr = new XMLHttpRequest();
|
|
104639
|
+
xhr.open(
|
|
104640
|
+
"GET",
|
|
104641
|
+
path2,
|
|
104642
|
+
/** async */
|
|
104643
|
+
false
|
|
104644
|
+
);
|
|
104645
|
+
xhr.send(null);
|
|
104646
|
+
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
104647
|
+
contents = xhr.responseText;
|
|
104648
|
+
}
|
|
104649
|
+
} else if (fs.existsSync(path2)) {
|
|
104650
|
+
contents = fs.readFileSync(path2, "utf8");
|
|
104651
|
+
}
|
|
104652
|
+
} catch (er) {
|
|
104653
|
+
}
|
|
104654
|
+
return fileContentsCache[path2] = contents;
|
|
104655
|
+
});
|
|
104656
|
+
function supportRelativeURL(file, url) {
|
|
104657
|
+
if (!file) return url;
|
|
104658
|
+
var dir = path.dirname(file);
|
|
104659
|
+
var match = /^\w+:\/\/[^\/]*/.exec(dir);
|
|
104660
|
+
var protocol = match ? match[0] : "";
|
|
104661
|
+
var startPath = dir.slice(protocol.length);
|
|
104662
|
+
if (protocol && /^\/\w\:/.test(startPath)) {
|
|
104663
|
+
protocol += "/";
|
|
104664
|
+
return protocol + path.resolve(dir.slice(protocol.length), url).replace(/\\/g, "/");
|
|
104665
|
+
}
|
|
104666
|
+
return protocol + path.resolve(dir.slice(protocol.length), url);
|
|
104667
|
+
}
|
|
104668
|
+
function retrieveSourceMapURL(source) {
|
|
104669
|
+
var fileData;
|
|
104670
|
+
if (isInBrowser()) {
|
|
104671
|
+
try {
|
|
104672
|
+
var xhr = new XMLHttpRequest();
|
|
104673
|
+
xhr.open("GET", source, false);
|
|
104674
|
+
xhr.send(null);
|
|
104675
|
+
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
|
104676
|
+
var sourceMapHeader = xhr.getResponseHeader("SourceMap") || xhr.getResponseHeader("X-SourceMap");
|
|
104677
|
+
if (sourceMapHeader) {
|
|
104678
|
+
return sourceMapHeader;
|
|
104679
|
+
}
|
|
104680
|
+
} catch (e) {
|
|
104681
|
+
}
|
|
104682
|
+
}
|
|
104683
|
+
fileData = retrieveFile(source);
|
|
104684
|
+
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
|
|
104685
|
+
var lastMatch, match;
|
|
104686
|
+
while (match = re.exec(fileData)) lastMatch = match;
|
|
104687
|
+
if (!lastMatch) return null;
|
|
104688
|
+
return lastMatch[1];
|
|
104689
|
+
}
|
|
104690
|
+
var retrieveSourceMap = handlerExec(retrieveMapHandlers);
|
|
104691
|
+
retrieveMapHandlers.push(function(source) {
|
|
104692
|
+
var sourceMappingURL = retrieveSourceMapURL(source);
|
|
104693
|
+
if (!sourceMappingURL) return null;
|
|
104694
|
+
var sourceMapData;
|
|
104695
|
+
if (reSourceMap.test(sourceMappingURL)) {
|
|
104696
|
+
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(",") + 1);
|
|
104697
|
+
sourceMapData = bufferFrom(rawData, "base64").toString();
|
|
104698
|
+
sourceMappingURL = source;
|
|
104699
|
+
} else {
|
|
104700
|
+
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
|
104701
|
+
sourceMapData = retrieveFile(sourceMappingURL);
|
|
104702
|
+
}
|
|
104703
|
+
if (!sourceMapData) {
|
|
104704
|
+
return null;
|
|
104705
|
+
}
|
|
104706
|
+
return {
|
|
104707
|
+
url: sourceMappingURL,
|
|
104708
|
+
map: sourceMapData
|
|
104709
|
+
};
|
|
104710
|
+
});
|
|
104711
|
+
function mapSourcePosition(position) {
|
|
104712
|
+
var sourceMap = sourceMapCache[position.source];
|
|
104713
|
+
if (!sourceMap) {
|
|
104714
|
+
var urlAndMap = retrieveSourceMap(position.source);
|
|
104715
|
+
if (urlAndMap) {
|
|
104716
|
+
sourceMap = sourceMapCache[position.source] = {
|
|
104717
|
+
url: urlAndMap.url,
|
|
104718
|
+
map: new SourceMapConsumer(urlAndMap.map)
|
|
104719
|
+
};
|
|
104720
|
+
if (sourceMap.map.sourcesContent) {
|
|
104721
|
+
sourceMap.map.sources.forEach(function(source, i) {
|
|
104722
|
+
var contents = sourceMap.map.sourcesContent[i];
|
|
104723
|
+
if (contents) {
|
|
104724
|
+
var url = supportRelativeURL(sourceMap.url, source);
|
|
104725
|
+
fileContentsCache[url] = contents;
|
|
104726
|
+
}
|
|
104727
|
+
});
|
|
104728
|
+
}
|
|
104729
|
+
} else {
|
|
104730
|
+
sourceMap = sourceMapCache[position.source] = {
|
|
104731
|
+
url: null,
|
|
104732
|
+
map: null
|
|
104733
|
+
};
|
|
104734
|
+
}
|
|
104735
|
+
}
|
|
104736
|
+
if (sourceMap && sourceMap.map && typeof sourceMap.map.originalPositionFor === "function") {
|
|
104737
|
+
var originalPosition = sourceMap.map.originalPositionFor(position);
|
|
104738
|
+
if (originalPosition.source !== null) {
|
|
104739
|
+
originalPosition.source = supportRelativeURL(
|
|
104740
|
+
sourceMap.url,
|
|
104741
|
+
originalPosition.source
|
|
104742
|
+
);
|
|
104743
|
+
return originalPosition;
|
|
104744
|
+
}
|
|
104745
|
+
}
|
|
104746
|
+
return position;
|
|
104747
|
+
}
|
|
104748
|
+
function mapEvalOrigin(origin) {
|
|
104749
|
+
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
|
104750
|
+
if (match) {
|
|
104751
|
+
var position = mapSourcePosition({
|
|
104752
|
+
source: match[2],
|
|
104753
|
+
line: +match[3],
|
|
104754
|
+
column: match[4] - 1
|
|
104755
|
+
});
|
|
104756
|
+
return "eval at " + match[1] + " (" + position.source + ":" + position.line + ":" + (position.column + 1) + ")";
|
|
104757
|
+
}
|
|
104758
|
+
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
|
104759
|
+
if (match) {
|
|
104760
|
+
return "eval at " + match[1] + " (" + mapEvalOrigin(match[2]) + ")";
|
|
104761
|
+
}
|
|
104762
|
+
return origin;
|
|
104763
|
+
}
|
|
104764
|
+
function CallSiteToString() {
|
|
104765
|
+
var fileName;
|
|
104766
|
+
var fileLocation = "";
|
|
104767
|
+
if (this.isNative()) {
|
|
104768
|
+
fileLocation = "native";
|
|
104769
|
+
} else {
|
|
104770
|
+
fileName = this.getScriptNameOrSourceURL();
|
|
104771
|
+
if (!fileName && this.isEval()) {
|
|
104772
|
+
fileLocation = this.getEvalOrigin();
|
|
104773
|
+
fileLocation += ", ";
|
|
104774
|
+
}
|
|
104775
|
+
if (fileName) {
|
|
104776
|
+
fileLocation += fileName;
|
|
104777
|
+
} else {
|
|
104778
|
+
fileLocation += "<anonymous>";
|
|
104779
|
+
}
|
|
104780
|
+
var lineNumber = this.getLineNumber();
|
|
104781
|
+
if (lineNumber != null) {
|
|
104782
|
+
fileLocation += ":" + lineNumber;
|
|
104783
|
+
var columnNumber = this.getColumnNumber();
|
|
104784
|
+
if (columnNumber) {
|
|
104785
|
+
fileLocation += ":" + columnNumber;
|
|
104786
|
+
}
|
|
104787
|
+
}
|
|
104788
|
+
}
|
|
104789
|
+
var line = "";
|
|
104790
|
+
var functionName = this.getFunctionName();
|
|
104791
|
+
var addSuffix = true;
|
|
104792
|
+
var isConstructor = this.isConstructor();
|
|
104793
|
+
var isMethodCall = !(this.isToplevel() || isConstructor);
|
|
104794
|
+
if (isMethodCall) {
|
|
104795
|
+
var typeName = this.getTypeName();
|
|
104796
|
+
if (typeName === "[object Object]") {
|
|
104797
|
+
typeName = "null";
|
|
104798
|
+
}
|
|
104799
|
+
var methodName = this.getMethodName();
|
|
104800
|
+
if (functionName) {
|
|
104801
|
+
if (typeName && functionName.indexOf(typeName) != 0) {
|
|
104802
|
+
line += typeName + ".";
|
|
104803
|
+
}
|
|
104804
|
+
line += functionName;
|
|
104805
|
+
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
|
104806
|
+
line += " [as " + methodName + "]";
|
|
104807
|
+
}
|
|
104808
|
+
} else {
|
|
104809
|
+
line += typeName + "." + (methodName || "<anonymous>");
|
|
104810
|
+
}
|
|
104811
|
+
} else if (isConstructor) {
|
|
104812
|
+
line += "new " + (functionName || "<anonymous>");
|
|
104813
|
+
} else if (functionName) {
|
|
104814
|
+
line += functionName;
|
|
104815
|
+
} else {
|
|
104816
|
+
line += fileLocation;
|
|
104817
|
+
addSuffix = false;
|
|
104818
|
+
}
|
|
104819
|
+
if (addSuffix) {
|
|
104820
|
+
line += " (" + fileLocation + ")";
|
|
104821
|
+
}
|
|
104822
|
+
return line;
|
|
104823
|
+
}
|
|
104824
|
+
function cloneCallSite(frame) {
|
|
104825
|
+
var object = {};
|
|
104826
|
+
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
|
104827
|
+
object[name] = /^(?:is|get)/.test(name) ? function() {
|
|
104828
|
+
return frame[name].call(frame);
|
|
104829
|
+
} : frame[name];
|
|
104830
|
+
});
|
|
104831
|
+
object.toString = CallSiteToString;
|
|
104832
|
+
return object;
|
|
104833
|
+
}
|
|
104834
|
+
function wrapCallSite(frame, state2) {
|
|
104835
|
+
if (state2 === void 0) {
|
|
104836
|
+
state2 = { nextPosition: null, curPosition: null };
|
|
104837
|
+
}
|
|
104838
|
+
if (frame.isNative()) {
|
|
104839
|
+
state2.curPosition = null;
|
|
104840
|
+
return frame;
|
|
104841
|
+
}
|
|
104842
|
+
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
|
104843
|
+
if (source) {
|
|
104844
|
+
var line = frame.getLineNumber();
|
|
104845
|
+
var column = frame.getColumnNumber() - 1;
|
|
104846
|
+
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
|
|
104847
|
+
var headerLength = noHeader.test(globalProcessVersion()) ? 0 : 62;
|
|
104848
|
+
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
|
|
104849
|
+
column -= headerLength;
|
|
104850
|
+
}
|
|
104851
|
+
var position = mapSourcePosition({
|
|
104852
|
+
source,
|
|
104853
|
+
line,
|
|
104854
|
+
column
|
|
104855
|
+
});
|
|
104856
|
+
state2.curPosition = position;
|
|
104857
|
+
frame = cloneCallSite(frame);
|
|
104858
|
+
var originalFunctionName = frame.getFunctionName;
|
|
104859
|
+
frame.getFunctionName = function() {
|
|
104860
|
+
if (state2.nextPosition == null) {
|
|
104861
|
+
return originalFunctionName();
|
|
104862
|
+
}
|
|
104863
|
+
return state2.nextPosition.name || originalFunctionName();
|
|
104864
|
+
};
|
|
104865
|
+
frame.getFileName = function() {
|
|
104866
|
+
return position.source;
|
|
104867
|
+
};
|
|
104868
|
+
frame.getLineNumber = function() {
|
|
104869
|
+
return position.line;
|
|
104870
|
+
};
|
|
104871
|
+
frame.getColumnNumber = function() {
|
|
104872
|
+
return position.column + 1;
|
|
104873
|
+
};
|
|
104874
|
+
frame.getScriptNameOrSourceURL = function() {
|
|
104875
|
+
return position.source;
|
|
104876
|
+
};
|
|
104877
|
+
return frame;
|
|
104878
|
+
}
|
|
104879
|
+
var origin = frame.isEval() && frame.getEvalOrigin();
|
|
104880
|
+
if (origin) {
|
|
104881
|
+
origin = mapEvalOrigin(origin);
|
|
104882
|
+
frame = cloneCallSite(frame);
|
|
104883
|
+
frame.getEvalOrigin = function() {
|
|
104884
|
+
return origin;
|
|
104885
|
+
};
|
|
104886
|
+
return frame;
|
|
104887
|
+
}
|
|
104888
|
+
return frame;
|
|
104889
|
+
}
|
|
104890
|
+
function prepareStackTrace(error2, stack) {
|
|
104891
|
+
if (emptyCacheBetweenOperations) {
|
|
104892
|
+
fileContentsCache = {};
|
|
104893
|
+
sourceMapCache = {};
|
|
104894
|
+
}
|
|
104895
|
+
var name = error2.name || "Error";
|
|
104896
|
+
var message = error2.message || "";
|
|
104897
|
+
var errorString = name + ": " + message;
|
|
104898
|
+
var state2 = { nextPosition: null, curPosition: null };
|
|
104899
|
+
var processedStack = [];
|
|
104900
|
+
for (var i = stack.length - 1; i >= 0; i--) {
|
|
104901
|
+
processedStack.push("\n at " + wrapCallSite(stack[i], state2));
|
|
104902
|
+
state2.nextPosition = state2.curPosition;
|
|
104903
|
+
}
|
|
104904
|
+
state2.curPosition = state2.nextPosition = null;
|
|
104905
|
+
return errorString + processedStack.reverse().join("");
|
|
104906
|
+
}
|
|
104907
|
+
function getErrorSource(error2) {
|
|
104908
|
+
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error2.stack);
|
|
104909
|
+
if (match) {
|
|
104910
|
+
var source = match[1];
|
|
104911
|
+
var line = +match[2];
|
|
104912
|
+
var column = +match[3];
|
|
104913
|
+
var contents = fileContentsCache[source];
|
|
104914
|
+
if (!contents && fs && fs.existsSync(source)) {
|
|
104915
|
+
try {
|
|
104916
|
+
contents = fs.readFileSync(source, "utf8");
|
|
104917
|
+
} catch (er) {
|
|
104918
|
+
contents = "";
|
|
104919
|
+
}
|
|
104920
|
+
}
|
|
104921
|
+
if (contents) {
|
|
104922
|
+
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
|
104923
|
+
if (code) {
|
|
104924
|
+
return source + ":" + line + "\n" + code + "\n" + new Array(column).join(" ") + "^";
|
|
104925
|
+
}
|
|
104926
|
+
}
|
|
104927
|
+
}
|
|
104928
|
+
return null;
|
|
104929
|
+
}
|
|
104930
|
+
function printErrorAndExit(error2) {
|
|
104931
|
+
var source = getErrorSource(error2);
|
|
104932
|
+
var stderr = globalProcessStderr();
|
|
104933
|
+
if (stderr && stderr._handle && stderr._handle.setBlocking) {
|
|
104934
|
+
stderr._handle.setBlocking(true);
|
|
104935
|
+
}
|
|
104936
|
+
if (source) {
|
|
104937
|
+
console.error();
|
|
104938
|
+
console.error(source);
|
|
104939
|
+
}
|
|
104940
|
+
console.error(error2.stack);
|
|
104941
|
+
globalProcessExit(1);
|
|
104942
|
+
}
|
|
104943
|
+
function shimEmitUncaughtException() {
|
|
104944
|
+
var origEmit = process.emit;
|
|
104945
|
+
process.emit = function(type) {
|
|
104946
|
+
if (type === "uncaughtException") {
|
|
104947
|
+
var hasStack = arguments[1] && arguments[1].stack;
|
|
104948
|
+
var hasListeners = this.listeners(type).length > 0;
|
|
104949
|
+
if (hasStack && !hasListeners) {
|
|
104950
|
+
return printErrorAndExit(arguments[1]);
|
|
104951
|
+
}
|
|
104952
|
+
}
|
|
104953
|
+
return origEmit.apply(this, arguments);
|
|
104954
|
+
};
|
|
104955
|
+
}
|
|
104956
|
+
var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0);
|
|
104957
|
+
var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0);
|
|
104958
|
+
exports.wrapCallSite = wrapCallSite;
|
|
104959
|
+
exports.getErrorSource = getErrorSource;
|
|
104960
|
+
exports.mapSourcePosition = mapSourcePosition;
|
|
104961
|
+
exports.retrieveSourceMap = retrieveSourceMap;
|
|
104962
|
+
exports.install = function(options) {
|
|
104963
|
+
options = options || {};
|
|
104964
|
+
if (options.environment) {
|
|
104965
|
+
environment = options.environment;
|
|
104966
|
+
if (["node", "browser", "auto"].indexOf(environment) === -1) {
|
|
104967
|
+
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}");
|
|
104968
|
+
}
|
|
104969
|
+
}
|
|
104970
|
+
if (options.retrieveFile) {
|
|
104971
|
+
if (options.overrideRetrieveFile) {
|
|
104972
|
+
retrieveFileHandlers.length = 0;
|
|
104973
|
+
}
|
|
104974
|
+
retrieveFileHandlers.unshift(options.retrieveFile);
|
|
104975
|
+
}
|
|
104976
|
+
if (options.retrieveSourceMap) {
|
|
104977
|
+
if (options.overrideRetrieveSourceMap) {
|
|
104978
|
+
retrieveMapHandlers.length = 0;
|
|
104979
|
+
}
|
|
104980
|
+
retrieveMapHandlers.unshift(options.retrieveSourceMap);
|
|
104981
|
+
}
|
|
104982
|
+
if (options.hookRequire && !isInBrowser()) {
|
|
104983
|
+
var Module = dynamicRequire(module, "module");
|
|
104984
|
+
var $compile = Module.prototype._compile;
|
|
104985
|
+
if (!$compile.__sourceMapSupport) {
|
|
104986
|
+
Module.prototype._compile = function(content, filename) {
|
|
104987
|
+
fileContentsCache[filename] = content;
|
|
104988
|
+
sourceMapCache[filename] = void 0;
|
|
104989
|
+
return $compile.call(this, content, filename);
|
|
104990
|
+
};
|
|
104991
|
+
Module.prototype._compile.__sourceMapSupport = true;
|
|
104992
|
+
}
|
|
104993
|
+
}
|
|
104994
|
+
if (!emptyCacheBetweenOperations) {
|
|
104995
|
+
emptyCacheBetweenOperations = "emptyCacheBetweenOperations" in options ? options.emptyCacheBetweenOperations : false;
|
|
104996
|
+
}
|
|
104997
|
+
if (!errorFormatterInstalled) {
|
|
104998
|
+
errorFormatterInstalled = true;
|
|
104999
|
+
Error.prepareStackTrace = prepareStackTrace;
|
|
105000
|
+
}
|
|
105001
|
+
if (!uncaughtShimInstalled) {
|
|
105002
|
+
var installHandler = "handleUncaughtExceptions" in options ? options.handleUncaughtExceptions : true;
|
|
105003
|
+
try {
|
|
105004
|
+
var worker_threads = dynamicRequire(module, "worker_threads");
|
|
105005
|
+
if (worker_threads.isMainThread === false) {
|
|
105006
|
+
installHandler = false;
|
|
105007
|
+
}
|
|
105008
|
+
} catch (e) {
|
|
105009
|
+
}
|
|
105010
|
+
if (installHandler && hasGlobalProcessEventEmitter()) {
|
|
105011
|
+
uncaughtShimInstalled = true;
|
|
105012
|
+
shimEmitUncaughtException();
|
|
105013
|
+
}
|
|
105014
|
+
}
|
|
105015
|
+
};
|
|
105016
|
+
exports.resetRetrieveHandlers = function() {
|
|
105017
|
+
retrieveFileHandlers.length = 0;
|
|
105018
|
+
retrieveMapHandlers.length = 0;
|
|
105019
|
+
retrieveFileHandlers = originalRetrieveFileHandlers.slice(0);
|
|
105020
|
+
retrieveMapHandlers = originalRetrieveMapHandlers.slice(0);
|
|
105021
|
+
retrieveSourceMap = handlerExec(retrieveMapHandlers);
|
|
105022
|
+
retrieveFile = handlerExec(retrieveFileHandlers);
|
|
105023
|
+
};
|
|
105024
|
+
}
|
|
105025
|
+
});
|
|
105026
|
+
|
|
101539
105027
|
// ../../node_modules/typescript/lib/typescript.js
|
|
101540
105028
|
var require_typescript = __commonJS({
|
|
101541
105029
|
"../../node_modules/typescript/lib/typescript.js"(exports, module) {
|
|
@@ -110192,7 +113680,7 @@ ${lanes.join("\n")}
|
|
|
110192
113680
|
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv, (arg) => /^--(?:inspect|debug)(?:-brk)?(?:=\d+)?$/i.test(arg)) || !!process.recordreplay,
|
|
110193
113681
|
tryEnableSourceMapsForHost() {
|
|
110194
113682
|
try {
|
|
110195
|
-
|
|
113683
|
+
require_source_map_support().install();
|
|
110196
113684
|
} catch {
|
|
110197
113685
|
}
|
|
110198
113686
|
},
|
|
@@ -338727,7 +342215,7 @@ var require_decoder = __commonJS({
|
|
|
338727
342215
|
});
|
|
338728
342216
|
|
|
338729
342217
|
// ../../node_modules/adm-zip/util/index.js
|
|
338730
|
-
var
|
|
342218
|
+
var require_util5 = __commonJS({
|
|
338731
342219
|
"../../node_modules/adm-zip/util/index.js"(exports, module) {
|
|
338732
342220
|
"use strict";
|
|
338733
342221
|
module.exports = require_utils2();
|
|
@@ -338742,7 +342230,7 @@ var require_util4 = __commonJS({
|
|
|
338742
342230
|
var require_entryHeader = __commonJS({
|
|
338743
342231
|
"../../node_modules/adm-zip/headers/entryHeader.js"(exports, module) {
|
|
338744
342232
|
"use strict";
|
|
338745
|
-
var Utils =
|
|
342233
|
+
var Utils = require_util5();
|
|
338746
342234
|
var Constants = Utils.Constants;
|
|
338747
342235
|
module.exports = function() {
|
|
338748
342236
|
var _verMade = 20, _version = 10, _flags = 0, _method = 0, _time = 0, _crc = 0, _compressedSize = 0, _size = 0, _fnameLen = 0, _extraLen = 0, _comLen = 0, _diskStart = 0, _inattr = 0, _attr = 0, _offset = 0;
|
|
@@ -339013,7 +342501,7 @@ var require_entryHeader = __commonJS({
|
|
|
339013
342501
|
var require_mainHeader = __commonJS({
|
|
339014
342502
|
"../../node_modules/adm-zip/headers/mainHeader.js"(exports, module) {
|
|
339015
342503
|
"use strict";
|
|
339016
|
-
var Utils =
|
|
342504
|
+
var Utils = require_util5();
|
|
339017
342505
|
var Constants = Utils.Constants;
|
|
339018
342506
|
module.exports = function() {
|
|
339019
342507
|
var _volumeEntries = 0, _totalEntries = 0, _size = 0, _offset = 0, _commentLength = 0;
|
|
@@ -339311,7 +342799,7 @@ var require_methods = __commonJS({
|
|
|
339311
342799
|
var require_zipEntry = __commonJS({
|
|
339312
342800
|
"../../node_modules/adm-zip/zipEntry.js"(exports, module) {
|
|
339313
342801
|
"use strict";
|
|
339314
|
-
var Utils =
|
|
342802
|
+
var Utils = require_util5();
|
|
339315
342803
|
var Headers = require_headers3();
|
|
339316
342804
|
var Constants = Utils.Constants;
|
|
339317
342805
|
var Methods = require_methods();
|
|
@@ -339645,7 +343133,7 @@ var require_zipFile = __commonJS({
|
|
|
339645
343133
|
"use strict";
|
|
339646
343134
|
var ZipEntry = require_zipEntry();
|
|
339647
343135
|
var Headers = require_headers3();
|
|
339648
|
-
var Utils =
|
|
343136
|
+
var Utils = require_util5();
|
|
339649
343137
|
module.exports = function(inBuffer, options) {
|
|
339650
343138
|
var entryList = [], entryTable = {}, _comment = Buffer.alloc(0), mainHeader = new Headers.MainHeader(), loadedEntries = false;
|
|
339651
343139
|
var password = null;
|
|
@@ -339990,7 +343478,7 @@ var require_zipFile = __commonJS({
|
|
|
339990
343478
|
var require_adm_zip = __commonJS({
|
|
339991
343479
|
"../../node_modules/adm-zip/adm-zip.js"(exports, module) {
|
|
339992
343480
|
"use strict";
|
|
339993
|
-
var Utils =
|
|
343481
|
+
var Utils = require_util5();
|
|
339994
343482
|
var pth = __require("path");
|
|
339995
343483
|
var ZipEntry = require_zipEntry();
|
|
339996
343484
|
var ZipFile = require_zipFile();
|
|
@@ -351623,7 +355111,7 @@ var require_package4 = __commonJS({
|
|
|
351623
355111
|
"package.json"(exports, module) {
|
|
351624
355112
|
module.exports = {
|
|
351625
355113
|
name: "@validate.qa/runner",
|
|
351626
|
-
version: "1.0.
|
|
355114
|
+
version: "1.0.89",
|
|
351627
355115
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
351628
355116
|
bin: {
|
|
351629
355117
|
"validate-runner": "dist/cli.js"
|
|
@@ -352484,6 +355972,68 @@ async function waitForUiSettle(sessionPath, opts = {}) {
|
|
|
352484
355972
|
}
|
|
352485
355973
|
return { settled: false, lastFingerprint, frames };
|
|
352486
355974
|
}
|
|
355975
|
+
var SYSTEM_UI_DISMISS_LABELS = [
|
|
355976
|
+
"OK",
|
|
355977
|
+
"Got it",
|
|
355978
|
+
"GOT IT",
|
|
355979
|
+
"Continue",
|
|
355980
|
+
"Close",
|
|
355981
|
+
"Dismiss",
|
|
355982
|
+
"I understand",
|
|
355983
|
+
"Accept",
|
|
355984
|
+
// Android 15+ / 16 KB page-size compatibility dialog primary action.
|
|
355985
|
+
"OK, got it"
|
|
355986
|
+
];
|
|
355987
|
+
function extractElementId(value) {
|
|
355988
|
+
if (!value || typeof value !== "object") return null;
|
|
355989
|
+
const v = value;
|
|
355990
|
+
const elementId = v.ELEMENT ?? v["element-6066-11e4-a52e-4f735466cecf"] ?? null;
|
|
355991
|
+
if (typeof elementId !== "string" || !ELEMENT_ID_PATTERN.test(elementId)) return null;
|
|
355992
|
+
return elementId;
|
|
355993
|
+
}
|
|
355994
|
+
async function dismissBlockingSystemUi(sessionPath, platform3, opts = {}) {
|
|
355995
|
+
const maxDismisses = Math.max(1, Math.min(5, opts.maxDismisses ?? 3));
|
|
355996
|
+
const dismissed = [];
|
|
355997
|
+
for (let i = 0; i < maxDismisses; i++) {
|
|
355998
|
+
let tapped = false;
|
|
355999
|
+
for (const label of SYSTEM_UI_DISMISS_LABELS) {
|
|
356000
|
+
try {
|
|
356001
|
+
const strategies = platform3 === "ANDROID" ? [
|
|
356002
|
+
{ using: "-android uiautomator", value: `new UiSelector().text("${label.replace(/"/g, '\\"')}")` },
|
|
356003
|
+
{ using: "accessibility id", value: label }
|
|
356004
|
+
] : [
|
|
356005
|
+
{ using: "accessibility id", value: label },
|
|
356006
|
+
{ using: "-ios predicate string", value: `label == "${label.replace(/"/g, '\\"')}" OR name == "${label.replace(/"/g, '\\"')}"` }
|
|
356007
|
+
];
|
|
356008
|
+
for (const strategy of strategies) {
|
|
356009
|
+
try {
|
|
356010
|
+
const elResult = await appiumRequest(`${sessionPath}/element`, {
|
|
356011
|
+
method: "POST",
|
|
356012
|
+
body: JSON.stringify(strategy)
|
|
356013
|
+
});
|
|
356014
|
+
const elementId = extractElementId(readValue(elResult));
|
|
356015
|
+
if (!elementId) continue;
|
|
356016
|
+
await appiumRequest(`${sessionPath}/element/${elementId}/click`, {
|
|
356017
|
+
method: "POST",
|
|
356018
|
+
body: "{}"
|
|
356019
|
+
});
|
|
356020
|
+
dismissed.push(label);
|
|
356021
|
+
tapped = true;
|
|
356022
|
+
await waitForUiSettle(sessionPath, { timeoutMs: 1200, pollMs: 200, minStableFrames: 1 });
|
|
356023
|
+
break;
|
|
356024
|
+
} catch (err) {
|
|
356025
|
+
if (isAppiumDriverDeadError(err)) throw err;
|
|
356026
|
+
}
|
|
356027
|
+
}
|
|
356028
|
+
if (tapped) break;
|
|
356029
|
+
} catch (err) {
|
|
356030
|
+
if (isAppiumDriverDeadError(err)) throw err;
|
|
356031
|
+
}
|
|
356032
|
+
}
|
|
356033
|
+
if (!tapped) break;
|
|
356034
|
+
}
|
|
356035
|
+
return { dismissed, ok: dismissed.length > 0 };
|
|
356036
|
+
}
|
|
352487
356037
|
async function waitForColdBootSettle(sessionPath) {
|
|
352488
356038
|
await waitForUiSettle(sessionPath, {
|
|
352489
356039
|
timeoutMs: MOBILE_COLD_BOOT_SETTLE_MS,
|
|
@@ -355224,6 +358774,107 @@ async function waitForColdBootContent(sessionId, log2, timeoutMs = 2e4) {
|
|
|
355224
358774
|
}
|
|
355225
358775
|
log2(` Cold-boot wait timed out after ${timeoutMs}ms (last tree had ${lastCount} node(s)) \u2014 proceeding anyway.`);
|
|
355226
358776
|
}
|
|
358777
|
+
async function dismissSystemUiAfterColdBoot(sessionId, platform3, log2) {
|
|
358778
|
+
try {
|
|
358779
|
+
const result = await dismissBlockingSystemUi(`/session/${sessionId}`, platform3);
|
|
358780
|
+
if (result.dismissed.length > 0) {
|
|
358781
|
+
log2(` Dismissed system UI: ${result.dismissed.join(" \u2192 ")}`);
|
|
358782
|
+
}
|
|
358783
|
+
} catch (err) {
|
|
358784
|
+
log2(` System UI dismiss skipped (${err instanceof Error ? err.message : String(err)})`);
|
|
358785
|
+
}
|
|
358786
|
+
}
|
|
358787
|
+
async function captureMobileStateValues(sessionId, kind) {
|
|
358788
|
+
const res = await wdRequest(`/session/${sessionId}/source`);
|
|
358789
|
+
const xml = typeof res?.value === "string" ? res.value : "";
|
|
358790
|
+
if (kind === "badge_count") {
|
|
358791
|
+
const nums = /* @__PURE__ */ new Set();
|
|
358792
|
+
for (const m of xml.matchAll(/\b(\d{1,6})\b/g)) {
|
|
358793
|
+
nums.add(m[1]);
|
|
358794
|
+
}
|
|
358795
|
+
const preferred = /* @__PURE__ */ new Set();
|
|
358796
|
+
for (const m of xml.matchAll(/(?:count|badge|open|unread|item|invoice|result|pending)[^>]{0,80}?\b(\d{1,6})\b/gi)) {
|
|
358797
|
+
preferred.add(m[1]);
|
|
358798
|
+
}
|
|
358799
|
+
for (const m of xml.matchAll(/\b(\d{1,6})\b[^>]{0,80}?(?:count|badge|open|unread|items?)/gi)) {
|
|
358800
|
+
preferred.add(m[1]);
|
|
358801
|
+
}
|
|
358802
|
+
return preferred.size > 0 ? [...preferred] : [...nums].slice(0, 20);
|
|
358803
|
+
}
|
|
358804
|
+
const labels = /* @__PURE__ */ new Set();
|
|
358805
|
+
const attrRe = /(?:text|content-desc|name|label)="([^"]{2,80})"/gi;
|
|
358806
|
+
for (const m of xml.matchAll(attrRe)) {
|
|
358807
|
+
const t = m[1].trim();
|
|
358808
|
+
if (t.length < 2 || t.length > 80) continue;
|
|
358809
|
+
if (/^(true|false|null|OK|Cancel)$/i.test(t)) continue;
|
|
358810
|
+
labels.add(t);
|
|
358811
|
+
}
|
|
358812
|
+
return [...labels].slice(0, 80);
|
|
358813
|
+
}
|
|
358814
|
+
function assertMobileStateDelta(before, after, expect, key, log2) {
|
|
358815
|
+
const beforeSet = new Set(before);
|
|
358816
|
+
const afterSet = new Set(after);
|
|
358817
|
+
const removed = before.filter((v) => !afterSet.has(v));
|
|
358818
|
+
const added = after.filter((v) => !beforeSet.has(v));
|
|
358819
|
+
log2(` assertStateDelta key=${key} expect=${expect} removed=${removed.length} added=${added.length}`);
|
|
358820
|
+
const exp = expect.toLowerCase().trim();
|
|
358821
|
+
if (exp === "changed" || exp === "any_change") {
|
|
358822
|
+
if (removed.length === 0 && added.length === 0) {
|
|
358823
|
+
throw new Error(`assertStateDelta(${key}): expected state to change, but capture is identical (${before.length} values)`);
|
|
358824
|
+
}
|
|
358825
|
+
return;
|
|
358826
|
+
}
|
|
358827
|
+
if (exp === "removed" || exp === "entity_removed" || exp.startsWith("removed:")) {
|
|
358828
|
+
const target = exp.startsWith("removed:") ? expect.slice("removed:".length).trim() : "";
|
|
358829
|
+
if (target) {
|
|
358830
|
+
if (!removed.includes(target) && afterSet.has(target)) {
|
|
358831
|
+
throw new Error(`assertStateDelta(${key}): expected "${target}" removed, but it is still present`);
|
|
358832
|
+
}
|
|
358833
|
+
if (!beforeSet.has(target)) {
|
|
358834
|
+
throw new Error(`assertStateDelta(${key}): expected "${target}" to have been in the prior capture`);
|
|
358835
|
+
}
|
|
358836
|
+
if (afterSet.has(target)) {
|
|
358837
|
+
throw new Error(`assertStateDelta(${key}): "${target}" was not removed`);
|
|
358838
|
+
}
|
|
358839
|
+
return;
|
|
358840
|
+
}
|
|
358841
|
+
if (removed.length === 0) {
|
|
358842
|
+
throw new Error(`assertStateDelta(${key}): expected at least one entity removed`);
|
|
358843
|
+
}
|
|
358844
|
+
return;
|
|
358845
|
+
}
|
|
358846
|
+
if (exp === "count_decreased" || exp === "count-1") {
|
|
358847
|
+
const b = before.map(Number).filter((n) => Number.isFinite(n));
|
|
358848
|
+
const a = after.map(Number).filter((n) => Number.isFinite(n));
|
|
358849
|
+
const bMax = b.length ? Math.max(...b) : NaN;
|
|
358850
|
+
const aMax = a.length ? Math.max(...a) : NaN;
|
|
358851
|
+
if (!Number.isFinite(bMax) || !Number.isFinite(aMax) || aMax >= bMax) {
|
|
358852
|
+
throw new Error(`assertStateDelta(${key}): expected count decrease (before max=${bMax}, after max=${aMax})`);
|
|
358853
|
+
}
|
|
358854
|
+
return;
|
|
358855
|
+
}
|
|
358856
|
+
if (exp === "count_increased" || exp === "count+1") {
|
|
358857
|
+
const b = before.map(Number).filter((n) => Number.isFinite(n));
|
|
358858
|
+
const a = after.map(Number).filter((n) => Number.isFinite(n));
|
|
358859
|
+
const bMax = b.length ? Math.max(...b) : NaN;
|
|
358860
|
+
const aMax = a.length ? Math.max(...a) : NaN;
|
|
358861
|
+
if (!Number.isFinite(bMax) || !Number.isFinite(aMax) || aMax <= bMax) {
|
|
358862
|
+
throw new Error(`assertStateDelta(${key}): expected count increase (before max=${bMax}, after max=${aMax})`);
|
|
358863
|
+
}
|
|
358864
|
+
return;
|
|
358865
|
+
}
|
|
358866
|
+
if (exp === "unchanged" || exp === "persisted") {
|
|
358867
|
+
if (removed.length > 0 || added.length > 0) {
|
|
358868
|
+
throw new Error(
|
|
358869
|
+
`assertStateDelta(${key}): expected persistence/unchanged, but removed=[${removed.slice(0, 5).join(", ")}] added=[${added.slice(0, 5).join(", ")}]`
|
|
358870
|
+
);
|
|
358871
|
+
}
|
|
358872
|
+
return;
|
|
358873
|
+
}
|
|
358874
|
+
if (removed.length === 0 && added.length === 0) {
|
|
358875
|
+
throw new Error(`assertStateDelta(${key}): expected change (expect=${expect}), state identical`);
|
|
358876
|
+
}
|
|
358877
|
+
}
|
|
355227
358878
|
async function restoreTargetAppIfExternal(sessionId, target, log2, source, failOnExternal) {
|
|
355228
358879
|
let boundary = null;
|
|
355229
358880
|
try {
|
|
@@ -356369,6 +360020,7 @@ async function executeMobileTest(options) {
|
|
|
356369
360020
|
}
|
|
356370
360021
|
const stepResults = [];
|
|
356371
360022
|
const screenshots = [];
|
|
360023
|
+
const stateBag = /* @__PURE__ */ new Map();
|
|
356372
360024
|
let apiCalls = [];
|
|
356373
360025
|
let sessionId = null;
|
|
356374
360026
|
let selectedDevice;
|
|
@@ -356579,6 +360231,9 @@ async function executeMobileTest(options) {
|
|
|
356579
360231
|
if (clearedAppDataBeforeLaunch) {
|
|
356580
360232
|
await waitForColdBootContent(sessionId, log2);
|
|
356581
360233
|
}
|
|
360234
|
+
if (options.target.launchMode !== "RESUME") {
|
|
360235
|
+
await dismissSystemUiAfterColdBoot(sessionId, options.target.platform, log2);
|
|
360236
|
+
}
|
|
356582
360237
|
if (options.target.launchMode === "DEEP_LINK" && options.target.deeplink) {
|
|
356583
360238
|
try {
|
|
356584
360239
|
log2(`Opening deep link: ${options.target.deeplink}`);
|
|
@@ -356673,6 +360328,25 @@ async function executeMobileTest(options) {
|
|
|
356673
360328
|
case "assertText":
|
|
356674
360329
|
await executeAssertText(sessionId, step, runPlatform, isCrossPlatform);
|
|
356675
360330
|
break;
|
|
360331
|
+
case "captureState": {
|
|
360332
|
+
const key = String(step.metadata?.stateKey ?? step.target?.primary ?? `state-${step.order}`);
|
|
360333
|
+
const kind = String(step.metadata?.stateKind ?? "list_ids");
|
|
360334
|
+
const values = await captureMobileStateValues(sessionId, kind);
|
|
360335
|
+
stateBag.set(key, { kind, values, capturedAt: Date.now() });
|
|
360336
|
+
log2(` captureState key=${key} kind=${kind} n=${values.length}`);
|
|
360337
|
+
break;
|
|
360338
|
+
}
|
|
360339
|
+
case "assertStateDelta": {
|
|
360340
|
+
const key = String(step.metadata?.stateKey ?? step.target?.primary ?? "");
|
|
360341
|
+
const expect = String(step.metadata?.expect ?? step.assertion ?? "changed");
|
|
360342
|
+
const prior = stateBag.get(key);
|
|
360343
|
+
if (!prior) {
|
|
360344
|
+
throw new Error(`assertStateDelta: no prior captureState for key "${key}"`);
|
|
360345
|
+
}
|
|
360346
|
+
const current = await captureMobileStateValues(sessionId, prior.kind);
|
|
360347
|
+
assertMobileStateDelta(prior.values, current, expect, key, log2);
|
|
360348
|
+
break;
|
|
360349
|
+
}
|
|
356676
360350
|
default: {
|
|
356677
360351
|
const _exhaustive = step.action;
|
|
356678
360352
|
status = "failed";
|
|
@@ -356851,6 +360525,10 @@ async function createMobileDiscoverySession(target, options) {
|
|
|
356851
360525
|
);
|
|
356852
360526
|
}
|
|
356853
360527
|
}
|
|
360528
|
+
try {
|
|
360529
|
+
await dismissBlockingSystemUi(`/session/${sessionId}`, target.platform);
|
|
360530
|
+
} catch {
|
|
360531
|
+
}
|
|
356854
360532
|
let stopped = false;
|
|
356855
360533
|
return {
|
|
356856
360534
|
sessionId,
|
|
@@ -356988,6 +360666,8 @@ async function driveHarvestStep(sessionId, step, elementId, platform3) {
|
|
|
356988
360666
|
case "waitForElement":
|
|
356989
360667
|
case "assertVisible":
|
|
356990
360668
|
case "assertText":
|
|
360669
|
+
case "captureState":
|
|
360670
|
+
case "assertStateDelta":
|
|
356991
360671
|
return true;
|
|
356992
360672
|
}
|
|
356993
360673
|
}
|
|
@@ -357021,6 +360701,7 @@ async function harvestPlatformLocators(options) {
|
|
|
357021
360701
|
try {
|
|
357022
360702
|
options.onSessionReady?.(session.sessionId, session.deviceId, platform3);
|
|
357023
360703
|
await freshLaunchTargetApp(session.sessionId, platform3, options.target.appId, log2);
|
|
360704
|
+
await dismissSystemUiAfterColdBoot(session.sessionId, platform3, log2);
|
|
357024
360705
|
if (options.target.launchMode === "DEEP_LINK" && options.target.deeplink) {
|
|
357025
360706
|
await openDeepLink(session.sessionId, platform3, options.target.deeplink, options.target.appId);
|
|
357026
360707
|
}
|
|
@@ -357296,7 +360977,9 @@ function decideMobileDeviceGate(input) {
|
|
|
357296
360977
|
}
|
|
357297
360978
|
}
|
|
357298
360979
|
const isHealForHeldTest = runMode === "heal" && !!testCaseId && healHoldTestCaseIds.has(testCaseId);
|
|
357299
|
-
const
|
|
360980
|
+
const rawReservedForHeals = isHealForHeldTest ? Math.max(0, healHoldTestCaseIds.size - 1) : healHoldTestCaseIds.size;
|
|
360981
|
+
const maxHealReserve = capacity <= 1 ? capacity : Math.max(1, capacity - 1);
|
|
360982
|
+
const reservedForHeals = Math.min(rawReservedForHeals, maxHealReserve);
|
|
357300
360983
|
if (activeMobileOps + reservedForHeals >= capacity) {
|
|
357301
360984
|
const reason = reservedForHeals > 0 ? `capacity reserved for pending auto-heal: ${activeMobileOps}+${reservedForHeals}/${capacity}` : `mobile capacity reached: ${activeMobileOps}/${capacity} in use`;
|
|
357302
360985
|
return { claim: false, disposition: "defer", reason };
|
|
@@ -359132,6 +362815,11 @@ var MobileBridgeDriver = class {
|
|
|
359132
362815
|
} catch (err) {
|
|
359133
362816
|
if (isRecoverableAppiumSessionFailure(err)) throw err;
|
|
359134
362817
|
}
|
|
362818
|
+
try {
|
|
362819
|
+
await dismissBlockingSystemUi(this.sessionPath, this.platform);
|
|
362820
|
+
} catch (err) {
|
|
362821
|
+
if (isRecoverableAppiumSessionFailure(err) || isAppiumDriverDeadError(err)) throw err;
|
|
362822
|
+
}
|
|
359135
362823
|
});
|
|
359136
362824
|
}
|
|
359137
362825
|
/**
|
|
@@ -359169,6 +362857,11 @@ var MobileBridgeDriver = class {
|
|
|
359169
362857
|
} catch (err) {
|
|
359170
362858
|
if (isRecoverableAppiumSessionFailure(err)) throw err;
|
|
359171
362859
|
}
|
|
362860
|
+
try {
|
|
362861
|
+
await dismissBlockingSystemUi(this.sessionPath, this.platform);
|
|
362862
|
+
} catch (err) {
|
|
362863
|
+
if (isRecoverableAppiumSessionFailure(err) || isAppiumDriverDeadError(err)) throw err;
|
|
362864
|
+
}
|
|
359172
362865
|
return true;
|
|
359173
362866
|
} catch (err) {
|
|
359174
362867
|
if (isRecoverableAppiumSessionFailure(err)) throw err;
|
|
@@ -362528,6 +366221,17 @@ ${finalVerifyResult.logs ?? ""}`;
|
|
|
362528
366221
|
}
|
|
362529
366222
|
};
|
|
362530
366223
|
log.info("\u{1FA7A} Mobile AI heal \u2014 Phase 1 (script) \u2192 Phase 2 (live device, lazy)...");
|
|
366224
|
+
const tagList = Array.isArray(run2.tags) ? run2.tags : [];
|
|
366225
|
+
const failureCount = Math.max(
|
|
366226
|
+
1,
|
|
366227
|
+
typeof run2.consecutiveFails === "number" && run2.consecutiveFails > 0 ? run2.consecutiveFails : tagList.includes("@bug-found") ? 2 : 1
|
|
366228
|
+
);
|
|
366229
|
+
const reproduceApiCalls = Array.isArray(nativeVerify.last?.apiCalls) ? nativeVerify.last.apiCalls.map((c) => ({
|
|
366230
|
+
method: typeof c.method === "string" ? c.method : void 0,
|
|
366231
|
+
url: typeof c.url === "string" ? c.url : void 0,
|
|
366232
|
+
status: typeof c.status === "number" ? c.status : void 0
|
|
366233
|
+
})) : void 0;
|
|
366234
|
+
const uiPathSucceeded = Array.isArray(reproduce.stepResults) && reproduce.stepResults.filter((s) => s.status === "passed").length >= Math.max(1, reproduce.stepResults.length - 1);
|
|
362531
366235
|
const heal = await (0, import_runner_core14.executeMobileTestWithHealing)(
|
|
362532
366236
|
mobileSteps,
|
|
362533
366237
|
healTarget,
|
|
@@ -362536,7 +366240,11 @@ ${finalVerifyResult.logs ?? ""}`;
|
|
|
362536
366240
|
logs: reproduce.logs,
|
|
362537
366241
|
failingSource: reproduce.failingSource,
|
|
362538
366242
|
testVariables: run2.testVariables,
|
|
362539
|
-
testName: run2.testName
|
|
366243
|
+
testName: run2.testName,
|
|
366244
|
+
tags: tagList,
|
|
366245
|
+
failureCount,
|
|
366246
|
+
apiCalls: reproduceApiCalls,
|
|
366247
|
+
uiPathSucceeded
|
|
362540
366248
|
},
|
|
362541
366249
|
healerOptions
|
|
362542
366250
|
);
|
|
@@ -362545,7 +366253,8 @@ ${finalVerifyResult.logs ?? ""}`;
|
|
|
362545
366253
|
heal,
|
|
362546
366254
|
finalError: finalRes?.error ?? null,
|
|
362547
366255
|
reproduceError,
|
|
362548
|
-
testVariables: run2.testVariables
|
|
366256
|
+
testVariables: run2.testVariables,
|
|
366257
|
+
originalSteps: mobileSteps
|
|
362549
366258
|
});
|
|
362550
366259
|
await postResult(opts.serverUrl, headers, run2.runId, {
|
|
362551
366260
|
status: outcome.status,
|