@validate.qa/runner 1.0.58 → 1.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +112 -33
- package/dist/cli.mjs +112 -33
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -72841,18 +72841,15 @@ var require_verification_inbox = __commonJS({
|
|
|
72841
72841
|
return { code: cleaned, confidence: "keyword" };
|
|
72842
72842
|
}
|
|
72843
72843
|
}
|
|
72844
|
-
const distinct = /* @__PURE__ */ new Set();
|
|
72845
72844
|
for (const body of bodies) {
|
|
72846
72845
|
if (!body)
|
|
72847
72846
|
continue;
|
|
72848
72847
|
for (const n of body.match(/\b[0-9]{4,8}\b/g) ?? []) {
|
|
72849
|
-
if (
|
|
72850
|
-
|
|
72848
|
+
if (looksLikeYearOrDate(n))
|
|
72849
|
+
continue;
|
|
72850
|
+
return { code: n, confidence: "fallback" };
|
|
72851
72851
|
}
|
|
72852
72852
|
}
|
|
72853
|
-
if (distinct.size === 1) {
|
|
72854
|
-
return { code: distinct.values().next().value ?? null, confidence: "fallback" };
|
|
72855
|
-
}
|
|
72856
72853
|
return { code: null, confidence: null };
|
|
72857
72854
|
}
|
|
72858
72855
|
function matchBestCode(line) {
|
|
@@ -73150,9 +73147,10 @@ var require_verification_inbox = __commonJS({
|
|
|
73150
73147
|
const satisfies = (m) => {
|
|
73151
73148
|
if (opts.require === "code")
|
|
73152
73149
|
return m.code !== null && m.codeConfidence !== "fallback";
|
|
73150
|
+
const linkOk = (l) => l !== null && (!opts.linkAcceptable || opts.linkAcceptable(l));
|
|
73153
73151
|
if (opts.require === "link")
|
|
73154
|
-
return m.link
|
|
73155
|
-
return m.
|
|
73152
|
+
return linkOk(m.link);
|
|
73153
|
+
return m.code !== null && m.codeConfidence !== "fallback" || linkOk(m.link);
|
|
73156
73154
|
};
|
|
73157
73155
|
let weakest = null;
|
|
73158
73156
|
const check2 = async () => {
|
|
@@ -73199,7 +73197,7 @@ var require_verification_inbox = __commonJS({
|
|
|
73199
73197
|
const since = new Date(Math.max(0, opts.sinceMs));
|
|
73200
73198
|
const lock = await client.getMailboxLock(mailbox);
|
|
73201
73199
|
const results = [];
|
|
73202
|
-
const
|
|
73200
|
+
const demoteMismatch = isPlusTagged(opts.toAddress) && Boolean(opts.demoteFilterMismatch);
|
|
73203
73201
|
try {
|
|
73204
73202
|
try {
|
|
73205
73203
|
await client.noop();
|
|
@@ -73245,7 +73243,7 @@ var require_verification_inbox = __commonJS({
|
|
|
73245
73243
|
continue;
|
|
73246
73244
|
const filterActive = Boolean(opts.fromMatch || opts.subjectMatch);
|
|
73247
73245
|
const filterMatched = (!opts.fromMatch || matchField(parsed.from?.text, opts.fromMatch)) && (!opts.subjectMatch || matchField(parsed.subject, opts.subjectMatch));
|
|
73248
|
-
if (filterActive && !filterMatched && !
|
|
73246
|
+
if (filterActive && !filterMatched && !demoteMismatch) {
|
|
73249
73247
|
if (opts.stats)
|
|
73250
73248
|
opts.stats.filteredOut += 1;
|
|
73251
73249
|
continue;
|
|
@@ -73383,7 +73381,8 @@ var require_inbox_tools = __commonJS({
|
|
|
73383
73381
|
// Captured at provision (needs a live reader); 0 = use the sinceMs floor.
|
|
73384
73382
|
sinceUid: 0,
|
|
73385
73383
|
sinceUidValidity: 0,
|
|
73386
|
-
knownLinks: /* @__PURE__ */ new Set()
|
|
73384
|
+
knownLinks: /* @__PURE__ */ new Set(),
|
|
73385
|
+
demoteFilterMismatch: opts.demoteFilterMismatch ?? false
|
|
73387
73386
|
};
|
|
73388
73387
|
}
|
|
73389
73388
|
exports2.PROVISION_IDENTITY_TOOL = {
|
|
@@ -73571,6 +73570,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73571
73570
|
sinceUidValidity: ctx.state.sinceUidValidity,
|
|
73572
73571
|
fromMatch: asStr(args.senderMatch),
|
|
73573
73572
|
subjectMatch: asStr(args.subjectMatch),
|
|
73573
|
+
demoteFilterMismatch: ctx.state.demoteFilterMismatch,
|
|
73574
73574
|
limit: 10
|
|
73575
73575
|
});
|
|
73576
73576
|
return ok({
|
|
@@ -73595,6 +73595,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73595
73595
|
sinceUidValidity: ctx.state.sinceUidValidity,
|
|
73596
73596
|
fromMatch: asStr(args.senderMatch),
|
|
73597
73597
|
subjectMatch: asStr(args.subjectMatch),
|
|
73598
|
+
demoteFilterMismatch: ctx.state.demoteFilterMismatch,
|
|
73598
73599
|
maxWaitMs: maxWaitSeconds * 1e3,
|
|
73599
73600
|
stats
|
|
73600
73601
|
});
|
|
@@ -73741,7 +73742,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73741
73742
|
const u = new URL(raw);
|
|
73742
73743
|
if (u.protocol !== "http:" && u.protocol !== "https:")
|
|
73743
73744
|
return false;
|
|
73744
|
-
host = u.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
73745
|
+
host = u.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.+$/, "");
|
|
73745
73746
|
} catch {
|
|
73746
73747
|
return false;
|
|
73747
73748
|
}
|
|
@@ -73757,7 +73758,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73757
73758
|
const dotted = host.match(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
|
73758
73759
|
if (dotted && !ipv4IsPublic(dotted[1]))
|
|
73759
73760
|
return false;
|
|
73760
|
-
const mapped = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
73761
|
+
const mapped = host.match(/^::(?:ffff:)?([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
73761
73762
|
if (mapped) {
|
|
73762
73763
|
const hi = parseInt(mapped[1], 16);
|
|
73763
73764
|
const lo = parseInt(mapped[2], 16);
|
|
@@ -86418,6 +86419,8 @@ var require_inbox_stamp = __commonJS({
|
|
|
86418
86419
|
exports2.INBOX_HELPER_TOKEN_RE = exports2.INBOX_HELPER_NAME = exports2.INBOX_REGION_RE = exports2.INBOX_MARKER_VERSION = void 0;
|
|
86419
86420
|
exports2.codeUsesInboxHelper = codeUsesInboxHelper;
|
|
86420
86421
|
exports2.stripInboxRegions = stripInboxRegions;
|
|
86422
|
+
exports2.codeUsesTestInboxIdentity = codeUsesTestInboxIdentity;
|
|
86423
|
+
exports2.codeSelfProvisionsRegistration = codeSelfProvisionsRegistration2;
|
|
86421
86424
|
exports2.renderInboxFn = renderInboxFn;
|
|
86422
86425
|
exports2.upsertInboxBlock = upsertInboxBlock;
|
|
86423
86426
|
var auth_recipe_js_1 = require_auth_recipe();
|
|
@@ -86432,12 +86435,54 @@ var require_inbox_stamp = __commonJS({
|
|
|
86432
86435
|
return false;
|
|
86433
86436
|
return exports2.INBOX_HELPER_TOKEN_RE.test(code) || /VALIDATE_QA_INBOX/.test(code);
|
|
86434
86437
|
}
|
|
86438
|
+
var INBOX_REGION_START = "// >>> VALIDATE_QA_INBOX";
|
|
86439
|
+
var INBOX_REGION_END = "// <<< VALIDATE_QA_INBOX";
|
|
86435
86440
|
function stripInboxRegions(code) {
|
|
86436
|
-
|
|
86441
|
+
if (!code || code.indexOf(INBOX_REGION_START) === -1)
|
|
86442
|
+
return code;
|
|
86443
|
+
let out = "";
|
|
86444
|
+
let i = 0;
|
|
86445
|
+
while (i < code.length) {
|
|
86446
|
+
const start = code.indexOf(INBOX_REGION_START, i);
|
|
86447
|
+
if (start === -1) {
|
|
86448
|
+
out += code.slice(i);
|
|
86449
|
+
break;
|
|
86450
|
+
}
|
|
86451
|
+
const end = code.indexOf(INBOX_REGION_END, start + INBOX_REGION_START.length);
|
|
86452
|
+
if (end === -1) {
|
|
86453
|
+
out += code.slice(i);
|
|
86454
|
+
break;
|
|
86455
|
+
}
|
|
86456
|
+
let lineEnd = code.indexOf("\n", end);
|
|
86457
|
+
lineEnd = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
86458
|
+
out += code.slice(i, start);
|
|
86459
|
+
i = lineEnd;
|
|
86460
|
+
}
|
|
86461
|
+
return out;
|
|
86462
|
+
}
|
|
86463
|
+
var TEST_INBOX_IDENTITY_RE = /VQA_TEST_INBOX_EMAIL|VQA_TEST_ACCOUNT_PASSWORD/;
|
|
86464
|
+
function codeUsesTestInboxIdentity(code) {
|
|
86465
|
+
if (!code)
|
|
86466
|
+
return false;
|
|
86467
|
+
return TEST_INBOX_IDENTITY_RE.test(stripInboxRegions(code));
|
|
86468
|
+
}
|
|
86469
|
+
function codeSelfProvisionsRegistration2(code) {
|
|
86470
|
+
return codeUsesTestInboxIdentity(code);
|
|
86437
86471
|
}
|
|
86438
86472
|
function countInboxRegions(code) {
|
|
86439
|
-
|
|
86440
|
-
|
|
86473
|
+
let count = 0;
|
|
86474
|
+
let i = 0;
|
|
86475
|
+
while (i < code.length) {
|
|
86476
|
+
const start = code.indexOf(INBOX_REGION_START, i);
|
|
86477
|
+
if (start === -1)
|
|
86478
|
+
break;
|
|
86479
|
+
const end = code.indexOf(INBOX_REGION_END, start + INBOX_REGION_START.length);
|
|
86480
|
+
if (end === -1)
|
|
86481
|
+
break;
|
|
86482
|
+
count++;
|
|
86483
|
+
i = end + INBOX_REGION_END.length;
|
|
86484
|
+
}
|
|
86485
|
+
return count;
|
|
86441
86486
|
}
|
|
86442
86487
|
function renderInboxFn() {
|
|
86443
86488
|
const lines = [
|
|
@@ -86531,7 +86576,12 @@ var require_test_inbox_broker = __commonJS({
|
|
|
86531
86576
|
return { found: true, code, link, subject: msg.subject, from: msg.from };
|
|
86532
86577
|
}
|
|
86533
86578
|
async function startTestInboxBroker(opts) {
|
|
86534
|
-
const
|
|
86579
|
+
const executionNonce = (0, node_crypto_1.randomBytes)(4).toString("hex");
|
|
86580
|
+
const identity = mintTestRunInboxIdentity(opts.config, {
|
|
86581
|
+
baseUrl: opts.baseUrl,
|
|
86582
|
+
projectId: opts.projectId,
|
|
86583
|
+
runId: `${opts.runId}#${executionNonce}`
|
|
86584
|
+
});
|
|
86535
86585
|
const reader = new verification_inbox_js_1.VerificationInboxReader(opts.config);
|
|
86536
86586
|
const sinceMs = Date.now();
|
|
86537
86587
|
let sinceUid = 0;
|
|
@@ -86571,6 +86621,12 @@ var require_test_inbox_broker = __commonJS({
|
|
|
86571
86621
|
sinceUidValidity,
|
|
86572
86622
|
maxWaitMs: timeoutMs,
|
|
86573
86623
|
require: require2,
|
|
86624
|
+
// The plus-tag recipient is unique to this run, so an unexpected ESP
|
|
86625
|
+
// sender is still this run's mail — demote, don't drop.
|
|
86626
|
+
demoteFilterMismatch: true,
|
|
86627
|
+
// Don't let a private/internal link end a `require:'link'` wait early —
|
|
86628
|
+
// keep polling for a public one (SSRF parity with the post-wait check).
|
|
86629
|
+
linkAcceptable: inbox_tools_js_1.isPublicHttpUrl,
|
|
86574
86630
|
stats
|
|
86575
86631
|
});
|
|
86576
86632
|
const publicLink = msg && msg.link && (0, inbox_tools_js_1.isPublicHttpUrl)(msg.link) ? msg.link : null;
|
|
@@ -86705,7 +86761,8 @@ var require_playwright_native = __commonJS({
|
|
|
86705
86761
|
runDir = (0, path_1.join)(RUNS_DIR, (0, crypto_1.randomUUID)());
|
|
86706
86762
|
await (0, promises_1.mkdir)(runDir, { recursive: true });
|
|
86707
86763
|
const isApiTest2 = playwrightCode.includes("@api") || playwrightCode.includes("{ request }") && !playwrightCode.includes("{ page");
|
|
86708
|
-
const
|
|
86764
|
+
const usesRealInboxWait = !isApiTest2 && (0, inbox_stamp_js_1.codeUsesInboxHelper)(playwrightCode);
|
|
86765
|
+
const selfProvisionsRegistration = !isApiTest2 && (0, inbox_stamp_js_1.codeSelfProvisionsRegistration)(playwrightCode);
|
|
86709
86766
|
const effectiveStandingMode = isApiTest2 ? authStandingMode ?? "legacy-if-configured" : "none";
|
|
86710
86767
|
const resolvedExtraHeaders = (0, api_auth_headers_js_1.resolveApiAuthHeaders)({
|
|
86711
86768
|
explicit: extraHttpHeaders,
|
|
@@ -86952,7 +87009,7 @@ test.afterEach(async ({ page }, testInfo) => {
|
|
|
86952
87009
|
module.exports = {
|
|
86953
87010
|
testDir: ${JSON.stringify(absTestDir)},
|
|
86954
87011
|
outputDir: ${JSON.stringify(absOutputDir)},
|
|
86955
|
-
timeout: ${
|
|
87012
|
+
timeout: ${usesRealInboxWait ? 24e4 : 6e4},
|
|
86956
87013
|
retries: 0,
|
|
86957
87014
|
use: {
|
|
86958
87015
|
baseURL: ${JSON.stringify(baseUrl)},
|
|
@@ -86978,7 +87035,7 @@ module.exports = {
|
|
|
86978
87035
|
const isolation = await (0, chromium_isolation_js_1.createChromiumIsolation)(runDir);
|
|
86979
87036
|
const processClaimEpoch = Number(process.env.CLAIM_EPOCH);
|
|
86980
87037
|
const callbackClaimEpoch = Number.isSafeInteger(validateContext?.claimEpoch) ? validateContext?.claimEpoch : Number.isSafeInteger(processClaimEpoch) && processClaimEpoch >= 0 ? processClaimEpoch : void 0;
|
|
86981
|
-
if (
|
|
87038
|
+
if (selfProvisionsRegistration && validateContext?.runId) {
|
|
86982
87039
|
const inboxConfig = (0, verification_inbox_js_1.loadVerificationInboxConfig)();
|
|
86983
87040
|
if (!inboxConfig) {
|
|
86984
87041
|
logs2.push("\u{1F4EA} Test uses __vqaWaitForEmail but this runner has no verification inbox configured \u2014 the helper will fail as CONFIG_ISSUE");
|
|
@@ -86996,8 +87053,8 @@ module.exports = {
|
|
|
86996
87053
|
logs2.push(`\u26A0 Inbox broker failed to start: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
86997
87054
|
}
|
|
86998
87055
|
}
|
|
86999
|
-
} else if (
|
|
87000
|
-
logs2.push("\u{1F4EA} Test
|
|
87056
|
+
} else if (selfProvisionsRegistration) {
|
|
87057
|
+
logs2.push("\u{1F4EA} Test self-provisions a registration identity (VQA_TEST_* / __vqaWaitForEmail) but no run callback context is available \u2014 the broker cannot start, so those values will be undefined at runtime");
|
|
87001
87058
|
}
|
|
87002
87059
|
if (validateContext?.runId && validateContext.serverUrl && validateContext.authHeader) {
|
|
87003
87060
|
try {
|
|
@@ -87038,16 +87095,20 @@ module.exports = {
|
|
|
87038
87095
|
...process.env.SHARED_AUTH_INJECT ? { SHARED_AUTH_INJECT: process.env.SHARED_AUTH_INJECT } : {},
|
|
87039
87096
|
// Register-and-verify tests: the run's minted registration identity. An
|
|
87040
87097
|
// address + a DERIVED throwaway-app password — never the IMAP secret,
|
|
87041
|
-
// which stays in this parent (test-inbox-broker.ts).
|
|
87042
|
-
//
|
|
87043
|
-
|
|
87098
|
+
// which stays in this parent (test-inbox-broker.ts). Injected whenever the
|
|
87099
|
+
// broker started, NOT gated on the callback proxy: a signup that registers
|
|
87100
|
+
// with this identity but needs no email verification uses the env yet never
|
|
87101
|
+
// touches the proxy — gating on the proxy left it with undefined creds. A
|
|
87102
|
+
// helper test still needs the proxy, and simply fails as CONFIG_ISSUE
|
|
87103
|
+
// without it; leaking the throwaway address/password to that child is inert.
|
|
87104
|
+
...inboxBroker ? inboxBroker.childEnv() : {}
|
|
87044
87105
|
};
|
|
87045
87106
|
delete childTestVariables.API_AUTH_HEADERS;
|
|
87046
87107
|
logs2.push("\u{1F680} Spawning playwright test...");
|
|
87047
87108
|
const stopLiveBrowserPolling = liveBrowserStatePath && liveBrowserHandle ? startLiveBrowserStatePolling(liveBrowserStatePath, liveBrowserHandle, onLiveBrowserSnapshot) : null;
|
|
87048
87109
|
let playResult;
|
|
87049
87110
|
try {
|
|
87050
|
-
playResult = await runPlaywright(configPath, childTestVariables, trustedRuntimeEnv,
|
|
87111
|
+
playResult = await runPlaywright(configPath, childTestVariables, trustedRuntimeEnv, usesRealInboxWait ? 3e5 : void 0);
|
|
87051
87112
|
} finally {
|
|
87052
87113
|
await stopLiveBrowserPolling?.();
|
|
87053
87114
|
}
|
|
@@ -94799,7 +94860,7 @@ var require_discover_generator = __commonJS({
|
|
|
94799
94860
|
var test_inbox_broker_js_1 = require_test_inbox_broker();
|
|
94800
94861
|
var REGISTER_SCENARIO_RE = /\b(register|registration|sign[\s-]?up|create[\s-]?(a[n]?[\s-]?)?(new[\s-]?)?account|verify[\s-]?(your[\s-]?)?email|email[\s-]?verification|confirm[\s-]?(your[\s-]?)?(email|account)|activate[\s-]?(your[\s-]?)?account|new[\s-]?account)\b/i;
|
|
94801
94862
|
function scenarioLooksLikeRegistration(scenario) {
|
|
94802
|
-
const hay = `${scenario.name ?? ""} ${scenario.description ?? ""} ${scenario.entryRoute ?? ""} ${(scenario.targetPages ?? []).join(" ")}`;
|
|
94863
|
+
const hay = `${scenario.name ?? ""} ${scenario.goal ?? ""} ${scenario.description ?? ""} ${scenario.entryRoute ?? ""} ${(scenario.targetPages ?? []).join(" ")}`;
|
|
94803
94864
|
return REGISTER_SCENARIO_RE.test(hay);
|
|
94804
94865
|
}
|
|
94805
94866
|
function buildEmailVerifyGenBlock(genEmail, genPassword) {
|
|
@@ -97752,7 +97813,7 @@ ${tailBlock}`;
|
|
|
97752
97813
|
const genEmail = (0, verification_inbox_js_1.applyPlusTag)(inboxGenConfig.address, genTag);
|
|
97753
97814
|
const genPassword = (0, verification_inbox_js_1.deriveRegistrationPassword)(genEmail);
|
|
97754
97815
|
genInboxReader = new verification_inbox_js_1.VerificationInboxReader(inboxGenConfig);
|
|
97755
|
-
genInboxState = (0, inbox_tools_js_1.createInboxRunState)(inboxGenConfig, { tag: genTag, passwordKey: test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV });
|
|
97816
|
+
genInboxState = (0, inbox_tools_js_1.createInboxRunState)(inboxGenConfig, { tag: genTag, passwordKey: test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV, demoteFilterMismatch: true });
|
|
97756
97817
|
genInboxCredentials = { ...credentials, [test_inbox_broker_js_1.TEST_INBOX_EMAIL_ENV]: genEmail, [test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV]: genPassword };
|
|
97757
97818
|
genInboxSecret = genPassword;
|
|
97758
97819
|
openaiTools.push(...inbox_tools_js_1.INBOX_TOOLS);
|
|
@@ -98314,6 +98375,13 @@ Do NOT assert that the button/tab/heading you interacted with is merely visible
|
|
|
98314
98375
|
logs2.push(` Strength gate: block persists after revision \u2014 tagged @needs-review (proves no outcome)`);
|
|
98315
98376
|
}
|
|
98316
98377
|
}
|
|
98378
|
+
const finalSelfProvisions = (0, inbox_stamp_js_1.codeSelfProvisionsRegistration)(result.playwrightCode);
|
|
98379
|
+
if (finalSelfProvisions) {
|
|
98380
|
+
if (!result.tags.includes("@email-verify"))
|
|
98381
|
+
result.tags.push("@email-verify");
|
|
98382
|
+
} else if (inboxGenConfig) {
|
|
98383
|
+
logs2.push(` \u26A0 Email-verify generation was armed but the emitted test neither calls __vqaWaitForEmail nor uses the VQA_TEST_* runtime identity \u2014 it may have hardcoded values (stale on re-run).`);
|
|
98384
|
+
}
|
|
98317
98385
|
const elapsed = Date.now() - startTime;
|
|
98318
98386
|
logs2.push(` Scenario test generated in ${iteration} iterations (${elapsed}ms, ${verifyCallCount} verify calls)`);
|
|
98319
98387
|
} else {
|
|
@@ -349882,9 +349950,9 @@ var require_dist2 = __commonJS({
|
|
|
349882
349950
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
349883
349951
|
};
|
|
349884
349952
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
349885
|
-
exports2.
|
|
349886
|
-
exports2.
|
|
349887
|
-
exports2.UNSUPPORTED_RENDERER_PREFIX = exports2.UnsupportedRendererError = exports2.buildCanvasModeAuthoringAddendum = exports2.buildUnsupportedRendererMessage = exports2.modelSupportsVision = exports2.decideCanvasStrategy = exports2.decideAppRenderType = exports2.detectCanvasApp = exports2.detectRateLimitBlock = exports2.isSafeCanonicalRedirect = exports2.resolveBaseUrlPreflight = exports2.checkBaseUrlRedirect = exports2.stripJsonFences = exports2.scrubCredentials = exports2.withAIRetry = exports2.snapshotMatchingChildren = exports2.findNewChromiumChildPid = exports2.killProcessTree = void 0;
|
|
349953
|
+
exports2.resolveRefFromSnapshot = exports2.replayAuthRecipeIntoBrowser = exports2.runRegisterCaptureRun = exports2.runLoginCaptureRun = exports2.filterLoginCaptureCredentials = exports2.buildLoginCaptureCredentials = exports2.isReservedRunnerEnvVar = exports2.RESERVED_RUNNER_ENV_VARS = exports2.AUTH_MARKER_VERSION = exports2.buildHealAuthStamp = exports2.extractAuthRegion = exports2.upsertAuthBlock = exports2.buildAuthRecipe = exports2.commandToReplayStep = exports2.buildReplayPlan = exports2.absoluteRoute = exports2.renderReplaySettleArrow = exports2.renderReplayClickArrow = exports2.renderAuthFn = exports2.filterFeatureGroupsToPathScope = exports2.isAuthFlowRoute = exports2.deriveSurveyPathScope = exports2.canonicalizeRoute = exports2.codeUsesInboxHelper = exports2.codeUsesTestInboxIdentity = exports2.codeSelfProvisionsRegistration = exports2.executeGrokPerBatchHeal = exports2.executeGrokPerTestHeal = exports2.headerVal = exports2.classifyAuthType = exports2.isTextExcerptable = exports2.isStaticAssetByExt = exports2.isApiCall = exports2.buildApiCallSummary = exports2.computeMobileHealOutcome = exports2.detectMobileStepSecretLeak = exports2.redactMobileSecretsFromText = exports2.MOBILE_LIVE_HEAL_SYSTEM_PROMPT = exports2.MOBILE_SCRIPT_HEAL_SYSTEM_PROMPT = exports2.executeMobileLiveHeal = exports2.executeMobileTestWithHealing = exports2.executeMobileScriptDrivenHeal = exports2.prepareMobileScenarioAppState = exports2.runMobileGeneratePhase = exports2.runMobileAIPlanner = exports2.buildMobileSiteMap = exports2.formatMobileEvidenceForPlanner = exports2.MOBILE_SCENARIO_SYSTEM_PROMPT = exports2.MOBILE_SURVEY_SYSTEM_PROMPT = exports2.runMobileExplorePhase = void 0;
|
|
349954
|
+
exports2.MAX_MANIFEST_FILES = exports2.toDiffSummary = exports2.isLikelyTestFile = exports2.sanitizeRepoRelPath = exports2.sha256Hex = exports2.hashFiles = exports2.enumerateTestFiles = exports2.buildNextManifest = exports2.detectRepoSwitch = exports2.classifyImportDiff = exports2.parseImportManifest = exports2.validateAuthoredMobileTest = exports2.buildMobileRepoAuthorSystemRules = exports2.buildMobileRepoAuthorKickoff = exports2.buildMobileRepoAuthorContractMd = exports2.REPO_ANALYSIS_SCHEMA_VERSION = exports2.validateSourceEndpoints = exports2.validateAuthoredTest = exports2.validateRepoMapFile = exports2.validateRepoMemoryFile = exports2.buildTestingStandardsSection = exports2.buildRepoAuthorSystemRules = exports2.buildRepoAuthorKickoff = exports2.buildRepoAuthorContractMd = exports2.buildRepoMapSystemRules = exports2.buildRepoMapKickoff = exports2.buildRepoMapContractMd = exports2.buildRepoMemorySystemRules = exports2.buildRepoMemoryKickoff = exports2.buildRepoMemoryContractMd = exports2.runRepoAnalysisOnRunner = exports2.MOBILE_IMPORT_SCHEMA_VERSION = exports2.validateImportedMobileTest = exports2.buildMobileImportSystemRules = exports2.buildMobileImportKickoff = exports2.buildMobileImportContractMd = exports2.IMPORT_SCHEMA_VERSION = exports2.validateImportResultFile = exports2.validateImportedTest = exports2.buildImportSystemRules = exports2.buildImportKickoff = exports2.buildImportContractMd = exports2.MAX_ARCHIVE_BYTES = exports2.isUnsafeEntryName = exports2.extractZipSafely = exports2.downloadArchiveCapped = exports2.detectArchiveKind = exports2.acquireRepoForImport = exports2.runFrameworkImportOnRunner = exports2.getAgenticEngine = void 0;
|
|
349955
|
+
exports2.UNSUPPORTED_RENDERER_PREFIX = exports2.UnsupportedRendererError = exports2.buildCanvasModeAuthoringAddendum = exports2.buildUnsupportedRendererMessage = exports2.modelSupportsVision = exports2.decideCanvasStrategy = exports2.decideAppRenderType = exports2.detectCanvasApp = exports2.detectRateLimitBlock = exports2.isSafeCanonicalRedirect = exports2.resolveBaseUrlPreflight = exports2.checkBaseUrlRedirect = exports2.stripJsonFences = exports2.scrubCredentials = exports2.withAIRetry = exports2.snapshotMatchingChildren = exports2.findNewChromiumChildPid = exports2.killProcessTree = exports2.gracefulCloseWithTreeKill = exports2.liveBrowserRegistry = exports2.REPO_SWITCH_REMOVED_FRACTION = void 0;
|
|
349888
349956
|
__exportStar(require_ai_provider(), exports2);
|
|
349889
349957
|
__exportStar(require_mobile_types(), exports2);
|
|
349890
349958
|
__exportStar(require_mobile_source_parser(), exports2);
|
|
@@ -349975,6 +350043,16 @@ var require_dist2 = __commonJS({
|
|
|
349975
350043
|
return grok_batch_healer_js_1.executeGrokPerBatchHeal;
|
|
349976
350044
|
} });
|
|
349977
350045
|
__exportStar(require_playwright_code(), exports2);
|
|
350046
|
+
var inbox_stamp_js_1 = require_inbox_stamp();
|
|
350047
|
+
Object.defineProperty(exports2, "codeSelfProvisionsRegistration", { enumerable: true, get: function() {
|
|
350048
|
+
return inbox_stamp_js_1.codeSelfProvisionsRegistration;
|
|
350049
|
+
} });
|
|
350050
|
+
Object.defineProperty(exports2, "codeUsesTestInboxIdentity", { enumerable: true, get: function() {
|
|
350051
|
+
return inbox_stamp_js_1.codeUsesTestInboxIdentity;
|
|
350052
|
+
} });
|
|
350053
|
+
Object.defineProperty(exports2, "codeUsesInboxHelper", { enumerable: true, get: function() {
|
|
350054
|
+
return inbox_stamp_js_1.codeUsesInboxHelper;
|
|
350055
|
+
} });
|
|
349978
350056
|
__exportStar(require_playwright_native(), exports2);
|
|
349979
350057
|
__exportStar(require_regression_runner(), exports2);
|
|
349980
350058
|
__exportStar(require_snapshot_parser(), exports2);
|
|
@@ -350304,7 +350382,7 @@ var require_package4 = __commonJS({
|
|
|
350304
350382
|
"package.json"(exports2, module2) {
|
|
350305
350383
|
module2.exports = {
|
|
350306
350384
|
name: "@validate.qa/runner",
|
|
350307
|
-
version: "1.0.
|
|
350385
|
+
version: "1.0.59",
|
|
350308
350386
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
350309
350387
|
bin: {
|
|
350310
350388
|
"validate-runner": "dist/cli.js"
|
|
@@ -357933,7 +358011,8 @@ async function executeRun(run2, opts, headers, requestLiveBrowserHeartbeat = ()
|
|
|
357933
358011
|
const codeUsesCreds = codeProvided && /TEST_USER_EMAIL|TEST_USER_PASSWORD|__vqaLogin/.test(code);
|
|
357934
358012
|
const tags = Array.isArray(run2.tags) ? run2.tags : [];
|
|
357935
358013
|
const isHallucinationShape = codeProvided && !codeUsesCreds && tags.includes("@inline-login") && !tags.includes("@api");
|
|
357936
|
-
const
|
|
358014
|
+
const selfProvisioningRegisterTest = codeProvided && !codeUsesCreds && tags.includes("@email-verify") && (0, import_runner_core13.codeSelfProvisionsRegistration)(code);
|
|
358015
|
+
const requireCreds = authPlan.needsLoginCreds && !legacyHeaderBypass && !isHallucinationShape && !selfProvisioningRegisterTest;
|
|
357937
358016
|
if (requireCreds && !run2.testVariables?.["TEST_USER_EMAIL"]?.trim()) {
|
|
357938
358017
|
preflightError = "Pre-flight failed: Missing TEST_USER_EMAIL. Tests that log in (tagged @auth, @needs-auth, @api, @auth-cookie-state, @auth-login-cookie, or @auth-login-bearer) require login credentials.";
|
|
357939
358018
|
} else if (requireCreds && !run2.testVariables?.["TEST_USER_PASSWORD"]?.trim()) {
|
package/dist/cli.mjs
CHANGED
|
@@ -72846,18 +72846,15 @@ var require_verification_inbox = __commonJS({
|
|
|
72846
72846
|
return { code: cleaned, confidence: "keyword" };
|
|
72847
72847
|
}
|
|
72848
72848
|
}
|
|
72849
|
-
const distinct = /* @__PURE__ */ new Set();
|
|
72850
72849
|
for (const body of bodies) {
|
|
72851
72850
|
if (!body)
|
|
72852
72851
|
continue;
|
|
72853
72852
|
for (const n of body.match(/\b[0-9]{4,8}\b/g) ?? []) {
|
|
72854
|
-
if (
|
|
72855
|
-
|
|
72853
|
+
if (looksLikeYearOrDate(n))
|
|
72854
|
+
continue;
|
|
72855
|
+
return { code: n, confidence: "fallback" };
|
|
72856
72856
|
}
|
|
72857
72857
|
}
|
|
72858
|
-
if (distinct.size === 1) {
|
|
72859
|
-
return { code: distinct.values().next().value ?? null, confidence: "fallback" };
|
|
72860
|
-
}
|
|
72861
72858
|
return { code: null, confidence: null };
|
|
72862
72859
|
}
|
|
72863
72860
|
function matchBestCode(line) {
|
|
@@ -73155,9 +73152,10 @@ var require_verification_inbox = __commonJS({
|
|
|
73155
73152
|
const satisfies = (m) => {
|
|
73156
73153
|
if (opts.require === "code")
|
|
73157
73154
|
return m.code !== null && m.codeConfidence !== "fallback";
|
|
73155
|
+
const linkOk = (l) => l !== null && (!opts.linkAcceptable || opts.linkAcceptable(l));
|
|
73158
73156
|
if (opts.require === "link")
|
|
73159
|
-
return m.link
|
|
73160
|
-
return m.
|
|
73157
|
+
return linkOk(m.link);
|
|
73158
|
+
return m.code !== null && m.codeConfidence !== "fallback" || linkOk(m.link);
|
|
73161
73159
|
};
|
|
73162
73160
|
let weakest = null;
|
|
73163
73161
|
const check2 = async () => {
|
|
@@ -73204,7 +73202,7 @@ var require_verification_inbox = __commonJS({
|
|
|
73204
73202
|
const since = new Date(Math.max(0, opts.sinceMs));
|
|
73205
73203
|
const lock = await client.getMailboxLock(mailbox);
|
|
73206
73204
|
const results = [];
|
|
73207
|
-
const
|
|
73205
|
+
const demoteMismatch = isPlusTagged(opts.toAddress) && Boolean(opts.demoteFilterMismatch);
|
|
73208
73206
|
try {
|
|
73209
73207
|
try {
|
|
73210
73208
|
await client.noop();
|
|
@@ -73250,7 +73248,7 @@ var require_verification_inbox = __commonJS({
|
|
|
73250
73248
|
continue;
|
|
73251
73249
|
const filterActive = Boolean(opts.fromMatch || opts.subjectMatch);
|
|
73252
73250
|
const filterMatched = (!opts.fromMatch || matchField(parsed.from?.text, opts.fromMatch)) && (!opts.subjectMatch || matchField(parsed.subject, opts.subjectMatch));
|
|
73253
|
-
if (filterActive && !filterMatched && !
|
|
73251
|
+
if (filterActive && !filterMatched && !demoteMismatch) {
|
|
73254
73252
|
if (opts.stats)
|
|
73255
73253
|
opts.stats.filteredOut += 1;
|
|
73256
73254
|
continue;
|
|
@@ -73388,7 +73386,8 @@ var require_inbox_tools = __commonJS({
|
|
|
73388
73386
|
// Captured at provision (needs a live reader); 0 = use the sinceMs floor.
|
|
73389
73387
|
sinceUid: 0,
|
|
73390
73388
|
sinceUidValidity: 0,
|
|
73391
|
-
knownLinks: /* @__PURE__ */ new Set()
|
|
73389
|
+
knownLinks: /* @__PURE__ */ new Set(),
|
|
73390
|
+
demoteFilterMismatch: opts.demoteFilterMismatch ?? false
|
|
73392
73391
|
};
|
|
73393
73392
|
}
|
|
73394
73393
|
exports.PROVISION_IDENTITY_TOOL = {
|
|
@@ -73576,6 +73575,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73576
73575
|
sinceUidValidity: ctx.state.sinceUidValidity,
|
|
73577
73576
|
fromMatch: asStr(args.senderMatch),
|
|
73578
73577
|
subjectMatch: asStr(args.subjectMatch),
|
|
73578
|
+
demoteFilterMismatch: ctx.state.demoteFilterMismatch,
|
|
73579
73579
|
limit: 10
|
|
73580
73580
|
});
|
|
73581
73581
|
return ok({
|
|
@@ -73600,6 +73600,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73600
73600
|
sinceUidValidity: ctx.state.sinceUidValidity,
|
|
73601
73601
|
fromMatch: asStr(args.senderMatch),
|
|
73602
73602
|
subjectMatch: asStr(args.subjectMatch),
|
|
73603
|
+
demoteFilterMismatch: ctx.state.demoteFilterMismatch,
|
|
73603
73604
|
maxWaitMs: maxWaitSeconds * 1e3,
|
|
73604
73605
|
stats
|
|
73605
73606
|
});
|
|
@@ -73746,7 +73747,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73746
73747
|
const u = new URL(raw);
|
|
73747
73748
|
if (u.protocol !== "http:" && u.protocol !== "https:")
|
|
73748
73749
|
return false;
|
|
73749
|
-
host = u.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
73750
|
+
host = u.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.+$/, "");
|
|
73750
73751
|
} catch {
|
|
73751
73752
|
return false;
|
|
73752
73753
|
}
|
|
@@ -73762,7 +73763,7 @@ var require_inbox_tools = __commonJS({
|
|
|
73762
73763
|
const dotted = host.match(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
|
73763
73764
|
if (dotted && !ipv4IsPublic(dotted[1]))
|
|
73764
73765
|
return false;
|
|
73765
|
-
const mapped = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
73766
|
+
const mapped = host.match(/^::(?:ffff:)?([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
73766
73767
|
if (mapped) {
|
|
73767
73768
|
const hi = parseInt(mapped[1], 16);
|
|
73768
73769
|
const lo = parseInt(mapped[2], 16);
|
|
@@ -86423,6 +86424,8 @@ var require_inbox_stamp = __commonJS({
|
|
|
86423
86424
|
exports.INBOX_HELPER_TOKEN_RE = exports.INBOX_HELPER_NAME = exports.INBOX_REGION_RE = exports.INBOX_MARKER_VERSION = void 0;
|
|
86424
86425
|
exports.codeUsesInboxHelper = codeUsesInboxHelper;
|
|
86425
86426
|
exports.stripInboxRegions = stripInboxRegions;
|
|
86427
|
+
exports.codeUsesTestInboxIdentity = codeUsesTestInboxIdentity;
|
|
86428
|
+
exports.codeSelfProvisionsRegistration = codeSelfProvisionsRegistration2;
|
|
86426
86429
|
exports.renderInboxFn = renderInboxFn;
|
|
86427
86430
|
exports.upsertInboxBlock = upsertInboxBlock;
|
|
86428
86431
|
var auth_recipe_js_1 = require_auth_recipe();
|
|
@@ -86437,12 +86440,54 @@ var require_inbox_stamp = __commonJS({
|
|
|
86437
86440
|
return false;
|
|
86438
86441
|
return exports.INBOX_HELPER_TOKEN_RE.test(code) || /VALIDATE_QA_INBOX/.test(code);
|
|
86439
86442
|
}
|
|
86443
|
+
var INBOX_REGION_START = "// >>> VALIDATE_QA_INBOX";
|
|
86444
|
+
var INBOX_REGION_END = "// <<< VALIDATE_QA_INBOX";
|
|
86440
86445
|
function stripInboxRegions(code) {
|
|
86441
|
-
|
|
86446
|
+
if (!code || code.indexOf(INBOX_REGION_START) === -1)
|
|
86447
|
+
return code;
|
|
86448
|
+
let out = "";
|
|
86449
|
+
let i = 0;
|
|
86450
|
+
while (i < code.length) {
|
|
86451
|
+
const start = code.indexOf(INBOX_REGION_START, i);
|
|
86452
|
+
if (start === -1) {
|
|
86453
|
+
out += code.slice(i);
|
|
86454
|
+
break;
|
|
86455
|
+
}
|
|
86456
|
+
const end = code.indexOf(INBOX_REGION_END, start + INBOX_REGION_START.length);
|
|
86457
|
+
if (end === -1) {
|
|
86458
|
+
out += code.slice(i);
|
|
86459
|
+
break;
|
|
86460
|
+
}
|
|
86461
|
+
let lineEnd = code.indexOf("\n", end);
|
|
86462
|
+
lineEnd = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
86463
|
+
out += code.slice(i, start);
|
|
86464
|
+
i = lineEnd;
|
|
86465
|
+
}
|
|
86466
|
+
return out;
|
|
86467
|
+
}
|
|
86468
|
+
var TEST_INBOX_IDENTITY_RE = /VQA_TEST_INBOX_EMAIL|VQA_TEST_ACCOUNT_PASSWORD/;
|
|
86469
|
+
function codeUsesTestInboxIdentity(code) {
|
|
86470
|
+
if (!code)
|
|
86471
|
+
return false;
|
|
86472
|
+
return TEST_INBOX_IDENTITY_RE.test(stripInboxRegions(code));
|
|
86473
|
+
}
|
|
86474
|
+
function codeSelfProvisionsRegistration2(code) {
|
|
86475
|
+
return codeUsesTestInboxIdentity(code);
|
|
86442
86476
|
}
|
|
86443
86477
|
function countInboxRegions(code) {
|
|
86444
|
-
|
|
86445
|
-
|
|
86478
|
+
let count = 0;
|
|
86479
|
+
let i = 0;
|
|
86480
|
+
while (i < code.length) {
|
|
86481
|
+
const start = code.indexOf(INBOX_REGION_START, i);
|
|
86482
|
+
if (start === -1)
|
|
86483
|
+
break;
|
|
86484
|
+
const end = code.indexOf(INBOX_REGION_END, start + INBOX_REGION_START.length);
|
|
86485
|
+
if (end === -1)
|
|
86486
|
+
break;
|
|
86487
|
+
count++;
|
|
86488
|
+
i = end + INBOX_REGION_END.length;
|
|
86489
|
+
}
|
|
86490
|
+
return count;
|
|
86446
86491
|
}
|
|
86447
86492
|
function renderInboxFn() {
|
|
86448
86493
|
const lines = [
|
|
@@ -86536,7 +86581,12 @@ var require_test_inbox_broker = __commonJS({
|
|
|
86536
86581
|
return { found: true, code, link, subject: msg.subject, from: msg.from };
|
|
86537
86582
|
}
|
|
86538
86583
|
async function startTestInboxBroker(opts) {
|
|
86539
|
-
const
|
|
86584
|
+
const executionNonce = (0, node_crypto_1.randomBytes)(4).toString("hex");
|
|
86585
|
+
const identity = mintTestRunInboxIdentity(opts.config, {
|
|
86586
|
+
baseUrl: opts.baseUrl,
|
|
86587
|
+
projectId: opts.projectId,
|
|
86588
|
+
runId: `${opts.runId}#${executionNonce}`
|
|
86589
|
+
});
|
|
86540
86590
|
const reader = new verification_inbox_js_1.VerificationInboxReader(opts.config);
|
|
86541
86591
|
const sinceMs = Date.now();
|
|
86542
86592
|
let sinceUid = 0;
|
|
@@ -86576,6 +86626,12 @@ var require_test_inbox_broker = __commonJS({
|
|
|
86576
86626
|
sinceUidValidity,
|
|
86577
86627
|
maxWaitMs: timeoutMs,
|
|
86578
86628
|
require: require2,
|
|
86629
|
+
// The plus-tag recipient is unique to this run, so an unexpected ESP
|
|
86630
|
+
// sender is still this run's mail — demote, don't drop.
|
|
86631
|
+
demoteFilterMismatch: true,
|
|
86632
|
+
// Don't let a private/internal link end a `require:'link'` wait early —
|
|
86633
|
+
// keep polling for a public one (SSRF parity with the post-wait check).
|
|
86634
|
+
linkAcceptable: inbox_tools_js_1.isPublicHttpUrl,
|
|
86579
86635
|
stats
|
|
86580
86636
|
});
|
|
86581
86637
|
const publicLink = msg && msg.link && (0, inbox_tools_js_1.isPublicHttpUrl)(msg.link) ? msg.link : null;
|
|
@@ -86710,7 +86766,8 @@ var require_playwright_native = __commonJS({
|
|
|
86710
86766
|
runDir = (0, path_1.join)(RUNS_DIR, (0, crypto_1.randomUUID)());
|
|
86711
86767
|
await (0, promises_1.mkdir)(runDir, { recursive: true });
|
|
86712
86768
|
const isApiTest2 = playwrightCode.includes("@api") || playwrightCode.includes("{ request }") && !playwrightCode.includes("{ page");
|
|
86713
|
-
const
|
|
86769
|
+
const usesRealInboxWait = !isApiTest2 && (0, inbox_stamp_js_1.codeUsesInboxHelper)(playwrightCode);
|
|
86770
|
+
const selfProvisionsRegistration = !isApiTest2 && (0, inbox_stamp_js_1.codeSelfProvisionsRegistration)(playwrightCode);
|
|
86714
86771
|
const effectiveStandingMode = isApiTest2 ? authStandingMode ?? "legacy-if-configured" : "none";
|
|
86715
86772
|
const resolvedExtraHeaders = (0, api_auth_headers_js_1.resolveApiAuthHeaders)({
|
|
86716
86773
|
explicit: extraHttpHeaders,
|
|
@@ -86957,7 +87014,7 @@ test.afterEach(async ({ page }, testInfo) => {
|
|
|
86957
87014
|
module.exports = {
|
|
86958
87015
|
testDir: ${JSON.stringify(absTestDir)},
|
|
86959
87016
|
outputDir: ${JSON.stringify(absOutputDir)},
|
|
86960
|
-
timeout: ${
|
|
87017
|
+
timeout: ${usesRealInboxWait ? 24e4 : 6e4},
|
|
86961
87018
|
retries: 0,
|
|
86962
87019
|
use: {
|
|
86963
87020
|
baseURL: ${JSON.stringify(baseUrl)},
|
|
@@ -86983,7 +87040,7 @@ module.exports = {
|
|
|
86983
87040
|
const isolation = await (0, chromium_isolation_js_1.createChromiumIsolation)(runDir);
|
|
86984
87041
|
const processClaimEpoch = Number(process.env.CLAIM_EPOCH);
|
|
86985
87042
|
const callbackClaimEpoch = Number.isSafeInteger(validateContext?.claimEpoch) ? validateContext?.claimEpoch : Number.isSafeInteger(processClaimEpoch) && processClaimEpoch >= 0 ? processClaimEpoch : void 0;
|
|
86986
|
-
if (
|
|
87043
|
+
if (selfProvisionsRegistration && validateContext?.runId) {
|
|
86987
87044
|
const inboxConfig = (0, verification_inbox_js_1.loadVerificationInboxConfig)();
|
|
86988
87045
|
if (!inboxConfig) {
|
|
86989
87046
|
logs2.push("\u{1F4EA} Test uses __vqaWaitForEmail but this runner has no verification inbox configured \u2014 the helper will fail as CONFIG_ISSUE");
|
|
@@ -87001,8 +87058,8 @@ module.exports = {
|
|
|
87001
87058
|
logs2.push(`\u26A0 Inbox broker failed to start: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
87002
87059
|
}
|
|
87003
87060
|
}
|
|
87004
|
-
} else if (
|
|
87005
|
-
logs2.push("\u{1F4EA} Test
|
|
87061
|
+
} else if (selfProvisionsRegistration) {
|
|
87062
|
+
logs2.push("\u{1F4EA} Test self-provisions a registration identity (VQA_TEST_* / __vqaWaitForEmail) but no run callback context is available \u2014 the broker cannot start, so those values will be undefined at runtime");
|
|
87006
87063
|
}
|
|
87007
87064
|
if (validateContext?.runId && validateContext.serverUrl && validateContext.authHeader) {
|
|
87008
87065
|
try {
|
|
@@ -87043,16 +87100,20 @@ module.exports = {
|
|
|
87043
87100
|
...process.env.SHARED_AUTH_INJECT ? { SHARED_AUTH_INJECT: process.env.SHARED_AUTH_INJECT } : {},
|
|
87044
87101
|
// Register-and-verify tests: the run's minted registration identity. An
|
|
87045
87102
|
// address + a DERIVED throwaway-app password — never the IMAP secret,
|
|
87046
|
-
// which stays in this parent (test-inbox-broker.ts).
|
|
87047
|
-
//
|
|
87048
|
-
|
|
87103
|
+
// which stays in this parent (test-inbox-broker.ts). Injected whenever the
|
|
87104
|
+
// broker started, NOT gated on the callback proxy: a signup that registers
|
|
87105
|
+
// with this identity but needs no email verification uses the env yet never
|
|
87106
|
+
// touches the proxy — gating on the proxy left it with undefined creds. A
|
|
87107
|
+
// helper test still needs the proxy, and simply fails as CONFIG_ISSUE
|
|
87108
|
+
// without it; leaking the throwaway address/password to that child is inert.
|
|
87109
|
+
...inboxBroker ? inboxBroker.childEnv() : {}
|
|
87049
87110
|
};
|
|
87050
87111
|
delete childTestVariables.API_AUTH_HEADERS;
|
|
87051
87112
|
logs2.push("\u{1F680} Spawning playwright test...");
|
|
87052
87113
|
const stopLiveBrowserPolling = liveBrowserStatePath && liveBrowserHandle ? startLiveBrowserStatePolling(liveBrowserStatePath, liveBrowserHandle, onLiveBrowserSnapshot) : null;
|
|
87053
87114
|
let playResult;
|
|
87054
87115
|
try {
|
|
87055
|
-
playResult = await runPlaywright(configPath, childTestVariables, trustedRuntimeEnv,
|
|
87116
|
+
playResult = await runPlaywright(configPath, childTestVariables, trustedRuntimeEnv, usesRealInboxWait ? 3e5 : void 0);
|
|
87056
87117
|
} finally {
|
|
87057
87118
|
await stopLiveBrowserPolling?.();
|
|
87058
87119
|
}
|
|
@@ -94804,7 +94865,7 @@ var require_discover_generator = __commonJS({
|
|
|
94804
94865
|
var test_inbox_broker_js_1 = require_test_inbox_broker();
|
|
94805
94866
|
var REGISTER_SCENARIO_RE = /\b(register|registration|sign[\s-]?up|create[\s-]?(a[n]?[\s-]?)?(new[\s-]?)?account|verify[\s-]?(your[\s-]?)?email|email[\s-]?verification|confirm[\s-]?(your[\s-]?)?(email|account)|activate[\s-]?(your[\s-]?)?account|new[\s-]?account)\b/i;
|
|
94806
94867
|
function scenarioLooksLikeRegistration(scenario) {
|
|
94807
|
-
const hay = `${scenario.name ?? ""} ${scenario.description ?? ""} ${scenario.entryRoute ?? ""} ${(scenario.targetPages ?? []).join(" ")}`;
|
|
94868
|
+
const hay = `${scenario.name ?? ""} ${scenario.goal ?? ""} ${scenario.description ?? ""} ${scenario.entryRoute ?? ""} ${(scenario.targetPages ?? []).join(" ")}`;
|
|
94808
94869
|
return REGISTER_SCENARIO_RE.test(hay);
|
|
94809
94870
|
}
|
|
94810
94871
|
function buildEmailVerifyGenBlock(genEmail, genPassword) {
|
|
@@ -97757,7 +97818,7 @@ ${tailBlock}`;
|
|
|
97757
97818
|
const genEmail = (0, verification_inbox_js_1.applyPlusTag)(inboxGenConfig.address, genTag);
|
|
97758
97819
|
const genPassword = (0, verification_inbox_js_1.deriveRegistrationPassword)(genEmail);
|
|
97759
97820
|
genInboxReader = new verification_inbox_js_1.VerificationInboxReader(inboxGenConfig);
|
|
97760
|
-
genInboxState = (0, inbox_tools_js_1.createInboxRunState)(inboxGenConfig, { tag: genTag, passwordKey: test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV });
|
|
97821
|
+
genInboxState = (0, inbox_tools_js_1.createInboxRunState)(inboxGenConfig, { tag: genTag, passwordKey: test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV, demoteFilterMismatch: true });
|
|
97761
97822
|
genInboxCredentials = { ...credentials, [test_inbox_broker_js_1.TEST_INBOX_EMAIL_ENV]: genEmail, [test_inbox_broker_js_1.TEST_INBOX_PASSWORD_ENV]: genPassword };
|
|
97762
97823
|
genInboxSecret = genPassword;
|
|
97763
97824
|
openaiTools.push(...inbox_tools_js_1.INBOX_TOOLS);
|
|
@@ -98319,6 +98380,13 @@ Do NOT assert that the button/tab/heading you interacted with is merely visible
|
|
|
98319
98380
|
logs2.push(` Strength gate: block persists after revision \u2014 tagged @needs-review (proves no outcome)`);
|
|
98320
98381
|
}
|
|
98321
98382
|
}
|
|
98383
|
+
const finalSelfProvisions = (0, inbox_stamp_js_1.codeSelfProvisionsRegistration)(result.playwrightCode);
|
|
98384
|
+
if (finalSelfProvisions) {
|
|
98385
|
+
if (!result.tags.includes("@email-verify"))
|
|
98386
|
+
result.tags.push("@email-verify");
|
|
98387
|
+
} else if (inboxGenConfig) {
|
|
98388
|
+
logs2.push(` \u26A0 Email-verify generation was armed but the emitted test neither calls __vqaWaitForEmail nor uses the VQA_TEST_* runtime identity \u2014 it may have hardcoded values (stale on re-run).`);
|
|
98389
|
+
}
|
|
98322
98390
|
const elapsed = Date.now() - startTime;
|
|
98323
98391
|
logs2.push(` Scenario test generated in ${iteration} iterations (${elapsed}ms, ${verifyCallCount} verify calls)`);
|
|
98324
98392
|
} else {
|
|
@@ -349887,9 +349955,9 @@ var require_dist2 = __commonJS({
|
|
|
349887
349955
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
349888
349956
|
};
|
|
349889
349957
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
349890
|
-
exports.
|
|
349891
|
-
exports.
|
|
349892
|
-
exports.UNSUPPORTED_RENDERER_PREFIX = exports.UnsupportedRendererError = exports.buildCanvasModeAuthoringAddendum = exports.buildUnsupportedRendererMessage = exports.modelSupportsVision = exports.decideCanvasStrategy = exports.decideAppRenderType = exports.detectCanvasApp = exports.detectRateLimitBlock = exports.isSafeCanonicalRedirect = exports.resolveBaseUrlPreflight = exports.checkBaseUrlRedirect = exports.stripJsonFences = exports.scrubCredentials = exports.withAIRetry = exports.snapshotMatchingChildren = exports.findNewChromiumChildPid = exports.killProcessTree = void 0;
|
|
349958
|
+
exports.resolveRefFromSnapshot = exports.replayAuthRecipeIntoBrowser = exports.runRegisterCaptureRun = exports.runLoginCaptureRun = exports.filterLoginCaptureCredentials = exports.buildLoginCaptureCredentials = exports.isReservedRunnerEnvVar = exports.RESERVED_RUNNER_ENV_VARS = exports.AUTH_MARKER_VERSION = exports.buildHealAuthStamp = exports.extractAuthRegion = exports.upsertAuthBlock = exports.buildAuthRecipe = exports.commandToReplayStep = exports.buildReplayPlan = exports.absoluteRoute = exports.renderReplaySettleArrow = exports.renderReplayClickArrow = exports.renderAuthFn = exports.filterFeatureGroupsToPathScope = exports.isAuthFlowRoute = exports.deriveSurveyPathScope = exports.canonicalizeRoute = exports.codeUsesInboxHelper = exports.codeUsesTestInboxIdentity = exports.codeSelfProvisionsRegistration = exports.executeGrokPerBatchHeal = exports.executeGrokPerTestHeal = exports.headerVal = exports.classifyAuthType = exports.isTextExcerptable = exports.isStaticAssetByExt = exports.isApiCall = exports.buildApiCallSummary = exports.computeMobileHealOutcome = exports.detectMobileStepSecretLeak = exports.redactMobileSecretsFromText = exports.MOBILE_LIVE_HEAL_SYSTEM_PROMPT = exports.MOBILE_SCRIPT_HEAL_SYSTEM_PROMPT = exports.executeMobileLiveHeal = exports.executeMobileTestWithHealing = exports.executeMobileScriptDrivenHeal = exports.prepareMobileScenarioAppState = exports.runMobileGeneratePhase = exports.runMobileAIPlanner = exports.buildMobileSiteMap = exports.formatMobileEvidenceForPlanner = exports.MOBILE_SCENARIO_SYSTEM_PROMPT = exports.MOBILE_SURVEY_SYSTEM_PROMPT = exports.runMobileExplorePhase = void 0;
|
|
349959
|
+
exports.MAX_MANIFEST_FILES = exports.toDiffSummary = exports.isLikelyTestFile = exports.sanitizeRepoRelPath = exports.sha256Hex = exports.hashFiles = exports.enumerateTestFiles = exports.buildNextManifest = exports.detectRepoSwitch = exports.classifyImportDiff = exports.parseImportManifest = exports.validateAuthoredMobileTest = exports.buildMobileRepoAuthorSystemRules = exports.buildMobileRepoAuthorKickoff = exports.buildMobileRepoAuthorContractMd = exports.REPO_ANALYSIS_SCHEMA_VERSION = exports.validateSourceEndpoints = exports.validateAuthoredTest = exports.validateRepoMapFile = exports.validateRepoMemoryFile = exports.buildTestingStandardsSection = exports.buildRepoAuthorSystemRules = exports.buildRepoAuthorKickoff = exports.buildRepoAuthorContractMd = exports.buildRepoMapSystemRules = exports.buildRepoMapKickoff = exports.buildRepoMapContractMd = exports.buildRepoMemorySystemRules = exports.buildRepoMemoryKickoff = exports.buildRepoMemoryContractMd = exports.runRepoAnalysisOnRunner = exports.MOBILE_IMPORT_SCHEMA_VERSION = exports.validateImportedMobileTest = exports.buildMobileImportSystemRules = exports.buildMobileImportKickoff = exports.buildMobileImportContractMd = exports.IMPORT_SCHEMA_VERSION = exports.validateImportResultFile = exports.validateImportedTest = exports.buildImportSystemRules = exports.buildImportKickoff = exports.buildImportContractMd = exports.MAX_ARCHIVE_BYTES = exports.isUnsafeEntryName = exports.extractZipSafely = exports.downloadArchiveCapped = exports.detectArchiveKind = exports.acquireRepoForImport = exports.runFrameworkImportOnRunner = exports.getAgenticEngine = void 0;
|
|
349960
|
+
exports.UNSUPPORTED_RENDERER_PREFIX = exports.UnsupportedRendererError = exports.buildCanvasModeAuthoringAddendum = exports.buildUnsupportedRendererMessage = exports.modelSupportsVision = exports.decideCanvasStrategy = exports.decideAppRenderType = exports.detectCanvasApp = exports.detectRateLimitBlock = exports.isSafeCanonicalRedirect = exports.resolveBaseUrlPreflight = exports.checkBaseUrlRedirect = exports.stripJsonFences = exports.scrubCredentials = exports.withAIRetry = exports.snapshotMatchingChildren = exports.findNewChromiumChildPid = exports.killProcessTree = exports.gracefulCloseWithTreeKill = exports.liveBrowserRegistry = exports.REPO_SWITCH_REMOVED_FRACTION = void 0;
|
|
349893
349961
|
__exportStar(require_ai_provider(), exports);
|
|
349894
349962
|
__exportStar(require_mobile_types(), exports);
|
|
349895
349963
|
__exportStar(require_mobile_source_parser(), exports);
|
|
@@ -349980,6 +350048,16 @@ var require_dist2 = __commonJS({
|
|
|
349980
350048
|
return grok_batch_healer_js_1.executeGrokPerBatchHeal;
|
|
349981
350049
|
} });
|
|
349982
350050
|
__exportStar(require_playwright_code(), exports);
|
|
350051
|
+
var inbox_stamp_js_1 = require_inbox_stamp();
|
|
350052
|
+
Object.defineProperty(exports, "codeSelfProvisionsRegistration", { enumerable: true, get: function() {
|
|
350053
|
+
return inbox_stamp_js_1.codeSelfProvisionsRegistration;
|
|
350054
|
+
} });
|
|
350055
|
+
Object.defineProperty(exports, "codeUsesTestInboxIdentity", { enumerable: true, get: function() {
|
|
350056
|
+
return inbox_stamp_js_1.codeUsesTestInboxIdentity;
|
|
350057
|
+
} });
|
|
350058
|
+
Object.defineProperty(exports, "codeUsesInboxHelper", { enumerable: true, get: function() {
|
|
350059
|
+
return inbox_stamp_js_1.codeUsesInboxHelper;
|
|
350060
|
+
} });
|
|
349983
350061
|
__exportStar(require_playwright_native(), exports);
|
|
349984
350062
|
__exportStar(require_regression_runner(), exports);
|
|
349985
350063
|
__exportStar(require_snapshot_parser(), exports);
|
|
@@ -350309,7 +350387,7 @@ var require_package4 = __commonJS({
|
|
|
350309
350387
|
"package.json"(exports, module) {
|
|
350310
350388
|
module.exports = {
|
|
350311
350389
|
name: "@validate.qa/runner",
|
|
350312
|
-
version: "1.0.
|
|
350390
|
+
version: "1.0.59",
|
|
350313
350391
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
350314
350392
|
bin: {
|
|
350315
350393
|
"validate-runner": "dist/cli.js"
|
|
@@ -357941,7 +358019,8 @@ async function executeRun(run2, opts, headers, requestLiveBrowserHeartbeat = ()
|
|
|
357941
358019
|
const codeUsesCreds = codeProvided && /TEST_USER_EMAIL|TEST_USER_PASSWORD|__vqaLogin/.test(code);
|
|
357942
358020
|
const tags = Array.isArray(run2.tags) ? run2.tags : [];
|
|
357943
358021
|
const isHallucinationShape = codeProvided && !codeUsesCreds && tags.includes("@inline-login") && !tags.includes("@api");
|
|
357944
|
-
const
|
|
358022
|
+
const selfProvisioningRegisterTest = codeProvided && !codeUsesCreds && tags.includes("@email-verify") && (0, import_runner_core13.codeSelfProvisionsRegistration)(code);
|
|
358023
|
+
const requireCreds = authPlan.needsLoginCreds && !legacyHeaderBypass && !isHallucinationShape && !selfProvisioningRegisterTest;
|
|
357945
358024
|
if (requireCreds && !run2.testVariables?.["TEST_USER_EMAIL"]?.trim()) {
|
|
357946
358025
|
preflightError = "Pre-flight failed: Missing TEST_USER_EMAIL. Tests that log in (tagged @auth, @needs-auth, @api, @auth-cookie-state, @auth-login-cookie, or @auth-login-bearer) require login credentials.";
|
|
357947
358026
|
} else if (requireCreds && !run2.testVariables?.["TEST_USER_PASSWORD"]?.trim()) {
|
package/package.json
CHANGED