@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
package/dist/inbox-mcp-server.js
CHANGED
|
@@ -52692,7 +52692,7 @@ var require_he = __commonJS({
|
|
|
52692
52692
|
var stringFromCharCode2 = String.fromCharCode;
|
|
52693
52693
|
var object = {};
|
|
52694
52694
|
var hasOwnProperty = object.hasOwnProperty;
|
|
52695
|
-
var
|
|
52695
|
+
var has2 = function(object2, propertyName) {
|
|
52696
52696
|
return hasOwnProperty.call(object2, propertyName);
|
|
52697
52697
|
};
|
|
52698
52698
|
var contains = function(array, value) {
|
|
@@ -52712,7 +52712,7 @@ var require_he = __commonJS({
|
|
|
52712
52712
|
var result = {};
|
|
52713
52713
|
var key2;
|
|
52714
52714
|
for (key2 in defaults) {
|
|
52715
|
-
result[key2] =
|
|
52715
|
+
result[key2] = has2(options, key2) ? options[key2] : defaults[key2];
|
|
52716
52716
|
}
|
|
52717
52717
|
return result;
|
|
52718
52718
|
};
|
|
@@ -52724,7 +52724,7 @@ var require_he = __commonJS({
|
|
|
52724
52724
|
}
|
|
52725
52725
|
return "\uFFFD";
|
|
52726
52726
|
}
|
|
52727
|
-
if (
|
|
52727
|
+
if (has2(decodeMapNumeric, codePoint)) {
|
|
52728
52728
|
if (strict) {
|
|
52729
52729
|
parseError("disallowed character reference");
|
|
52730
52730
|
}
|
|
@@ -52765,7 +52765,7 @@ var require_he = __commonJS({
|
|
|
52765
52765
|
};
|
|
52766
52766
|
if (encodeEverything) {
|
|
52767
52767
|
string = string.replace(regexAsciiWhitelist, function(symbol) {
|
|
52768
|
-
if (useNamedReferences &&
|
|
52768
|
+
if (useNamedReferences && has2(encodeMap, symbol)) {
|
|
52769
52769
|
return "&" + encodeMap[symbol] + ";";
|
|
52770
52770
|
}
|
|
52771
52771
|
return escapeBmpSymbol(symbol);
|
|
@@ -52890,7 +52890,7 @@ var require_he = __commonJS({
|
|
|
52890
52890
|
freeModule.exports = he;
|
|
52891
52891
|
} else {
|
|
52892
52892
|
for (var key in he) {
|
|
52893
|
-
|
|
52893
|
+
has2(he, key) && (freeExports[key] = he[key]);
|
|
52894
52894
|
}
|
|
52895
52895
|
}
|
|
52896
52896
|
} else {
|
|
@@ -70679,7 +70679,7 @@ function unescapeQuotedBody(raw) {
|
|
|
70679
70679
|
return raw.replace(/\\(['"`\\])/g, "$1");
|
|
70680
70680
|
}
|
|
70681
70681
|
function extractRoleNameValue(line) {
|
|
70682
|
-
const m = line.match(new RegExp(`getByRole\\s*\\([^,]
|
|
70682
|
+
const m = line.match(new RegExp(`getByRole\\s*\\([^,]{1,200},\\s*\\{[^}]{0,200}?name\\s*:\\s*(?:${QUOTED_BODY}|\\/([^/]*?)\\/)`, "i"));
|
|
70683
70683
|
if (!m)
|
|
70684
70684
|
return null;
|
|
70685
70685
|
const raw = m[1] ?? m[2] ?? m[3];
|
|
@@ -71387,6 +71387,8 @@ function stripCoverageComments(code) {
|
|
|
71387
71387
|
let copyFrom = 0;
|
|
71388
71388
|
let i = 0;
|
|
71389
71389
|
let quote = null;
|
|
71390
|
+
let prev = "";
|
|
71391
|
+
let noRegexBefore = 0;
|
|
71390
71392
|
while (i < code.length) {
|
|
71391
71393
|
const ch = code[i];
|
|
71392
71394
|
if (quote) {
|
|
@@ -71394,12 +71396,24 @@ function stripCoverageComments(code) {
|
|
|
71394
71396
|
i += 2;
|
|
71395
71397
|
continue;
|
|
71396
71398
|
}
|
|
71397
|
-
if (ch === quote || ch === "\n" && quote !== "`")
|
|
71399
|
+
if (ch === quote || ch === "\n" && quote !== "`") {
|
|
71398
71400
|
quote = null;
|
|
71401
|
+
prev = ch === "\n" ? prev : ch;
|
|
71402
|
+
}
|
|
71399
71403
|
i++;
|
|
71400
71404
|
continue;
|
|
71401
71405
|
}
|
|
71402
71406
|
const next = code[i + 1];
|
|
71407
|
+
if (ch === "/" && next !== "*" && next !== "/" && i >= noRegexBefore && (prev === "" || REGEX_PRECEDER2.includes(prev))) {
|
|
71408
|
+
const end = regexLiteralEnd3(code, i);
|
|
71409
|
+
if (end > 0) {
|
|
71410
|
+
i = end;
|
|
71411
|
+
prev = "a";
|
|
71412
|
+
continue;
|
|
71413
|
+
}
|
|
71414
|
+
const eol = code.indexOf("\n", i);
|
|
71415
|
+
noRegexBefore = eol === -1 ? code.length : eol;
|
|
71416
|
+
}
|
|
71403
71417
|
if (ch === "/" && next === "*") {
|
|
71404
71418
|
const end = code.indexOf("*/", i + 2);
|
|
71405
71419
|
const stop = end === -1 ? code.length : end + 2;
|
|
@@ -71418,11 +71432,39 @@ function stripCoverageComments(code) {
|
|
|
71418
71432
|
}
|
|
71419
71433
|
if (ch === '"' || ch === "'" || ch === "`")
|
|
71420
71434
|
quote = ch;
|
|
71435
|
+
if (ch !== " " && ch !== " " && ch !== "\n" && ch !== "\r")
|
|
71436
|
+
prev = ch;
|
|
71421
71437
|
i++;
|
|
71422
71438
|
}
|
|
71423
71439
|
out.push(code.slice(copyFrom));
|
|
71424
71440
|
return out.join("");
|
|
71425
71441
|
}
|
|
71442
|
+
function regexLiteralEnd3(code, start) {
|
|
71443
|
+
let inClass = false;
|
|
71444
|
+
for (let j = start + 1; j < code.length; j++) {
|
|
71445
|
+
const c = code[j];
|
|
71446
|
+
if (c === "\n")
|
|
71447
|
+
return -1;
|
|
71448
|
+
if (c === "\\") {
|
|
71449
|
+
j++;
|
|
71450
|
+
continue;
|
|
71451
|
+
}
|
|
71452
|
+
if (inClass) {
|
|
71453
|
+
if (c === "]")
|
|
71454
|
+
inClass = false;
|
|
71455
|
+
continue;
|
|
71456
|
+
}
|
|
71457
|
+
if (c === "[")
|
|
71458
|
+
inClass = true;
|
|
71459
|
+
else if (c === "/") {
|
|
71460
|
+
let k = j + 1;
|
|
71461
|
+
while (k < code.length && isIdentChar(code[k]))
|
|
71462
|
+
k++;
|
|
71463
|
+
return k;
|
|
71464
|
+
}
|
|
71465
|
+
}
|
|
71466
|
+
return -1;
|
|
71467
|
+
}
|
|
71426
71468
|
function isIdentChar(ch) {
|
|
71427
71469
|
if (!ch)
|
|
71428
71470
|
return false;
|
|
@@ -72080,7 +72122,7 @@ function assessTitleCoverage(title, code) {
|
|
|
72080
72122
|
const repeatedHit = [...repeated].some((term) => hay.includes(term));
|
|
72081
72123
|
return { covered: hit >= needed || repeatedHit, missingTerms };
|
|
72082
72124
|
}
|
|
72083
|
-
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;
|
|
72125
|
+
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;
|
|
72084
72126
|
var init_expected_outcome_coverage = __esm({
|
|
72085
72127
|
"../shared/dist/expected-outcome-coverage.js"() {
|
|
72086
72128
|
"use strict";
|
|
@@ -72117,6 +72159,7 @@ var init_expected_outcome_coverage = __esm({
|
|
|
72117
72159
|
]);
|
|
72118
72160
|
MAX_ASSERTION_JOIN_CHARS = 8e3;
|
|
72119
72161
|
MAX_COVERAGE_LINE_CHARS = 2e3;
|
|
72162
|
+
REGEX_PRECEDER2 = "(,=:[!&|?{};+-*%<>~^";
|
|
72120
72163
|
BLOCK_SCAFFOLD = /=>|\b(?:test|describe|it|beforeEach|afterEach|beforeAll|afterAll|function)\b/;
|
|
72121
72164
|
cachedAssertionInput = null;
|
|
72122
72165
|
cachedAssertionSource = { raw: "", normalized: "", bindings: /* @__PURE__ */ new Map(), bindingRefs: /* @__PURE__ */ new Map() };
|
|
@@ -72567,7 +72610,7 @@ function detectsErrorBannerAssertion(code) {
|
|
|
72567
72610
|
const cleaned = stripCommentsAndLogs(stripLoginScaffolding(code));
|
|
72568
72611
|
const lines = cleaned.split("\n");
|
|
72569
72612
|
const candidates = [];
|
|
72570
|
-
const positive = (stmt) => !
|
|
72613
|
+
const positive = (stmt) => !claimsAbsence(stmt);
|
|
72571
72614
|
const statements = liveExpectStatements(cleaned).map((s) => s.stmt);
|
|
72572
72615
|
for (const stmt of statements) {
|
|
72573
72616
|
if (positive(stmt))
|
|
@@ -72696,6 +72739,12 @@ function detectsObservedFailureAsExpected(code) {
|
|
|
72696
72739
|
return FAILURE_STATUS_ASSERT.some((re) => re.test(stmt)) || hasFailedListener && FAILED_LIST_ASSERT.test(stmt);
|
|
72697
72740
|
});
|
|
72698
72741
|
}
|
|
72742
|
+
function claimsAbsence(stmt) {
|
|
72743
|
+
const negated = NEGATED_ASSERT_NOT.test(stmt);
|
|
72744
|
+
const bare = negated ? stmt.replace(NOT_BEFORE_MATCHER, ".") : stmt;
|
|
72745
|
+
const absenceMatcher = /\.toBeHidden\s*\(|\.toHaveCount\s*\(\s*0\s*\)/.test(bare) || VALUE_ABSENCE.test(bare) || OPTION_ABSENCE.test(bare);
|
|
72746
|
+
return negated !== absenceMatcher;
|
|
72747
|
+
}
|
|
72699
72748
|
function isVacuousErrorAbsence(stmt, presence) {
|
|
72700
72749
|
if (!ABSENCE_MATCHER.test(stmt))
|
|
72701
72750
|
return false;
|
|
@@ -72711,19 +72760,53 @@ function isChromeTarget(stmt) {
|
|
|
72711
72760
|
return CHROME_LOCATOR.test(stmt) && !CONTENT_ROLE.test(stmt) && !/getByText\s*\(/.test(stmt);
|
|
72712
72761
|
}
|
|
72713
72762
|
function countsAsContentText(stmt) {
|
|
72714
|
-
if (!TEXT_CONTENT_MATCHER.test(stmt))
|
|
72763
|
+
if (!TEXT_CONTENT_MATCHER.test(stmt) || NEGATED_ASSERT.test(stmt))
|
|
72715
72764
|
return false;
|
|
72716
72765
|
if (isSymbolOnlyArgument(stmt, TEXT_CONTENT_MATCHER))
|
|
72717
72766
|
return false;
|
|
72718
|
-
|
|
72767
|
+
return onContentTarget(stmt);
|
|
72768
|
+
}
|
|
72769
|
+
function onContentTarget(stmt) {
|
|
72770
|
+
return !isChromeTarget(stmt) || /getByRole\s*\(\s*['"`]main['"`]/i.test(stmt);
|
|
72771
|
+
}
|
|
72772
|
+
function provesTextRemoved(stmt, presence) {
|
|
72773
|
+
const m = stmt.match(NEGATED_TEXT);
|
|
72774
|
+
if (!m || !onContentTarget(stmt))
|
|
72775
|
+
return false;
|
|
72776
|
+
const text = m[1] ?? m[2];
|
|
72777
|
+
if (text === void 0)
|
|
72719
72778
|
return true;
|
|
72720
|
-
|
|
72779
|
+
if (!/[\p{L}\p{N}]/u.test(text))
|
|
72780
|
+
return false;
|
|
72781
|
+
return !ERROR_TEXT_WORDS.test(text) || presence().includes(text);
|
|
72721
72782
|
}
|
|
72722
72783
|
function isDataContentRole(stmt) {
|
|
72723
72784
|
return CONTENT_ROLE.test(stmt) && !ANNOUNCE_ROLE.test(stmt);
|
|
72724
72785
|
}
|
|
72786
|
+
function destructuresRequest(code) {
|
|
72787
|
+
let readTo = -1;
|
|
72788
|
+
for (const m of code.matchAll(ASYNC_DESTRUCTURE_OPEN)) {
|
|
72789
|
+
const start = m.index + m[0].length;
|
|
72790
|
+
if (start <= readTo)
|
|
72791
|
+
continue;
|
|
72792
|
+
let end = start;
|
|
72793
|
+
while (end < code.length && code[end] !== "}" && code[end] !== ")")
|
|
72794
|
+
end++;
|
|
72795
|
+
readTo = end;
|
|
72796
|
+
if (end === code.length)
|
|
72797
|
+
return false;
|
|
72798
|
+
if (code[end] !== "}" || !REQUEST_WORD.test(code.slice(start, end)))
|
|
72799
|
+
continue;
|
|
72800
|
+
let close = end + 1;
|
|
72801
|
+
while (close < code.length && /\s/.test(code[close]))
|
|
72802
|
+
close++;
|
|
72803
|
+
if (code[close] === ")")
|
|
72804
|
+
return true;
|
|
72805
|
+
}
|
|
72806
|
+
return false;
|
|
72807
|
+
}
|
|
72725
72808
|
function isApiTest(code) {
|
|
72726
|
-
const usesRequestFixture =
|
|
72809
|
+
const usesRequestFixture = destructuresRequest(code) || /\brequest\.(get|post|put|patch|delete|head|fetch)\s*\(/.test(code);
|
|
72727
72810
|
if (!usesRequestFixture)
|
|
72728
72811
|
return false;
|
|
72729
72812
|
const drivesUi = /\bpage\.(getBy\w+|locator|click|fill|goto|waitForURL|reload)\s*\(/.test(code) || /\.(click|fill|check|uncheck|selectOption|pressSequentially)\s*\(/.test(code);
|
|
@@ -72982,6 +73065,9 @@ function hasOnlyConstantAssertions(code) {
|
|
|
72982
73065
|
const { constant, real } = constantAssertions(code);
|
|
72983
73066
|
return constant.length > 0 && real === 0;
|
|
72984
73067
|
}
|
|
73068
|
+
function envValueKey(name) {
|
|
73069
|
+
return `\0env:${name}`;
|
|
73070
|
+
}
|
|
72985
73071
|
function enteredValues(stmts) {
|
|
72986
73072
|
const values = /* @__PURE__ */ new Map();
|
|
72987
73073
|
const navLines = [];
|
|
@@ -72990,24 +73076,55 @@ function enteredValues(stmts) {
|
|
|
72990
73076
|
navLines.push(startLine);
|
|
72991
73077
|
let m;
|
|
72992
73078
|
ENTERED_VALUE.lastIndex = 0;
|
|
72993
|
-
|
|
72994
|
-
const
|
|
72995
|
-
if (!
|
|
72996
|
-
values.set(value, startLine);
|
|
72997
|
-
|
|
73079
|
+
const add = (value) => {
|
|
73080
|
+
const lines = values.get(value);
|
|
73081
|
+
if (!lines)
|
|
73082
|
+
values.set(value, [startLine]);
|
|
73083
|
+
else if (lines[lines.length - 1] !== startLine)
|
|
73084
|
+
lines.push(startLine);
|
|
73085
|
+
};
|
|
73086
|
+
while (m = ENTERED_VALUE.exec(stmt))
|
|
73087
|
+
add((m[1] ?? m[2] ?? m[3]).toLowerCase());
|
|
73088
|
+
ENTERED_ENV.lastIndex = 0;
|
|
73089
|
+
while (m = ENTERED_ENV.exec(stmt))
|
|
73090
|
+
add(envValueKey(m[1] ?? m[2] ?? m[3] ?? m[4]));
|
|
72998
73091
|
}
|
|
72999
73092
|
return { values, navLines };
|
|
73000
73093
|
}
|
|
73001
|
-
function
|
|
73094
|
+
function countBelow(lines, line) {
|
|
73095
|
+
let lo = 0;
|
|
73096
|
+
let hi = lines.length;
|
|
73097
|
+
while (lo < hi) {
|
|
73098
|
+
const mid = lo + hi >> 1;
|
|
73099
|
+
if (lines[mid] < line)
|
|
73100
|
+
lo = mid + 1;
|
|
73101
|
+
else
|
|
73102
|
+
hi = mid;
|
|
73103
|
+
}
|
|
73104
|
+
return lo;
|
|
73105
|
+
}
|
|
73106
|
+
function enteredLinesOf(stmt, entered) {
|
|
73002
73107
|
const m = stmt.match(/\.toHaveValue\s*\(\s*(['"`])((?:(?!\1).)+)\1/);
|
|
73003
|
-
if (
|
|
73108
|
+
if (m)
|
|
73109
|
+
return entered.values.get(m[2].toLowerCase());
|
|
73110
|
+
const env = stmt.match(HAVE_VALUE_ENV);
|
|
73111
|
+
return env ? entered.values.get(envValueKey(env[1] ?? env[2])) : void 0;
|
|
73112
|
+
}
|
|
73113
|
+
function typedSinceLastNav(stmt, entered, startLine, lines = enteredLinesOf(stmt, entered)) {
|
|
73114
|
+
if (!lines || startLine === void 0)
|
|
73115
|
+
return false;
|
|
73116
|
+
const before = countBelow(lines, startLine);
|
|
73117
|
+
if (before === 0)
|
|
73004
73118
|
return false;
|
|
73005
|
-
|
|
73006
|
-
|
|
73119
|
+
return countBelow(entered.navLines, startLine) === countBelow(entered.navLines, lines[before - 1] + 1);
|
|
73120
|
+
}
|
|
73121
|
+
function isEnteredValueEcho(stmt, entered, startLine) {
|
|
73122
|
+
const lines = enteredLinesOf(stmt, entered);
|
|
73123
|
+
if (!lines)
|
|
73007
73124
|
return false;
|
|
73008
|
-
if (startLine === void 0)
|
|
73125
|
+
if (startLine === void 0 || lines[0] >= startLine)
|
|
73009
73126
|
return true;
|
|
73010
|
-
return
|
|
73127
|
+
return typedSinceLastNav(stmt, entered, startLine, lines);
|
|
73011
73128
|
}
|
|
73012
73129
|
function isAnyValueMatcher(stmt) {
|
|
73013
73130
|
if (/\.not\.toHaveValue\s*\(\s*(?:['"`]{2}|\/\^?\$?\/)/.test(stmt))
|
|
@@ -73097,6 +73214,43 @@ function hasAttributeTransition(stmts) {
|
|
|
73097
73214
|
return true;
|
|
73098
73215
|
return false;
|
|
73099
73216
|
}
|
|
73217
|
+
function comparesWithItself(subject, tail) {
|
|
73218
|
+
const m = SELF_COMPARE_MATCHER.exec(tail);
|
|
73219
|
+
if (!m)
|
|
73220
|
+
return false;
|
|
73221
|
+
const args = balancedArguments(tail, m[0].length, MATCHER_ARGS_MAX);
|
|
73222
|
+
if (args === null)
|
|
73223
|
+
return false;
|
|
73224
|
+
const squash2 = (x) => x.replace(/^\s*await\s+/, "").replace(/\s+/g, "");
|
|
73225
|
+
const expected = squash2(args);
|
|
73226
|
+
return expected === squash2(m[1] === "toHaveCount" ? `${subject}.count()` : subject);
|
|
73227
|
+
}
|
|
73228
|
+
function asPlainAssertion(s) {
|
|
73229
|
+
const { stmt } = s;
|
|
73230
|
+
if (COUNT_AT_LEAST_ZERO.test(stmt))
|
|
73231
|
+
return [];
|
|
73232
|
+
const subject = extractExpectSubject(stmt);
|
|
73233
|
+
if (subject === null)
|
|
73234
|
+
return [s];
|
|
73235
|
+
const plain = subject.replace(/^await\s+/, "").trim();
|
|
73236
|
+
const subjectAt = stmt.indexOf(subject, stmt.search(EXPECT_CALL_RE));
|
|
73237
|
+
const tail = stmt.slice(subjectAt + subject.length).trimStart();
|
|
73238
|
+
const as = (rewritten) => [{ ...s, stmt: rewritten }];
|
|
73239
|
+
if (LOCATOR_EXPR.test(plain) && !LOCATOR_VALUE_READ.test(plain) && ALWAYS_TRUE_ON_OBJECT.test(tail))
|
|
73240
|
+
return [];
|
|
73241
|
+
if (DEFINED_VALUE_READ.test(plain) && ALWAYS_DEFINED.test(tail))
|
|
73242
|
+
return [];
|
|
73243
|
+
if (comparesWithItself(plain, tail))
|
|
73244
|
+
return [];
|
|
73245
|
+
const visible = /^(.+)\.\s*isVisible\s*\(\s*\)$/s.exec(plain);
|
|
73246
|
+
if (visible && IS_VISIBLE_TRUE.test(tail))
|
|
73247
|
+
return as(`await expect(${visible[1]}).toBeVisible();`);
|
|
73248
|
+
if (/^page\s*\.\s*(?:url|title)\s*\(\s*\)$/.test(plain) && PAGE_VALUE_MATCHER.test(tail)) {
|
|
73249
|
+
const matcher = plain.includes("url") ? "toHaveURL" : "toHaveTitle";
|
|
73250
|
+
return as(`await expect(page)${tail.replace(/^\)\s*\.\s*\w+\s*\(/, `.${matcher}(`)}`);
|
|
73251
|
+
}
|
|
73252
|
+
return [s];
|
|
73253
|
+
}
|
|
73100
73254
|
function creditsOutcomeAlways(stmt, entered, startLine) {
|
|
73101
73255
|
if (!OUTCOME_ALWAYS.some((re) => re.test(stmt)))
|
|
73102
73256
|
return false;
|
|
@@ -73170,6 +73324,8 @@ function classifyOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstM
|
|
|
73170
73324
|
continue;
|
|
73171
73325
|
if (isVacuousErrorAbsence(stmt, presence))
|
|
73172
73326
|
continue;
|
|
73327
|
+
if (COUNT_ONE.test(stmt) && quotedAssertedStrings(stmt).some((t) => clicked.has(t.toLowerCase())))
|
|
73328
|
+
continue;
|
|
73173
73329
|
if (creditsOutcomeAlways(stmt, entered, startLine))
|
|
73174
73330
|
return { kind: "durable" };
|
|
73175
73331
|
if (mutated && !NEGATED_ASSERT.test(stmt) && MESSAGE_SURFACE.test(stmt) && OUTCOME_TEXT.test(assertedText(stmt))) {
|
|
@@ -73179,12 +73335,15 @@ function classifyOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstM
|
|
|
73179
73335
|
else
|
|
73180
73336
|
return { kind: "durable" };
|
|
73181
73337
|
}
|
|
73182
|
-
|
|
73338
|
+
const retyped = typedSinceLastNav(stmt, entered, startLine);
|
|
73339
|
+
if (!retyped && STATE_MATCHER.test(stmt) && (persistence && startLine !== void 0 ? reopenedAfterSave(startLine, persistence, persistence.reloadCalls) : reloaded))
|
|
73183
73340
|
return { kind: "durable" };
|
|
73184
|
-
if (provesStoredControlValue(stmt, startLine, persistence))
|
|
73341
|
+
if (!retyped && provesStoredControlValue(stmt, startLine, persistence))
|
|
73185
73342
|
return { kind: "durable" };
|
|
73186
73343
|
if (countsAsContentText(stmt))
|
|
73187
73344
|
return { kind: "durable" };
|
|
73345
|
+
if (provesTextRemoved(stmt, presence))
|
|
73346
|
+
return { kind: "durable" };
|
|
73188
73347
|
if (mutated && VISIBILITY_MATCHER.test(stmt)) {
|
|
73189
73348
|
const revealsText = GET_BY_TEXT.test(stmt) || HAS_TEXT_FILTER.test(stmt) || CONTENT_ROLE.test(stmt);
|
|
73190
73349
|
if (revealsText && !isChromeTarget(stmt)) {
|
|
@@ -73251,7 +73410,7 @@ function detectOutcomeProof(stmts, mutated, reloaded, clicked, entered, firstMut
|
|
|
73251
73410
|
function validateAssertionStrength(code, opts = {}) {
|
|
73252
73411
|
const body = stripLoginScaffolding(code);
|
|
73253
73412
|
const lines = body.split("\n");
|
|
73254
|
-
const stmts = liveExpectStatements(stripCoverageComments(body));
|
|
73413
|
+
const stmts = liveExpectStatements(stripCoverageComments(body)).flatMap(asPlainAssertion);
|
|
73255
73414
|
const base2 = (extra) => ({
|
|
73256
73415
|
apiTest: false,
|
|
73257
73416
|
interacted: false,
|
|
@@ -73457,7 +73616,7 @@ function validateAssertionStrength(code, opts = {}) {
|
|
|
73457
73616
|
signals
|
|
73458
73617
|
};
|
|
73459
73618
|
}
|
|
73460
|
-
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;
|
|
73619
|
+
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;
|
|
73461
73620
|
var init_assertion_strength = __esm({
|
|
73462
73621
|
"../shared/dist/assertion-strength.js"() {
|
|
73463
73622
|
"use strict";
|
|
@@ -73482,8 +73641,8 @@ var init_assertion_strength = __esm({
|
|
|
73482
73641
|
// form field value
|
|
73483
73642
|
/\.toMatch\s*\(/,
|
|
73484
73643
|
// string/regex content match (e.g. textContent() vs /[2-9] selected/)
|
|
73485
|
-
|
|
73486
|
-
// a control became DISABLED — a gating/validation outcome
|
|
73644
|
+
/(?<!\.not\s*)\.\s*toBeDisabled\s*\(/,
|
|
73645
|
+
// a control became DISABLED — a gating/validation outcome (not.toBeDisabled is the toBeEnabled twin)
|
|
73487
73646
|
/\.not\.toBeVisible\s*\(/,
|
|
73488
73647
|
/\.toBeHidden\s*\(/
|
|
73489
73648
|
// something the action removed/closed (disappearance proof)
|
|
@@ -73491,7 +73650,7 @@ var init_assertion_strength = __esm({
|
|
|
73491
73650
|
FORM_INPUT = /\.(fill|selectOption|setInputFiles|check|uncheck|setChecked|pressSequentially)\s*\(|keyboard\.type\s*\(/;
|
|
73492
73651
|
ANY_CLICK = /\.click\s*\(/;
|
|
73493
73652
|
NAV_LOCATOR = /getByRole\s*\(\s*['"`](?:link|menuitem)['"`]/i;
|
|
73494
|
-
URL_PROOF = /\.toHaveURL\s*\(|\.waitForURL\s*\(/;
|
|
73653
|
+
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*\)/;
|
|
73495
73654
|
RELOAD = /\.reload\s*\(/;
|
|
73496
73655
|
EXPECT_STMT = /\bexpect\s*[.(]/;
|
|
73497
73656
|
BLOCK_SCAFFOLD2 = /=>|\b(?:test|describe|it|beforeEach|afterEach|beforeAll|afterAll|function)\b/;
|
|
@@ -73520,6 +73679,7 @@ var init_assertion_strength = __esm({
|
|
|
73520
73679
|
INBOX_START = /^\s*\/\/\s*>>>\s*VALIDATE_QA_INBOX/;
|
|
73521
73680
|
INBOX_END = /^\s*\/\/\s*<<<\s*VALIDATE_QA_INBOX/;
|
|
73522
73681
|
NEGATED_ASSERT = /\.not\s*\.\s*to[A-Z]\w*|\.toBeHidden\s*\(/;
|
|
73682
|
+
NEGATED_ASSERT_NOT = /\.not\s*\.\s*to[A-Z]/;
|
|
73523
73683
|
CONST_CHAIN_MAX_DEPTH = 5;
|
|
73524
73684
|
TYPED_INPUT = /\.(fill|type|pressSequentially|setInputFiles)\s*\(/;
|
|
73525
73685
|
TITLE_LINE = /^\s*(?:test|describe)(?:\.\w+)?\s*\(/;
|
|
@@ -73535,8 +73695,14 @@ var init_assertion_strength = __esm({
|
|
|
73535
73695
|
CATCH_ALL_PATTERN = /^(['"`])\*\*(?:\/\*)?\1$|^\/\.\*\/[a-z]*$/;
|
|
73536
73696
|
GUARD_HANDLER = /\bMUTATING\.has\s*\(|blockedbyclient|Read-only guard/;
|
|
73537
73697
|
ABSENCE_MATCHER = /\.not\.toBeVisible\s*\(|\.toBeHidden\s*\(|\.toHaveCount\s*\(\s*0\s*\)/;
|
|
73698
|
+
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*\())/;
|
|
73699
|
+
OPTION_ABSENCE = /\.(?:toBeVisible\s*\(\s*\{[^{}()]{0,200}\bvisible|toBeAttached\s*\(\s*\{[^{}()]{0,200}\battached)\s*:\s*false\b/;
|
|
73700
|
+
NOT_BEFORE_MATCHER = /\.not\s*\.\s*(?=to[A-Z])/g;
|
|
73538
73701
|
ERROR_TEXT_WORDS = /error|fail|wrong|try again|unable|could ?n.?t|can.?t|problem|invalid|unavailable/i;
|
|
73539
73702
|
TEXT_REGEX_ARG = /(?:getByText|hasText|getByRole\([^)]{0,200}name)\s*[:(]\s*(\/(?:\\.|[^/\\\n])+\/[a-z]*)/;
|
|
73703
|
+
NEGATED_TEXT = /\.not\s*\.\s*(?:toHaveText|toContainText)\s*\(\s*(?:['"`]([^'"`]*)['"`]|\/((?:\\.|[^/\\\n])+)\/)?/;
|
|
73704
|
+
ASYNC_DESTRUCTURE_OPEN = /async\s*\(\s*\{/g;
|
|
73705
|
+
REQUEST_WORD = /\brequest\b/;
|
|
73540
73706
|
ROLE_NAME_RE = /getByRole\s*\(\s*['"`][a-z]+['"`]\s*,\s*\{[^}]*?name\s*:\s*(?:['"`]([^'"`]+)['"`]|\/([^/]+)\/)/gi;
|
|
73541
73707
|
INTERACT_VERB = /\.(click|fill|check|uncheck|setChecked|selectOption|pressSequentially)\s*\(/;
|
|
73542
73708
|
ROLE_SIG_RE = /getByRole\s*\(\s*['"`]([a-z]+)['"`]\s*,\s*\{[^}]*?name\s*:\s*(?:['"`]([^'"`]+)['"`]|\/([^/]+)\/)/gi;
|
|
@@ -73557,7 +73723,20 @@ var init_assertion_strength = __esm({
|
|
|
73557
73723
|
MATCHER_OPEN = /\s*(?:\.\s*(?:not|resolves|rejects)\s*)*\.\s*[A-Za-z_$][\w$]*\s*\(/y;
|
|
73558
73724
|
ENTERED_VALUE = /\.(?:fill|pressSequentially)\s*\(\s*['"`]([^'"`]+)['"`]|keyboard\.type\s*\(\s*['"`]([^'"`]+)['"`]|\.selectOption\s*\(\s*(?:\[\s*)?(?:\{\s*(?:label|value)\s*:\s*)?['"`]([^'"`]+)['"`]/g;
|
|
73559
73725
|
PAGE_NAV = /\.(?:goto|reload)\s*\(/;
|
|
73726
|
+
ENV_READ = String.raw`process\.env(?:(?:\?\.|\.)([A-Za-z_]\w*)|(?:\?\.)?\[\s*['"]([A-Za-z_]\w*)['"]\s*\])`;
|
|
73727
|
+
ENTERED_ENV = new RegExp(String.raw`\.(?:fill|pressSequentially)\s*\(\s*${ENV_READ}|keyboard\.type\s*\(\s*${ENV_READ}`, "g");
|
|
73728
|
+
HAVE_VALUE_ENV = new RegExp(String.raw`\.toHaveValue\s*\(\s*${ENV_READ}`);
|
|
73560
73729
|
IN_FLIGHT_TEXT = /^(?:(?:sending|saving|loading|searching|checking|processing|submitting|preparing|updating|please wait|working|one moment)\b[^.]{0,40}\.{2,3}|\.{3}|…)$/i;
|
|
73730
|
+
LOCATOR_VALUE_READ = /\.(?:count|textContent|innerText|innerHTML|inputValue|getAttribute|isVisible|isHidden|isChecked|isEnabled|isDisabled|isEditable|allTextContents|allInnerTexts|evaluate|evaluateAll|boundingBox|all)\s*\(/;
|
|
73731
|
+
LOCATOR_EXPR = /^(?:this\.)?page\s*\.\s*(?:getBy\w+|locator)\s*\(/;
|
|
73732
|
+
ALWAYS_TRUE_ON_OBJECT = /^\)\s*\.\s*(?:toBeTruthy|toBeDefined|not\s*\.\s*(?:toBeNull|toBeUndefined|toBeFalsy))\s*\(/;
|
|
73733
|
+
COUNT_AT_LEAST_ZERO = /\.(?:count\s*\(\s*\)|length)[\s)]{0,10}\.(?:toBeGreaterThanOrEqual\s*\(\s*0\s*\)|toBeGreaterThan\s*\(\s*-\s*1\s*\))/;
|
|
73734
|
+
DEFINED_VALUE_READ = /\.\s*(?:count|textContent|innerText|innerHTML|inputValue|getAttribute|title|url|isVisible|isHidden|isChecked|isEnabled|isDisabled|isEditable|allTextContents|allInnerTexts)\s*\([^()]*\)$/;
|
|
73735
|
+
ALWAYS_DEFINED = /^\)\s*\.\s*(?:toBeDefined|not\s*\.\s*toBeUndefined)\s*\(/;
|
|
73736
|
+
SELF_COMPARE_MATCHER = /^\)\s*\.\s*(toBe|toEqual|toStrictEqual|toHaveCount)\s*\(/;
|
|
73737
|
+
IS_VISIBLE_TRUE = /^\)*\s*\.\s*(?:toBe\s*\(\s*true\s*\)|toBeTruthy\s*\(\s*\))/;
|
|
73738
|
+
PAGE_VALUE_MATCHER = /^\)\s*\.\s*(?:toBe|toEqual|toStrictEqual|toMatch|toContain)\s*\(/;
|
|
73739
|
+
COUNT_ONE = /\.\s*toHaveCount\s*\(\s*1\s*\)/;
|
|
73561
73740
|
FORM_CONTROL_LOCATOR = /getByRole\s*\(\s*['"`](?:combobox|switch|checkbox|radio|textbox|searchbox|spinbutton|slider)['"`]|getByLabel\s*\(|getByPlaceholder\s*\(/;
|
|
73562
73741
|
CONTROL_VALUE_MATCHER = /\.(?:toHaveValue|toHaveText|toContainText)\s*\(|\.toHaveAttribute\s*\(\s*['"`]aria-checked['"`]/;
|
|
73563
73742
|
COPY_CONTROL = /\bcopy\b/i;
|
|
@@ -73766,7 +73945,7 @@ function reportedBugWhere() {
|
|
|
73766
73945
|
function bugReviewStatus(status) {
|
|
73767
73946
|
return status === "QUARANTINED" ? "confirmed" : "needs-review";
|
|
73768
73947
|
}
|
|
73769
|
-
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;
|
|
73948
|
+
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;
|
|
73770
73949
|
var init_run_classification = __esm({
|
|
73771
73950
|
"../shared/dist/run-classification.js"() {
|
|
73772
73951
|
"use strict";
|
|
@@ -73786,6 +73965,7 @@ var init_run_classification = __esm({
|
|
|
73786
73965
|
UNEXPECTED_PASS_ERROR_PREFIX = "UNEXPECTED_PASS:";
|
|
73787
73966
|
BUG_TEST_BROKEN_ERROR_PREFIX = "BUG_TEST_BROKEN:";
|
|
73788
73967
|
BUG_TEST_BROKEN_REASON = "bug test broken (not a bug verdict)";
|
|
73968
|
+
TEST_DID_NOT_RUN_ERROR = "Test did not run (a dependency failed or the run was interrupted)";
|
|
73789
73969
|
EMAIL_NOT_RECEIVED_PREFIXES = [
|
|
73790
73970
|
"VERIFICATION_EMAIL_NOT_RECEIVED:",
|
|
73791
73971
|
"VERIFICATION_EMAIL_HAS_NO_CODE:",
|
|
@@ -76527,6 +76707,23 @@ var init_auth_block_detector = __esm({
|
|
|
76527
76707
|
}
|
|
76528
76708
|
});
|
|
76529
76709
|
|
|
76710
|
+
// ../shared/dist/auth-session-stamp.js
|
|
76711
|
+
function parseAuthSessionStamp(value) {
|
|
76712
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
76713
|
+
return null;
|
|
76714
|
+
const { shared, role, generation } = value;
|
|
76715
|
+
if (shared !== true || role !== "producer" && role !== "follower")
|
|
76716
|
+
return null;
|
|
76717
|
+
return typeof generation === "string" && AUTH_SESSION_GENERATION_RE.test(generation) ? { shared: true, role, generation } : { shared: true, role };
|
|
76718
|
+
}
|
|
76719
|
+
var AUTH_SESSION_GENERATION_RE;
|
|
76720
|
+
var init_auth_session_stamp = __esm({
|
|
76721
|
+
"../shared/dist/auth-session-stamp.js"() {
|
|
76722
|
+
"use strict";
|
|
76723
|
+
AUTH_SESSION_GENERATION_RE = /^[0-9a-z]{1,16}$/;
|
|
76724
|
+
}
|
|
76725
|
+
});
|
|
76726
|
+
|
|
76530
76727
|
// ../shared/dist/auth-state-freshness.js
|
|
76531
76728
|
function isCsrfTokenName(name) {
|
|
76532
76729
|
return /csrf|xsrf|forgery|authenticity|requestverification/.test(name.toLowerCase());
|
|
@@ -77755,7 +77952,7 @@ var init_agentic_cli_runtime = __esm({
|
|
|
77755
77952
|
GROK_CLI_DEFAULT_MODEL = "grok-4.7";
|
|
77756
77953
|
GROK_CLI_DEFAULT_REASONING_EFFORT = "high";
|
|
77757
77954
|
CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5-5";
|
|
77758
|
-
CLAUDE_CLI_DEFAULT_EFFORT = "
|
|
77955
|
+
CLAUDE_CLI_DEFAULT_EFFORT = "high";
|
|
77759
77956
|
MUSE_CLI_DEFAULT_MODEL = "muse-spark-1.3-contributor";
|
|
77760
77957
|
MUSE_CLI_DEFAULT_EFFORT = "high";
|
|
77761
77958
|
CODEX_CLI_DEFAULT_MODEL = "gpt-6.1-sol";
|
|
@@ -77806,9 +78003,25 @@ function isOpenCodeGoModelId(id) {
|
|
|
77806
78003
|
function hasOpenCodeGoPrefix(id) {
|
|
77807
78004
|
return (id?.trim() ?? "").startsWith(OPENCODE_GO_PREFIX);
|
|
77808
78005
|
}
|
|
78006
|
+
function hasOpenCodeGo2Prefix(id) {
|
|
78007
|
+
return (id?.trim() ?? "").startsWith(OPENCODE_GO_2_PREFIX);
|
|
78008
|
+
}
|
|
77809
78009
|
function openCodeGoWireModel(id) {
|
|
77810
78010
|
const trimmed = id?.trim() ?? "";
|
|
77811
|
-
|
|
78011
|
+
if (!isOpenCodeGoModelId(trimmed))
|
|
78012
|
+
return null;
|
|
78013
|
+
return trimmed.slice((hasOpenCodeGo2Prefix(trimmed) ? OPENCODE_GO_2_PREFIX : OPENCODE_GO_PREFIX).length);
|
|
78014
|
+
}
|
|
78015
|
+
function isZaiModelId(id) {
|
|
78016
|
+
const trimmed = id?.trim() ?? "";
|
|
78017
|
+
return ZAI_MODEL_PATTERN.test(trimmed) && !trimmed.includes("..");
|
|
78018
|
+
}
|
|
78019
|
+
function hasZaiPrefix(id) {
|
|
78020
|
+
return (id?.trim() ?? "").startsWith(ZAI_PREFIX);
|
|
78021
|
+
}
|
|
78022
|
+
function zaiWireModel(id) {
|
|
78023
|
+
const trimmed = id?.trim() ?? "";
|
|
78024
|
+
return isZaiModelId(trimmed) ? trimmed.slice(ZAI_PREFIX.length) : null;
|
|
77812
78025
|
}
|
|
77813
78026
|
function isEngineId(value) {
|
|
77814
78027
|
return CLI_ENGINE_MODEL_IDS.includes(value);
|
|
@@ -77906,7 +78119,7 @@ function museCliContributorMode(env = process.env) {
|
|
|
77906
78119
|
const raw = (env.MUSE_CLI_CONTRIBUTOR_MODE ?? "").trim().toLowerCase();
|
|
77907
78120
|
return raw === "off" || raw === "false" || raw === "0" || raw === "no" ? "off" : "on";
|
|
77908
78121
|
}
|
|
77909
|
-
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;
|
|
78122
|
+
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;
|
|
77910
78123
|
var init_engine_spec = __esm({
|
|
77911
78124
|
"../shared/dist/engine-spec.js"() {
|
|
77912
78125
|
"use strict";
|
|
@@ -77965,7 +78178,10 @@ var init_engine_spec = __esm({
|
|
|
77965
78178
|
OPENROUTER_PREFIX = "openrouter:";
|
|
77966
78179
|
OPENROUTER_MODEL_PATTERN = /^openrouter:[a-z0-9][a-z0-9._-]{0,40}\/[A-Za-z0-9._:-]{1,100}$/;
|
|
77967
78180
|
OPENCODE_GO_PREFIX = "opencode-go:";
|
|
77968
|
-
|
|
78181
|
+
OPENCODE_GO_2_PREFIX = "opencode-go-2:";
|
|
78182
|
+
OPENCODE_GO_MODEL_PATTERN = /^opencode-go(?:-2)?:[a-z0-9][a-z0-9._-]{0,100}$/;
|
|
78183
|
+
ZAI_PREFIX = "zai:";
|
|
78184
|
+
ZAI_MODEL_PATTERN = /^zai:glm-[a-z0-9][a-z0-9._-]{0,60}$/;
|
|
77969
78185
|
}
|
|
77970
78186
|
});
|
|
77971
78187
|
|
|
@@ -78250,6 +78466,8 @@ var init_api_model_catalog = __esm({
|
|
|
78250
78466
|
authCaptureModel: "Login capture",
|
|
78251
78467
|
plannerModel: "Scenario Planner",
|
|
78252
78468
|
plannerGateModel: "Planner Gate",
|
|
78469
|
+
pwAgentsHealerModel: "Test Healer (Playwright agents)",
|
|
78470
|
+
pwAgentsReviewModel: "Plan Review (Playwright agents)",
|
|
78253
78471
|
generationModel: "Code Generation",
|
|
78254
78472
|
reviewModel: "Code Review",
|
|
78255
78473
|
apiTestModel: "API Test Generator",
|
|
@@ -78274,11 +78492,6 @@ var init_api_model_catalog = __esm({
|
|
|
78274
78492
|
});
|
|
78275
78493
|
|
|
78276
78494
|
// ../shared/dist/provider-chains.js
|
|
78277
|
-
function isClaudeModel(id) {
|
|
78278
|
-
if (/claude|anthropic/i.test(id))
|
|
78279
|
-
return true;
|
|
78280
|
-
return API_MODEL_CATALOG.some((m) => m.provider === "anthropic" && (m.id === id || m.apiModel === id));
|
|
78281
|
-
}
|
|
78282
78495
|
function chainKey(modelId) {
|
|
78283
78496
|
const id = canonicalModelId(modelId);
|
|
78284
78497
|
if (!id)
|
|
@@ -78286,34 +78499,83 @@ function chainKey(modelId) {
|
|
|
78286
78499
|
const entry = API_MODEL_CATALOG.find((m) => m.id === id || m.apiModel === id);
|
|
78287
78500
|
return entry?.id ?? id;
|
|
78288
78501
|
}
|
|
78502
|
+
function has(map2, key) {
|
|
78503
|
+
return Object.prototype.hasOwnProperty.call(map2, key);
|
|
78504
|
+
}
|
|
78289
78505
|
function providerChainFor(modelId) {
|
|
78290
78506
|
const key = chainKey(modelId);
|
|
78291
|
-
|
|
78292
|
-
|
|
78293
|
-
|
|
78507
|
+
return key && has(PROVIDER_CHAINS, key) ? PROVIDER_CHAINS[key] : [];
|
|
78508
|
+
}
|
|
78509
|
+
function providerChainLeadsFor(modelId) {
|
|
78510
|
+
const key = chainKey(modelId);
|
|
78511
|
+
return key && has(PROVIDER_CHAIN_LEADS, key) ? PROVIDER_CHAIN_LEADS[key] : [];
|
|
78512
|
+
}
|
|
78513
|
+
function allChains() {
|
|
78514
|
+
return [...Object.entries(PROVIDER_CHAINS), ...Object.entries(PROVIDER_CHAIN_LEADS)];
|
|
78294
78515
|
}
|
|
78295
78516
|
function isProviderChainHopId(modelId) {
|
|
78296
78517
|
const id = modelId ?? "";
|
|
78297
|
-
return id !== "" &&
|
|
78518
|
+
return id !== "" && allChains().some(([, hops]) => hops.includes(id));
|
|
78298
78519
|
}
|
|
78299
78520
|
function providerChainPrimariesForHop(hopId) {
|
|
78300
78521
|
const id = hopId ?? "";
|
|
78301
78522
|
if (!id)
|
|
78302
78523
|
return [];
|
|
78303
|
-
return
|
|
78524
|
+
return allChains().filter(([, hops]) => hops.includes(id)).map(([primary]) => primary);
|
|
78525
|
+
}
|
|
78526
|
+
function providerChainHostOf(value, modelValue) {
|
|
78527
|
+
if (value === modelValue)
|
|
78528
|
+
return "own";
|
|
78529
|
+
if (hasZaiPrefix(value))
|
|
78530
|
+
return "zai";
|
|
78531
|
+
if (hasOpenCodeGo2Prefix(value))
|
|
78532
|
+
return "opencode-go-2";
|
|
78533
|
+
if (hasOpenCodeGoPrefix(value))
|
|
78534
|
+
return "opencode-go";
|
|
78535
|
+
if (hasOpenRouterPrefix(value))
|
|
78536
|
+
return "openrouter";
|
|
78537
|
+
return "own";
|
|
78538
|
+
}
|
|
78539
|
+
function providerHostPlan(modelId) {
|
|
78540
|
+
const key = chainKey(modelId);
|
|
78541
|
+
if (!key)
|
|
78542
|
+
return [];
|
|
78543
|
+
const own = { host: hasOpenRouterPrefix(key) ? "openrouter" : "own", value: key };
|
|
78544
|
+
const steps = [
|
|
78545
|
+
...providerChainLeadsFor(key).map((value) => ({ host: providerChainHostOf(value, key), value })),
|
|
78546
|
+
own,
|
|
78547
|
+
...providerChainFor(key).map((value) => ({ host: providerChainHostOf(value, key), value }))
|
|
78548
|
+
];
|
|
78549
|
+
const notOffered = Object.prototype.hasOwnProperty.call(PROVIDER_HOST_NOT_OFFERED, key) ? PROVIDER_HOST_NOT_OFFERED[key] : {};
|
|
78550
|
+
for (const [host, reason] of Object.entries(notOffered)) {
|
|
78551
|
+
const at = steps.findIndex((step) => step === own) + 1;
|
|
78552
|
+
steps.splice(at, 0, { host, value: null, notOffered: reason });
|
|
78553
|
+
}
|
|
78554
|
+
return steps;
|
|
78304
78555
|
}
|
|
78305
|
-
var PROVIDER_CHAINS;
|
|
78556
|
+
var PROVIDER_CHAINS, PROVIDER_CHAIN_LEADS, PROVIDER_HOST_NOT_OFFERED;
|
|
78306
78557
|
var init_provider_chains = __esm({
|
|
78307
78558
|
"../shared/dist/provider-chains.js"() {
|
|
78308
78559
|
"use strict";
|
|
78309
78560
|
init_api_model_catalog();
|
|
78561
|
+
init_engine_spec();
|
|
78310
78562
|
PROVIDER_CHAINS = {
|
|
78311
|
-
"minimax-m3": ["
|
|
78312
|
-
"minimax-m3.1-flash": ["
|
|
78563
|
+
"minimax-m3": ["opencode-go:minimax-m3", "openrouter:minimax/minimax-m3"],
|
|
78564
|
+
"minimax-m3.1-flash": ["opencode-go:minimax-m3.1-flash", "openrouter:minimax/minimax-m3.1-flash"],
|
|
78313
78565
|
"muse-spark-1.3-contributor": ["openrouter:meta/muse-spark-1.3-contributor"],
|
|
78314
|
-
"
|
|
78315
|
-
"
|
|
78316
|
-
"
|
|
78566
|
+
"claude-haiku-5-5": ["opencode-go:claude-haiku-5-5", "openrouter:anthropic/claude-haiku-5.5"],
|
|
78567
|
+
"gemini-3.1-pro-preview": ["openrouter:google/gemini-3.1-pro-preview"],
|
|
78568
|
+
"deepseek-flash": ["opencode-go-2:deepseek-v4.1-flash", "opencode-go:deepseek-v4.1-flash", "openrouter:deepseek/deepseek-v4.1-flash"],
|
|
78569
|
+
"deepseek-v4-pro": ["opencode-go-2:deepseek-v4-pro", "opencode-go:deepseek-v4-pro", "openrouter:deepseek/deepseek-v4-pro"]
|
|
78570
|
+
};
|
|
78571
|
+
PROVIDER_CHAIN_LEADS = {
|
|
78572
|
+
"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"],
|
|
78573
|
+
"openrouter:z-ai/glm-5.3": ["zai:glm-5.3", "opencode-go-2:glm-5.3", "opencode-go:glm-5.3"],
|
|
78574
|
+
"openrouter:z-ai/glm-5.2": ["zai:glm-5.2", "opencode-go-2:glm-5.2", "opencode-go:glm-5.2"]
|
|
78575
|
+
};
|
|
78576
|
+
PROVIDER_HOST_NOT_OFFERED = {
|
|
78577
|
+
"muse-spark-1.3-contributor": { "opencode-go": "OpenCode Go serves Muse only on its Responses API" },
|
|
78578
|
+
"gemini-3.1-pro-preview": { "opencode-go": "OpenCode Go does not serve Gemini" }
|
|
78317
78579
|
};
|
|
78318
78580
|
}
|
|
78319
78581
|
});
|
|
@@ -80272,7 +80534,7 @@ function stateLiteralsOf(line) {
|
|
|
80272
80534
|
const out = [];
|
|
80273
80535
|
for (const m of line.matchAll(STRING_LITERAL_RE)) {
|
|
80274
80536
|
const text = m[1] ?? m[2] ?? m[3] ?? "";
|
|
80275
|
-
if (
|
|
80537
|
+
if (PLACEHOLDER_ATTR_RE.test(text))
|
|
80276
80538
|
continue;
|
|
80277
80539
|
if (PLACEHOLDER_CALL_TAIL_RE.test(line.slice(Math.max(0, m.index - 40), m.index)))
|
|
80278
80540
|
continue;
|
|
@@ -80368,7 +80630,7 @@ function formatReadinessPollAdvisory(findings) {
|
|
|
80368
80630
|
const where = findings.length === 1 ? "One place" : `${findings.length} places`;
|
|
80369
80631
|
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}`;
|
|
80370
80632
|
}
|
|
80371
|
-
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;
|
|
80633
|
+
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;
|
|
80372
80634
|
var init_readiness_poll = __esm({
|
|
80373
80635
|
"../shared/dist/readiness-poll.js"() {
|
|
80374
80636
|
"use strict";
|
|
@@ -80381,7 +80643,7 @@ var init_readiness_poll = __esm({
|
|
|
80381
80643
|
STRING_LITERAL_RE = /'((?:\\.|[^'\\\n]){0,300})'|"((?:\\.|[^"\\\n]){0,300})"|`((?:\\.|[^`\\\n]){0,300})`/g;
|
|
80382
80644
|
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;
|
|
80383
80645
|
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;
|
|
80384
|
-
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,
|
|
80646
|
+
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;
|
|
80385
80647
|
LOCATOR_LINE_RE = /\.(?:getBy[A-Z]\w{0,30}|locator|toHaveText|toContainText)\s{0,20}\(/;
|
|
80386
80648
|
CLICK_RE = /\.(?:click|dblclick|tap)\s{0,20}\(/;
|
|
80387
80649
|
RELOAD_RE = /\bpage\.reload\s{0,20}\(/;
|
|
@@ -80395,6 +80657,7 @@ var init_readiness_poll = __esm({
|
|
|
80395
80657
|
TEST_END_RE = /^\s{0,20}\}\s{0,20}\)\s{0,20};?\s{0,20}$/;
|
|
80396
80658
|
TEST_START_RE = /\btest(?:\.\w{1,20})?\s{0,20}\(/;
|
|
80397
80659
|
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;
|
|
80660
|
+
PLACEHOLDER_ATTR_RE = /placeholder\s{0,4}[*^$~|]?=/;
|
|
80398
80661
|
PLACEHOLDER_CALL_TAIL_RE = /getByPlaceholder\s{0,20}\(\s{0,20}$/;
|
|
80399
80662
|
POLL_SHAPE = "await expect(async () => { await page.reload(); await expect(<the finished state>).toBeVisible({ timeout: 1500 }); }).toPass({ timeout: 20000 });";
|
|
80400
80663
|
}
|
|
@@ -80796,6 +81059,15 @@ function computes(line) {
|
|
|
80796
81059
|
const code = line.replace(STRING_RE, '""').replace(REGEX_LITERAL_RE, "$1RX").replace(LITERAL_ARITH_RE, "N");
|
|
80797
81060
|
return COMPUTE_RE.test(code) || RELATIONAL_RE.test(line);
|
|
80798
81061
|
}
|
|
81062
|
+
function identifiersIn(line) {
|
|
81063
|
+
const code = line.replace(STRING_RE, '""').replace(REGEX_LITERAL_RE, "$1RX");
|
|
81064
|
+
return [code, ...[...line.matchAll(TEMPLATE_EXPR_RE)].map((m) => m[1])].flatMap((part) => part.match(IDENTIFIER_RE) ?? []);
|
|
81065
|
+
}
|
|
81066
|
+
function addTyped(typed, value) {
|
|
81067
|
+
const d = digitsOf(value);
|
|
81068
|
+
if (/\d/.test(d))
|
|
81069
|
+
typed.add(d);
|
|
81070
|
+
}
|
|
80799
81071
|
function reasonFor4(kind, label, value) {
|
|
80800
81072
|
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.`;
|
|
80801
81073
|
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.`;
|
|
@@ -80807,25 +81079,32 @@ function analyzeDerivedValues(rawCode) {
|
|
|
80807
81079
|
for (const body of testBodies(rawCode)) {
|
|
80808
81080
|
if (findings.length >= MAX_FINDINGS4)
|
|
80809
81081
|
break;
|
|
80810
|
-
if (body.some(computes))
|
|
80811
|
-
continue;
|
|
80812
81082
|
const typed = /* @__PURE__ */ new Set();
|
|
80813
81083
|
const definitions = /* @__PURE__ */ new Map();
|
|
81084
|
+
const computed = /* @__PURE__ */ new Set();
|
|
81085
|
+
const usesComputed = (text) => identifiersIn(text).some((id) => computed.has(id));
|
|
80814
81086
|
for (const line of body) {
|
|
80815
81087
|
if (FILL_RE2.test(line) && !EXPECT_RE3.test(line)) {
|
|
80816
|
-
for (const m of line.matchAll(
|
|
80817
|
-
|
|
80818
|
-
|
|
80819
|
-
|
|
80820
|
-
|
|
81088
|
+
for (const m of line.matchAll(QUOTED_RE))
|
|
81089
|
+
addTyped(typed, m[1]);
|
|
81090
|
+
const arg = FILL_ARG_RE.exec(line)?.[1];
|
|
81091
|
+
const literal = arg === void 0 ? null : LITERAL_VALUE_RE.exec(definitions.get(arg) ?? "");
|
|
81092
|
+
const value = literal?.slice(1).find((v) => v !== void 0);
|
|
81093
|
+
if (value !== void 0)
|
|
81094
|
+
addTyped(typed, value);
|
|
80821
81095
|
}
|
|
80822
81096
|
const def = DEFINITION_RE.exec(line);
|
|
80823
|
-
if (def)
|
|
81097
|
+
if (def) {
|
|
80824
81098
|
definitions.set(def[1], def[2]);
|
|
81099
|
+
if (computes(def[2]) || usesComputed(def[2]))
|
|
81100
|
+
computed.add(def[1]);
|
|
81101
|
+
}
|
|
80825
81102
|
}
|
|
80826
81103
|
for (const line of body) {
|
|
80827
81104
|
if (!EXPECT_RE3.test(line) || !VALUE_MATCHER_RE2.test(line) || /\.not\s{0,20}\./.test(line))
|
|
80828
81105
|
continue;
|
|
81106
|
+
if (computes(line) || usesComputed(line))
|
|
81107
|
+
continue;
|
|
80829
81108
|
const subject = EXPECT_SUBJECT_RE.exec(line)?.[1];
|
|
80830
81109
|
const label = DERIVED_WORD_RE.exec(`${line} ${(subject && definitions.get(subject)) ?? ""}`)?.[0];
|
|
80831
81110
|
if (!label)
|
|
@@ -80855,7 +81134,7 @@ function formatDerivedValueAdvisory(findings) {
|
|
|
80855
81134
|
const where = findings.length === 1 ? "One computed value is" : `${findings.length} computed values are`;
|
|
80856
81135
|
return `${where} checked against a copied number or only its shape (${short4(first.line, 90)}). ${first.reason}`;
|
|
80857
81136
|
}
|
|
80858
|
-
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;
|
|
81137
|
+
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;
|
|
80859
81138
|
var init_derived_value_check = __esm({
|
|
80860
81139
|
"../shared/dist/derived-value-check.js"() {
|
|
80861
81140
|
"use strict";
|
|
@@ -80875,6 +81154,11 @@ var init_derived_value_check = __esm({
|
|
|
80875
81154
|
DEFINITION_RE = /\b(?:const|let)\s{1,10}([\w$]{1,60})\s{0,10}=\s{0,10}([^\n]{0,300})/;
|
|
80876
81155
|
EXPECT_SUBJECT_RE = /\bexpect(?:\.soft)?\s{0,20}\(\s{0,20}([\w$]{1,60})/;
|
|
80877
81156
|
LITERAL_ARITH_RE = /\b\d[\d_.]{0,15}(?:\s{0,5}[*/+-]\s{0,5}\d[\d_.]{0,15}){1,8}\b/g;
|
|
81157
|
+
TEMPLATE_EXPR_RE = /\$\{([^{}\n]{0,200})\}/g;
|
|
81158
|
+
IDENTIFIER_RE = /[A-Za-z_$][\w$]{0,60}/g;
|
|
81159
|
+
QUOTED_RE = /['"`]([^'"`\n]{0,40})['"`]/g;
|
|
81160
|
+
FILL_ARG_RE = /\.(?:fill|type|pressSequentially|selectOption)\s{0,20}\(\s{0,20}([A-Za-z_$][\w$]{0,60})\s{0,20}[,)]/;
|
|
81161
|
+
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}$/;
|
|
80878
81162
|
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.";
|
|
80879
81163
|
}
|
|
80880
81164
|
});
|
|
@@ -82909,6 +83193,99 @@ function formatStaleAfterSubmitAdvisory(rawCode) {
|
|
|
82909
83193
|
const more = described.length > 3 ? ` (+${described.length - 3} more)` : "";
|
|
82910
83194
|
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+$/)`;
|
|
82911
83195
|
}
|
|
83196
|
+
function regexLiteralEnd4(text, at) {
|
|
83197
|
+
let inClass = false;
|
|
83198
|
+
for (let i = at + 1; i < text.length; i++) {
|
|
83199
|
+
const ch = text[i];
|
|
83200
|
+
if (ch === "\n")
|
|
83201
|
+
return -1;
|
|
83202
|
+
if (ch === "\\") {
|
|
83203
|
+
i++;
|
|
83204
|
+
continue;
|
|
83205
|
+
}
|
|
83206
|
+
if (inClass) {
|
|
83207
|
+
if (ch === "]")
|
|
83208
|
+
inClass = false;
|
|
83209
|
+
continue;
|
|
83210
|
+
}
|
|
83211
|
+
if (ch === "[") {
|
|
83212
|
+
inClass = true;
|
|
83213
|
+
continue;
|
|
83214
|
+
}
|
|
83215
|
+
if (ch === "/")
|
|
83216
|
+
return i + 1;
|
|
83217
|
+
}
|
|
83218
|
+
return -1;
|
|
83219
|
+
}
|
|
83220
|
+
function startsWithRegexLiteral(text) {
|
|
83221
|
+
const t = text.trimStart();
|
|
83222
|
+
return t[0] === "/" && t[1] !== "/" && t[1] !== "*" && regexLiteralEnd4(t, 0) !== -1;
|
|
83223
|
+
}
|
|
83224
|
+
function afterFirstArg(args) {
|
|
83225
|
+
let depth = 0;
|
|
83226
|
+
let quote = null;
|
|
83227
|
+
for (let i = 0; i < args.length; i++) {
|
|
83228
|
+
const ch = args[i];
|
|
83229
|
+
if (quote) {
|
|
83230
|
+
if (ch === "\\") {
|
|
83231
|
+
i++;
|
|
83232
|
+
continue;
|
|
83233
|
+
}
|
|
83234
|
+
if (ch === quote)
|
|
83235
|
+
quote = null;
|
|
83236
|
+
continue;
|
|
83237
|
+
}
|
|
83238
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
83239
|
+
quote = ch;
|
|
83240
|
+
continue;
|
|
83241
|
+
}
|
|
83242
|
+
if (ch === "(" || ch === "[" || ch === "{")
|
|
83243
|
+
depth++;
|
|
83244
|
+
else if (ch === ")" || ch === "]" || ch === "}")
|
|
83245
|
+
depth--;
|
|
83246
|
+
else if (ch === "," && depth === 0)
|
|
83247
|
+
return args.slice(i + 1);
|
|
83248
|
+
}
|
|
83249
|
+
return "";
|
|
83250
|
+
}
|
|
83251
|
+
function analyzeRegexMatchers(rawCode) {
|
|
83252
|
+
if (!rawCode || typeof rawCode !== "string")
|
|
83253
|
+
return [];
|
|
83254
|
+
const code = stripComments2(rawCode.slice(0, MAX_LINT_INPUT));
|
|
83255
|
+
const out = [];
|
|
83256
|
+
const re = /\bexpect(?:\.soft)?\s{0,20}\(/g;
|
|
83257
|
+
let m;
|
|
83258
|
+
let examined = 0;
|
|
83259
|
+
let line = 1;
|
|
83260
|
+
let lineAt2 = 0;
|
|
83261
|
+
while ((m = re.exec(code)) !== null && examined++ < MAX_CALLS && out.length < MAX_REGEX_MATCHER_FINDINGS) {
|
|
83262
|
+
const subj = readBalanced(code, m.index + m[0].length);
|
|
83263
|
+
if (!subj)
|
|
83264
|
+
continue;
|
|
83265
|
+
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));
|
|
83266
|
+
if (!mm || !REGEX_EQUALITY_MATCHERS.has(mm[2]))
|
|
83267
|
+
continue;
|
|
83268
|
+
const args = readBalanced(code, subj.end + 1 + mm[0].length);
|
|
83269
|
+
if (!args)
|
|
83270
|
+
continue;
|
|
83271
|
+
const expected = mm[2] === "toHaveJSProperty" ? afterFirstArg(args.text) : args.text;
|
|
83272
|
+
if (!startsWithRegexLiteral(expected))
|
|
83273
|
+
continue;
|
|
83274
|
+
if (mm[2] !== "toHaveJSProperty" && mm[2] !== "toContain" && (startsWithRegexLiteral(subj.text) || /^new\s+RegExp\b/.test(subj.text.trim())))
|
|
83275
|
+
continue;
|
|
83276
|
+
for (let i = code.indexOf("\n", lineAt2); i !== -1 && i < m.index; i = code.indexOf("\n", i + 1)) {
|
|
83277
|
+
line++;
|
|
83278
|
+
lineAt2 = i + 1;
|
|
83279
|
+
}
|
|
83280
|
+
out.push({ line, matcher: mm[2], negated: mm[1] !== void 0 });
|
|
83281
|
+
}
|
|
83282
|
+
return out;
|
|
83283
|
+
}
|
|
83284
|
+
function formatRegexMatcherNote(findings) {
|
|
83285
|
+
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"}.`);
|
|
83286
|
+
return `${lines.join("\n")}
|
|
83287
|
+
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.`;
|
|
83288
|
+
}
|
|
82912
83289
|
function lintTestQuality(rawCode, opts = {}) {
|
|
82913
83290
|
if (!rawCode || typeof rawCode !== "string")
|
|
82914
83291
|
return [];
|
|
@@ -82916,6 +83293,10 @@ function lintTestQuality(rawCode, opts = {}) {
|
|
|
82916
83293
|
return lintTestData(rawCode, { pageContacts: opts.pageContacts });
|
|
82917
83294
|
if (opts.only === "test-data-blocking")
|
|
82918
83295
|
return analyzeTestData(rawCode, { pageContacts: opts.pageContacts }).blocking;
|
|
83296
|
+
if (opts.only === "regex-matcher") {
|
|
83297
|
+
const found = analyzeRegexMatchers(rawCode);
|
|
83298
|
+
return found.length > 0 ? [formatRegexMatcherNote(found)] : [];
|
|
83299
|
+
}
|
|
82919
83300
|
const warnings = [];
|
|
82920
83301
|
if (rawCode.length > MAX_LINT_INPUT) {
|
|
82921
83302
|
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).`);
|
|
@@ -83190,7 +83571,7 @@ function specItemsFromTestPlans(testPlans) {
|
|
|
83190
83571
|
}
|
|
83191
83572
|
return [...new Set(out)].slice(0, 200);
|
|
83192
83573
|
}
|
|
83193
|
-
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;
|
|
83574
|
+
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;
|
|
83194
83575
|
var init_test_authoring_quality = __esm({
|
|
83195
83576
|
"../shared/dist/test-authoring-quality.js"() {
|
|
83196
83577
|
"use strict";
|
|
@@ -83422,6 +83803,8 @@ var init_test_authoring_quality = __esm({
|
|
|
83422
83803
|
};
|
|
83423
83804
|
LIVE_WRITE_NAME = /\b(?:submit|place|book|reserve|confirm|pay|send|checkout|order|register|sign\s?up|create account)\b/i;
|
|
83424
83805
|
BUNDLED_CHECKS_BEFORE_WRITE = 5;
|
|
83806
|
+
MAX_REGEX_MATCHER_FINDINGS = 10;
|
|
83807
|
+
REGEX_EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual", "toContain", "toHaveJSProperty"]);
|
|
83425
83808
|
STOP = /* @__PURE__ */ new Set([
|
|
83426
83809
|
"a",
|
|
83427
83810
|
"an",
|
|
@@ -83650,6 +84033,19 @@ var init_fence_runs = __esm({
|
|
|
83650
84033
|
}
|
|
83651
84034
|
});
|
|
83652
84035
|
|
|
84036
|
+
// ../shared/dist/trailing-slashes.js
|
|
84037
|
+
function stripTrailingSlashes(value) {
|
|
84038
|
+
let end = value.length;
|
|
84039
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47)
|
|
84040
|
+
end--;
|
|
84041
|
+
return end === value.length ? value : value.slice(0, end);
|
|
84042
|
+
}
|
|
84043
|
+
var init_trailing_slashes = __esm({
|
|
84044
|
+
"../shared/dist/trailing-slashes.js"() {
|
|
84045
|
+
"use strict";
|
|
84046
|
+
}
|
|
84047
|
+
});
|
|
84048
|
+
|
|
83653
84049
|
// ../shared/dist/survey-bug-signature.js
|
|
83654
84050
|
function normalizeWords(text) {
|
|
83655
84051
|
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();
|
|
@@ -83660,7 +84056,7 @@ function normalizeBugPath(route) {
|
|
|
83660
84056
|
if (hash >= 0 && path[hash + 1] !== "/")
|
|
83661
84057
|
path = path.slice(0, hash);
|
|
83662
84058
|
const segments = path.toLowerCase().split("/").map((segment) => /\d/.test(segment) ? ":id" : segment);
|
|
83663
|
-
const joined = segments.join("/")
|
|
84059
|
+
const joined = stripTrailingSlashes(segments.join("/"));
|
|
83664
84060
|
return joined || (path.startsWith("/") ? "/" : "");
|
|
83665
84061
|
}
|
|
83666
84062
|
function isGenericConsoleMessage(message) {
|
|
@@ -83794,6 +84190,7 @@ var SIGNATURE_SOURCE_MAX_CHARS, UUID, PREFIXED_ID, HEX_RUN, NUMBER_RUN, GENERIC_
|
|
|
83794
84190
|
var init_survey_bug_signature = __esm({
|
|
83795
84191
|
"../shared/dist/survey-bug-signature.js"() {
|
|
83796
84192
|
"use strict";
|
|
84193
|
+
init_trailing_slashes();
|
|
83797
84194
|
SIGNATURE_SOURCE_MAX_CHARS = 800;
|
|
83798
84195
|
UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g;
|
|
83799
84196
|
PREFIXED_ID = /\b[a-z]{1,8}[-_]\d+\b/g;
|
|
@@ -85074,9 +85471,9 @@ function lastLocatorLabels(chain) {
|
|
|
85074
85471
|
if (t)
|
|
85075
85472
|
labels.push(t[1]);
|
|
85076
85473
|
}
|
|
85077
|
-
const
|
|
85078
|
-
if (
|
|
85079
|
-
labels.push(
|
|
85474
|
+
const has2 = optionText(last.args, HAS_TEXT_OPTION_RE);
|
|
85475
|
+
if (has2 !== null)
|
|
85476
|
+
labels.push(has2);
|
|
85080
85477
|
}
|
|
85081
85478
|
return labels.map((l) => l.replace(/^[\s^(?:]+/, "").trim());
|
|
85082
85479
|
}
|
|
@@ -85833,14 +86230,17 @@ var init_promotion_quality_gate = __esm({
|
|
|
85833
86230
|
SOURCE_RANK = { generator: 0, classifier: 0, healer: 1, human: 2 };
|
|
85834
86231
|
strengthCheck = {
|
|
85835
86232
|
id: "assertion-strength",
|
|
85836
|
-
run({ code, strengthGate, flagContradictedAdditions }) {
|
|
86233
|
+
run({ code, tags, strengthGate, flagContradictedAdditions }) {
|
|
85837
86234
|
const verdict = validateAssertionStrength(code, { flagContradictedAdditions: flagContradictedAdditions === true });
|
|
85838
86235
|
if (verdict.severity === "route-bug")
|
|
85839
86236
|
return [{ check: "route-bug" }];
|
|
85840
|
-
|
|
86237
|
+
const authDowngrade = verdict.severity === "downgrade" && tags.some((t) => t.toLowerCase() === "@auth");
|
|
86238
|
+
if (verdict.severity !== "block" && !authDowngrade)
|
|
85841
86239
|
return [];
|
|
85842
86240
|
const revealed = strengthGate?.severity === "none" && strengthGate.revealEvidence === "revealed" && strengthGate.source !== "heal";
|
|
85843
|
-
|
|
86241
|
+
if (revealed)
|
|
86242
|
+
return [];
|
|
86243
|
+
return [{ check: authDowngrade ? "strength-downgrade-auth" : "strength-block" }];
|
|
85844
86244
|
}
|
|
85845
86245
|
};
|
|
85846
86246
|
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;
|
|
@@ -86247,6 +86647,7 @@ __export(dist_exports, {
|
|
|
86247
86647
|
AUDIO_CHUNK_DURATION_MS: () => AUDIO_CHUNK_DURATION_MS,
|
|
86248
86648
|
AUTH_PATH_SIGNATURE: () => AUTH_PATH_SIGNATURE,
|
|
86249
86649
|
AUTH_PROVIDER_HOST_SIGNATURES: () => AUTH_PROVIDER_HOST_SIGNATURES,
|
|
86650
|
+
AUTH_SESSION_GENERATION_RE: () => AUTH_SESSION_GENERATION_RE,
|
|
86250
86651
|
AUTH_STATE_EXPIRY_SKEW_MS: () => AUTH_STATE_EXPIRY_SKEW_MS,
|
|
86251
86652
|
AUTH_TAG_COOKIE_STATE: () => AUTH_TAG_COOKIE_STATE,
|
|
86252
86653
|
AUTH_TAG_LOGIN_BEARER: () => AUTH_TAG_LOGIN_BEARER,
|
|
@@ -86379,6 +86780,8 @@ __export(dist_exports, {
|
|
|
86379
86780
|
LIVE_FRAME_STALE_MS: () => LIVE_FRAME_STALE_MS,
|
|
86380
86781
|
LIVE_FRAME_UNFOCUSED_INTERVAL_MS: () => LIVE_FRAME_UNFOCUSED_INTERVAL_MS,
|
|
86381
86782
|
LIVE_THUMBNAIL_MAX_BASE64_BYTES: () => LIVE_THUMBNAIL_MAX_BASE64_BYTES,
|
|
86783
|
+
MAX_BALANCED_SCAN: () => MAX_BALANCED_SCAN,
|
|
86784
|
+
MAX_CALLS: () => MAX_CALLS,
|
|
86382
86785
|
MAX_CREDIT_TOPUP_CENTS: () => MAX_CREDIT_TOPUP_CENTS,
|
|
86383
86786
|
MAX_DEEPLINK_LENGTH: () => MAX_DEEPLINK_LENGTH,
|
|
86384
86787
|
MAX_EMAIL_ADDRESS_LENGTH: () => MAX_EMAIL_ADDRESS_LENGTH,
|
|
@@ -86423,6 +86826,7 @@ __export(dist_exports, {
|
|
|
86423
86826
|
MUSE_ENGINE_DEFAULT_MODEL: () => MUSE_ENGINE_DEFAULT_MODEL,
|
|
86424
86827
|
MUSE_ENGINE_MODELS: () => MUSE_ENGINE_MODELS,
|
|
86425
86828
|
NOREPLY_EMAIL: () => NOREPLY_EMAIL,
|
|
86829
|
+
OPENCODE_GO_2_PREFIX: () => OPENCODE_GO_2_PREFIX,
|
|
86426
86830
|
OPENCODE_GO_MODEL_PATTERN: () => OPENCODE_GO_MODEL_PATTERN,
|
|
86427
86831
|
OPENCODE_GO_PREFIX: () => OPENCODE_GO_PREFIX,
|
|
86428
86832
|
OPENROUTER_MAX_CALL_COST_USD: () => OPENROUTER_MAX_CALL_COST_USD,
|
|
@@ -86458,6 +86862,8 @@ __export(dist_exports, {
|
|
|
86458
86862
|
PROMOTION_GATE_MAX_CODE_CHARS: () => PROMOTION_GATE_MAX_CODE_CHARS,
|
|
86459
86863
|
PROMOTION_QUALITY_CHECKS: () => PROMOTION_QUALITY_CHECKS,
|
|
86460
86864
|
PROVIDER_CHAINS: () => PROVIDER_CHAINS,
|
|
86865
|
+
PROVIDER_CHAIN_LEADS: () => PROVIDER_CHAIN_LEADS,
|
|
86866
|
+
PROVIDER_HOST_NOT_OFFERED: () => PROVIDER_HOST_NOT_OFFERED,
|
|
86461
86867
|
PUBLIC_PLANS: () => PUBLIC_PLANS,
|
|
86462
86868
|
QUARANTINE_CLOSE_TAGS: () => QUARANTINE_CLOSE_TAGS,
|
|
86463
86869
|
READINESS_POLL_MAX_CODE_CHARS: () => READINESS_POLL_MAX_CODE_CHARS,
|
|
@@ -86496,6 +86902,7 @@ __export(dist_exports, {
|
|
|
86496
86902
|
SURVEY_NOTES_RENDER_MAX_CHARS: () => SURVEY_NOTES_RENDER_MAX_CHARS,
|
|
86497
86903
|
SURVEY_NOTE_KEYS: () => SURVEY_NOTE_KEYS,
|
|
86498
86904
|
SUSPICIOUS_PASS_TAG: () => SUSPICIOUS_PASS_TAG,
|
|
86905
|
+
TEST_DID_NOT_RUN_ERROR: () => TEST_DID_NOT_RUN_ERROR,
|
|
86499
86906
|
TEST_QUALITY_CONVENTIONS: () => TEST_QUALITY_CONVENTIONS,
|
|
86500
86907
|
TEST_USER_ENV_KEYS: () => TEST_USER_ENV_KEYS,
|
|
86501
86908
|
TEST_VARIABLE_SECRET_KEY_PATTERN: () => TEST_VARIABLE_SECRET_KEY_PATTERN,
|
|
@@ -86511,6 +86918,8 @@ __export(dist_exports, {
|
|
|
86511
86918
|
VOICE_PREVIEW_SAMPLE: () => VOICE_PREVIEW_SAMPLE,
|
|
86512
86919
|
WEB_PROXY_CHAIN_HEADER: () => WEB_PROXY_CHAIN_HEADER,
|
|
86513
86920
|
WITHHELD_CREDENTIAL_TEXT: () => WITHHELD_CREDENTIAL_TEXT,
|
|
86921
|
+
ZAI_MODEL_PATTERN: () => ZAI_MODEL_PATTERN,
|
|
86922
|
+
ZAI_PREFIX: () => ZAI_PREFIX,
|
|
86514
86923
|
accumulateStatements: () => accumulateStatements,
|
|
86515
86924
|
adoptBrokerFailover: () => adoptBrokerFailover,
|
|
86516
86925
|
aiCostToCreditCents: () => aiCostToCreditCents,
|
|
@@ -86519,6 +86928,7 @@ __export(dist_exports, {
|
|
|
86519
86928
|
analyzeMobileSelectorQuality: () => analyzeMobileSelectorQuality,
|
|
86520
86929
|
analyzePersistenceReread: () => analyzePersistenceReread,
|
|
86521
86930
|
analyzeReadinessPolling: () => analyzeReadinessPolling,
|
|
86931
|
+
analyzeRegexMatchers: () => analyzeRegexMatchers,
|
|
86522
86932
|
analyzeSharedAccountUse: () => analyzeSharedAccountUse,
|
|
86523
86933
|
analyzeStaleAfterSubmit: () => analyzeStaleAfterSubmit,
|
|
86524
86934
|
analyzeTestData: () => analyzeTestData,
|
|
@@ -86682,6 +87092,7 @@ __export(dist_exports, {
|
|
|
86682
87092
|
formatPersistenceRereadAdvisory: () => formatPersistenceRereadAdvisory,
|
|
86683
87093
|
formatPoolBudgetLine: () => formatPoolBudgetLine,
|
|
86684
87094
|
formatReadinessPollAdvisory: () => formatReadinessPollAdvisory,
|
|
87095
|
+
formatRegexMatcherNote: () => formatRegexMatcherNote,
|
|
86685
87096
|
formatStaleAfterSubmitAdvisory: () => formatStaleAfterSubmitAdvisory,
|
|
86686
87097
|
formatSuspiciousExpectation: () => formatSuspiciousExpectation,
|
|
86687
87098
|
formatUrlWaitAdvisory: () => formatUrlWaitAdvisory,
|
|
@@ -86720,12 +87131,14 @@ __export(dist_exports, {
|
|
|
86720
87131
|
hasEncodedRequestBody: () => hasEncodedRequestBody,
|
|
86721
87132
|
hasEngineSpecParts: () => hasEngineSpecParts,
|
|
86722
87133
|
hasOnlyConstantAssertions: () => hasOnlyConstantAssertions,
|
|
87134
|
+
hasOpenCodeGo2Prefix: () => hasOpenCodeGo2Prefix,
|
|
86723
87135
|
hasOpenCodeGoPrefix: () => hasOpenCodeGoPrefix,
|
|
86724
87136
|
hasOpenRouterPrefix: () => hasOpenRouterPrefix,
|
|
86725
87137
|
hasPlatformLocator: () => hasPlatformLocator,
|
|
86726
87138
|
hasReadOnlyMarker: () => hasReadOnlyMarker,
|
|
86727
87139
|
hasSurveyNotes: () => hasSurveyNotes,
|
|
86728
87140
|
hasTestFailContract: () => hasTestFailContract,
|
|
87141
|
+
hasZaiPrefix: () => hasZaiPrefix,
|
|
86729
87142
|
healMobileTestSteps: () => healMobileTestSteps,
|
|
86730
87143
|
healthRunWhere: () => healthRunWhere,
|
|
86731
87144
|
heldCodeRecord: () => heldCodeRecord,
|
|
@@ -86829,6 +87242,7 @@ __export(dist_exports, {
|
|
|
86829
87242
|
isValidSttProvider: () => isValidSttProvider,
|
|
86830
87243
|
isValidTtsModel: () => isValidTtsModel,
|
|
86831
87244
|
isValidTtsVoiceId: () => isValidTtsVoiceId,
|
|
87245
|
+
isZaiModelId: () => isZaiModelId,
|
|
86832
87246
|
jsEscapedForms: () => jsEscapedForms,
|
|
86833
87247
|
jsonStructureRefusalOf: () => jsonStructureRefusalOf,
|
|
86834
87248
|
jsonStructureVerify: () => jsonStructureVerify,
|
|
@@ -86877,6 +87291,7 @@ __export(dist_exports, {
|
|
|
86877
87291
|
parseApiCardModelUpdate: () => parseApiCardModelUpdate,
|
|
86878
87292
|
parseAppTimezone: () => parseAppTimezone,
|
|
86879
87293
|
parseAuditGroupScopeId: () => parseAuditGroupScopeId,
|
|
87294
|
+
parseAuthSessionStamp: () => parseAuthSessionStamp,
|
|
86880
87295
|
parseBoolFlag: () => parseBoolFlag,
|
|
86881
87296
|
parseDbPoolSize: () => parseDbPoolSize,
|
|
86882
87297
|
parseDeepgramListenResponse: () => parseDeepgramListenResponse,
|
|
@@ -86920,7 +87335,11 @@ __export(dist_exports, {
|
|
|
86920
87335
|
profileKeyRoute: () => profileKeyRoute,
|
|
86921
87336
|
projectAppHosts: () => projectAppHosts,
|
|
86922
87337
|
providerChainFor: () => providerChainFor,
|
|
87338
|
+
providerChainHostOf: () => providerChainHostOf,
|
|
87339
|
+
providerChainLeadsFor: () => providerChainLeadsFor,
|
|
86923
87340
|
providerChainPrimariesForHop: () => providerChainPrimariesForHop,
|
|
87341
|
+
providerHostPlan: () => providerHostPlan,
|
|
87342
|
+
readBalanced: () => readBalanced,
|
|
86924
87343
|
readChatFailover: () => readChatFailover,
|
|
86925
87344
|
readChatReasoningTokens: () => readChatReasoningTokens,
|
|
86926
87345
|
readChatUsage: () => readChatUsage,
|
|
@@ -87003,6 +87422,7 @@ __export(dist_exports, {
|
|
|
87003
87422
|
stripCoverageComments: () => stripCoverageComments,
|
|
87004
87423
|
stripEnvironmentalPrefix: () => stripEnvironmentalPrefix,
|
|
87005
87424
|
stripLoginScaffolding: () => stripLoginScaffolding,
|
|
87425
|
+
stripTrailingSlashes: () => stripTrailingSlashes,
|
|
87006
87426
|
strongerNeedsReviewSource: () => strongerNeedsReviewSource,
|
|
87007
87427
|
sttModelsForProvider: () => sttModelsForProvider,
|
|
87008
87428
|
summarizeHealth: () => summarizeHealth,
|
|
@@ -87030,7 +87450,8 @@ __export(dist_exports, {
|
|
|
87030
87450
|
withReviewSource: () => withReviewSource,
|
|
87031
87451
|
withoutNotChargedClaim: () => withoutNotChargedClaim,
|
|
87032
87452
|
withoutServerOnlySpendFields: () => withoutServerOnlySpendFields,
|
|
87033
|
-
withoutSurveyNotes: () => withoutSurveyNotes
|
|
87453
|
+
withoutSurveyNotes: () => withoutSurveyNotes,
|
|
87454
|
+
zaiWireModel: () => zaiWireModel
|
|
87034
87455
|
});
|
|
87035
87456
|
var init_dist = __esm({
|
|
87036
87457
|
"../shared/dist/index.js"() {
|
|
@@ -87072,6 +87493,7 @@ var init_dist = __esm({
|
|
|
87072
87493
|
init_admin_view_return_to();
|
|
87073
87494
|
init_auth_plan();
|
|
87074
87495
|
init_auth_block_detector();
|
|
87496
|
+
init_auth_session_stamp();
|
|
87075
87497
|
init_auth_state_freshness();
|
|
87076
87498
|
init_skip_coverage_detector();
|
|
87077
87499
|
init_feature_coverage();
|
|
@@ -87128,6 +87550,7 @@ var init_dist = __esm({
|
|
|
87128
87550
|
init_promotion_quality_gate();
|
|
87129
87551
|
init_regex_alternation();
|
|
87130
87552
|
init_page_evidence();
|
|
87553
|
+
init_trailing_slashes();
|
|
87131
87554
|
}
|
|
87132
87555
|
});
|
|
87133
87556
|
|