@validate.qa/runner 1.0.100 → 1.0.101
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/chunk-2OKZY3WN.mjs +291 -0
- package/dist/{chunk-5P4ANVDY.mjs → chunk-4SZC5ZX3.mjs} +5092 -760
- package/dist/{chunk-2XD63NU5.mjs → chunk-BBTK6OX6.mjs} +567 -84
- package/dist/{chunk-WDXLAZ2J.mjs → chunk-CO5KHIVX.mjs} +3 -2
- package/dist/{chunk-HMUC3DKS.mjs → chunk-CYWHPXNZ.mjs} +2281 -2
- package/dist/{chunk-MAO6ADAO.mjs → chunk-FQUH2PU2.mjs} +1 -1
- package/dist/{chunk-MBKGTELT.mjs → chunk-IGXGSDE3.mjs} +701 -283
- package/dist/{chunk-II7QW7MZ.mjs → chunk-M3VZGHZQ.mjs} +14 -11
- package/dist/{chunk-GIIIVO2W.mjs → chunk-SN3PN4G4.mjs} +151 -11
- package/dist/{chunk-6NIT2CCH.mjs → chunk-TPU42VH2.mjs} +10 -9
- package/dist/{chunk-MHFP3QXU.mjs → chunk-XZUUBMP3.mjs} +1 -1
- package/dist/cli.js +8994 -1015
- package/dist/cli.mjs +211 -170
- package/dist/credential-mcp-server.js +503 -79
- package/dist/credential-mcp-server.mjs +3 -3
- package/dist/discovery-mcp-server.js +654 -87
- package/dist/discovery-mcp-server.mjs +4 -4
- package/dist/dist-VTPBY2C4.mjs +17 -0
- package/dist/inbox-mcp-server.js +496 -73
- package/dist/inbox-mcp-server.mjs +3 -3
- package/dist/route-seed-worker.js +2780 -74
- package/dist/route-seed-worker.mjs +14 -7
- package/dist/run-write-guard-preload.js +1206 -160
- package/dist/run-write-guard-preload.mjs +5 -285
- package/dist/run-write-guard.js +1206 -160
- package/dist/run-write-guard.mjs +3 -3
- package/package.json +3 -3
- package/dist/dist-DFNLMH6L.mjs +0 -16
|
@@ -3304,7 +3304,7 @@ function unescapeQuotedBody(raw) {
|
|
|
3304
3304
|
return raw.replace(/\\(['"`\\])/g, "$1");
|
|
3305
3305
|
}
|
|
3306
3306
|
function extractRoleNameValue(line) {
|
|
3307
|
-
const m = line.match(new RegExp(`getByRole\\s*\\([^,]
|
|
3307
|
+
const m = line.match(new RegExp(`getByRole\\s*\\([^,]{1,200},\\s*\\{[^}]{0,200}?name\\s*:\\s*(?:${QUOTED_BODY}|\\/([^/]*?)\\/)`, "i"));
|
|
3308
3308
|
if (!m)
|
|
3309
3309
|
return null;
|
|
3310
3310
|
const raw = m[1] ?? m[2] ?? m[3];
|
|
@@ -4012,6 +4012,8 @@ function stripCoverageComments(code) {
|
|
|
4012
4012
|
let copyFrom = 0;
|
|
4013
4013
|
let i = 0;
|
|
4014
4014
|
let quote = null;
|
|
4015
|
+
let prev = "";
|
|
4016
|
+
let noRegexBefore = 0;
|
|
4015
4017
|
while (i < code.length) {
|
|
4016
4018
|
const ch = code[i];
|
|
4017
4019
|
if (quote) {
|
|
@@ -4019,12 +4021,24 @@ function stripCoverageComments(code) {
|
|
|
4019
4021
|
i += 2;
|
|
4020
4022
|
continue;
|
|
4021
4023
|
}
|
|
4022
|
-
if (ch === quote || ch === "\n" && quote !== "`")
|
|
4024
|
+
if (ch === quote || ch === "\n" && quote !== "`") {
|
|
4023
4025
|
quote = null;
|
|
4026
|
+
prev = ch === "\n" ? prev : ch;
|
|
4027
|
+
}
|
|
4024
4028
|
i++;
|
|
4025
4029
|
continue;
|
|
4026
4030
|
}
|
|
4027
4031
|
const next = code[i + 1];
|
|
4032
|
+
if (ch === "/" && next !== "*" && next !== "/" && i >= noRegexBefore && (prev === "" || REGEX_PRECEDER2.includes(prev))) {
|
|
4033
|
+
const end = regexLiteralEnd3(code, i);
|
|
4034
|
+
if (end > 0) {
|
|
4035
|
+
i = end;
|
|
4036
|
+
prev = "a";
|
|
4037
|
+
continue;
|
|
4038
|
+
}
|
|
4039
|
+
const eol = code.indexOf("\n", i);
|
|
4040
|
+
noRegexBefore = eol === -1 ? code.length : eol;
|
|
4041
|
+
}
|
|
4028
4042
|
if (ch === "/" && next === "*") {
|
|
4029
4043
|
const end = code.indexOf("*/", i + 2);
|
|
4030
4044
|
const stop = end === -1 ? code.length : end + 2;
|
|
@@ -4043,11 +4057,39 @@ function stripCoverageComments(code) {
|
|
|
4043
4057
|
}
|
|
4044
4058
|
if (ch === '"' || ch === "'" || ch === "`")
|
|
4045
4059
|
quote = ch;
|
|
4060
|
+
if (ch !== " " && ch !== " " && ch !== "\n" && ch !== "\r")
|
|
4061
|
+
prev = ch;
|
|
4046
4062
|
i++;
|
|
4047
4063
|
}
|
|
4048
4064
|
out.push(code.slice(copyFrom));
|
|
4049
4065
|
return out.join("");
|
|
4050
4066
|
}
|
|
4067
|
+
function regexLiteralEnd3(code, start) {
|
|
4068
|
+
let inClass = false;
|
|
4069
|
+
for (let j = start + 1; j < code.length; j++) {
|
|
4070
|
+
const c = code[j];
|
|
4071
|
+
if (c === "\n")
|
|
4072
|
+
return -1;
|
|
4073
|
+
if (c === "\\") {
|
|
4074
|
+
j++;
|
|
4075
|
+
continue;
|
|
4076
|
+
}
|
|
4077
|
+
if (inClass) {
|
|
4078
|
+
if (c === "]")
|
|
4079
|
+
inClass = false;
|
|
4080
|
+
continue;
|
|
4081
|
+
}
|
|
4082
|
+
if (c === "[")
|
|
4083
|
+
inClass = true;
|
|
4084
|
+
else if (c === "/") {
|
|
4085
|
+
let k = j + 1;
|
|
4086
|
+
while (k < code.length && isIdentChar(code[k]))
|
|
4087
|
+
k++;
|
|
4088
|
+
return k;
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
return -1;
|
|
4092
|
+
}
|
|
4051
4093
|
function isIdentChar(ch) {
|
|
4052
4094
|
if (!ch)
|
|
4053
4095
|
return false;
|
|
@@ -4705,7 +4747,7 @@ function assessTitleCoverage(title, code) {
|
|
|
4705
4747
|
const repeatedHit = [...repeated].some((term) => hay.includes(term));
|
|
4706
4748
|
return { covered: hit >= needed || repeatedHit, missingTerms };
|
|
4707
4749
|
}
|
|
4708
|
-
var COVERAGE_STOP_WORDS, MAX_ASSERTION_JOIN_CHARS, MAX_COVERAGE_LINE_CHARS, BLOCK_SCAFFOLD, cachedAssertionInput, cachedAssertionSource, LOCAL_BINDING, ASSERTED_STATUS_RE, MAX_RESOLVED_NAMES_PER_LINE, WORD_CHAR_RE, NOT_CONTAIN_TEXT_RE, PLACE_PHRASE_RE, PLACE_WORD_MIN_CHARS, PLACE_FUNCTION_WORDS, HIDDEN_STATE_TERMS, HIDDEN_ELEMENT_LINE_RE, HIDDEN_LINE_RE, MAX_SHOWN_EARLIER_LINES, SHOWN_EARLIER_LITERAL_RE, SHARED_PREFIX_MIN_CHARS, MAX_SHOWN_EARLIER_LITERALS, VALUE_SHAPE_RE, VALUE_SHAPE_ALL_RE, TITLE_TERM_MIN;
|
|
4750
|
+
var COVERAGE_STOP_WORDS, MAX_ASSERTION_JOIN_CHARS, MAX_COVERAGE_LINE_CHARS, REGEX_PRECEDER2, BLOCK_SCAFFOLD, cachedAssertionInput, cachedAssertionSource, LOCAL_BINDING, ASSERTED_STATUS_RE, MAX_RESOLVED_NAMES_PER_LINE, WORD_CHAR_RE, NOT_CONTAIN_TEXT_RE, PLACE_PHRASE_RE, PLACE_WORD_MIN_CHARS, PLACE_FUNCTION_WORDS, HIDDEN_STATE_TERMS, HIDDEN_ELEMENT_LINE_RE, HIDDEN_LINE_RE, MAX_SHOWN_EARLIER_LINES, SHOWN_EARLIER_LITERAL_RE, SHARED_PREFIX_MIN_CHARS, MAX_SHOWN_EARLIER_LITERALS, VALUE_SHAPE_RE, VALUE_SHAPE_ALL_RE, TITLE_TERM_MIN;
|
|
4709
4751
|
var init_expected_outcome_coverage = __esm({
|
|
4710
4752
|
"../shared/dist/expected-outcome-coverage.js"() {
|
|
4711
4753
|
"use strict";
|
|
@@ -4742,6 +4784,7 @@ var init_expected_outcome_coverage = __esm({
|
|
|
4742
4784
|
]);
|
|
4743
4785
|
MAX_ASSERTION_JOIN_CHARS = 8e3;
|
|
4744
4786
|
MAX_COVERAGE_LINE_CHARS = 2e3;
|
|
4787
|
+
REGEX_PRECEDER2 = "(,=:[!&|?{};+-*%<>~^";
|
|
4745
4788
|
BLOCK_SCAFFOLD = /=>|\b(?:test|describe|it|beforeEach|afterEach|beforeAll|afterAll|function)\b/;
|
|
4746
4789
|
cachedAssertionInput = null;
|
|
4747
4790
|
cachedAssertionSource = { raw: "", normalized: "", bindings: /* @__PURE__ */ new Map(), bindingRefs: /* @__PURE__ */ new Map() };
|
|
@@ -5192,7 +5235,7 @@ function detectsErrorBannerAssertion(code) {
|
|
|
5192
5235
|
const cleaned = stripCommentsAndLogs(stripLoginScaffolding(code));
|
|
5193
5236
|
const lines = cleaned.split("\n");
|
|
5194
5237
|
const candidates = [];
|
|
5195
|
-
const positive = (stmt) => !
|
|
5238
|
+
const positive = (stmt) => !claimsAbsence(stmt);
|
|
5196
5239
|
const statements = liveExpectStatements(cleaned).map((s) => s.stmt);
|
|
5197
5240
|
for (const stmt of statements) {
|
|
5198
5241
|
if (positive(stmt))
|
|
@@ -5321,6 +5364,12 @@ function detectsObservedFailureAsExpected(code) {
|
|
|
5321
5364
|
return FAILURE_STATUS_ASSERT.some((re) => re.test(stmt)) || hasFailedListener && FAILED_LIST_ASSERT.test(stmt);
|
|
5322
5365
|
});
|
|
5323
5366
|
}
|
|
5367
|
+
function claimsAbsence(stmt) {
|
|
5368
|
+
const negated = NEGATED_ASSERT_NOT.test(stmt);
|
|
5369
|
+
const bare = negated ? stmt.replace(NOT_BEFORE_MATCHER, ".") : stmt;
|
|
5370
|
+
const absenceMatcher = /\.toBeHidden\s*\(|\.toHaveCount\s*\(\s*0\s*\)/.test(bare) || VALUE_ABSENCE.test(bare) || OPTION_ABSENCE.test(bare);
|
|
5371
|
+
return negated !== absenceMatcher;
|
|
5372
|
+
}
|
|
5324
5373
|
function isVacuousErrorAbsence(stmt, presence) {
|
|
5325
5374
|
if (!ABSENCE_MATCHER.test(stmt))
|
|
5326
5375
|
return false;
|
|
@@ -5336,19 +5385,53 @@ function isChromeTarget(stmt) {
|
|
|
5336
5385
|
return CHROME_LOCATOR.test(stmt) && !CONTENT_ROLE.test(stmt) && !/getByText\s*\(/.test(stmt);
|
|
5337
5386
|
}
|
|
5338
5387
|
function countsAsContentText(stmt) {
|
|
5339
|
-
if (!TEXT_CONTENT_MATCHER.test(stmt))
|
|
5388
|
+
if (!TEXT_CONTENT_MATCHER.test(stmt) || NEGATED_ASSERT.test(stmt))
|
|
5340
5389
|
return false;
|
|
5341
5390
|
if (isSymbolOnlyArgument(stmt, TEXT_CONTENT_MATCHER))
|
|
5342
5391
|
return false;
|
|
5343
|
-
|
|
5392
|
+
return onContentTarget(stmt);
|
|
5393
|
+
}
|
|
5394
|
+
function onContentTarget(stmt) {
|
|
5395
|
+
return !isChromeTarget(stmt) || /getByRole\s*\(\s*['"`]main['"`]/i.test(stmt);
|
|
5396
|
+
}
|
|
5397
|
+
function provesTextRemoved(stmt, presence) {
|
|
5398
|
+
const m = stmt.match(NEGATED_TEXT);
|
|
5399
|
+
if (!m || !onContentTarget(stmt))
|
|
5400
|
+
return false;
|
|
5401
|
+
const text = m[1] ?? m[2];
|
|
5402
|
+
if (text === void 0)
|
|
5344
5403
|
return true;
|
|
5345
|
-
|
|
5404
|
+
if (!/[\p{L}\p{N}]/u.test(text))
|
|
5405
|
+
return false;
|
|
5406
|
+
return !ERROR_TEXT_WORDS.test(text) || presence().includes(text);
|
|
5346
5407
|
}
|
|
5347
5408
|
function isDataContentRole(stmt) {
|
|
5348
5409
|
return CONTENT_ROLE.test(stmt) && !ANNOUNCE_ROLE.test(stmt);
|
|
5349
5410
|
}
|
|
5411
|
+
function destructuresRequest(code) {
|
|
5412
|
+
let readTo = -1;
|
|
5413
|
+
for (const m of code.matchAll(ASYNC_DESTRUCTURE_OPEN)) {
|
|
5414
|
+
const start = m.index + m[0].length;
|
|
5415
|
+
if (start <= readTo)
|
|
5416
|
+
continue;
|
|
5417
|
+
let end = start;
|
|
5418
|
+
while (end < code.length && code[end] !== "}" && code[end] !== ")")
|
|
5419
|
+
end++;
|
|
5420
|
+
readTo = end;
|
|
5421
|
+
if (end === code.length)
|
|
5422
|
+
return false;
|
|
5423
|
+
if (code[end] !== "}" || !REQUEST_WORD.test(code.slice(start, end)))
|
|
5424
|
+
continue;
|
|
5425
|
+
let close = end + 1;
|
|
5426
|
+
while (close < code.length && /\s/.test(code[close]))
|
|
5427
|
+
close++;
|
|
5428
|
+
if (code[close] === ")")
|
|
5429
|
+
return true;
|
|
5430
|
+
}
|
|
5431
|
+
return false;
|
|
5432
|
+
}
|
|
5350
5433
|
function isApiTest(code) {
|
|
5351
|
-
const usesRequestFixture =
|
|
5434
|
+
const usesRequestFixture = destructuresRequest(code) || /\brequest\.(get|post|put|patch|delete|head|fetch)\s*\(/.test(code);
|
|
5352
5435
|
if (!usesRequestFixture)
|
|
5353
5436
|
return false;
|
|
5354
5437
|
const drivesUi = /\bpage\.(getBy\w+|locator|click|fill|goto|waitForURL|reload)\s*\(/.test(code) || /\.(click|fill|check|uncheck|selectOption|pressSequentially)\s*\(/.test(code);
|
|
@@ -5607,6 +5690,9 @@ function hasOnlyConstantAssertions(code) {
|
|
|
5607
5690
|
const { constant, real } = constantAssertions(code);
|
|
5608
5691
|
return constant.length > 0 && real === 0;
|
|
5609
5692
|
}
|
|
5693
|
+
function envValueKey(name) {
|
|
5694
|
+
return `\0env:${name}`;
|
|
5695
|
+
}
|
|
5610
5696
|
function enteredValues(stmts) {
|
|
5611
5697
|
const values = /* @__PURE__ */ new Map();
|
|
5612
5698
|
const navLines = [];
|
|
@@ -5615,24 +5701,55 @@ function enteredValues(stmts) {
|
|
|
5615
5701
|
navLines.push(startLine);
|
|
5616
5702
|
let m;
|
|
5617
5703
|
ENTERED_VALUE.lastIndex = 0;
|
|
5618
|
-
|
|
5619
|
-
const
|
|
5620
|
-
if (!
|
|
5621
|
-
values.set(value, startLine);
|
|
5622
|
-
|
|
5704
|
+
const add = (value) => {
|
|
5705
|
+
const lines = values.get(value);
|
|
5706
|
+
if (!lines)
|
|
5707
|
+
values.set(value, [startLine]);
|
|
5708
|
+
else if (lines[lines.length - 1] !== startLine)
|
|
5709
|
+
lines.push(startLine);
|
|
5710
|
+
};
|
|
5711
|
+
while (m = ENTERED_VALUE.exec(stmt))
|
|
5712
|
+
add((m[1] ?? m[2] ?? m[3]).toLowerCase());
|
|
5713
|
+
ENTERED_ENV.lastIndex = 0;
|
|
5714
|
+
while (m = ENTERED_ENV.exec(stmt))
|
|
5715
|
+
add(envValueKey(m[1] ?? m[2] ?? m[3] ?? m[4]));
|
|
5623
5716
|
}
|
|
5624
5717
|
return { values, navLines };
|
|
5625
5718
|
}
|
|
5626
|
-
function
|
|
5719
|
+
function countBelow(lines, line) {
|
|
5720
|
+
let lo = 0;
|
|
5721
|
+
let hi = lines.length;
|
|
5722
|
+
while (lo < hi) {
|
|
5723
|
+
const mid = lo + hi >> 1;
|
|
5724
|
+
if (lines[mid] < line)
|
|
5725
|
+
lo = mid + 1;
|
|
5726
|
+
else
|
|
5727
|
+
hi = mid;
|
|
5728
|
+
}
|
|
5729
|
+
return lo;
|
|
5730
|
+
}
|
|
5731
|
+
function enteredLinesOf(stmt, entered) {
|
|
5627
5732
|
const m = stmt.match(/\.toHaveValue\s*\(\s*(['"`])((?:(?!\1).)+)\1/);
|
|
5628
|
-
if (
|
|
5733
|
+
if (m)
|
|
5734
|
+
return entered.values.get(m[2].toLowerCase());
|
|
5735
|
+
const env = stmt.match(HAVE_VALUE_ENV);
|
|
5736
|
+
return env ? entered.values.get(envValueKey(env[1] ?? env[2])) : void 0;
|
|
5737
|
+
}
|
|
5738
|
+
function typedSinceLastNav(stmt, entered, startLine, lines = enteredLinesOf(stmt, entered)) {
|
|
5739
|
+
if (!lines || startLine === void 0)
|
|
5740
|
+
return false;
|
|
5741
|
+
const before = countBelow(lines, startLine);
|
|
5742
|
+
if (before === 0)
|
|
5629
5743
|
return false;
|
|
5630
|
-
|
|
5631
|
-
|
|
5744
|
+
return countBelow(entered.navLines, startLine) === countBelow(entered.navLines, lines[before - 1] + 1);
|
|
5745
|
+
}
|
|
5746
|
+
function isEnteredValueEcho(stmt, entered, startLine) {
|
|
5747
|
+
const lines = enteredLinesOf(stmt, entered);
|
|
5748
|
+
if (!lines)
|
|
5632
5749
|
return false;
|
|
5633
|
-
if (startLine === void 0)
|
|
5750
|
+
if (startLine === void 0 || lines[0] >= startLine)
|
|
5634
5751
|
return true;
|
|
5635
|
-
return
|
|
5752
|
+
return typedSinceLastNav(stmt, entered, startLine, lines);
|
|
5636
5753
|
}
|
|
5637
5754
|
function isAnyValueMatcher(stmt) {
|
|
5638
5755
|
if (/\.not\.toHaveValue\s*\(\s*(?:['"`]{2}|\/\^?\$?\/)/.test(stmt))
|
|
@@ -5722,6 +5839,43 @@ function hasAttributeTransition(stmts) {
|
|
|
5722
5839
|
return true;
|
|
5723
5840
|
return false;
|
|
5724
5841
|
}
|
|
5842
|
+
function comparesWithItself(subject, tail) {
|
|
5843
|
+
const m = SELF_COMPARE_MATCHER.exec(tail);
|
|
5844
|
+
if (!m)
|
|
5845
|
+
return false;
|
|
5846
|
+
const args = balancedArguments(tail, m[0].length, MATCHER_ARGS_MAX);
|
|
5847
|
+
if (args === null)
|
|
5848
|
+
return false;
|
|
5849
|
+
const squash2 = (x) => x.replace(/^\s*await\s+/, "").replace(/\s+/g, "");
|
|
5850
|
+
const expected = squash2(args);
|
|
5851
|
+
return expected === squash2(m[1] === "toHaveCount" ? `${subject}.count()` : subject);
|
|
5852
|
+
}
|
|
5853
|
+
function asPlainAssertion(s) {
|
|
5854
|
+
const { stmt } = s;
|
|
5855
|
+
if (COUNT_AT_LEAST_ZERO.test(stmt))
|
|
5856
|
+
return [];
|
|
5857
|
+
const subject = extractExpectSubject(stmt);
|
|
5858
|
+
if (subject === null)
|
|
5859
|
+
return [s];
|
|
5860
|
+
const plain = subject.replace(/^await\s+/, "").trim();
|
|
5861
|
+
const subjectAt = stmt.indexOf(subject, stmt.search(EXPECT_CALL_RE));
|
|
5862
|
+
const tail = stmt.slice(subjectAt + subject.length).trimStart();
|
|
5863
|
+
const as = (rewritten) => [{ ...s, stmt: rewritten }];
|
|
5864
|
+
if (LOCATOR_EXPR.test(plain) && !LOCATOR_VALUE_READ.test(plain) && ALWAYS_TRUE_ON_OBJECT.test(tail))
|
|
5865
|
+
return [];
|
|
5866
|
+
if (DEFINED_VALUE_READ.test(plain) && ALWAYS_DEFINED.test(tail))
|
|
5867
|
+
return [];
|
|
5868
|
+
if (comparesWithItself(plain, tail))
|
|
5869
|
+
return [];
|
|
5870
|
+
const visible = /^(.+)\.\s*isVisible\s*\(\s*\)$/s.exec(plain);
|
|
5871
|
+
if (visible && IS_VISIBLE_TRUE.test(tail))
|
|
5872
|
+
return as(`await expect(${visible[1]}).toBeVisible();`);
|
|
5873
|
+
if (/^page\s*\.\s*(?:url|title)\s*\(\s*\)$/.test(plain) && PAGE_VALUE_MATCHER.test(tail)) {
|
|
5874
|
+
const matcher = plain.includes("url") ? "toHaveURL" : "toHaveTitle";
|
|
5875
|
+
return as(`await expect(page)${tail.replace(/^\)\s*\.\s*\w+\s*\(/, `.${matcher}(`)}`);
|
|
5876
|
+
}
|
|
5877
|
+
return [s];
|
|
5878
|
+
}
|
|
5725
5879
|
function creditsOutcomeAlways(stmt, entered, startLine) {
|
|
5726
5880
|
if (!OUTCOME_ALWAYS.some((re) => re.test(stmt)))
|
|
5727
5881
|
return false;
|
|
@@ -5795,6 +5949,8 @@ function classifyOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstM
|
|
|
5795
5949
|
continue;
|
|
5796
5950
|
if (isVacuousErrorAbsence(stmt, presence))
|
|
5797
5951
|
continue;
|
|
5952
|
+
if (COUNT_ONE.test(stmt) && quotedAssertedStrings(stmt).some((t) => clicked.has(t.toLowerCase())))
|
|
5953
|
+
continue;
|
|
5798
5954
|
if (creditsOutcomeAlways(stmt, entered, startLine))
|
|
5799
5955
|
return { kind: "durable" };
|
|
5800
5956
|
if (mutated && !NEGATED_ASSERT.test(stmt) && MESSAGE_SURFACE.test(stmt) && OUTCOME_TEXT.test(assertedText(stmt))) {
|
|
@@ -5804,12 +5960,15 @@ function classifyOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstM
|
|
|
5804
5960
|
else
|
|
5805
5961
|
return { kind: "durable" };
|
|
5806
5962
|
}
|
|
5807
|
-
|
|
5963
|
+
const retyped = typedSinceLastNav(stmt, entered, startLine);
|
|
5964
|
+
if (!retyped && STATE_MATCHER.test(stmt) && (persistence && startLine !== void 0 ? reopenedAfterSave(startLine, persistence, persistence.reloadCalls) : reloaded))
|
|
5808
5965
|
return { kind: "durable" };
|
|
5809
|
-
if (provesStoredControlValue(stmt, startLine, persistence))
|
|
5966
|
+
if (!retyped && provesStoredControlValue(stmt, startLine, persistence))
|
|
5810
5967
|
return { kind: "durable" };
|
|
5811
5968
|
if (countsAsContentText(stmt))
|
|
5812
5969
|
return { kind: "durable" };
|
|
5970
|
+
if (provesTextRemoved(stmt, presence))
|
|
5971
|
+
return { kind: "durable" };
|
|
5813
5972
|
if (mutated && VISIBILITY_MATCHER.test(stmt)) {
|
|
5814
5973
|
const revealsText = GET_BY_TEXT.test(stmt) || HAS_TEXT_FILTER.test(stmt) || CONTENT_ROLE.test(stmt);
|
|
5815
5974
|
if (revealsText && !isChromeTarget(stmt)) {
|
|
@@ -5876,7 +6035,7 @@ function detectOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstMut
|
|
|
5876
6035
|
function validateAssertionStrength(code, opts = {}) {
|
|
5877
6036
|
const body = stripLoginScaffolding(code);
|
|
5878
6037
|
const lines = body.split("\n");
|
|
5879
|
-
const stmts = liveExpectStatements(stripCoverageComments(body));
|
|
6038
|
+
const stmts = liveExpectStatements(stripCoverageComments(body)).flatMap(asPlainAssertion);
|
|
5880
6039
|
const base2 = (extra) => ({
|
|
5881
6040
|
apiTest: false,
|
|
5882
6041
|
interacted: false,
|
|
@@ -6082,7 +6241,7 @@ function validateAssertionStrength(code, opts = {}) {
|
|
|
6082
6241
|
signals
|
|
6083
6242
|
};
|
|
6084
6243
|
}
|
|
6085
|
-
var ERROR_BANNER, OUTCOME_ALWAYS, FORM_INPUT, ANY_CLICK, NAV_LOCATOR, URL_PROOF, RELOAD, EXPECT_STMT, BLOCK_SCAFFOLD2, TEST_BLOCK_OPEN, LOCATOR_BINDING, EXPECT_OPEN, STATE_MATCHER, CHROME_LOCATOR, CONTENT_ROLE, GET_BY_TEXT, BARE_CONTAINER_ROLE, HAS_TEXT_FILTER, OUTCOME_TEXT, SUCCESS_NOTICE_TEXT, NOT_A_SUCCESS_NOTICE, ANNOUNCE_ROLE, MESSAGE_SURFACE, TEXT_CONTENT_MATCHER, VISIBILITY_MATCHER, ADDITIVE_AFFORDANCE, EXCLUDE_AFFORDANCE, EMPTY_STATE_TEXT, AUTH_START, AUTH_END, LOGIN_CALL_LINE, INBOX_START, INBOX_END, NEGATED_ASSERT, CONST_CHAIN_MAX_DEPTH, TYPED_INPUT, TITLE_LINE, FAILURE_STATUS_ASSERT, FAILED_LIST_ASSERT, ENDPOINT_DOWN, NAVIGATION_RESPONSE_VAR, DIRECT_REQUEST_VAR, CATCH_ALL_PATTERN, GUARD_HANDLER, ABSENCE_MATCHER, ERROR_TEXT_WORDS, TEXT_REGEX_ARG, ROLE_NAME_RE, INTERACT_VERB, ROLE_SIG_RE, TRANSIENT_CONTROL_ROLES, POLL_CALLBACK, CONSTANT_WORD, CONSTANT_GLUE_CHARS, WORD_CHAR, MATCHER_ARGS_MAX, MATCHER_OPEN, ENTERED_VALUE, PAGE_NAV, IN_FLIGHT_TEXT, FORM_CONTROL_LOCATOR, CONTROL_VALUE_MATCHER, COPY_CONTROL, COPIED_NOTICE, SEND_CONTROL, SEND_NOTICE, MARK_READ_CONTROL, APP_DATA_FIELD;
|
|
6244
|
+
var ERROR_BANNER, OUTCOME_ALWAYS, FORM_INPUT, ANY_CLICK, NAV_LOCATOR, URL_PROOF, RELOAD, EXPECT_STMT, BLOCK_SCAFFOLD2, TEST_BLOCK_OPEN, LOCATOR_BINDING, EXPECT_OPEN, STATE_MATCHER, CHROME_LOCATOR, CONTENT_ROLE, GET_BY_TEXT, BARE_CONTAINER_ROLE, HAS_TEXT_FILTER, OUTCOME_TEXT, SUCCESS_NOTICE_TEXT, NOT_A_SUCCESS_NOTICE, ANNOUNCE_ROLE, MESSAGE_SURFACE, TEXT_CONTENT_MATCHER, VISIBILITY_MATCHER, ADDITIVE_AFFORDANCE, EXCLUDE_AFFORDANCE, EMPTY_STATE_TEXT, AUTH_START, AUTH_END, LOGIN_CALL_LINE, INBOX_START, INBOX_END, NEGATED_ASSERT, NEGATED_ASSERT_NOT, CONST_CHAIN_MAX_DEPTH, TYPED_INPUT, TITLE_LINE, FAILURE_STATUS_ASSERT, FAILED_LIST_ASSERT, ENDPOINT_DOWN, NAVIGATION_RESPONSE_VAR, DIRECT_REQUEST_VAR, CATCH_ALL_PATTERN, GUARD_HANDLER, ABSENCE_MATCHER, VALUE_ABSENCE, OPTION_ABSENCE, NOT_BEFORE_MATCHER, ERROR_TEXT_WORDS, TEXT_REGEX_ARG, NEGATED_TEXT, ASYNC_DESTRUCTURE_OPEN, REQUEST_WORD, ROLE_NAME_RE, INTERACT_VERB, ROLE_SIG_RE, TRANSIENT_CONTROL_ROLES, POLL_CALLBACK, CONSTANT_WORD, CONSTANT_GLUE_CHARS, WORD_CHAR, MATCHER_ARGS_MAX, MATCHER_OPEN, ENTERED_VALUE, PAGE_NAV, ENV_READ, ENTERED_ENV, HAVE_VALUE_ENV, IN_FLIGHT_TEXT, LOCATOR_VALUE_READ, LOCATOR_EXPR, ALWAYS_TRUE_ON_OBJECT, COUNT_AT_LEAST_ZERO, DEFINED_VALUE_READ, ALWAYS_DEFINED, SELF_COMPARE_MATCHER, IS_VISIBLE_TRUE, PAGE_VALUE_MATCHER, COUNT_ONE, FORM_CONTROL_LOCATOR, CONTROL_VALUE_MATCHER, COPY_CONTROL, COPIED_NOTICE, SEND_CONTROL, SEND_NOTICE, MARK_READ_CONTROL, APP_DATA_FIELD;
|
|
6086
6245
|
var init_assertion_strength = __esm({
|
|
6087
6246
|
"../shared/dist/assertion-strength.js"() {
|
|
6088
6247
|
"use strict";
|
|
@@ -6107,8 +6266,8 @@ var init_assertion_strength = __esm({
|
|
|
6107
6266
|
// form field value
|
|
6108
6267
|
/\.toMatch\s*\(/,
|
|
6109
6268
|
// string/regex content match (e.g. textContent() vs /[2-9] selected/)
|
|
6110
|
-
|
|
6111
|
-
// a control became DISABLED — a gating/validation outcome
|
|
6269
|
+
/(?<!\.not\s*)\.\s*toBeDisabled\s*\(/,
|
|
6270
|
+
// a control became DISABLED — a gating/validation outcome (not.toBeDisabled is the toBeEnabled twin)
|
|
6112
6271
|
/\.not\.toBeVisible\s*\(/,
|
|
6113
6272
|
/\.toBeHidden\s*\(/
|
|
6114
6273
|
// something the action removed/closed (disappearance proof)
|
|
@@ -6116,7 +6275,7 @@ var init_assertion_strength = __esm({
|
|
|
6116
6275
|
FORM_INPUT = /\.(fill|selectOption|setInputFiles|check|uncheck|setChecked|pressSequentially)\s*\(|keyboard\.type\s*\(/;
|
|
6117
6276
|
ANY_CLICK = /\.click\s*\(/;
|
|
6118
6277
|
NAV_LOCATOR = /getByRole\s*\(\s*['"`](?:link|menuitem)['"`]/i;
|
|
6119
|
-
URL_PROOF = /\.toHaveURL\s*\(|\.waitForURL\s*\(/;
|
|
6278
|
+
URL_PROOF = /\.toHaveURL\s*\(|\.waitForURL\s*\(|\bexpect\s*\(\s*(?:await\s+)?page\s*\.\s*url\s*\(\s*\)\s*\)|\bexpect\s*\.\s*poll\s*\(\s*(?:async\s*)?\(\s*\)\s*=>\s*(?:\{\s*return\s+)?page\s*\.\s*url\s*\(\s*\)/;
|
|
6120
6279
|
RELOAD = /\.reload\s*\(/;
|
|
6121
6280
|
EXPECT_STMT = /\bexpect\s*[.(]/;
|
|
6122
6281
|
BLOCK_SCAFFOLD2 = /=>|\b(?:test|describe|it|beforeEach|afterEach|beforeAll|afterAll|function)\b/;
|
|
@@ -6145,6 +6304,7 @@ var init_assertion_strength = __esm({
|
|
|
6145
6304
|
INBOX_START = /^\s*\/\/\s*>>>\s*VALIDATE_QA_INBOX/;
|
|
6146
6305
|
INBOX_END = /^\s*\/\/\s*<<<\s*VALIDATE_QA_INBOX/;
|
|
6147
6306
|
NEGATED_ASSERT = /\.not\s*\.\s*to[A-Z]\w*|\.toBeHidden\s*\(/;
|
|
6307
|
+
NEGATED_ASSERT_NOT = /\.not\s*\.\s*to[A-Z]/;
|
|
6148
6308
|
CONST_CHAIN_MAX_DEPTH = 5;
|
|
6149
6309
|
TYPED_INPUT = /\.(fill|type|pressSequentially|setInputFiles)\s*\(/;
|
|
6150
6310
|
TITLE_LINE = /^\s*(?:test|describe)(?:\.\w+)?\s*\(/;
|
|
@@ -6160,8 +6320,14 @@ var init_assertion_strength = __esm({
|
|
|
6160
6320
|
CATCH_ALL_PATTERN = /^(['"`])\*\*(?:\/\*)?\1$|^\/\.\*\/[a-z]*$/;
|
|
6161
6321
|
GUARD_HANDLER = /\bMUTATING\.has\s*\(|blockedbyclient|Read-only guard/;
|
|
6162
6322
|
ABSENCE_MATCHER = /\.not\.toBeVisible\s*\(|\.toBeHidden\s*\(|\.toHaveCount\s*\(\s*0\s*\)/;
|
|
6323
|
+
VALUE_ABSENCE = /\.(?:count\s*\(\s*\)[\s)]{0,10}\.(?:(?:toBe|toEqual|toStrictEqual)\s*\(\s*0\s*\)|toBeLessThan\s*\(\s*1\s*\))|isVisible\s*\(\s*\)[\s)]{0,10}\.(?:(?:toBe|toEqual|toStrictEqual)\s*\(\s*false\s*\)|toBeFalsy\s*\()|isHidden\s*\(\s*\)[\s)]{0,10}\.(?:(?:toBe|toEqual|toStrictEqual)\s*\(\s*true\s*\)|toBeTruthy\s*\())/;
|
|
6324
|
+
OPTION_ABSENCE = /\.(?:toBeVisible\s*\(\s*\{[^{}()]{0,200}\bvisible|toBeAttached\s*\(\s*\{[^{}()]{0,200}\battached)\s*:\s*false\b/;
|
|
6325
|
+
NOT_BEFORE_MATCHER = /\.not\s*\.\s*(?=to[A-Z])/g;
|
|
6163
6326
|
ERROR_TEXT_WORDS = /error|fail|wrong|try again|unable|could ?n.?t|can.?t|problem|invalid|unavailable/i;
|
|
6164
6327
|
TEXT_REGEX_ARG = /(?:getByText|hasText|getByRole\([^)]{0,200}name)\s*[:(]\s*(\/(?:\\.|[^/\\\n])+\/[a-z]*)/;
|
|
6328
|
+
NEGATED_TEXT = /\.not\s*\.\s*(?:toHaveText|toContainText)\s*\(\s*(?:['"`]([^'"`]*)['"`]|\/((?:\\.|[^/\\\n])+)\/)?/;
|
|
6329
|
+
ASYNC_DESTRUCTURE_OPEN = /async\s*\(\s*\{/g;
|
|
6330
|
+
REQUEST_WORD = /\brequest\b/;
|
|
6165
6331
|
ROLE_NAME_RE = /getByRole\s*\(\s*['"`][a-z]+['"`]\s*,\s*\{[^}]*?name\s*:\s*(?:['"`]([^'"`]+)['"`]|\/([^/]+)\/)/gi;
|
|
6166
6332
|
INTERACT_VERB = /\.(click|fill|check|uncheck|setChecked|selectOption|pressSequentially)\s*\(/;
|
|
6167
6333
|
ROLE_SIG_RE = /getByRole\s*\(\s*['"`]([a-z]+)['"`]\s*,\s*\{[^}]*?name\s*:\s*(?:['"`]([^'"`]+)['"`]|\/([^/]+)\/)/gi;
|
|
@@ -6182,7 +6348,20 @@ var init_assertion_strength = __esm({
|
|
|
6182
6348
|
MATCHER_OPEN = /\s*(?:\.\s*(?:not|resolves|rejects)\s*)*\.\s*[A-Za-z_$][\w$]*\s*\(/y;
|
|
6183
6349
|
ENTERED_VALUE = /\.(?:fill|pressSequentially)\s*\(\s*['"`]([^'"`]+)['"`]|keyboard\.type\s*\(\s*['"`]([^'"`]+)['"`]|\.selectOption\s*\(\s*(?:\[\s*)?(?:\{\s*(?:label|value)\s*:\s*)?['"`]([^'"`]+)['"`]/g;
|
|
6184
6350
|
PAGE_NAV = /\.(?:goto|reload)\s*\(/;
|
|
6351
|
+
ENV_READ = String.raw`process\.env(?:(?:\?\.|\.)([A-Za-z_]\w*)|(?:\?\.)?\[\s*['"]([A-Za-z_]\w*)['"]\s*\])`;
|
|
6352
|
+
ENTERED_ENV = new RegExp(String.raw`\.(?:fill|pressSequentially)\s*\(\s*${ENV_READ}|keyboard\.type\s*\(\s*${ENV_READ}`, "g");
|
|
6353
|
+
HAVE_VALUE_ENV = new RegExp(String.raw`\.toHaveValue\s*\(\s*${ENV_READ}`);
|
|
6185
6354
|
IN_FLIGHT_TEXT = /^(?:(?:sending|saving|loading|searching|checking|processing|submitting|preparing|updating|please wait|working|one moment)\b[^.]{0,40}\.{2,3}|\.{3}|…)$/i;
|
|
6355
|
+
LOCATOR_VALUE_READ = /\.(?:count|textContent|innerText|innerHTML|inputValue|getAttribute|isVisible|isHidden|isChecked|isEnabled|isDisabled|isEditable|allTextContents|allInnerTexts|evaluate|evaluateAll|boundingBox|all)\s*\(/;
|
|
6356
|
+
LOCATOR_EXPR = /^(?:this\.)?page\s*\.\s*(?:getBy\w+|locator)\s*\(/;
|
|
6357
|
+
ALWAYS_TRUE_ON_OBJECT = /^\)\s*\.\s*(?:toBeTruthy|toBeDefined|not\s*\.\s*(?:toBeNull|toBeUndefined|toBeFalsy))\s*\(/;
|
|
6358
|
+
COUNT_AT_LEAST_ZERO = /\.(?:count\s*\(\s*\)|length)[\s)]{0,10}\.(?:toBeGreaterThanOrEqual\s*\(\s*0\s*\)|toBeGreaterThan\s*\(\s*-\s*1\s*\))/;
|
|
6359
|
+
DEFINED_VALUE_READ = /\.\s*(?:count|textContent|innerText|innerHTML|inputValue|getAttribute|title|url|isVisible|isHidden|isChecked|isEnabled|isDisabled|isEditable|allTextContents|allInnerTexts)\s*\([^()]*\)$/;
|
|
6360
|
+
ALWAYS_DEFINED = /^\)\s*\.\s*(?:toBeDefined|not\s*\.\s*toBeUndefined)\s*\(/;
|
|
6361
|
+
SELF_COMPARE_MATCHER = /^\)\s*\.\s*(toBe|toEqual|toStrictEqual|toHaveCount)\s*\(/;
|
|
6362
|
+
IS_VISIBLE_TRUE = /^\)*\s*\.\s*(?:toBe\s*\(\s*true\s*\)|toBeTruthy\s*\(\s*\))/;
|
|
6363
|
+
PAGE_VALUE_MATCHER = /^\)\s*\.\s*(?:toBe|toEqual|toStrictEqual|toMatch|toContain)\s*\(/;
|
|
6364
|
+
COUNT_ONE = /\.\s*toHaveCount\s*\(\s*1\s*\)/;
|
|
6186
6365
|
FORM_CONTROL_LOCATOR = /getByRole\s*\(\s*['"`](?:combobox|switch|checkbox|radio|textbox|searchbox|spinbutton|slider)['"`]|getByLabel\s*\(|getByPlaceholder\s*\(/;
|
|
6187
6366
|
CONTROL_VALUE_MATCHER = /\.(?:toHaveValue|toHaveText|toContainText)\s*\(|\.toHaveAttribute\s*\(\s*['"`]aria-checked['"`]/;
|
|
6188
6367
|
COPY_CONTROL = /\bcopy\b/i;
|
|
@@ -6391,7 +6570,7 @@ function reportedBugWhere() {
|
|
|
6391
6570
|
function bugReviewStatus(status) {
|
|
6392
6571
|
return status === "QUARANTINED" ? "confirmed" : "needs-review";
|
|
6393
6572
|
}
|
|
6394
|
-
var USER_CANCELLED_RUN_ERROR, HEAL_PATCH_HELD_RUN_ERROR_PREFIX, RUNNER_INTERRUPT_ERROR_PREFIX, SERVER_INTERRUPT_ERROR_PREFIX, RUN_LOST_ERROR_PREFIX, RUN_INTERRUPTED_ERROR_PREFIXES, RUN_INTERRUPTION_RETRIED_MARKER, RUN_INTERRUPTION_NOT_RETRIED_MARKERS, BUG_ASSERTION_TAG, UNEXPECTED_PASS_ERROR_PREFIX, BUG_TEST_BROKEN_ERROR_PREFIX, BUG_TEST_BROKEN_REASON, EMAIL_NOT_RECEIVED_PREFIXES, ENVIRONMENTAL_ERROR_PREFIXES, ENVIRONMENTAL_ERROR_STORED_PREFIXES, BUG_SURFACE_SUPPRESSING_TAGS, QUARANTINE_CLOSE_TAGS, BUG_CANDIDATE_TAG, BUG_TEST_BROKEN_TAG;
|
|
6573
|
+
var USER_CANCELLED_RUN_ERROR, HEAL_PATCH_HELD_RUN_ERROR_PREFIX, RUNNER_INTERRUPT_ERROR_PREFIX, SERVER_INTERRUPT_ERROR_PREFIX, RUN_LOST_ERROR_PREFIX, RUN_INTERRUPTED_ERROR_PREFIXES, RUN_INTERRUPTION_RETRIED_MARKER, RUN_INTERRUPTION_NOT_RETRIED_MARKERS, BUG_ASSERTION_TAG, UNEXPECTED_PASS_ERROR_PREFIX, BUG_TEST_BROKEN_ERROR_PREFIX, BUG_TEST_BROKEN_REASON, TEST_DID_NOT_RUN_ERROR, EMAIL_NOT_RECEIVED_PREFIXES, ENVIRONMENTAL_ERROR_PREFIXES, ENVIRONMENTAL_ERROR_STORED_PREFIXES, BUG_SURFACE_SUPPRESSING_TAGS, QUARANTINE_CLOSE_TAGS, BUG_CANDIDATE_TAG, BUG_TEST_BROKEN_TAG;
|
|
6395
6574
|
var init_run_classification = __esm({
|
|
6396
6575
|
"../shared/dist/run-classification.js"() {
|
|
6397
6576
|
"use strict";
|
|
@@ -6411,6 +6590,7 @@ var init_run_classification = __esm({
|
|
|
6411
6590
|
UNEXPECTED_PASS_ERROR_PREFIX = "UNEXPECTED_PASS:";
|
|
6412
6591
|
BUG_TEST_BROKEN_ERROR_PREFIX = "BUG_TEST_BROKEN:";
|
|
6413
6592
|
BUG_TEST_BROKEN_REASON = "bug test broken (not a bug verdict)";
|
|
6593
|
+
TEST_DID_NOT_RUN_ERROR = "Test did not run (a dependency failed or the run was interrupted)";
|
|
6414
6594
|
EMAIL_NOT_RECEIVED_PREFIXES = [
|
|
6415
6595
|
"VERIFICATION_EMAIL_NOT_RECEIVED:",
|
|
6416
6596
|
"VERIFICATION_EMAIL_HAS_NO_CODE:",
|
|
@@ -9152,6 +9332,23 @@ var init_auth_block_detector = __esm({
|
|
|
9152
9332
|
}
|
|
9153
9333
|
});
|
|
9154
9334
|
|
|
9335
|
+
// ../shared/dist/auth-session-stamp.js
|
|
9336
|
+
function parseAuthSessionStamp(value) {
|
|
9337
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
9338
|
+
return null;
|
|
9339
|
+
const { shared, role, generation } = value;
|
|
9340
|
+
if (shared !== true || role !== "producer" && role !== "follower")
|
|
9341
|
+
return null;
|
|
9342
|
+
return typeof generation === "string" && AUTH_SESSION_GENERATION_RE.test(generation) ? { shared: true, role, generation } : { shared: true, role };
|
|
9343
|
+
}
|
|
9344
|
+
var AUTH_SESSION_GENERATION_RE;
|
|
9345
|
+
var init_auth_session_stamp = __esm({
|
|
9346
|
+
"../shared/dist/auth-session-stamp.js"() {
|
|
9347
|
+
"use strict";
|
|
9348
|
+
AUTH_SESSION_GENERATION_RE = /^[0-9a-z]{1,16}$/;
|
|
9349
|
+
}
|
|
9350
|
+
});
|
|
9351
|
+
|
|
9155
9352
|
// ../shared/dist/auth-state-freshness.js
|
|
9156
9353
|
function isCsrfTokenName(name) {
|
|
9157
9354
|
return /csrf|xsrf|forgery|authenticity|requestverification/.test(name.toLowerCase());
|
|
@@ -10380,7 +10577,7 @@ var init_agentic_cli_runtime = __esm({
|
|
|
10380
10577
|
GROK_CLI_DEFAULT_MODEL = "grok-4.7";
|
|
10381
10578
|
GROK_CLI_DEFAULT_REASONING_EFFORT = "high";
|
|
10382
10579
|
CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5-5";
|
|
10383
|
-
CLAUDE_CLI_DEFAULT_EFFORT = "
|
|
10580
|
+
CLAUDE_CLI_DEFAULT_EFFORT = "high";
|
|
10384
10581
|
MUSE_CLI_DEFAULT_MODEL = "muse-spark-1.3-contributor";
|
|
10385
10582
|
MUSE_CLI_DEFAULT_EFFORT = "high";
|
|
10386
10583
|
CODEX_CLI_DEFAULT_MODEL = "gpt-6.1-sol";
|
|
@@ -10431,9 +10628,25 @@ function isOpenCodeGoModelId(id) {
|
|
|
10431
10628
|
function hasOpenCodeGoPrefix(id) {
|
|
10432
10629
|
return (id?.trim() ?? "").startsWith(OPENCODE_GO_PREFIX);
|
|
10433
10630
|
}
|
|
10631
|
+
function hasOpenCodeGo2Prefix(id) {
|
|
10632
|
+
return (id?.trim() ?? "").startsWith(OPENCODE_GO_2_PREFIX);
|
|
10633
|
+
}
|
|
10434
10634
|
function openCodeGoWireModel(id) {
|
|
10435
10635
|
const trimmed = id?.trim() ?? "";
|
|
10436
|
-
|
|
10636
|
+
if (!isOpenCodeGoModelId(trimmed))
|
|
10637
|
+
return null;
|
|
10638
|
+
return trimmed.slice((hasOpenCodeGo2Prefix(trimmed) ? OPENCODE_GO_2_PREFIX : OPENCODE_GO_PREFIX).length);
|
|
10639
|
+
}
|
|
10640
|
+
function isZaiModelId(id) {
|
|
10641
|
+
const trimmed = id?.trim() ?? "";
|
|
10642
|
+
return ZAI_MODEL_PATTERN.test(trimmed) && !trimmed.includes("..");
|
|
10643
|
+
}
|
|
10644
|
+
function hasZaiPrefix(id) {
|
|
10645
|
+
return (id?.trim() ?? "").startsWith(ZAI_PREFIX);
|
|
10646
|
+
}
|
|
10647
|
+
function zaiWireModel(id) {
|
|
10648
|
+
const trimmed = id?.trim() ?? "";
|
|
10649
|
+
return isZaiModelId(trimmed) ? trimmed.slice(ZAI_PREFIX.length) : null;
|
|
10437
10650
|
}
|
|
10438
10651
|
function isEngineId(value) {
|
|
10439
10652
|
return CLI_ENGINE_MODEL_IDS.includes(value);
|
|
@@ -10531,7 +10744,7 @@ function museCliContributorMode(env = process.env) {
|
|
|
10531
10744
|
const raw = (env.MUSE_CLI_CONTRIBUTOR_MODE ?? "").trim().toLowerCase();
|
|
10532
10745
|
return raw === "off" || raw === "false" || raw === "0" || raw === "no" ? "off" : "on";
|
|
10533
10746
|
}
|
|
10534
|
-
var CLI_ENGINE_MODEL_IDS, BROWSER_CLI_ENGINE_IDS, PIPELINE_STEPS, CLI_ENGINE_RULES, ENGINE_NAMES, OPENROUTER_PREFIX, OPENROUTER_MODEL_PATTERN, OPENCODE_GO_PREFIX, OPENCODE_GO_MODEL_PATTERN;
|
|
10747
|
+
var CLI_ENGINE_MODEL_IDS, BROWSER_CLI_ENGINE_IDS, PIPELINE_STEPS, CLI_ENGINE_RULES, ENGINE_NAMES, OPENROUTER_PREFIX, OPENROUTER_MODEL_PATTERN, OPENCODE_GO_PREFIX, OPENCODE_GO_2_PREFIX, OPENCODE_GO_MODEL_PATTERN, ZAI_PREFIX, ZAI_MODEL_PATTERN;
|
|
10535
10748
|
var init_engine_spec = __esm({
|
|
10536
10749
|
"../shared/dist/engine-spec.js"() {
|
|
10537
10750
|
"use strict";
|
|
@@ -10590,7 +10803,10 @@ var init_engine_spec = __esm({
|
|
|
10590
10803
|
OPENROUTER_PREFIX = "openrouter:";
|
|
10591
10804
|
OPENROUTER_MODEL_PATTERN = /^openrouter:[a-z0-9][a-z0-9._-]{0,40}\/[A-Za-z0-9._:-]{1,100}$/;
|
|
10592
10805
|
OPENCODE_GO_PREFIX = "opencode-go:";
|
|
10593
|
-
|
|
10806
|
+
OPENCODE_GO_2_PREFIX = "opencode-go-2:";
|
|
10807
|
+
OPENCODE_GO_MODEL_PATTERN = /^opencode-go(?:-2)?:[a-z0-9][a-z0-9._-]{0,100}$/;
|
|
10808
|
+
ZAI_PREFIX = "zai:";
|
|
10809
|
+
ZAI_MODEL_PATTERN = /^zai:glm-[a-z0-9][a-z0-9._-]{0,60}$/;
|
|
10594
10810
|
}
|
|
10595
10811
|
});
|
|
10596
10812
|
|
|
@@ -10875,6 +11091,8 @@ var init_api_model_catalog = __esm({
|
|
|
10875
11091
|
authCaptureModel: "Login capture",
|
|
10876
11092
|
plannerModel: "Scenario Planner",
|
|
10877
11093
|
plannerGateModel: "Planner Gate",
|
|
11094
|
+
pwAgentsHealerModel: "Test Healer (Playwright agents)",
|
|
11095
|
+
pwAgentsReviewModel: "Plan Review (Playwright agents)",
|
|
10878
11096
|
generationModel: "Code Generation",
|
|
10879
11097
|
reviewModel: "Code Review",
|
|
10880
11098
|
apiTestModel: "API Test Generator",
|
|
@@ -10899,11 +11117,6 @@ var init_api_model_catalog = __esm({
|
|
|
10899
11117
|
});
|
|
10900
11118
|
|
|
10901
11119
|
// ../shared/dist/provider-chains.js
|
|
10902
|
-
function isClaudeModel(id) {
|
|
10903
|
-
if (/claude|anthropic/i.test(id))
|
|
10904
|
-
return true;
|
|
10905
|
-
return API_MODEL_CATALOG.some((m) => m.provider === "anthropic" && (m.id === id || m.apiModel === id));
|
|
10906
|
-
}
|
|
10907
11120
|
function chainKey(modelId) {
|
|
10908
11121
|
const id = canonicalModelId(modelId);
|
|
10909
11122
|
if (!id)
|
|
@@ -10911,34 +11124,83 @@ function chainKey(modelId) {
|
|
|
10911
11124
|
const entry = API_MODEL_CATALOG.find((m) => m.id === id || m.apiModel === id);
|
|
10912
11125
|
return entry?.id ?? id;
|
|
10913
11126
|
}
|
|
11127
|
+
function has(map2, key) {
|
|
11128
|
+
return Object.prototype.hasOwnProperty.call(map2, key);
|
|
11129
|
+
}
|
|
10914
11130
|
function providerChainFor(modelId) {
|
|
10915
11131
|
const key = chainKey(modelId);
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
11132
|
+
return key && has(PROVIDER_CHAINS, key) ? PROVIDER_CHAINS[key] : [];
|
|
11133
|
+
}
|
|
11134
|
+
function providerChainLeadsFor(modelId) {
|
|
11135
|
+
const key = chainKey(modelId);
|
|
11136
|
+
return key && has(PROVIDER_CHAIN_LEADS, key) ? PROVIDER_CHAIN_LEADS[key] : [];
|
|
11137
|
+
}
|
|
11138
|
+
function allChains() {
|
|
11139
|
+
return [...Object.entries(PROVIDER_CHAINS), ...Object.entries(PROVIDER_CHAIN_LEADS)];
|
|
10919
11140
|
}
|
|
10920
11141
|
function isProviderChainHopId(modelId) {
|
|
10921
11142
|
const id = modelId ?? "";
|
|
10922
|
-
return id !== "" &&
|
|
11143
|
+
return id !== "" && allChains().some(([, hops]) => hops.includes(id));
|
|
10923
11144
|
}
|
|
10924
11145
|
function providerChainPrimariesForHop(hopId) {
|
|
10925
11146
|
const id = hopId ?? "";
|
|
10926
11147
|
if (!id)
|
|
10927
11148
|
return [];
|
|
10928
|
-
return
|
|
11149
|
+
return allChains().filter(([, hops]) => hops.includes(id)).map(([primary]) => primary);
|
|
11150
|
+
}
|
|
11151
|
+
function providerChainHostOf(value, modelValue) {
|
|
11152
|
+
if (value === modelValue)
|
|
11153
|
+
return "own";
|
|
11154
|
+
if (hasZaiPrefix(value))
|
|
11155
|
+
return "zai";
|
|
11156
|
+
if (hasOpenCodeGo2Prefix(value))
|
|
11157
|
+
return "opencode-go-2";
|
|
11158
|
+
if (hasOpenCodeGoPrefix(value))
|
|
11159
|
+
return "opencode-go";
|
|
11160
|
+
if (hasOpenRouterPrefix(value))
|
|
11161
|
+
return "openrouter";
|
|
11162
|
+
return "own";
|
|
11163
|
+
}
|
|
11164
|
+
function providerHostPlan(modelId) {
|
|
11165
|
+
const key = chainKey(modelId);
|
|
11166
|
+
if (!key)
|
|
11167
|
+
return [];
|
|
11168
|
+
const own = { host: hasOpenRouterPrefix(key) ? "openrouter" : "own", value: key };
|
|
11169
|
+
const steps = [
|
|
11170
|
+
...providerChainLeadsFor(key).map((value) => ({ host: providerChainHostOf(value, key), value })),
|
|
11171
|
+
own,
|
|
11172
|
+
...providerChainFor(key).map((value) => ({ host: providerChainHostOf(value, key), value }))
|
|
11173
|
+
];
|
|
11174
|
+
const notOffered = Object.prototype.hasOwnProperty.call(PROVIDER_HOST_NOT_OFFERED, key) ? PROVIDER_HOST_NOT_OFFERED[key] : {};
|
|
11175
|
+
for (const [host, reason] of Object.entries(notOffered)) {
|
|
11176
|
+
const at = steps.findIndex((step) => step === own) + 1;
|
|
11177
|
+
steps.splice(at, 0, { host, value: null, notOffered: reason });
|
|
11178
|
+
}
|
|
11179
|
+
return steps;
|
|
10929
11180
|
}
|
|
10930
|
-
var PROVIDER_CHAINS;
|
|
11181
|
+
var PROVIDER_CHAINS, PROVIDER_CHAIN_LEADS, PROVIDER_HOST_NOT_OFFERED;
|
|
10931
11182
|
var init_provider_chains = __esm({
|
|
10932
11183
|
"../shared/dist/provider-chains.js"() {
|
|
10933
11184
|
"use strict";
|
|
10934
11185
|
init_api_model_catalog();
|
|
11186
|
+
init_engine_spec();
|
|
10935
11187
|
PROVIDER_CHAINS = {
|
|
10936
|
-
"minimax-m3": ["
|
|
10937
|
-
"minimax-m3.1-flash": ["
|
|
11188
|
+
"minimax-m3": ["opencode-go:minimax-m3", "openrouter:minimax/minimax-m3"],
|
|
11189
|
+
"minimax-m3.1-flash": ["opencode-go:minimax-m3.1-flash", "openrouter:minimax/minimax-m3.1-flash"],
|
|
10938
11190
|
"muse-spark-1.3-contributor": ["openrouter:meta/muse-spark-1.3-contributor"],
|
|
10939
|
-
"
|
|
10940
|
-
"
|
|
10941
|
-
"
|
|
11191
|
+
"claude-haiku-5-5": ["opencode-go:claude-haiku-5-5", "openrouter:anthropic/claude-haiku-5.5"],
|
|
11192
|
+
"gemini-3.1-pro-preview": ["openrouter:google/gemini-3.1-pro-preview"],
|
|
11193
|
+
"deepseek-flash": ["opencode-go-2:deepseek-v4.1-flash", "opencode-go:deepseek-v4.1-flash", "openrouter:deepseek/deepseek-v4.1-flash"],
|
|
11194
|
+
"deepseek-v4-pro": ["opencode-go-2:deepseek-v4-pro", "opencode-go:deepseek-v4-pro", "openrouter:deepseek/deepseek-v4-pro"]
|
|
11195
|
+
};
|
|
11196
|
+
PROVIDER_CHAIN_LEADS = {
|
|
11197
|
+
"openrouter:z-ai/glm-5.3-flash": ["zai:glm-5.3-flash", "opencode-go-2:glm-5.3-flash", "opencode-go:glm-5.3-flash"],
|
|
11198
|
+
"openrouter:z-ai/glm-5.3": ["zai:glm-5.3", "opencode-go-2:glm-5.3", "opencode-go:glm-5.3"],
|
|
11199
|
+
"openrouter:z-ai/glm-5.2": ["zai:glm-5.2", "opencode-go-2:glm-5.2", "opencode-go:glm-5.2"]
|
|
11200
|
+
};
|
|
11201
|
+
PROVIDER_HOST_NOT_OFFERED = {
|
|
11202
|
+
"muse-spark-1.3-contributor": { "opencode-go": "OpenCode Go serves Muse only on its Responses API" },
|
|
11203
|
+
"gemini-3.1-pro-preview": { "opencode-go": "OpenCode Go does not serve Gemini" }
|
|
10942
11204
|
};
|
|
10943
11205
|
}
|
|
10944
11206
|
});
|
|
@@ -12897,7 +13159,7 @@ function stateLiteralsOf(line) {
|
|
|
12897
13159
|
const out = [];
|
|
12898
13160
|
for (const m of line.matchAll(STRING_LITERAL_RE)) {
|
|
12899
13161
|
const text = m[1] ?? m[2] ?? m[3] ?? "";
|
|
12900
|
-
if (
|
|
13162
|
+
if (PLACEHOLDER_ATTR_RE.test(text))
|
|
12901
13163
|
continue;
|
|
12902
13164
|
if (PLACEHOLDER_CALL_TAIL_RE.test(line.slice(Math.max(0, m.index - 40), m.index)))
|
|
12903
13165
|
continue;
|
|
@@ -12993,7 +13255,7 @@ function formatReadinessPollAdvisory(findings) {
|
|
|
12993
13255
|
const where = findings.length === 1 ? "One place" : `${findings.length} places`;
|
|
12994
13256
|
return `${where} re-check a background state once and assert the finished state at once (${short(first.line, 90)} then ${short(first.assertion, 90)}). ${first.reason}`;
|
|
12995
13257
|
}
|
|
12996
|
-
var READINESS_POLL_MAX_CODE_CHARS, MAX_LINE_CHARS, MAX_FINDINGS, ASSERTION_WINDOW_LINES, MAX_BLOCK_CHARS, MAX_HEAD_CHARS, STRING_LITERAL_RE, RECHECK_NAME_RE, RETRY_NAME_RE, PENDING_STATE_RE, LOCATOR_LINE_RE, CLICK_RE, RELOAD_RE, GOTO_RE, ACTION_RE, EXPECT_RE, NEGATED_RE, PENDING_ENDED_RE, POSITIVE_MATCHER_RE, ZERO_COUNT_RE, TEST_END_RE, TEST_START_RE, POLL_OPEN_RE, PLACEHOLDER_CALL_TAIL_RE, POLL_SHAPE;
|
|
13258
|
+
var READINESS_POLL_MAX_CODE_CHARS, MAX_LINE_CHARS, MAX_FINDINGS, ASSERTION_WINDOW_LINES, MAX_BLOCK_CHARS, MAX_HEAD_CHARS, STRING_LITERAL_RE, RECHECK_NAME_RE, RETRY_NAME_RE, PENDING_STATE_RE, LOCATOR_LINE_RE, CLICK_RE, RELOAD_RE, GOTO_RE, ACTION_RE, EXPECT_RE, NEGATED_RE, PENDING_ENDED_RE, POSITIVE_MATCHER_RE, ZERO_COUNT_RE, TEST_END_RE, TEST_START_RE, POLL_OPEN_RE, PLACEHOLDER_ATTR_RE, PLACEHOLDER_CALL_TAIL_RE, POLL_SHAPE;
|
|
12997
13259
|
var init_readiness_poll = __esm({
|
|
12998
13260
|
"../shared/dist/readiness-poll.js"() {
|
|
12999
13261
|
"use strict";
|
|
@@ -13006,7 +13268,7 @@ var init_readiness_poll = __esm({
|
|
|
13006
13268
|
STRING_LITERAL_RE = /'((?:\\.|[^'\\\n]){0,300})'|"((?:\\.|[^"\\\n]){0,300})"|`((?:\\.|[^`\\\n]){0,300})`/g;
|
|
13007
13269
|
RECHECK_NAME_RE = /^\s{0,10}(?:check again|check (?:status|availability|now|for updates|progress)|re-?check(?: status)?|update status|see (?:latest|updates))\s{0,10}(?:\.\.\.|…)?\s{0,10}$/i;
|
|
13008
13270
|
RETRY_NAME_RE = /^\s{0,10}(?:refresh(?: (?:status|list|page|results|now))?|reload(?: (?:page|results|list))?|try again|retry|load (?:again|latest))\s{0,10}(?:\.\.\.|…)?\s{0,10}$/i;
|
|
13009
|
-
PENDING_STATE_RE = /\b(?:searching|checking|sending|pending|processing|queued|in progress|loading|generating|calculating|preparing|verifying|syncing|refreshing|not ready|please wait|waiting)\b|\b[a-z]{3,
|
|
13271
|
+
PENDING_STATE_RE = /\b(?:searching|checking|sending|pending|processing|queued|in progress|loading|generating|calculating|preparing|verifying|syncing|refreshing|not ready|please wait|waiting)\b|\b(?:saving|uploading|downloading|signing|logging|submitting|creating|updating|deleting|importing|exporting|publishing|connecting|redirecting|authenticating|installing|retrieving|fetching|analy[sz]ing|running|rendering|restarting|building|compiling|booting|provisioning|deploying|indexing|migrating|launching|initiali[sz]ing|optimi[sz]ing|converting|processing)(?:\s{1,3}[a-z]{1,20}){0,2}\s{0,3}(?:\.\.\.|…)\s{0,10}$|^\s{0,10}(?:starting|scanning|working|applying|finishing)(?:\s{1,3}[a-z]{1,20}){0,2}\s{0,3}(?:\.\.\.|…)\s{0,10}$|^\s{0,10}[a-z]{3,40}(?<!th)ing\s{0,3}(?:\.\.\.|…)\s{0,10}$/i;
|
|
13010
13272
|
LOCATOR_LINE_RE = /\.(?:getBy[A-Z]\w{0,30}|locator|toHaveText|toContainText)\s{0,20}\(/;
|
|
13011
13273
|
CLICK_RE = /\.(?:click|dblclick|tap)\s{0,20}\(/;
|
|
13012
13274
|
RELOAD_RE = /\bpage\.reload\s{0,20}\(/;
|
|
@@ -13020,6 +13282,7 @@ var init_readiness_poll = __esm({
|
|
|
13020
13282
|
TEST_END_RE = /^\s{0,20}\}\s{0,20}\)\s{0,20};?\s{0,20}$/;
|
|
13021
13283
|
TEST_START_RE = /\btest(?:\.\w{1,20})?\s{0,20}\(/;
|
|
13022
13284
|
POLL_OPEN_RE = /\bexpect(?:\.soft)?\s{0,20}\(\s{0,20}async\b|\bexpect\.poll\s{0,20}\(|\bfor\s{0,20}\(|\bwhile\s{0,20}\(|\bdo\s{0,20}\{/g;
|
|
13285
|
+
PLACEHOLDER_ATTR_RE = /placeholder\s{0,4}[*^$~|]?=/;
|
|
13023
13286
|
PLACEHOLDER_CALL_TAIL_RE = /getByPlaceholder\s{0,20}\(\s{0,20}$/;
|
|
13024
13287
|
POLL_SHAPE = "await expect(async () => { await page.reload(); await expect(<the finished state>).toBeVisible({ timeout: 1500 }); }).toPass({ timeout: 20000 });";
|
|
13025
13288
|
}
|
|
@@ -13421,6 +13684,15 @@ function computes(line) {
|
|
|
13421
13684
|
const code = line.replace(STRING_RE, '""').replace(REGEX_LITERAL_RE, "$1RX").replace(LITERAL_ARITH_RE, "N");
|
|
13422
13685
|
return COMPUTE_RE.test(code) || RELATIONAL_RE.test(line);
|
|
13423
13686
|
}
|
|
13687
|
+
function identifiersIn(line) {
|
|
13688
|
+
const code = line.replace(STRING_RE, '""').replace(REGEX_LITERAL_RE, "$1RX");
|
|
13689
|
+
return [code, ...[...line.matchAll(TEMPLATE_EXPR_RE)].map((m) => m[1])].flatMap((part) => part.match(IDENTIFIER_RE) ?? []);
|
|
13690
|
+
}
|
|
13691
|
+
function addTyped(typed, value) {
|
|
13692
|
+
const d = digitsOf(value);
|
|
13693
|
+
if (/\d/.test(d))
|
|
13694
|
+
typed.add(d);
|
|
13695
|
+
}
|
|
13424
13696
|
function reasonFor4(kind, label, value) {
|
|
13425
13697
|
const what = kind === "derived-value-shape-only" ? `The ${label} is checked only for its shape, so any amount passes, including a wrongly computed one.` : `The ${label} is checked against a number written into the test (${value}). That number was read off the page, so when the page computes it wrong the check still passes.`;
|
|
13426
13698
|
return `${what} Instead, ${COMPUTE_SHAPE} If the number is not computed from other values (a list price, an id, a fixed fee), leave it as it is. Keep the existing checks.`;
|
|
@@ -13432,25 +13704,32 @@ function analyzeDerivedValues(rawCode) {
|
|
|
13432
13704
|
for (const body of testBodies(rawCode)) {
|
|
13433
13705
|
if (findings.length >= MAX_FINDINGS4)
|
|
13434
13706
|
break;
|
|
13435
|
-
if (body.some(computes))
|
|
13436
|
-
continue;
|
|
13437
13707
|
const typed = /* @__PURE__ */ new Set();
|
|
13438
13708
|
const definitions = /* @__PURE__ */ new Map();
|
|
13709
|
+
const computed = /* @__PURE__ */ new Set();
|
|
13710
|
+
const usesComputed = (text) => identifiersIn(text).some((id) => computed.has(id));
|
|
13439
13711
|
for (const line of body) {
|
|
13440
13712
|
if (FILL_RE2.test(line) && !EXPECT_RE3.test(line)) {
|
|
13441
|
-
for (const m of line.matchAll(
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13713
|
+
for (const m of line.matchAll(QUOTED_RE))
|
|
13714
|
+
addTyped(typed, m[1]);
|
|
13715
|
+
const arg = FILL_ARG_RE.exec(line)?.[1];
|
|
13716
|
+
const literal = arg === void 0 ? null : LITERAL_VALUE_RE.exec(definitions.get(arg) ?? "");
|
|
13717
|
+
const value = literal?.slice(1).find((v) => v !== void 0);
|
|
13718
|
+
if (value !== void 0)
|
|
13719
|
+
addTyped(typed, value);
|
|
13446
13720
|
}
|
|
13447
13721
|
const def = DEFINITION_RE.exec(line);
|
|
13448
|
-
if (def)
|
|
13722
|
+
if (def) {
|
|
13449
13723
|
definitions.set(def[1], def[2]);
|
|
13724
|
+
if (computes(def[2]) || usesComputed(def[2]))
|
|
13725
|
+
computed.add(def[1]);
|
|
13726
|
+
}
|
|
13450
13727
|
}
|
|
13451
13728
|
for (const line of body) {
|
|
13452
13729
|
if (!EXPECT_RE3.test(line) || !VALUE_MATCHER_RE2.test(line) || /\.not\s{0,20}\./.test(line))
|
|
13453
13730
|
continue;
|
|
13731
|
+
if (computes(line) || usesComputed(line))
|
|
13732
|
+
continue;
|
|
13454
13733
|
const subject = EXPECT_SUBJECT_RE.exec(line)?.[1];
|
|
13455
13734
|
const label = DERIVED_WORD_RE.exec(`${line} ${(subject && definitions.get(subject)) ?? ""}`)?.[0];
|
|
13456
13735
|
if (!label)
|
|
@@ -13480,7 +13759,7 @@ function formatDerivedValueAdvisory(findings) {
|
|
|
13480
13759
|
const where = findings.length === 1 ? "One computed value is" : `${findings.length} computed values are`;
|
|
13481
13760
|
return `${where} checked against a copied number or only its shape (${short4(first.line, 90)}). ${first.reason}`;
|
|
13482
13761
|
}
|
|
13483
|
-
var MAX_FINDINGS4, EXPECT_RE3, DERIVED_WORD_RE, VALUE_MATCHER_RE2, MONEY_TOKEN_RE, SHAPE_ARG_RE, FILL_RE2, EXPECT_MESSAGE_RE, STRING_RE, REGEX_LITERAL_RE, COMPUTE_RE, RELATIONAL_RE, DEFINITION_RE, EXPECT_SUBJECT_RE, LITERAL_ARITH_RE, COMPUTE_SHAPE;
|
|
13762
|
+
var MAX_FINDINGS4, EXPECT_RE3, DERIVED_WORD_RE, VALUE_MATCHER_RE2, MONEY_TOKEN_RE, SHAPE_ARG_RE, FILL_RE2, EXPECT_MESSAGE_RE, STRING_RE, REGEX_LITERAL_RE, COMPUTE_RE, RELATIONAL_RE, DEFINITION_RE, EXPECT_SUBJECT_RE, LITERAL_ARITH_RE, TEMPLATE_EXPR_RE, IDENTIFIER_RE, QUOTED_RE, FILL_ARG_RE, LITERAL_VALUE_RE, COMPUTE_SHAPE;
|
|
13484
13763
|
var init_derived_value_check = __esm({
|
|
13485
13764
|
"../shared/dist/derived-value-check.js"() {
|
|
13486
13765
|
"use strict";
|
|
@@ -13500,6 +13779,11 @@ var init_derived_value_check = __esm({
|
|
|
13500
13779
|
DEFINITION_RE = /\b(?:const|let)\s{1,10}([\w$]{1,60})\s{0,10}=\s{0,10}([^\n]{0,300})/;
|
|
13501
13780
|
EXPECT_SUBJECT_RE = /\bexpect(?:\.soft)?\s{0,20}\(\s{0,20}([\w$]{1,60})/;
|
|
13502
13781
|
LITERAL_ARITH_RE = /\b\d[\d_.]{0,15}(?:\s{0,5}[*/+-]\s{0,5}\d[\d_.]{0,15}){1,8}\b/g;
|
|
13782
|
+
TEMPLATE_EXPR_RE = /\$\{([^{}\n]{0,200})\}/g;
|
|
13783
|
+
IDENTIFIER_RE = /[A-Za-z_$][\w$]{0,60}/g;
|
|
13784
|
+
QUOTED_RE = /['"`]([^'"`\n]{0,40})['"`]/g;
|
|
13785
|
+
FILL_ARG_RE = /\.(?:fill|type|pressSequentially|selectOption)\s{0,20}\(\s{0,20}([A-Za-z_$][\w$]{0,60})\s{0,20}[,)]/;
|
|
13786
|
+
LITERAL_VALUE_RE = /^\s{0,10}(?:'([^'\n]{0,40})'|"([^"\n]{0,40})"|`([^`$\n]{0,40})`|(\d[\d_,]{0,15}(?:\.\d{1,4})?))\s{0,10};?\s{0,10}$/;
|
|
13503
13787
|
COMPUTE_SHAPE = "compute the expected value in the test from its inputs (the values the test typed, or each input read from the page) and compare: const toNumber = (s) => Number(s.replace(/[^\\d.-]/g, '')); const unit = toNumber(await <unit price locator>.innerText()); then expect(toNumber(await <shown value locator>.innerText())).toBeCloseTo(unit * quantity, 2); for several lines, read them all and sum them with reduce. For a comma-decimal price like \u20AC1.234,56, drop the dots and turn the comma into a point before Number, since the replace above would read it as 1.23456.";
|
|
13504
13788
|
}
|
|
13505
13789
|
});
|
|
@@ -15534,6 +15818,99 @@ function formatStaleAfterSubmitAdvisory(rawCode) {
|
|
|
15534
15818
|
const more = described.length > 3 ? ` (+${described.length - 3} more)` : "";
|
|
15535
15819
|
return `stale-after-submit: ${described.slice(0, 3).join("; ")}${more}; these pass before the request lands and still pass if the server rejects or ignores the save. Wait for the result instead: page.waitForResponse around the click, or assert something the submit creates (the new row, the confirmation message, a path with an end anchor such as /\\/orders\\/\\d+$/)`;
|
|
15536
15820
|
}
|
|
15821
|
+
function regexLiteralEnd4(text, at) {
|
|
15822
|
+
let inClass = false;
|
|
15823
|
+
for (let i = at + 1; i < text.length; i++) {
|
|
15824
|
+
const ch = text[i];
|
|
15825
|
+
if (ch === "\n")
|
|
15826
|
+
return -1;
|
|
15827
|
+
if (ch === "\\") {
|
|
15828
|
+
i++;
|
|
15829
|
+
continue;
|
|
15830
|
+
}
|
|
15831
|
+
if (inClass) {
|
|
15832
|
+
if (ch === "]")
|
|
15833
|
+
inClass = false;
|
|
15834
|
+
continue;
|
|
15835
|
+
}
|
|
15836
|
+
if (ch === "[") {
|
|
15837
|
+
inClass = true;
|
|
15838
|
+
continue;
|
|
15839
|
+
}
|
|
15840
|
+
if (ch === "/")
|
|
15841
|
+
return i + 1;
|
|
15842
|
+
}
|
|
15843
|
+
return -1;
|
|
15844
|
+
}
|
|
15845
|
+
function startsWithRegexLiteral(text) {
|
|
15846
|
+
const t = text.trimStart();
|
|
15847
|
+
return t[0] === "/" && t[1] !== "/" && t[1] !== "*" && regexLiteralEnd4(t, 0) !== -1;
|
|
15848
|
+
}
|
|
15849
|
+
function afterFirstArg(args) {
|
|
15850
|
+
let depth = 0;
|
|
15851
|
+
let quote = null;
|
|
15852
|
+
for (let i = 0; i < args.length; i++) {
|
|
15853
|
+
const ch = args[i];
|
|
15854
|
+
if (quote) {
|
|
15855
|
+
if (ch === "\\") {
|
|
15856
|
+
i++;
|
|
15857
|
+
continue;
|
|
15858
|
+
}
|
|
15859
|
+
if (ch === quote)
|
|
15860
|
+
quote = null;
|
|
15861
|
+
continue;
|
|
15862
|
+
}
|
|
15863
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
15864
|
+
quote = ch;
|
|
15865
|
+
continue;
|
|
15866
|
+
}
|
|
15867
|
+
if (ch === "(" || ch === "[" || ch === "{")
|
|
15868
|
+
depth++;
|
|
15869
|
+
else if (ch === ")" || ch === "]" || ch === "}")
|
|
15870
|
+
depth--;
|
|
15871
|
+
else if (ch === "," && depth === 0)
|
|
15872
|
+
return args.slice(i + 1);
|
|
15873
|
+
}
|
|
15874
|
+
return "";
|
|
15875
|
+
}
|
|
15876
|
+
function analyzeRegexMatchers(rawCode) {
|
|
15877
|
+
if (!rawCode || typeof rawCode !== "string")
|
|
15878
|
+
return [];
|
|
15879
|
+
const code = stripComments2(rawCode.slice(0, MAX_LINT_INPUT));
|
|
15880
|
+
const out = [];
|
|
15881
|
+
const re = /\bexpect(?:\.soft)?\s{0,20}\(/g;
|
|
15882
|
+
let m;
|
|
15883
|
+
let examined = 0;
|
|
15884
|
+
let line = 1;
|
|
15885
|
+
let lineAt2 = 0;
|
|
15886
|
+
while ((m = re.exec(code)) !== null && examined++ < MAX_CALLS && out.length < MAX_REGEX_MATCHER_FINDINGS) {
|
|
15887
|
+
const subj = readBalanced(code, m.index + m[0].length);
|
|
15888
|
+
if (!subj)
|
|
15889
|
+
continue;
|
|
15890
|
+
const mm = /^\s{0,20}(\.\s{0,20}not)?\s{0,20}\.\s{0,20}(\w{1,40})\s{0,20}\(/.exec(code.slice(subj.end + 1, subj.end + 1 + 80));
|
|
15891
|
+
if (!mm || !REGEX_EQUALITY_MATCHERS.has(mm[2]))
|
|
15892
|
+
continue;
|
|
15893
|
+
const args = readBalanced(code, subj.end + 1 + mm[0].length);
|
|
15894
|
+
if (!args)
|
|
15895
|
+
continue;
|
|
15896
|
+
const expected = mm[2] === "toHaveJSProperty" ? afterFirstArg(args.text) : args.text;
|
|
15897
|
+
if (!startsWithRegexLiteral(expected))
|
|
15898
|
+
continue;
|
|
15899
|
+
if (mm[2] !== "toHaveJSProperty" && mm[2] !== "toContain" && (startsWithRegexLiteral(subj.text) || /^new\s+RegExp\b/.test(subj.text.trim())))
|
|
15900
|
+
continue;
|
|
15901
|
+
for (let i = code.indexOf("\n", lineAt2); i !== -1 && i < m.index; i = code.indexOf("\n", i + 1)) {
|
|
15902
|
+
line++;
|
|
15903
|
+
lineAt2 = i + 1;
|
|
15904
|
+
}
|
|
15905
|
+
out.push({ line, matcher: mm[2], negated: mm[1] !== void 0 });
|
|
15906
|
+
}
|
|
15907
|
+
return out;
|
|
15908
|
+
}
|
|
15909
|
+
function formatRegexMatcherNote(findings) {
|
|
15910
|
+
const lines = findings.map((f) => `Line ${f.line}: .${f.negated ? "not." : ""}${f.matcher}(\u2026 /regex/ \u2026) ${f.negated ? "always passes (a regex never equals the value), so it checks nothing" : "can never pass: this matcher compares by equality and a regex never equals a value"}.`);
|
|
15911
|
+
return `${lines.join("\n")}
|
|
15912
|
+
A regex only works in toMatch, toHaveText, toContainText, toHaveValue and similar text matchers. For a DOM property read it first: expect(await loc.evaluate((n) => n.<prop>)).toMatch(/re/). Or give toHaveJSProperty the exact string (or boolean) the page shows. Keep every other line as-is.`;
|
|
15913
|
+
}
|
|
15537
15914
|
function lintTestQuality(rawCode, opts = {}) {
|
|
15538
15915
|
if (!rawCode || typeof rawCode !== "string")
|
|
15539
15916
|
return [];
|
|
@@ -15541,6 +15918,10 @@ function lintTestQuality(rawCode, opts = {}) {
|
|
|
15541
15918
|
return lintTestData(rawCode, { pageContacts: opts.pageContacts });
|
|
15542
15919
|
if (opts.only === "test-data-blocking")
|
|
15543
15920
|
return analyzeTestData(rawCode, { pageContacts: opts.pageContacts }).blocking;
|
|
15921
|
+
if (opts.only === "regex-matcher") {
|
|
15922
|
+
const found = analyzeRegexMatchers(rawCode);
|
|
15923
|
+
return found.length > 0 ? [formatRegexMatcherNote(found)] : [];
|
|
15924
|
+
}
|
|
15544
15925
|
const warnings = [];
|
|
15545
15926
|
if (rawCode.length > MAX_LINT_INPUT) {
|
|
15546
15927
|
warnings.push(`The code is ${Math.round(rawCode.length / 1024)} KB; the quality lint checked only the first ${MAX_LINT_INPUT / 1e3} KB. Split it into smaller tests (one behaviour per test).`);
|
|
@@ -15815,7 +16196,7 @@ function specItemsFromTestPlans(testPlans) {
|
|
|
15815
16196
|
}
|
|
15816
16197
|
return [...new Set(out)].slice(0, 200);
|
|
15817
16198
|
}
|
|
15818
|
-
var READ_ONLY_TAGS, PRODUCTION_READ_ONLY_GUARD_TEMPLATE, HOST_AGNOSTIC_URL_TEMPLATE, TEST_QUALITY_CONVENTIONS, NON_PROD_HOST_LABEL, NON_PROD_HOST_TOKEN, TRANSIENT_TEXT, STRING_LITERAL, FIRST_LITERAL, GET_BY_TEXT_LITERAL2, ROLE_NAME_LITERAL2, MAX_LINT_INPUT, MAX_BALANCED_SCAN, MAX_CALLS, MAX_SEEN_SCAN, ACTION_CALL, BY_NAME_LOCATOR, ACTION_AFTER, MAX_CONTACTS, MAX_SNAPSHOT_SCAN, PHONE_IN_TEXT, EMAIL_IN_TEXT, TEL_HREF, MAILTO_HREF, FIELD_LINE, INBOX_EMAIL_READ, MAIL_READ_CALL, RESERVED_EMAIL_TLD, PHONE_LABEL, NON_PHONE_NUMBER_LABEL, IDENTITY_LABEL, LOOKUP_LABEL, NON_NAME_SUFFIX_LABEL, DATE_LIKE, SIGNUP_ACTION_NAME, SIGNUP_SUBMIT_NAME, LOGIN_ACTION_NAME, SIGNUP_GOTO, LOGIN_GOTO, MINTED_INBOX_ALIAS, STAMP_EVAL, RECORDING_VALUE_PLACEHOLDERS, NEGATIVE_TEST_TITLE, NEGATIVE_SIGNUP_ASSERT, STORED_LOGIN_RE, CONFIRM_CLICK_RE, SAVE_UPDATE_RE, NOT_A_CONFIRM_RE, ENTITY_WORDS, CREATE_ENTITY_CLICK_RE, RESTORE_CLICK_RE, MAX_ACCOUNT_ACTIONS, MAX_TRY_BLOCKS, MAX_STATEMENT_LOOKBACK, MAX_FINDINGS5, MAX_TRY_BODY, AUTH_REGION_START, AUTH_REGION_END, INBOX_REGION_START, INBOX_REGION_END, ACCOUNT_ROUTE_RE, ENTITY_WORD_RES, PERSIST_CALL_RE, FILL_IDENT_ARG_RE, PERSIST_ARGS_RE, HOST_IN_URL_ARG, URL_WAIT_TOKEN, GLOB_ESCAPED, URL_WAIT_MAX_PATH, URL_WAIT_MAX_GLOB_STARS, UNREACHED_MAX_PATHS, UNREACHED_MATCH_BUDGET, STALE_TOKEN, RESULT_WAIT, WRITE_CALL_PRESENT, SUBMIT_CALL_PRESENT, TEST_CALL, VALUE_WRITE_CALLS, SUBMIT_CALLS, DISTINCT_PAGE_CALLS, OWN_CONTROL_MATCHERS, OUTCOME_CONTENT_MATCHERS, OUTCOME_STATE_MATCHERS, ANY_CONTENT_ARG, ROOT_SUBJECT, LITERAL_SUBJECT, MATCHER_AFTER_EXPECT, STALE_MAX_EVENTS, CHECKED, UNCHECKED, squash, NOT_JUDGED, STALE_REASON_TEXT, LIVE_WRITE_NAME, BUNDLED_CHECKS_BEFORE_WRITE, STOP, SYNONYMS, AREA_TOKENS;
|
|
16199
|
+
var READ_ONLY_TAGS, PRODUCTION_READ_ONLY_GUARD_TEMPLATE, HOST_AGNOSTIC_URL_TEMPLATE, TEST_QUALITY_CONVENTIONS, NON_PROD_HOST_LABEL, NON_PROD_HOST_TOKEN, TRANSIENT_TEXT, STRING_LITERAL, FIRST_LITERAL, GET_BY_TEXT_LITERAL2, ROLE_NAME_LITERAL2, MAX_LINT_INPUT, MAX_BALANCED_SCAN, MAX_CALLS, MAX_SEEN_SCAN, ACTION_CALL, BY_NAME_LOCATOR, ACTION_AFTER, MAX_CONTACTS, MAX_SNAPSHOT_SCAN, PHONE_IN_TEXT, EMAIL_IN_TEXT, TEL_HREF, MAILTO_HREF, FIELD_LINE, INBOX_EMAIL_READ, MAIL_READ_CALL, RESERVED_EMAIL_TLD, PHONE_LABEL, NON_PHONE_NUMBER_LABEL, IDENTITY_LABEL, LOOKUP_LABEL, NON_NAME_SUFFIX_LABEL, DATE_LIKE, SIGNUP_ACTION_NAME, SIGNUP_SUBMIT_NAME, LOGIN_ACTION_NAME, SIGNUP_GOTO, LOGIN_GOTO, MINTED_INBOX_ALIAS, STAMP_EVAL, RECORDING_VALUE_PLACEHOLDERS, NEGATIVE_TEST_TITLE, NEGATIVE_SIGNUP_ASSERT, STORED_LOGIN_RE, CONFIRM_CLICK_RE, SAVE_UPDATE_RE, NOT_A_CONFIRM_RE, ENTITY_WORDS, CREATE_ENTITY_CLICK_RE, RESTORE_CLICK_RE, MAX_ACCOUNT_ACTIONS, MAX_TRY_BLOCKS, MAX_STATEMENT_LOOKBACK, MAX_FINDINGS5, MAX_TRY_BODY, AUTH_REGION_START, AUTH_REGION_END, INBOX_REGION_START, INBOX_REGION_END, ACCOUNT_ROUTE_RE, ENTITY_WORD_RES, PERSIST_CALL_RE, FILL_IDENT_ARG_RE, PERSIST_ARGS_RE, HOST_IN_URL_ARG, URL_WAIT_TOKEN, GLOB_ESCAPED, URL_WAIT_MAX_PATH, URL_WAIT_MAX_GLOB_STARS, UNREACHED_MAX_PATHS, UNREACHED_MATCH_BUDGET, STALE_TOKEN, RESULT_WAIT, WRITE_CALL_PRESENT, SUBMIT_CALL_PRESENT, TEST_CALL, VALUE_WRITE_CALLS, SUBMIT_CALLS, DISTINCT_PAGE_CALLS, OWN_CONTROL_MATCHERS, OUTCOME_CONTENT_MATCHERS, OUTCOME_STATE_MATCHERS, ANY_CONTENT_ARG, ROOT_SUBJECT, LITERAL_SUBJECT, MATCHER_AFTER_EXPECT, STALE_MAX_EVENTS, CHECKED, UNCHECKED, squash, NOT_JUDGED, STALE_REASON_TEXT, LIVE_WRITE_NAME, BUNDLED_CHECKS_BEFORE_WRITE, MAX_REGEX_MATCHER_FINDINGS, REGEX_EQUALITY_MATCHERS, STOP, SYNONYMS, AREA_TOKENS;
|
|
15819
16200
|
var init_test_authoring_quality = __esm({
|
|
15820
16201
|
"../shared/dist/test-authoring-quality.js"() {
|
|
15821
16202
|
"use strict";
|
|
@@ -16047,6 +16428,8 @@ var init_test_authoring_quality = __esm({
|
|
|
16047
16428
|
};
|
|
16048
16429
|
LIVE_WRITE_NAME = /\b(?:submit|place|book|reserve|confirm|pay|send|checkout|order|register|sign\s?up|create account)\b/i;
|
|
16049
16430
|
BUNDLED_CHECKS_BEFORE_WRITE = 5;
|
|
16431
|
+
MAX_REGEX_MATCHER_FINDINGS = 10;
|
|
16432
|
+
REGEX_EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual", "toContain", "toHaveJSProperty"]);
|
|
16050
16433
|
STOP = /* @__PURE__ */ new Set([
|
|
16051
16434
|
"a",
|
|
16052
16435
|
"an",
|
|
@@ -16275,6 +16658,19 @@ var init_fence_runs = __esm({
|
|
|
16275
16658
|
}
|
|
16276
16659
|
});
|
|
16277
16660
|
|
|
16661
|
+
// ../shared/dist/trailing-slashes.js
|
|
16662
|
+
function stripTrailingSlashes(value) {
|
|
16663
|
+
let end = value.length;
|
|
16664
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47)
|
|
16665
|
+
end--;
|
|
16666
|
+
return end === value.length ? value : value.slice(0, end);
|
|
16667
|
+
}
|
|
16668
|
+
var init_trailing_slashes = __esm({
|
|
16669
|
+
"../shared/dist/trailing-slashes.js"() {
|
|
16670
|
+
"use strict";
|
|
16671
|
+
}
|
|
16672
|
+
});
|
|
16673
|
+
|
|
16278
16674
|
// ../shared/dist/survey-bug-signature.js
|
|
16279
16675
|
function normalizeWords(text) {
|
|
16280
16676
|
return text.toLowerCase().replace(UUID, " id ").replace(PREFIXED_ID, " id ").replace(HEX_RUN, (run) => /\d/.test(run) ? " id " : run).replace(NUMBER_RUN, " # ").replace(/[^\p{L}\p{N}#]+/gu, " ").replace(/\s+/g, " ").trim();
|
|
@@ -16285,7 +16681,7 @@ function normalizeBugPath(route) {
|
|
|
16285
16681
|
if (hash >= 0 && path[hash + 1] !== "/")
|
|
16286
16682
|
path = path.slice(0, hash);
|
|
16287
16683
|
const segments = path.toLowerCase().split("/").map((segment) => /\d/.test(segment) ? ":id" : segment);
|
|
16288
|
-
const joined = segments.join("/")
|
|
16684
|
+
const joined = stripTrailingSlashes(segments.join("/"));
|
|
16289
16685
|
return joined || (path.startsWith("/") ? "/" : "");
|
|
16290
16686
|
}
|
|
16291
16687
|
function isGenericConsoleMessage(message) {
|
|
@@ -16419,6 +16815,7 @@ var SIGNATURE_SOURCE_MAX_CHARS, UUID, PREFIXED_ID, HEX_RUN, NUMBER_RUN, GENERIC_
|
|
|
16419
16815
|
var init_survey_bug_signature = __esm({
|
|
16420
16816
|
"../shared/dist/survey-bug-signature.js"() {
|
|
16421
16817
|
"use strict";
|
|
16818
|
+
init_trailing_slashes();
|
|
16422
16819
|
SIGNATURE_SOURCE_MAX_CHARS = 800;
|
|
16423
16820
|
UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g;
|
|
16424
16821
|
PREFIXED_ID = /\b[a-z]{1,8}[-_]\d+\b/g;
|
|
@@ -17699,9 +18096,9 @@ function lastLocatorLabels(chain) {
|
|
|
17699
18096
|
if (t)
|
|
17700
18097
|
labels.push(t[1]);
|
|
17701
18098
|
}
|
|
17702
|
-
const
|
|
17703
|
-
if (
|
|
17704
|
-
labels.push(
|
|
18099
|
+
const has2 = optionText(last.args, HAS_TEXT_OPTION_RE);
|
|
18100
|
+
if (has2 !== null)
|
|
18101
|
+
labels.push(has2);
|
|
17705
18102
|
}
|
|
17706
18103
|
return labels.map((l) => l.replace(/^[\s^(?:]+/, "").trim());
|
|
17707
18104
|
}
|
|
@@ -18458,14 +18855,17 @@ var init_promotion_quality_gate = __esm({
|
|
|
18458
18855
|
SOURCE_RANK = { generator: 0, classifier: 0, healer: 1, human: 2 };
|
|
18459
18856
|
strengthCheck = {
|
|
18460
18857
|
id: "assertion-strength",
|
|
18461
|
-
run({ code, strengthGate, flagContradictedAdditions }) {
|
|
18858
|
+
run({ code, tags, strengthGate, flagContradictedAdditions }) {
|
|
18462
18859
|
const verdict = validateAssertionStrength(code, { flagContradictedAdditions: flagContradictedAdditions === true });
|
|
18463
18860
|
if (verdict.severity === "route-bug")
|
|
18464
18861
|
return [{ check: "route-bug" }];
|
|
18465
|
-
|
|
18862
|
+
const authDowngrade = verdict.severity === "downgrade" && tags.some((t) => t.toLowerCase() === "@auth");
|
|
18863
|
+
if (verdict.severity !== "block" && !authDowngrade)
|
|
18466
18864
|
return [];
|
|
18467
18865
|
const revealed = strengthGate?.severity === "none" && strengthGate.revealEvidence === "revealed" && strengthGate.source !== "heal";
|
|
18468
|
-
|
|
18866
|
+
if (revealed)
|
|
18867
|
+
return [];
|
|
18868
|
+
return [{ check: authDowngrade ? "strength-downgrade-auth" : "strength-block" }];
|
|
18469
18869
|
}
|
|
18470
18870
|
};
|
|
18471
18871
|
STRING_CONST = /\b(?:const|let|var)\s{1,20}([A-Za-z_$][\w$]{0,60})\s{0,20}=\s{0,20}(?:'([^'\\\n]{0,300})'|"([^"\\\n]{0,300})"|`([^`\\$\n]{0,300})`)\s{0,20}[;\n]/g;
|
|
@@ -18872,6 +19272,7 @@ __export(dist_exports, {
|
|
|
18872
19272
|
AUDIO_CHUNK_DURATION_MS: () => AUDIO_CHUNK_DURATION_MS,
|
|
18873
19273
|
AUTH_PATH_SIGNATURE: () => AUTH_PATH_SIGNATURE,
|
|
18874
19274
|
AUTH_PROVIDER_HOST_SIGNATURES: () => AUTH_PROVIDER_HOST_SIGNATURES,
|
|
19275
|
+
AUTH_SESSION_GENERATION_RE: () => AUTH_SESSION_GENERATION_RE,
|
|
18875
19276
|
AUTH_STATE_EXPIRY_SKEW_MS: () => AUTH_STATE_EXPIRY_SKEW_MS,
|
|
18876
19277
|
AUTH_TAG_COOKIE_STATE: () => AUTH_TAG_COOKIE_STATE,
|
|
18877
19278
|
AUTH_TAG_LOGIN_BEARER: () => AUTH_TAG_LOGIN_BEARER,
|
|
@@ -19004,6 +19405,8 @@ __export(dist_exports, {
|
|
|
19004
19405
|
LIVE_FRAME_STALE_MS: () => LIVE_FRAME_STALE_MS,
|
|
19005
19406
|
LIVE_FRAME_UNFOCUSED_INTERVAL_MS: () => LIVE_FRAME_UNFOCUSED_INTERVAL_MS,
|
|
19006
19407
|
LIVE_THUMBNAIL_MAX_BASE64_BYTES: () => LIVE_THUMBNAIL_MAX_BASE64_BYTES,
|
|
19408
|
+
MAX_BALANCED_SCAN: () => MAX_BALANCED_SCAN,
|
|
19409
|
+
MAX_CALLS: () => MAX_CALLS,
|
|
19007
19410
|
MAX_CREDIT_TOPUP_CENTS: () => MAX_CREDIT_TOPUP_CENTS,
|
|
19008
19411
|
MAX_DEEPLINK_LENGTH: () => MAX_DEEPLINK_LENGTH,
|
|
19009
19412
|
MAX_EMAIL_ADDRESS_LENGTH: () => MAX_EMAIL_ADDRESS_LENGTH,
|
|
@@ -19048,6 +19451,7 @@ __export(dist_exports, {
|
|
|
19048
19451
|
MUSE_ENGINE_DEFAULT_MODEL: () => MUSE_ENGINE_DEFAULT_MODEL,
|
|
19049
19452
|
MUSE_ENGINE_MODELS: () => MUSE_ENGINE_MODELS,
|
|
19050
19453
|
NOREPLY_EMAIL: () => NOREPLY_EMAIL,
|
|
19454
|
+
OPENCODE_GO_2_PREFIX: () => OPENCODE_GO_2_PREFIX,
|
|
19051
19455
|
OPENCODE_GO_MODEL_PATTERN: () => OPENCODE_GO_MODEL_PATTERN,
|
|
19052
19456
|
OPENCODE_GO_PREFIX: () => OPENCODE_GO_PREFIX,
|
|
19053
19457
|
OPENROUTER_MAX_CALL_COST_USD: () => OPENROUTER_MAX_CALL_COST_USD,
|
|
@@ -19083,6 +19487,8 @@ __export(dist_exports, {
|
|
|
19083
19487
|
PROMOTION_GATE_MAX_CODE_CHARS: () => PROMOTION_GATE_MAX_CODE_CHARS,
|
|
19084
19488
|
PROMOTION_QUALITY_CHECKS: () => PROMOTION_QUALITY_CHECKS,
|
|
19085
19489
|
PROVIDER_CHAINS: () => PROVIDER_CHAINS,
|
|
19490
|
+
PROVIDER_CHAIN_LEADS: () => PROVIDER_CHAIN_LEADS,
|
|
19491
|
+
PROVIDER_HOST_NOT_OFFERED: () => PROVIDER_HOST_NOT_OFFERED,
|
|
19086
19492
|
PUBLIC_PLANS: () => PUBLIC_PLANS,
|
|
19087
19493
|
QUARANTINE_CLOSE_TAGS: () => QUARANTINE_CLOSE_TAGS,
|
|
19088
19494
|
READINESS_POLL_MAX_CODE_CHARS: () => READINESS_POLL_MAX_CODE_CHARS,
|
|
@@ -19121,6 +19527,7 @@ __export(dist_exports, {
|
|
|
19121
19527
|
SURVEY_NOTES_RENDER_MAX_CHARS: () => SURVEY_NOTES_RENDER_MAX_CHARS,
|
|
19122
19528
|
SURVEY_NOTE_KEYS: () => SURVEY_NOTE_KEYS,
|
|
19123
19529
|
SUSPICIOUS_PASS_TAG: () => SUSPICIOUS_PASS_TAG,
|
|
19530
|
+
TEST_DID_NOT_RUN_ERROR: () => TEST_DID_NOT_RUN_ERROR,
|
|
19124
19531
|
TEST_QUALITY_CONVENTIONS: () => TEST_QUALITY_CONVENTIONS,
|
|
19125
19532
|
TEST_USER_ENV_KEYS: () => TEST_USER_ENV_KEYS,
|
|
19126
19533
|
TEST_VARIABLE_SECRET_KEY_PATTERN: () => TEST_VARIABLE_SECRET_KEY_PATTERN,
|
|
@@ -19136,6 +19543,8 @@ __export(dist_exports, {
|
|
|
19136
19543
|
VOICE_PREVIEW_SAMPLE: () => VOICE_PREVIEW_SAMPLE,
|
|
19137
19544
|
WEB_PROXY_CHAIN_HEADER: () => WEB_PROXY_CHAIN_HEADER,
|
|
19138
19545
|
WITHHELD_CREDENTIAL_TEXT: () => WITHHELD_CREDENTIAL_TEXT,
|
|
19546
|
+
ZAI_MODEL_PATTERN: () => ZAI_MODEL_PATTERN,
|
|
19547
|
+
ZAI_PREFIX: () => ZAI_PREFIX,
|
|
19139
19548
|
accumulateStatements: () => accumulateStatements,
|
|
19140
19549
|
adoptBrokerFailover: () => adoptBrokerFailover,
|
|
19141
19550
|
aiCostToCreditCents: () => aiCostToCreditCents,
|
|
@@ -19144,6 +19553,7 @@ __export(dist_exports, {
|
|
|
19144
19553
|
analyzeMobileSelectorQuality: () => analyzeMobileSelectorQuality,
|
|
19145
19554
|
analyzePersistenceReread: () => analyzePersistenceReread,
|
|
19146
19555
|
analyzeReadinessPolling: () => analyzeReadinessPolling,
|
|
19556
|
+
analyzeRegexMatchers: () => analyzeRegexMatchers,
|
|
19147
19557
|
analyzeSharedAccountUse: () => analyzeSharedAccountUse,
|
|
19148
19558
|
analyzeStaleAfterSubmit: () => analyzeStaleAfterSubmit,
|
|
19149
19559
|
analyzeTestData: () => analyzeTestData,
|
|
@@ -19307,6 +19717,7 @@ __export(dist_exports, {
|
|
|
19307
19717
|
formatPersistenceRereadAdvisory: () => formatPersistenceRereadAdvisory,
|
|
19308
19718
|
formatPoolBudgetLine: () => formatPoolBudgetLine,
|
|
19309
19719
|
formatReadinessPollAdvisory: () => formatReadinessPollAdvisory,
|
|
19720
|
+
formatRegexMatcherNote: () => formatRegexMatcherNote,
|
|
19310
19721
|
formatStaleAfterSubmitAdvisory: () => formatStaleAfterSubmitAdvisory,
|
|
19311
19722
|
formatSuspiciousExpectation: () => formatSuspiciousExpectation,
|
|
19312
19723
|
formatUrlWaitAdvisory: () => formatUrlWaitAdvisory,
|
|
@@ -19345,12 +19756,14 @@ __export(dist_exports, {
|
|
|
19345
19756
|
hasEncodedRequestBody: () => hasEncodedRequestBody,
|
|
19346
19757
|
hasEngineSpecParts: () => hasEngineSpecParts,
|
|
19347
19758
|
hasOnlyConstantAssertions: () => hasOnlyConstantAssertions,
|
|
19759
|
+
hasOpenCodeGo2Prefix: () => hasOpenCodeGo2Prefix,
|
|
19348
19760
|
hasOpenCodeGoPrefix: () => hasOpenCodeGoPrefix,
|
|
19349
19761
|
hasOpenRouterPrefix: () => hasOpenRouterPrefix,
|
|
19350
19762
|
hasPlatformLocator: () => hasPlatformLocator,
|
|
19351
19763
|
hasReadOnlyMarker: () => hasReadOnlyMarker,
|
|
19352
19764
|
hasSurveyNotes: () => hasSurveyNotes,
|
|
19353
19765
|
hasTestFailContract: () => hasTestFailContract,
|
|
19766
|
+
hasZaiPrefix: () => hasZaiPrefix,
|
|
19354
19767
|
healMobileTestSteps: () => healMobileTestSteps,
|
|
19355
19768
|
healthRunWhere: () => healthRunWhere,
|
|
19356
19769
|
heldCodeRecord: () => heldCodeRecord,
|
|
@@ -19454,6 +19867,7 @@ __export(dist_exports, {
|
|
|
19454
19867
|
isValidSttProvider: () => isValidSttProvider,
|
|
19455
19868
|
isValidTtsModel: () => isValidTtsModel,
|
|
19456
19869
|
isValidTtsVoiceId: () => isValidTtsVoiceId,
|
|
19870
|
+
isZaiModelId: () => isZaiModelId,
|
|
19457
19871
|
jsEscapedForms: () => jsEscapedForms,
|
|
19458
19872
|
jsonStructureRefusalOf: () => jsonStructureRefusalOf,
|
|
19459
19873
|
jsonStructureVerify: () => jsonStructureVerify,
|
|
@@ -19502,6 +19916,7 @@ __export(dist_exports, {
|
|
|
19502
19916
|
parseApiCardModelUpdate: () => parseApiCardModelUpdate,
|
|
19503
19917
|
parseAppTimezone: () => parseAppTimezone,
|
|
19504
19918
|
parseAuditGroupScopeId: () => parseAuditGroupScopeId,
|
|
19919
|
+
parseAuthSessionStamp: () => parseAuthSessionStamp,
|
|
19505
19920
|
parseBoolFlag: () => parseBoolFlag,
|
|
19506
19921
|
parseDbPoolSize: () => parseDbPoolSize,
|
|
19507
19922
|
parseDeepgramListenResponse: () => parseDeepgramListenResponse,
|
|
@@ -19545,7 +19960,11 @@ __export(dist_exports, {
|
|
|
19545
19960
|
profileKeyRoute: () => profileKeyRoute,
|
|
19546
19961
|
projectAppHosts: () => projectAppHosts,
|
|
19547
19962
|
providerChainFor: () => providerChainFor,
|
|
19963
|
+
providerChainHostOf: () => providerChainHostOf,
|
|
19964
|
+
providerChainLeadsFor: () => providerChainLeadsFor,
|
|
19548
19965
|
providerChainPrimariesForHop: () => providerChainPrimariesForHop,
|
|
19966
|
+
providerHostPlan: () => providerHostPlan,
|
|
19967
|
+
readBalanced: () => readBalanced,
|
|
19549
19968
|
readChatFailover: () => readChatFailover,
|
|
19550
19969
|
readChatReasoningTokens: () => readChatReasoningTokens,
|
|
19551
19970
|
readChatUsage: () => readChatUsage,
|
|
@@ -19628,6 +20047,7 @@ __export(dist_exports, {
|
|
|
19628
20047
|
stripCoverageComments: () => stripCoverageComments,
|
|
19629
20048
|
stripEnvironmentalPrefix: () => stripEnvironmentalPrefix,
|
|
19630
20049
|
stripLoginScaffolding: () => stripLoginScaffolding,
|
|
20050
|
+
stripTrailingSlashes: () => stripTrailingSlashes,
|
|
19631
20051
|
strongerNeedsReviewSource: () => strongerNeedsReviewSource,
|
|
19632
20052
|
sttModelsForProvider: () => sttModelsForProvider,
|
|
19633
20053
|
summarizeHealth: () => summarizeHealth,
|
|
@@ -19655,7 +20075,8 @@ __export(dist_exports, {
|
|
|
19655
20075
|
withReviewSource: () => withReviewSource,
|
|
19656
20076
|
withoutNotChargedClaim: () => withoutNotChargedClaim,
|
|
19657
20077
|
withoutServerOnlySpendFields: () => withoutServerOnlySpendFields,
|
|
19658
|
-
withoutSurveyNotes: () => withoutSurveyNotes
|
|
20078
|
+
withoutSurveyNotes: () => withoutSurveyNotes,
|
|
20079
|
+
zaiWireModel: () => zaiWireModel
|
|
19659
20080
|
});
|
|
19660
20081
|
var init_dist = __esm({
|
|
19661
20082
|
"../shared/dist/index.js"() {
|
|
@@ -19697,6 +20118,7 @@ var init_dist = __esm({
|
|
|
19697
20118
|
init_admin_view_return_to();
|
|
19698
20119
|
init_auth_plan();
|
|
19699
20120
|
init_auth_block_detector();
|
|
20121
|
+
init_auth_session_stamp();
|
|
19700
20122
|
init_auth_state_freshness();
|
|
19701
20123
|
init_skip_coverage_detector();
|
|
19702
20124
|
init_feature_coverage();
|
|
@@ -19753,6 +20175,7 @@ var init_dist = __esm({
|
|
|
19753
20175
|
init_promotion_quality_gate();
|
|
19754
20176
|
init_regex_alternation();
|
|
19755
20177
|
init_page_evidence();
|
|
20178
|
+
init_trailing_slashes();
|
|
19756
20179
|
}
|
|
19757
20180
|
});
|
|
19758
20181
|
|
|
@@ -22892,11 +23315,13 @@ var require_proc_table = __commonJS({
|
|
|
22892
23315
|
"../runner-core/dist/utils/proc-table.js"(exports2) {
|
|
22893
23316
|
"use strict";
|
|
22894
23317
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
23318
|
+
exports2.PS_MAX_BUFFER = void 0;
|
|
22895
23319
|
exports2.isMissingBinaryError = isMissingBinaryError;
|
|
22896
23320
|
exports2.parseProcStat = parseProcStat;
|
|
22897
23321
|
exports2.readProcRssKb = readProcRssKb;
|
|
22898
23322
|
exports2.readProcTable = readProcTable;
|
|
22899
23323
|
var node_fs_1 = require("fs");
|
|
23324
|
+
exports2.PS_MAX_BUFFER = 32 * 1024 * 1024;
|
|
22900
23325
|
var CLOCK_TICKS_PER_SECOND = 100;
|
|
22901
23326
|
function isMissingBinaryError(error2) {
|
|
22902
23327
|
return error2?.code === "ENOENT";
|
|
@@ -22982,14 +23407,13 @@ var require_kill_tree = __commonJS({
|
|
|
22982
23407
|
var proc_table_js_1 = require_proc_table();
|
|
22983
23408
|
var execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
22984
23409
|
var PS_TIMEOUT_MS = 2e3;
|
|
22985
|
-
var PS_BUFFER = 1024 * 1024;
|
|
22986
23410
|
async function listProcessRows(timeoutMs = PS_TIMEOUT_MS) {
|
|
22987
23411
|
const controller = new AbortController();
|
|
22988
23412
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
22989
23413
|
timer.unref?.();
|
|
22990
23414
|
try {
|
|
22991
23415
|
const { stdout } = await execFileAsync("ps", ["-A", "-o", "pid=,ppid=,command="], {
|
|
22992
|
-
maxBuffer:
|
|
23416
|
+
maxBuffer: proc_table_js_1.PS_MAX_BUFFER,
|
|
22993
23417
|
signal: controller.signal
|
|
22994
23418
|
});
|
|
22995
23419
|
const rows = [];
|
|
@@ -23026,7 +23450,7 @@ var require_kill_tree = __commonJS({
|
|
|
23026
23450
|
timer.unref?.();
|
|
23027
23451
|
try {
|
|
23028
23452
|
const { stdout } = await execFileAsync("ps", ["-A", "-o", "pid=,ppid=,pgid=,stat="], {
|
|
23029
|
-
maxBuffer:
|
|
23453
|
+
maxBuffer: proc_table_js_1.PS_MAX_BUFFER,
|
|
23030
23454
|
signal: controller.signal
|
|
23031
23455
|
});
|
|
23032
23456
|
const tree = /* @__PURE__ */ new Map();
|
|
@@ -23136,15 +23560,15 @@ var require_kill_tree = __commonJS({
|
|
|
23136
23560
|
const rows = await listProcessRows(timeoutMs);
|
|
23137
23561
|
return new Set(rows.filter((row) => row.ppid === parentPid && commandRegex.test(row.command)).map((row) => row.pid));
|
|
23138
23562
|
} catch {
|
|
23139
|
-
return
|
|
23563
|
+
return null;
|
|
23140
23564
|
}
|
|
23141
23565
|
}
|
|
23142
23566
|
var chromiumLaunchTail = Promise.resolve();
|
|
23143
23567
|
async function launchWithChromiumRootPid(launch, options = {}) {
|
|
23144
23568
|
const run = async () => {
|
|
23145
|
-
const prior = await snapshotMatchingChildren(process.pid, options.commandRegex, options.timeoutMs).catch(() =>
|
|
23569
|
+
const prior = await snapshotMatchingChildren(process.pid, options.commandRegex, options.timeoutMs).catch(() => null);
|
|
23146
23570
|
const value = await launch();
|
|
23147
|
-
const rootPid = await findNewChromiumChildPid(process.pid, prior, options).catch(() => null);
|
|
23571
|
+
const rootPid = prior ? await findNewChromiumChildPid(process.pid, prior, options).catch(() => null) : null;
|
|
23148
23572
|
return { value, rootPid };
|
|
23149
23573
|
};
|
|
23150
23574
|
const turn = chromiumLaunchTail.then(run);
|
|
@@ -76648,7 +77072,7 @@ var require_he = __commonJS({
|
|
|
76648
77072
|
var stringFromCharCode2 = String.fromCharCode;
|
|
76649
77073
|
var object = {};
|
|
76650
77074
|
var hasOwnProperty = object.hasOwnProperty;
|
|
76651
|
-
var
|
|
77075
|
+
var has2 = function(object2, propertyName) {
|
|
76652
77076
|
return hasOwnProperty.call(object2, propertyName);
|
|
76653
77077
|
};
|
|
76654
77078
|
var contains = function(array, value) {
|
|
@@ -76668,7 +77092,7 @@ var require_he = __commonJS({
|
|
|
76668
77092
|
var result = {};
|
|
76669
77093
|
var key2;
|
|
76670
77094
|
for (key2 in defaults) {
|
|
76671
|
-
result[key2] =
|
|
77095
|
+
result[key2] = has2(options, key2) ? options[key2] : defaults[key2];
|
|
76672
77096
|
}
|
|
76673
77097
|
return result;
|
|
76674
77098
|
};
|
|
@@ -76680,7 +77104,7 @@ var require_he = __commonJS({
|
|
|
76680
77104
|
}
|
|
76681
77105
|
return "\uFFFD";
|
|
76682
77106
|
}
|
|
76683
|
-
if (
|
|
77107
|
+
if (has2(decodeMapNumeric, codePoint)) {
|
|
76684
77108
|
if (strict) {
|
|
76685
77109
|
parseError("disallowed character reference");
|
|
76686
77110
|
}
|
|
@@ -76721,7 +77145,7 @@ var require_he = __commonJS({
|
|
|
76721
77145
|
};
|
|
76722
77146
|
if (encodeEverything) {
|
|
76723
77147
|
string = string.replace(regexAsciiWhitelist, function(symbol) {
|
|
76724
|
-
if (useNamedReferences &&
|
|
77148
|
+
if (useNamedReferences && has2(encodeMap, symbol)) {
|
|
76725
77149
|
return "&" + encodeMap[symbol] + ";";
|
|
76726
77150
|
}
|
|
76727
77151
|
return escapeBmpSymbol(symbol);
|
|
@@ -76846,7 +77270,7 @@ var require_he = __commonJS({
|
|
|
76846
77270
|
freeModule.exports = he;
|
|
76847
77271
|
} else {
|
|
76848
77272
|
for (var key in he) {
|
|
76849
|
-
|
|
77273
|
+
has2(he, key) && (freeExports[key] = he[key]);
|
|
76850
77274
|
}
|
|
76851
77275
|
}
|
|
76852
77276
|
} else {
|