@validate.qa/runner 1.0.101 → 1.0.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/{chunk-SN3PN4G4.mjs → chunk-36AWDKPL.mjs} +6 -2
- package/dist/{chunk-CYWHPXNZ.mjs → chunk-7SH3COMQ.mjs} +1 -1
- package/dist/{chunk-BBTK6OX6.mjs → chunk-BECCGMU4.mjs} +383 -11
- package/dist/{chunk-4SZC5ZX3.mjs → chunk-CG75I3ZZ.mjs} +25477 -5374
- package/dist/{chunk-TPU42VH2.mjs → chunk-CMM4DOXC.mjs} +10 -5
- package/dist/{chunk-M3VZGHZQ.mjs → chunk-NNJYKR3O.mjs} +22 -11
- package/dist/{chunk-IGXGSDE3.mjs → chunk-OTKJZIOD.mjs} +1298 -384
- package/dist/{chunk-CO5KHIVX.mjs → chunk-TK5KEGNW.mjs} +1 -1
- package/dist/{chunk-FQUH2PU2.mjs → chunk-WVLBQDFP.mjs} +140 -7
- package/dist/{chunk-2OKZY3WN.mjs → chunk-YI3ZC2XI.mjs} +2 -2
- package/dist/{chunk-XZUUBMP3.mjs → chunk-YIM746WO.mjs} +1 -1
- package/dist/cli.js +140692 -118903
- package/dist/cli.mjs +362 -108
- package/dist/credential-mcp-server.js +1402 -350
- package/dist/credential-mcp-server.mjs +3 -3
- package/dist/discovery-mcp-server.js +1330 -401
- package/dist/discovery-mcp-server.mjs +4 -4
- package/dist/dist-2G7YTNH5.mjs +17 -0
- package/dist/inbox-mcp-server.js +1676 -629
- package/dist/inbox-mcp-server.mjs +3 -3
- package/dist/route-seed-worker.js +1244 -330
- package/dist/route-seed-worker.mjs +4 -4
- package/dist/run-write-guard-preload.js +1622 -332
- package/dist/run-write-guard-preload.mjs +4 -4
- package/dist/run-write-guard.js +1622 -332
- package/dist/run-write-guard.mjs +3 -3
- package/dist/spec-driver.js +1 -1
- package/dist/spec-driver.mjs +1 -1
- package/package.json +3 -2
- package/dist/dist-VTPBY2C4.mjs +0 -17
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
require_google_signin,
|
|
3
3
|
require_harness_init_script,
|
|
4
4
|
require_test_inbox_broker
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WVLBQDFP.mjs";
|
|
6
6
|
import {
|
|
7
7
|
dist_exports,
|
|
8
8
|
init_dist
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-OTKJZIOD.mjs";
|
|
10
10
|
import {
|
|
11
11
|
__commonJS,
|
|
12
12
|
__require,
|
|
@@ -33,6 +33,7 @@ var require_browser_config = __commonJS({
|
|
|
33
33
|
exports.fullChromiumCloudLaunch = fullChromiumCloudLaunch;
|
|
34
34
|
exports.chooseCloudBrowser = chooseCloudBrowser;
|
|
35
35
|
exports.appTimezoneConfigLine = appTimezoneConfigLine;
|
|
36
|
+
exports.discoveryTimezoneId = discoveryTimezoneId;
|
|
36
37
|
exports.getMCPBrowserConfig = getMCPBrowserConfig;
|
|
37
38
|
exports.getPlaywrightLaunchOptions = getPlaywrightLaunchOptions;
|
|
38
39
|
exports.getLaunchOptions = getLaunchOptions;
|
|
@@ -251,7 +252,7 @@ var require_browser_config = __commonJS({
|
|
|
251
252
|
try {
|
|
252
253
|
(0, fs_1.cpSync)(localStateSrc, (0, path_1.join)(tempDir, "Local State"));
|
|
253
254
|
} catch (err) {
|
|
254
|
-
throw new Error(`Cannot copy Chrome profile (${err instanceof Error ? err.message : String(err)}). Quit Google Chrome completely, or use getChromeUserDataDirSource() for seeding
|
|
255
|
+
throw new Error(`Cannot copy Chrome profile (${err instanceof Error ? err.message : String(err)}). Quit Google Chrome completely, or use getChromeUserDataDirSource() for seeding.`, { cause: err });
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
for (const file of essentialFiles) {
|
|
@@ -442,6 +443,10 @@ var require_browser_config = __commonJS({
|
|
|
442
443
|
const zone = (0, shared_1.appTimezoneFromVariables)(vars);
|
|
443
444
|
return zone ? `timezoneId: ${JSON.stringify(zone)},` : "";
|
|
444
445
|
}
|
|
446
|
+
function discoveryTimezoneId(ctx) {
|
|
447
|
+
const vars = ctx.variableContext;
|
|
448
|
+
return (0, shared_1.appTimezoneFromVariables)(vars?.publicTestVariables) ?? (0, shared_1.appTimezoneFromVariables)(vars?.allTestVariables);
|
|
449
|
+
}
|
|
445
450
|
function getMCPBrowserConfig(opts) {
|
|
446
451
|
const userDataDir = opts?.forceIsolated ? null : getTestUserDataDir();
|
|
447
452
|
const timezoneOption = opts?.timezoneId ? { timezoneId: opts.timezoneId } : {};
|
|
@@ -1253,7 +1258,7 @@ var require_runs_dir = __commonJS({
|
|
|
1253
1258
|
} catch (error) {
|
|
1254
1259
|
if (error.code === "EEXIST" && resolvesFrom(runsDir) === own)
|
|
1255
1260
|
return;
|
|
1256
|
-
throw new Error(`Could not link ${link} to the runner's node_modules (${error.message}). Set RUNS_DIR to a writable folder outside node_modules that can resolve @playwright/test
|
|
1261
|
+
throw new Error(`Could not link ${link} to the runner's node_modules (${error.message}). Set RUNS_DIR to a writable folder outside node_modules that can resolve @playwright/test.`, { cause: error });
|
|
1257
1262
|
}
|
|
1258
1263
|
}
|
|
1259
1264
|
}
|
|
@@ -3179,7 +3184,7 @@ var require_survey_door_harvester = __commonJS({
|
|
|
3179
3184
|
}
|
|
3180
3185
|
if (!payload)
|
|
3181
3186
|
continue;
|
|
3182
|
-
const cleaned = payload.replace(/^\s*```(json)?\s*\n
|
|
3187
|
+
const cleaned = payload.replace(/^\s*```(json)?\s*\n?/i, "").replace(/\n?```\s*$/, "").trim();
|
|
3183
3188
|
if (!cleaned)
|
|
3184
3189
|
continue;
|
|
3185
3190
|
try {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_route_manifest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TK5KEGNW.mjs";
|
|
4
4
|
import {
|
|
5
5
|
require_survey_network_guard
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-36AWDKPL.mjs";
|
|
7
7
|
import {
|
|
8
8
|
dist_exports,
|
|
9
9
|
init_dist
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OTKJZIOD.mjs";
|
|
11
11
|
import {
|
|
12
12
|
__commonJS,
|
|
13
13
|
__toCommonJS
|
|
@@ -20,6 +20,7 @@ var require_exploration_parser = __commonJS({
|
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.extractCodeLines = extractCodeLines;
|
|
22
22
|
exports.extractProvenLocator = extractProvenLocator;
|
|
23
|
+
exports.maskTypedValues = maskTypedValues;
|
|
23
24
|
exports.sanitizePromptCodeLine = sanitizePromptCodeLine;
|
|
24
25
|
exports.extractPageUrl = extractPageUrl;
|
|
25
26
|
exports.extractPageTitle = extractPageTitle;
|
|
@@ -34,7 +35,7 @@ var require_exploration_parser = __commonJS({
|
|
|
34
35
|
var shared_1 = (init_dist(), __toCommonJS(dist_exports));
|
|
35
36
|
function extractCodeLines(toolResultContent) {
|
|
36
37
|
const isPlaywrightLine = (l) => l.startsWith("await page.") || l.startsWith("await expect(");
|
|
37
|
-
const codeSection = toolResultContent.match(/###\s*Ran Playwright code\s*\n([\s\S]*?)(?=\n###|\n$|$)/);
|
|
38
|
+
const codeSection = toolResultContent.match(/###\s*Ran Playwright code\s*\n(?![^\S\n]*\n)([\s\S]*?)(?=\n###|\n$|$)/);
|
|
38
39
|
if (codeSection) {
|
|
39
40
|
return codeSection[1].split("\n").map((l) => l.trim()).filter(isPlaywrightLine).map((l) => l.replace(/;$/, ""));
|
|
40
41
|
}
|
|
@@ -78,7 +79,7 @@ var require_exploration_parser = __commonJS({
|
|
|
78
79
|
cut = idx;
|
|
79
80
|
}
|
|
80
81
|
let locator = cut > start ? codeLine.slice(start, cut) : codeLine.slice(start);
|
|
81
|
-
locator = locator.trim().replace(
|
|
82
|
+
locator = locator.trim().replace(/(?<!;);+\s*$/, "").trim();
|
|
82
83
|
if (!locator.includes("("))
|
|
83
84
|
return null;
|
|
84
85
|
if (!/^(getBy\w+|locator)\(/.test(locator))
|
|
@@ -158,13 +159,17 @@ var require_exploration_parser = __commonJS({
|
|
|
158
159
|
return false;
|
|
159
160
|
return RECORD_TITLE_WITH_COMPANY.test(name);
|
|
160
161
|
}
|
|
162
|
+
var TYPED_VALUE_CALL_RE = /\.(fill|type|pressSequentially|insertText)\(\s*(['"`])(?:\\.|(?!\2)[^\\])*\2(\s*,\s*\{[^{}]*\})?\s*\)/g;
|
|
163
|
+
var TWO_ARG_TYPED_VALUE_CALL_RE = /\.(fill|type)\(\s*((?:(['"`])(?:\\.|(?!\3)[^\\])*\3|[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*))\s*,\s*(['"`])(?:\\.|(?!\4)[^\\])*\4(\s*,\s*\{[^{}]*\})?\s*\)/g;
|
|
164
|
+
function maskTypedValues(codeLine, mask) {
|
|
165
|
+
return codeLine.replace(TWO_ARG_TYPED_VALUE_CALL_RE, (_all, method, selector, _selQuote, _quote, options) => `.${method}(${selector}, ${mask}${options ?? ""})`).replace(TYPED_VALUE_CALL_RE, (_all, method, _quote, options) => `.${method}(${mask}${options ?? ""})`);
|
|
166
|
+
}
|
|
161
167
|
function sanitizePromptCodeLine(codeLine) {
|
|
162
168
|
let sanitized = codeLine;
|
|
163
169
|
sanitized = sanitized.replace(/getByRole\('(textbox|searchbox|combobox|spinbutton)',\s*\{\s*name:\s*['"]([^'"]*)['"]\s*\}\)/g, (match, role, name, _offset, line) => looksDynamicFieldLabel(name, line) ? `getByRole('${role}')` : match);
|
|
164
170
|
sanitized = sanitized.replace(/getByLabel\(\s*(['"])([^'"]*)\1\s*\)(?=\)?\.(?:fill|type|toHaveValue|inputValue|press)\()/g, (match, _quote, label, _offset, line) => looksDynamicFieldLabel(label, line) ? "getByRole('textbox')" : match);
|
|
165
171
|
sanitized = sanitized.replace(/getByLabel\(\s*(['"])([^'"]*)\1\s*\)(?=\)?\.selectOption\()/g, (match, _quote, label, _offset, line) => looksDynamicFieldLabel(label, line) ? "getByRole('combobox')" : match);
|
|
166
|
-
sanitized = sanitized
|
|
167
|
-
sanitized = sanitized.replace(/\.type\(\s*(['"]).*?\1\s*\)/g, ".type('<test-value>')");
|
|
172
|
+
sanitized = maskTypedValues(sanitized, "'<test-value>'");
|
|
168
173
|
sanitized = sanitized.replace(/\.toHaveValue\(\s*(['"]).*?\1\s*\)/g, ".toHaveValue(/./)");
|
|
169
174
|
sanitized = sanitized.replace(/getByRole\('heading',\s*\{\s*name:\s*'([^']*)'\s*\}\)/g, (match, name) => looksDynamicRecordTitle(name) ? "getByRole('heading')" : match);
|
|
170
175
|
sanitized = sanitized.replace(/getByRole\('heading',\s*\{\s*name:\s*"([^"]*)"\s*\}\)/g, (match, name) => looksDynamicRecordTitle(name) ? "getByRole('heading')" : match);
|
|
@@ -188,7 +193,7 @@ var require_exploration_parser = __commonJS({
|
|
|
188
193
|
return match ? match[1].trim() : null;
|
|
189
194
|
}
|
|
190
195
|
function extractSnapshotSection(content) {
|
|
191
|
-
const match = content.match(/###\s*Snapshot\s*\n([\s\S]*?)(?=\n###|$)/);
|
|
196
|
+
const match = content.match(/###\s*Snapshot\s*\n(?![^\S\n]*\n)([\s\S]*?)(?=\n###|$)/);
|
|
192
197
|
if (!match)
|
|
193
198
|
return null;
|
|
194
199
|
if (/^\s*- \[Snapshot\]\([^)\n]*\)\s*$/.test(match[1]))
|
|
@@ -256,7 +261,7 @@ var require_exploration_parser = __commonJS({
|
|
|
256
261
|
return hints;
|
|
257
262
|
}
|
|
258
263
|
function extractFirstAlert(snapshotYaml) {
|
|
259
|
-
const match = snapshotYaml.match(
|
|
264
|
+
const match = snapshotYaml.match(/^[^\S\n\r\u2028\u2029]*-\s+(?:alert|status)\s+"([^"]+)"/m);
|
|
260
265
|
return match ? match[1] : null;
|
|
261
266
|
}
|
|
262
267
|
function buildInteractionLogEntry(toolName, toolArgs, codeLines, pageUrl, pageTitle, snapshotSection) {
|
|
@@ -297,6 +302,12 @@ var require_exploration_parser = __commonJS({
|
|
|
297
302
|
return /^\d{10,}$/.test(value);
|
|
298
303
|
return false;
|
|
299
304
|
}
|
|
305
|
+
function hashRouterPathWithoutTrailingSlash(hash) {
|
|
306
|
+
const q = hash.indexOf("?");
|
|
307
|
+
const path = q < 0 ? hash : hash.slice(0, q);
|
|
308
|
+
const stripped = (0, shared_1.stripTrailingSlashes)(path);
|
|
309
|
+
return stripped === "#" || stripped === "" ? hash : stripped + (q < 0 ? "" : hash.slice(q));
|
|
310
|
+
}
|
|
300
311
|
function normalizeRoute(url) {
|
|
301
312
|
let route = url.pathname;
|
|
302
313
|
const encodeQueryPart = (part) => part.replace(/[%&=#+?]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
|
|
@@ -315,7 +326,7 @@ var require_exploration_parser = __commonJS({
|
|
|
315
326
|
}
|
|
316
327
|
}
|
|
317
328
|
if (url.hash && url.hash !== "#" && url.hash !== "#/") {
|
|
318
|
-
route += url.hash;
|
|
329
|
+
route += url.hash.startsWith("#/") ? hashRouterPathWithoutTrailingSlash(url.hash) : url.hash;
|
|
319
330
|
}
|
|
320
331
|
return route;
|
|
321
332
|
}
|
|
@@ -1948,7 +1959,7 @@ var require_repo_feature_verification = __commonJS({
|
|
|
1948
1959
|
return null;
|
|
1949
1960
|
}
|
|
1950
1961
|
function normalizeControlText(text) {
|
|
1951
|
-
return text.toLowerCase().replace(/[
|
|
1962
|
+
return text.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}\p{M}]+/gu, " ").trim();
|
|
1952
1963
|
}
|
|
1953
1964
|
var SESSION_END_LABEL = /^(?:log|sign) ?(?:out|off)$/;
|
|
1954
1965
|
var SESSION_END_SPELLINGS = ["log out", "logout", "log off", "logoff", "sign out", "signout", "sign off", "signoff"];
|