@crvy/rprtr 0.3.0 → 0.3.2
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/CHANGELOG.md +24 -0
- package/README.md +8 -0
- package/dist/{chunk-4YJL655E.js → chunk-7YLKL3SL.js} +6 -1
- package/dist/{chunk-IFHYWPXG.js → chunk-C5SVPK2O.js} +79 -43
- package/dist/cli.js +2 -2
- package/dist/index.css +28 -0
- package/dist/reporter.cjs +6 -1
- package/dist/reporter.js +1 -1
- package/dist/server/docker-launcher.d.ts +3 -3
- package/dist/server/docker-launcher.d.ts.map +1 -1
- package/dist/server/docker-support.d.ts +25 -3
- package/dist/server/docker-support.d.ts.map +1 -1
- package/dist/server/run-controller.d.ts.map +1 -1
- package/dist/server.cjs +84 -43
- package/dist/server.js +2 -2
- package/dist/snapshot-path-resolver.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.2] - 2026-08-25
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **resolver:** Trim anonymous baseline names at 100 chars like Playwright
|
|
13
|
+
## [0.3.1] - 2026-08-24
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **server:** Warn once that native Windows docker mode is experimental
|
|
18
|
+
|
|
19
|
+
### Documentation
|
|
20
|
+
|
|
21
|
+
- Windows OS support design spec (WSL2 recommended, native win32 experimental)
|
|
22
|
+
- Windows OS support implementation plan
|
|
23
|
+
- Recommend WSL2 on Windows, mark native win32 docker mode experimental
|
|
24
|
+
- **server:** Refresh stale comments after docker-support extraction
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **server:** Separator-agnostic rewriteContainerPath for Windows hosts
|
|
29
|
+
- **server:** Posix --test-list entries in docker mode
|
|
30
|
+
- **server:** Mount --test-list tmpfile at a fixed container path
|
|
31
|
+
- **server:** Keep host PATH and Windows env noise out of docker containers
|
|
8
32
|
## [0.3.0] - 2026-08-24
|
|
9
33
|
|
|
10
34
|
### Added
|
package/README.md
CHANGED
|
@@ -146,6 +146,14 @@ The server still runs on your host; only `playwright test` executes in the conta
|
|
|
146
146
|
|
|
147
147
|
Programmatic equivalents: `startServer({ runMode: 'docker', docker: { image, platform, command, extraArgs } })`. `docker.command` overrides the container-side invocation verbatim (e.g. `['pnpm', 'exec', 'playwright']`); `docker.extraArgs` appends raw `docker run` flags.
|
|
148
148
|
|
|
149
|
+
### Windows
|
|
150
|
+
|
|
151
|
+
The recommended Windows setup is **WSL2**: enable Docker Desktop's WSL2 integration (Settings → Resources → WSL integration), keep the project inside the WSL filesystem (e.g. `~/proj` in your distro, not `/mnt/c/...` — bind-mounts from `/mnt/c` are slow and lack inotify events), and run `npx crvy-rprtr` from the WSL shell. Paths and rendering then behave exactly as on Linux, so baselines match CI.
|
|
152
|
+
|
|
153
|
+
Running natively on a Windows host (PowerShell/cmd) works but is **experimental**: Docker Desktop translates the `C:\proj:/work` mount, and crvy-rprtr rewrites Windows paths in container arguments, but this path has no CI coverage — expect a one-time experimental warning on the first run. Local (`--run-mode local`) Windows runs can never match Linux CI baselines (DirectWrite vs fontconfig text rendering) — which is exactly the problem Docker mode solves, so prefer WSL2.
|
|
154
|
+
|
|
155
|
+
Known limitations on native Windows: UNC project roots (`\\server\share\...`) are unsupported; drive-letter casing is normalized (`C:` ≡ `c:`), but path body case is not; Windows-specific host env vars (`PATH`, `TEMP`, `APPDATA`, `ProgramFiles`, ...) are filtered out so the container keeps its own environment (user env vars like API keys are still forwarded); single-file bind mounts (used for `--test-list`) can be flaky on some Docker Desktop versions — if the container sees an empty or missing test list, that is why.
|
|
156
|
+
|
|
149
157
|
Notes:
|
|
150
158
|
|
|
151
159
|
> **Important — baselines are image-specific, not architecture-specific.** Text rendering follows the image's fontconfig: Ubuntu-based images (including the default `mcr.microsoft.com/playwright:*-noble`) render text with subpixel (LCD) antialiasing and slight hinting, while Debian-based images (e.g. `node:24` + `playwright install --with-deps`) render grayscale with full hinting — different pixels _and_ slightly different text widths. Generate and verify baselines in the **same image** everywhere (CI and local), and regenerate baselines once after switching image flavor. See [docs/docker-screenshot-determinism.md](docs/docker-screenshot-determinism.md) for the full investigation.
|
|
@@ -9,6 +9,7 @@ import { createHash } from "crypto";
|
|
|
9
9
|
import { basename, dirname, extname, join, parse, relative, resolve } from "path";
|
|
10
10
|
var DEFAULT_SCREENSHOT_TEMPLATE = "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}";
|
|
11
11
|
var WINDOWS_FILESYSTEM_FRIENDLY_LENGTH = 60;
|
|
12
|
+
var PLAYWRIGHT_SNAPSHOT_NAME_LIMIT = 100;
|
|
12
13
|
function isUnsafeFilePathCharacter(character) {
|
|
13
14
|
const codePoint = character.codePointAt(0);
|
|
14
15
|
return codePoint !== void 0 && (codePoint <= 44 || codePoint >= 46 && codePoint <= 47 || codePoint >= 58 && codePoint <= 64 || codePoint >= 91 && codePoint <= 96 || codePoint >= 123 && codePoint <= 127);
|
|
@@ -138,7 +139,11 @@ function reporterTitlesWithoutProjectAndFile(reporterTitlePath) {
|
|
|
138
139
|
return reporterTitlePath.slice(3).filter((part) => part !== "");
|
|
139
140
|
}
|
|
140
141
|
function anonymousNameFromTitles(titles, occurrenceIndex) {
|
|
141
|
-
|
|
142
|
+
const fullTitleWithoutSpec = `${titles.join(" ")} ${occurrenceIndex}`;
|
|
143
|
+
return sanitizeFilePathBeforeExtension(
|
|
144
|
+
`${trimLongString(fullTitleWithoutSpec, PLAYWRIGHT_SNAPSHOT_NAME_LIMIT)}.png`,
|
|
145
|
+
".png"
|
|
146
|
+
);
|
|
142
147
|
}
|
|
143
148
|
function anonymousName(reporterTitlePath, occurrenceIndex) {
|
|
144
149
|
return anonymousNameFromTitles(reporterTitlesWithoutProjectAndFile(reporterTitlePath), occurrenceIndex);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
isForeignAbsolutePath,
|
|
17
17
|
resolveBaselineTargets,
|
|
18
18
|
safeParse
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7YLKL3SL.js";
|
|
20
20
|
|
|
21
21
|
// src/server/app.ts
|
|
22
22
|
import { dirname as dirname4, join as join6 } from "path";
|
|
@@ -297,10 +297,46 @@ var detectProjectAgent = async (cwd) => {
|
|
|
297
297
|
}
|
|
298
298
|
};
|
|
299
299
|
function rewriteContainerPath(path, mapping) {
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
const normalizedPath = normalizeForMatch(path);
|
|
301
|
+
const normalizedFrom = normalizeForMatch(mapping.from);
|
|
302
|
+
if (normalizedPath === normalizedFrom) return mapping.to;
|
|
303
|
+
if (normalizedPath.startsWith(`${normalizedFrom}/`)) return mapping.to + normalizedPath.slice(normalizedFrom.length);
|
|
302
304
|
return path;
|
|
303
305
|
}
|
|
306
|
+
function normalizeForMatch(p) {
|
|
307
|
+
return p.replace(/\\/g, "/").replace(/^[A-Z](?=:)/, (c) => c.toLowerCase());
|
|
308
|
+
}
|
|
309
|
+
var CONTAINER_TEST_LIST_PATH = "/tmp/crvy-rprtr-test-list.txt";
|
|
310
|
+
var REPORTER_BARE_SPECIFIER = "@crvy/rprtr";
|
|
311
|
+
var PATH_FLAGS = /* @__PURE__ */ new Set(["--config", "--reporter", "--test-list"]);
|
|
312
|
+
function rewritePlaywrightArgs(playwrightArgs, ctx, workDir, warn) {
|
|
313
|
+
const args = [];
|
|
314
|
+
const bindMounts = [];
|
|
315
|
+
for (let i = 0; i < playwrightArgs.length; i++) {
|
|
316
|
+
const flag = playwrightArgs[i];
|
|
317
|
+
if (!PATH_FLAGS.has(flag)) {
|
|
318
|
+
args.push(flag);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
const value = playwrightArgs[i + 1];
|
|
322
|
+
if (value === void 0) break;
|
|
323
|
+
i += 1;
|
|
324
|
+
args.push(flag);
|
|
325
|
+
const rewritten = rewriteContainerPath(value, { from: ctx.cwd, to: workDir });
|
|
326
|
+
if (flag === "--reporter" && rewritten === value) {
|
|
327
|
+
args.push(REPORTER_BARE_SPECIFIER);
|
|
328
|
+
} else if (flag === "--test-list" && rewritten === value) {
|
|
329
|
+
args.push(CONTAINER_TEST_LIST_PATH);
|
|
330
|
+
bindMounts.push(`${value}:${CONTAINER_TEST_LIST_PATH}:ro`);
|
|
331
|
+
} else {
|
|
332
|
+
if (flag === "--config" && rewritten === value) {
|
|
333
|
+
warn(`--config "${value}" is outside the project directory and will not resolve inside the container.`);
|
|
334
|
+
}
|
|
335
|
+
args.push(rewritten);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return { args, bindMounts };
|
|
339
|
+
}
|
|
304
340
|
function resolvePlaywrightVersion(cwd) {
|
|
305
341
|
try {
|
|
306
342
|
const req = createRequire(join2(cwd, "package.json"));
|
|
@@ -321,15 +357,18 @@ function testListEntry(d, file) {
|
|
|
321
357
|
const prefix = d.projectName !== void 0 && d.projectName !== "" ? `[${d.projectName}] \u203A ` : "";
|
|
322
358
|
return `${prefix}${loc} \u203A ${title}`;
|
|
323
359
|
}
|
|
324
|
-
function buildTestListEntries(tests, rootDir, cwd) {
|
|
360
|
+
function buildTestListEntries(tests, rootDir, cwd, pathStyle = "host") {
|
|
361
|
+
const convert = (p) => pathStyle === "posix" ? p.replace(/\\/g, "/") : p;
|
|
325
362
|
if (rootDir !== void 0) {
|
|
326
|
-
return tests.map(
|
|
363
|
+
return tests.map(
|
|
364
|
+
(d) => testListEntry(d, convert(isAbsolute(d.file) ? relative(rootDir, d.file) || d.file : d.file))
|
|
365
|
+
);
|
|
327
366
|
}
|
|
328
367
|
return tests.flatMap((d) => {
|
|
329
|
-
if (!isAbsolute(d.file)) return [testListEntry(d, d.file)];
|
|
368
|
+
if (!isAbsolute(d.file)) return [testListEntry(d, convert(d.file))];
|
|
330
369
|
const rel = relative(cwd ?? process.cwd(), d.file);
|
|
331
|
-
const segments = rel.split(sep);
|
|
332
|
-
return segments.map((_, i) => testListEntry(d, segments.slice(i).join(sep)));
|
|
370
|
+
const segments = pathStyle === "posix" ? rel.split(/[\\/]/) : rel.split(sep);
|
|
371
|
+
return segments.map((_, i) => testListEntry(d, convert(segments.slice(i).join(sep))));
|
|
333
372
|
});
|
|
334
373
|
}
|
|
335
374
|
|
|
@@ -444,7 +483,12 @@ var RunController = class {
|
|
|
444
483
|
if (reporterModule !== null) args.push("--reporter", reporterModule);
|
|
445
484
|
if (filters.update === true) args.push("--update-snapshots");
|
|
446
485
|
if (useTestList && tests !== void 0) {
|
|
447
|
-
const content = buildTestListEntries(
|
|
486
|
+
const content = buildTestListEntries(
|
|
487
|
+
tests,
|
|
488
|
+
ctx.rootDir,
|
|
489
|
+
ctx.cwd,
|
|
490
|
+
this.deps.containerPathMapping === void 0 ? "host" : "posix"
|
|
491
|
+
).join("\n");
|
|
448
492
|
const writeTemp = this.deps.writeTempFile ?? defaultWriteTempFile;
|
|
449
493
|
this.testListPath = writeTemp(content);
|
|
450
494
|
args.push("--test-list", this.testListPath);
|
|
@@ -574,8 +618,14 @@ var ENV_DENYLIST = /* @__PURE__ */ new Set([
|
|
|
574
618
|
"TZ",
|
|
575
619
|
"LANG",
|
|
576
620
|
"LC_ALL",
|
|
577
|
-
"PLAYWRIGHT_HTML_OPEN"
|
|
621
|
+
"PLAYWRIGHT_HTML_OPEN",
|
|
622
|
+
"PATH"
|
|
578
623
|
]);
|
|
624
|
+
var WINDOWS_ENV_NOISE = new Set(
|
|
625
|
+
"SYSTEMROOT COMSPEC WINDIR PATHEXT OS PROGRAMFILES PROGRAMFILES(X86) PROGRAMW6432 PROGRAMDATA ALLUSERSPROFILE PUBLIC APPDATA LOCALAPPDATA TEMP TMP USERPROFILE HOMEDRIVE HOMEPATH USERNAME PSMODULEPATH DRIVERDATA NUMBER_OF_PROCESSORS PROCESSOR_ARCHITECTURE PROCESSOR_IDENTIFIER PROCESSOR_LEVEL PROCESSOR_REVISION".split(
|
|
626
|
+
" "
|
|
627
|
+
)
|
|
628
|
+
);
|
|
579
629
|
var DockerUnavailableError = class extends Error {
|
|
580
630
|
constructor() {
|
|
581
631
|
super("Docker daemon is not available");
|
|
@@ -590,6 +640,12 @@ async function detectAgentName(detect2, cwd) {
|
|
|
590
640
|
return detected?.name ?? null;
|
|
591
641
|
}
|
|
592
642
|
async function prepareDocker(state, exec, ctx, deps, onProgress) {
|
|
643
|
+
if (deps.platform === "win32" && !state.warnedWin32) {
|
|
644
|
+
state.warnedWin32 = true;
|
|
645
|
+
deps.warn(
|
|
646
|
+
"Native Windows host detected: docker run mode is experimental on this platform. For CI-identical baselines, run crvy-rprtr from WSL2 with the project stored in the WSL filesystem."
|
|
647
|
+
);
|
|
648
|
+
}
|
|
593
649
|
if (!await probeDockerDaemon(exec)) {
|
|
594
650
|
state.available = false;
|
|
595
651
|
throw new DockerUnavailableError();
|
|
@@ -613,36 +669,6 @@ async function prepareDocker(state, exec, ctx, deps, onProgress) {
|
|
|
613
669
|
}
|
|
614
670
|
}
|
|
615
671
|
}
|
|
616
|
-
var REPORTER_BARE_SPECIFIER = "@crvy/rprtr";
|
|
617
|
-
var PATH_FLAGS = /* @__PURE__ */ new Set(["--config", "--reporter", "--test-list"]);
|
|
618
|
-
function rewritePlaywrightArgs(playwrightArgs, ctx, workDir, warn) {
|
|
619
|
-
const args = [];
|
|
620
|
-
const bindMounts = [];
|
|
621
|
-
for (let i = 0; i < playwrightArgs.length; i++) {
|
|
622
|
-
const flag = playwrightArgs[i];
|
|
623
|
-
if (!PATH_FLAGS.has(flag)) {
|
|
624
|
-
args.push(flag);
|
|
625
|
-
continue;
|
|
626
|
-
}
|
|
627
|
-
const value = playwrightArgs[i + 1];
|
|
628
|
-
if (value === void 0) break;
|
|
629
|
-
i += 1;
|
|
630
|
-
args.push(flag);
|
|
631
|
-
const rewritten = rewriteContainerPath(value, { from: ctx.cwd, to: workDir });
|
|
632
|
-
if (flag === "--reporter" && rewritten === value) {
|
|
633
|
-
args.push(REPORTER_BARE_SPECIFIER);
|
|
634
|
-
} else if (flag === "--test-list" && rewritten === value) {
|
|
635
|
-
args.push(value);
|
|
636
|
-
bindMounts.push(`${value}:${value}:ro`);
|
|
637
|
-
} else {
|
|
638
|
-
if (flag === "--config" && rewritten === value) {
|
|
639
|
-
warn(`--config "${value}" is outside the project directory and will not resolve inside the container.`);
|
|
640
|
-
}
|
|
641
|
-
args.push(rewritten);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
return { args, bindMounts };
|
|
645
|
-
}
|
|
646
672
|
function buildDockerRunArgs(ctx, playwrightArgs, deps) {
|
|
647
673
|
const { args: rewrittenArgs, bindMounts } = rewritePlaywrightArgs(playwrightArgs, ctx, deps.workDir, deps.warn);
|
|
648
674
|
const args = [
|
|
@@ -666,7 +692,8 @@ function buildDockerRunArgs(ctx, playwrightArgs, deps) {
|
|
|
666
692
|
args.push("-e", "CRVY_RPRTR_PORTABLE_ARTIFACTS=1", "-e", "TZ=UTC", "-e", "LANG=C.UTF-8", "-e", "LC_ALL=C.UTF-8");
|
|
667
693
|
args.push("-e", "PLAYWRIGHT_HTML_OPEN=never");
|
|
668
694
|
for (const [key, value] of Object.entries(deps.env)) {
|
|
669
|
-
|
|
695
|
+
const upper = key.toUpperCase();
|
|
696
|
+
if (ENV_DENYLIST.has(upper) || WINDOWS_ENV_NOISE.has(upper) || value === void 0) continue;
|
|
670
697
|
args.push("-e", key);
|
|
671
698
|
}
|
|
672
699
|
if (deps.docker?.extraArgs !== void 0) args.push(...deps.docker.extraArgs);
|
|
@@ -682,7 +709,13 @@ function stripCi(env) {
|
|
|
682
709
|
return out;
|
|
683
710
|
}
|
|
684
711
|
function createState(docker) {
|
|
685
|
-
return {
|
|
712
|
+
return {
|
|
713
|
+
available: void 0,
|
|
714
|
+
prepared: null,
|
|
715
|
+
image: null,
|
|
716
|
+
command: docker?.command ?? DEFAULT_CONTAINER_COMMAND,
|
|
717
|
+
warnedWin32: false
|
|
718
|
+
};
|
|
686
719
|
}
|
|
687
720
|
function buildLauncher(state, deps) {
|
|
688
721
|
return {
|
|
@@ -699,11 +732,13 @@ function buildLauncher(state, deps) {
|
|
|
699
732
|
docker: deps.docker,
|
|
700
733
|
getPlaywrightVersion: deps.getVersion,
|
|
701
734
|
detectAgent: deps.detectAgent,
|
|
702
|
-
warn: deps.warn
|
|
735
|
+
warn: deps.warn,
|
|
736
|
+
platform: deps.platform
|
|
703
737
|
},
|
|
704
738
|
onProgress
|
|
705
739
|
).catch((error) => {
|
|
706
740
|
state.prepared = null;
|
|
741
|
+
state.warnedWin32 = false;
|
|
707
742
|
throw error;
|
|
708
743
|
});
|
|
709
744
|
return state.prepared;
|
|
@@ -739,6 +774,7 @@ function createDockerLauncher(options) {
|
|
|
739
774
|
getVersion: options.getPlaywrightVersion ?? resolvePlaywrightVersion,
|
|
740
775
|
detectAgent: options.detectAgent,
|
|
741
776
|
warn: options.warn ?? defaultWarn,
|
|
777
|
+
platform: options.platform ?? process.platform,
|
|
742
778
|
docker: options.docker,
|
|
743
779
|
port: options.port
|
|
744
780
|
});
|
package/dist/cli.js
CHANGED
package/dist/index.css
CHANGED
|
@@ -430,6 +430,9 @@
|
|
|
430
430
|
.rotate-90 {
|
|
431
431
|
rotate: 90deg;
|
|
432
432
|
}
|
|
433
|
+
.transform {
|
|
434
|
+
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
|
435
|
+
}
|
|
433
436
|
.animate-pulse-dot {
|
|
434
437
|
animation: var(--animate-pulse-dot);
|
|
435
438
|
}
|
|
@@ -1187,6 +1190,26 @@
|
|
|
1187
1190
|
inherits: false;
|
|
1188
1191
|
initial-value: 0;
|
|
1189
1192
|
}
|
|
1193
|
+
@property --tw-rotate-x {
|
|
1194
|
+
syntax: "*";
|
|
1195
|
+
inherits: false;
|
|
1196
|
+
}
|
|
1197
|
+
@property --tw-rotate-y {
|
|
1198
|
+
syntax: "*";
|
|
1199
|
+
inherits: false;
|
|
1200
|
+
}
|
|
1201
|
+
@property --tw-rotate-z {
|
|
1202
|
+
syntax: "*";
|
|
1203
|
+
inherits: false;
|
|
1204
|
+
}
|
|
1205
|
+
@property --tw-skew-x {
|
|
1206
|
+
syntax: "*";
|
|
1207
|
+
inherits: false;
|
|
1208
|
+
}
|
|
1209
|
+
@property --tw-skew-y {
|
|
1210
|
+
syntax: "*";
|
|
1211
|
+
inherits: false;
|
|
1212
|
+
}
|
|
1190
1213
|
@property --tw-border-style {
|
|
1191
1214
|
syntax: "*";
|
|
1192
1215
|
inherits: false;
|
|
@@ -1362,6 +1385,11 @@
|
|
|
1362
1385
|
--tw-translate-x: 0;
|
|
1363
1386
|
--tw-translate-y: 0;
|
|
1364
1387
|
--tw-translate-z: 0;
|
|
1388
|
+
--tw-rotate-x: initial;
|
|
1389
|
+
--tw-rotate-y: initial;
|
|
1390
|
+
--tw-rotate-z: initial;
|
|
1391
|
+
--tw-skew-x: initial;
|
|
1392
|
+
--tw-skew-y: initial;
|
|
1365
1393
|
--tw-border-style: solid;
|
|
1366
1394
|
--tw-leading: initial;
|
|
1367
1395
|
--tw-font-weight: initial;
|
package/dist/reporter.cjs
CHANGED
|
@@ -777,6 +777,7 @@ var import_crypto2 = require("crypto");
|
|
|
777
777
|
var import_path3 = require("path");
|
|
778
778
|
var DEFAULT_SCREENSHOT_TEMPLATE = "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}";
|
|
779
779
|
var WINDOWS_FILESYSTEM_FRIENDLY_LENGTH = 60;
|
|
780
|
+
var PLAYWRIGHT_SNAPSHOT_NAME_LIMIT = 100;
|
|
780
781
|
function isUnsafeFilePathCharacter(character) {
|
|
781
782
|
const codePoint = character.codePointAt(0);
|
|
782
783
|
return codePoint !== void 0 && (codePoint <= 44 || codePoint >= 46 && codePoint <= 47 || codePoint >= 58 && codePoint <= 64 || codePoint >= 91 && codePoint <= 96 || codePoint >= 123 && codePoint <= 127);
|
|
@@ -906,7 +907,11 @@ function reporterTitlesWithoutProjectAndFile(reporterTitlePath) {
|
|
|
906
907
|
return reporterTitlePath.slice(3).filter((part) => part !== "");
|
|
907
908
|
}
|
|
908
909
|
function anonymousNameFromTitles(titles, occurrenceIndex) {
|
|
909
|
-
|
|
910
|
+
const fullTitleWithoutSpec = `${titles.join(" ")} ${occurrenceIndex}`;
|
|
911
|
+
return sanitizeFilePathBeforeExtension(
|
|
912
|
+
`${trimLongString(fullTitleWithoutSpec, PLAYWRIGHT_SNAPSHOT_NAME_LIMIT)}.png`,
|
|
913
|
+
".png"
|
|
914
|
+
);
|
|
910
915
|
}
|
|
911
916
|
function anonymousName(reporterTitlePath, occurrenceIndex) {
|
|
912
917
|
return anonymousNameFromTitles(reporterTitlesWithoutProjectAndFile(reporterTitlePath), occurrenceIndex);
|
package/dist/reporter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DetectAgent, type DockerExec } from './docker-support.ts';
|
|
1
|
+
import { type DetectAgent, type DockerExec, type Warn } from './docker-support.ts';
|
|
2
2
|
import type { RunLauncher } from './run-launcher.ts';
|
|
3
3
|
export declare const DOCKER_WORK_DIR = "/work";
|
|
4
4
|
export interface DockerOptions {
|
|
@@ -7,7 +7,6 @@ export interface DockerOptions {
|
|
|
7
7
|
command?: string[];
|
|
8
8
|
extraArgs?: string[];
|
|
9
9
|
}
|
|
10
|
-
type Warn = (message: string) => void;
|
|
11
10
|
export interface DockerLauncherOptions {
|
|
12
11
|
port: number;
|
|
13
12
|
docker?: DockerOptions;
|
|
@@ -18,10 +17,11 @@ export interface DockerLauncherOptions {
|
|
|
18
17
|
containerName?: string;
|
|
19
18
|
workDir?: string;
|
|
20
19
|
warn?: Warn;
|
|
20
|
+
/** Injectable host-platform seam for tests; defaults to process.platform. */
|
|
21
|
+
platform?: NodeJS.Platform;
|
|
21
22
|
}
|
|
22
23
|
export declare class DockerUnavailableError extends Error {
|
|
23
24
|
constructor();
|
|
24
25
|
}
|
|
25
26
|
export declare function createDockerLauncher(options: DockerLauncherOptions): RunLauncher;
|
|
26
|
-
export {};
|
|
27
27
|
//# sourceMappingURL=docker-launcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-launcher.d.ts","sourceRoot":"","sources":["../../src/server/docker-launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,WAAW,EAChB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"docker-launcher.d.ts","sourceRoot":"","sources":["../../src/server/docker-launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,IAAI,EACV,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAA4B,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE9E,eAAO,MAAM,eAAe,UAAU,CAAA;AAKtC,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,aAAa,GAAG,aAAa,CAAA;IACxC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACrD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;CAC3B;AAyBD,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAgMD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,WAAW,CAahF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RunContext } from './run-controller.ts';
|
|
1
2
|
export interface DockerExecResult {
|
|
2
3
|
exitCode: number;
|
|
3
4
|
stdout: string;
|
|
@@ -32,11 +33,30 @@ export interface ContainerPathMapping {
|
|
|
32
33
|
to: string;
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
|
-
* Maps an absolute path
|
|
36
|
+
* Maps an absolute path between the container's mount namespace and the host.
|
|
36
37
|
* Only exact matches and direct descendants of `mapping.from` are rewritten;
|
|
37
|
-
* prefix lookalikes like `/workspace` are left untouched.
|
|
38
|
+
* prefix lookalikes like `/workspace` are left untouched. Matching is
|
|
39
|
+
* separator- and drive-letter-case-insensitive so Windows host paths
|
|
40
|
+
* (`C:\proj\...`) rewrite correctly; the normalized form feeds the rewritten
|
|
41
|
+
* remainder, but unmatched paths return verbatim so callers can detect
|
|
42
|
+
* "not rewritten" via `rewritten === value`.
|
|
38
43
|
*/
|
|
39
44
|
export declare function rewriteContainerPath(path: string, mapping: ContainerPathMapping): string;
|
|
45
|
+
export type Warn = (message: string) => void;
|
|
46
|
+
interface RewrittenArgs {
|
|
47
|
+
args: string[];
|
|
48
|
+
/** Extra `-v <host>:<container>:ro` bind mounts (e.g. the host --test-list tmpfile onto its fixed container path). */
|
|
49
|
+
bindMounts: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Translates host paths in playwright args so they resolve inside the container.
|
|
53
|
+
* - `--config` / `--reporter` under ctx.cwd → `${workDir}/...`.
|
|
54
|
+
* - `--reporter` outside ctx.cwd (resolved from the server's own package) → bare `@crvy/rprtr`.
|
|
55
|
+
* - `--test-list` outside ctx.cwd (host tmpdir) → fixed container path (`CONTAINER_TEST_LIST_PATH`), plus a read-only bind mount of the host file onto it.
|
|
56
|
+
* - `--config` outside ctx.cwd → value unchanged plus a warning (the container cannot see it).
|
|
57
|
+
* Equals-form (`--flag=value`) and dangling trailing flags are NOT rewritten; run-controller emits pairs only.
|
|
58
|
+
*/
|
|
59
|
+
export declare function rewritePlaywrightArgs(playwrightArgs: string[], ctx: RunContext, workDir: string, warn: Warn): RewrittenArgs;
|
|
40
60
|
/** Reads the installed `@playwright/test` version from cwd; null when unresolvable (→ positional fallback). */
|
|
41
61
|
export declare function resolvePlaywrightVersion(cwd: string): string | null;
|
|
42
62
|
/**
|
|
@@ -60,7 +80,9 @@ type TestListDescriptor = {
|
|
|
60
80
|
* emits one candidate entry per plausible base (every suffix of the cwd-relative path):
|
|
61
81
|
* Playwright derives rootDir from testDir when set, and non-matching entries are
|
|
62
82
|
* ignored silently, so exactly one candidate matches the intended test.
|
|
83
|
+
* `pathStyle: 'posix'` (docker mode) converts backslashes so the in-container
|
|
84
|
+
* Linux Playwright can match entries; the default `'host'` keeps host separators.
|
|
63
85
|
*/
|
|
64
|
-
export declare function buildTestListEntries(tests: readonly TestListDescriptor[], rootDir?: string, cwd?: string): string[];
|
|
86
|
+
export declare function buildTestListEntries(tests: readonly TestListDescriptor[], rootDir?: string, cwd?: string, pathStyle?: 'host' | 'posix'): string[];
|
|
65
87
|
export {};
|
|
66
88
|
//# sourceMappingURL=docker-support.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-support.d.ts","sourceRoot":"","sources":["../../src/server/docker-support.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAEtE,wBAAgB,gBAAgB,IAAI,UAAU,CAiB7C;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAO1E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO5F;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOvF;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAIrG;AAeD,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAAY,CAAA;AAEnE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,cAAc,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,MAAM,EAAE,CAcX;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;AAExE,eAAO,MAAM,kBAAkB,EAAE,WAOhC,CAAA;AAED,8FAA8F;AAC9F,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACX;AAED
|
|
1
|
+
{"version":3,"file":"docker-support.d.ts","sourceRoot":"","sources":["../../src/server/docker-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-controller.d.ts","sourceRoot":"","sources":["../../src/server/run-controller.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAE9D,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,UAAU,GAAG,oBAAoB,CAAA;CAAE,CAAA;AAE9F,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAA;IAC1D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAA;IAClD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAAA;CAC/E;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,IAAI,UAAU,GAAG,IAAI,CAAA;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAA;IAChD,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACxC,gGAAgG;IAChG,cAAc,CAAC,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxC,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAC3C,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;QACpD,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;KACxC,CAAA;IACD,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IAChD,2DAA2D;IAC3D,QAAQ,EAAE,WAAW,CAAA;IACrB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACrD,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;IAC3C,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAkBD,0HAA0H;AAC1H,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAO/E;AAgBD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWjE;AAED,qBAAa,aAAa;IAKZ,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAsB;gBAEb,IAAI,EAAE,iBAAiB;IAEpD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"run-controller.d.ts","sourceRoot":"","sources":["../../src/server/run-controller.ts"],"names":[],"mappings":"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"}
|
package/dist/server.cjs
CHANGED
|
@@ -747,10 +747,46 @@ var detectProjectAgent = async (cwd) => {
|
|
|
747
747
|
}
|
|
748
748
|
};
|
|
749
749
|
function rewriteContainerPath(path, mapping) {
|
|
750
|
-
|
|
751
|
-
|
|
750
|
+
const normalizedPath = normalizeForMatch(path);
|
|
751
|
+
const normalizedFrom = normalizeForMatch(mapping.from);
|
|
752
|
+
if (normalizedPath === normalizedFrom) return mapping.to;
|
|
753
|
+
if (normalizedPath.startsWith(`${normalizedFrom}/`)) return mapping.to + normalizedPath.slice(normalizedFrom.length);
|
|
752
754
|
return path;
|
|
753
755
|
}
|
|
756
|
+
function normalizeForMatch(p) {
|
|
757
|
+
return p.replace(/\\/g, "/").replace(/^[A-Z](?=:)/, (c) => c.toLowerCase());
|
|
758
|
+
}
|
|
759
|
+
var CONTAINER_TEST_LIST_PATH = "/tmp/crvy-rprtr-test-list.txt";
|
|
760
|
+
var REPORTER_BARE_SPECIFIER = "@crvy/rprtr";
|
|
761
|
+
var PATH_FLAGS = /* @__PURE__ */ new Set(["--config", "--reporter", "--test-list"]);
|
|
762
|
+
function rewritePlaywrightArgs(playwrightArgs, ctx, workDir, warn) {
|
|
763
|
+
const args = [];
|
|
764
|
+
const bindMounts = [];
|
|
765
|
+
for (let i = 0; i < playwrightArgs.length; i++) {
|
|
766
|
+
const flag = playwrightArgs[i];
|
|
767
|
+
if (!PATH_FLAGS.has(flag)) {
|
|
768
|
+
args.push(flag);
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
const value = playwrightArgs[i + 1];
|
|
772
|
+
if (value === void 0) break;
|
|
773
|
+
i += 1;
|
|
774
|
+
args.push(flag);
|
|
775
|
+
const rewritten = rewriteContainerPath(value, { from: ctx.cwd, to: workDir });
|
|
776
|
+
if (flag === "--reporter" && rewritten === value) {
|
|
777
|
+
args.push(REPORTER_BARE_SPECIFIER);
|
|
778
|
+
} else if (flag === "--test-list" && rewritten === value) {
|
|
779
|
+
args.push(CONTAINER_TEST_LIST_PATH);
|
|
780
|
+
bindMounts.push(`${value}:${CONTAINER_TEST_LIST_PATH}:ro`);
|
|
781
|
+
} else {
|
|
782
|
+
if (flag === "--config" && rewritten === value) {
|
|
783
|
+
warn(`--config "${value}" is outside the project directory and will not resolve inside the container.`);
|
|
784
|
+
}
|
|
785
|
+
args.push(rewritten);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
return { args, bindMounts };
|
|
789
|
+
}
|
|
754
790
|
function resolvePlaywrightVersion(cwd) {
|
|
755
791
|
try {
|
|
756
792
|
const req = (0, import_node_module.createRequire)((0, import_node_path.join)(cwd, "package.json"));
|
|
@@ -771,15 +807,18 @@ function testListEntry(d, file) {
|
|
|
771
807
|
const prefix = d.projectName !== void 0 && d.projectName !== "" ? `[${d.projectName}] \u203A ` : "";
|
|
772
808
|
return `${prefix}${loc} \u203A ${title}`;
|
|
773
809
|
}
|
|
774
|
-
function buildTestListEntries(tests, rootDir, cwd) {
|
|
810
|
+
function buildTestListEntries(tests, rootDir, cwd, pathStyle = "host") {
|
|
811
|
+
const convert = (p) => pathStyle === "posix" ? p.replace(/\\/g, "/") : p;
|
|
775
812
|
if (rootDir !== void 0) {
|
|
776
|
-
return tests.map(
|
|
813
|
+
return tests.map(
|
|
814
|
+
(d) => testListEntry(d, convert((0, import_node_path.isAbsolute)(d.file) ? (0, import_node_path.relative)(rootDir, d.file) || d.file : d.file))
|
|
815
|
+
);
|
|
777
816
|
}
|
|
778
817
|
return tests.flatMap((d) => {
|
|
779
|
-
if (!(0, import_node_path.isAbsolute)(d.file)) return [testListEntry(d, d.file)];
|
|
818
|
+
if (!(0, import_node_path.isAbsolute)(d.file)) return [testListEntry(d, convert(d.file))];
|
|
780
819
|
const rel = (0, import_node_path.relative)(cwd ?? process.cwd(), d.file);
|
|
781
|
-
const segments = rel.split(import_node_path.sep);
|
|
782
|
-
return segments.map((_, i) => testListEntry(d, segments.slice(i).join(import_node_path.sep)));
|
|
820
|
+
const segments = pathStyle === "posix" ? rel.split(/[\\/]/) : rel.split(import_node_path.sep);
|
|
821
|
+
return segments.map((_, i) => testListEntry(d, convert(segments.slice(i).join(import_node_path.sep))));
|
|
783
822
|
});
|
|
784
823
|
}
|
|
785
824
|
|
|
@@ -895,7 +934,12 @@ var RunController = class {
|
|
|
895
934
|
if (reporterModule !== null) args.push("--reporter", reporterModule);
|
|
896
935
|
if (filters.update === true) args.push("--update-snapshots");
|
|
897
936
|
if (useTestList && tests !== void 0) {
|
|
898
|
-
const content = buildTestListEntries(
|
|
937
|
+
const content = buildTestListEntries(
|
|
938
|
+
tests,
|
|
939
|
+
ctx.rootDir,
|
|
940
|
+
ctx.cwd,
|
|
941
|
+
this.deps.containerPathMapping === void 0 ? "host" : "posix"
|
|
942
|
+
).join("\n");
|
|
899
943
|
const writeTemp = this.deps.writeTempFile ?? defaultWriteTempFile;
|
|
900
944
|
this.testListPath = writeTemp(content);
|
|
901
945
|
args.push("--test-list", this.testListPath);
|
|
@@ -1025,8 +1069,14 @@ var ENV_DENYLIST = /* @__PURE__ */ new Set([
|
|
|
1025
1069
|
"TZ",
|
|
1026
1070
|
"LANG",
|
|
1027
1071
|
"LC_ALL",
|
|
1028
|
-
"PLAYWRIGHT_HTML_OPEN"
|
|
1072
|
+
"PLAYWRIGHT_HTML_OPEN",
|
|
1073
|
+
"PATH"
|
|
1029
1074
|
]);
|
|
1075
|
+
var WINDOWS_ENV_NOISE = new Set(
|
|
1076
|
+
"SYSTEMROOT COMSPEC WINDIR PATHEXT OS PROGRAMFILES PROGRAMFILES(X86) PROGRAMW6432 PROGRAMDATA ALLUSERSPROFILE PUBLIC APPDATA LOCALAPPDATA TEMP TMP USERPROFILE HOMEDRIVE HOMEPATH USERNAME PSMODULEPATH DRIVERDATA NUMBER_OF_PROCESSORS PROCESSOR_ARCHITECTURE PROCESSOR_IDENTIFIER PROCESSOR_LEVEL PROCESSOR_REVISION".split(
|
|
1077
|
+
" "
|
|
1078
|
+
)
|
|
1079
|
+
);
|
|
1030
1080
|
var DockerUnavailableError = class extends Error {
|
|
1031
1081
|
constructor() {
|
|
1032
1082
|
super("Docker daemon is not available");
|
|
@@ -1041,6 +1091,12 @@ async function detectAgentName(detect2, cwd) {
|
|
|
1041
1091
|
return detected?.name ?? null;
|
|
1042
1092
|
}
|
|
1043
1093
|
async function prepareDocker(state, exec, ctx, deps, onProgress) {
|
|
1094
|
+
if (deps.platform === "win32" && !state.warnedWin32) {
|
|
1095
|
+
state.warnedWin32 = true;
|
|
1096
|
+
deps.warn(
|
|
1097
|
+
"Native Windows host detected: docker run mode is experimental on this platform. For CI-identical baselines, run crvy-rprtr from WSL2 with the project stored in the WSL filesystem."
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1044
1100
|
if (!await probeDockerDaemon(exec)) {
|
|
1045
1101
|
state.available = false;
|
|
1046
1102
|
throw new DockerUnavailableError();
|
|
@@ -1064,36 +1120,6 @@ async function prepareDocker(state, exec, ctx, deps, onProgress) {
|
|
|
1064
1120
|
}
|
|
1065
1121
|
}
|
|
1066
1122
|
}
|
|
1067
|
-
var REPORTER_BARE_SPECIFIER = "@crvy/rprtr";
|
|
1068
|
-
var PATH_FLAGS = /* @__PURE__ */ new Set(["--config", "--reporter", "--test-list"]);
|
|
1069
|
-
function rewritePlaywrightArgs(playwrightArgs, ctx, workDir, warn) {
|
|
1070
|
-
const args = [];
|
|
1071
|
-
const bindMounts = [];
|
|
1072
|
-
for (let i = 0; i < playwrightArgs.length; i++) {
|
|
1073
|
-
const flag = playwrightArgs[i];
|
|
1074
|
-
if (!PATH_FLAGS.has(flag)) {
|
|
1075
|
-
args.push(flag);
|
|
1076
|
-
continue;
|
|
1077
|
-
}
|
|
1078
|
-
const value = playwrightArgs[i + 1];
|
|
1079
|
-
if (value === void 0) break;
|
|
1080
|
-
i += 1;
|
|
1081
|
-
args.push(flag);
|
|
1082
|
-
const rewritten = rewriteContainerPath(value, { from: ctx.cwd, to: workDir });
|
|
1083
|
-
if (flag === "--reporter" && rewritten === value) {
|
|
1084
|
-
args.push(REPORTER_BARE_SPECIFIER);
|
|
1085
|
-
} else if (flag === "--test-list" && rewritten === value) {
|
|
1086
|
-
args.push(value);
|
|
1087
|
-
bindMounts.push(`${value}:${value}:ro`);
|
|
1088
|
-
} else {
|
|
1089
|
-
if (flag === "--config" && rewritten === value) {
|
|
1090
|
-
warn(`--config "${value}" is outside the project directory and will not resolve inside the container.`);
|
|
1091
|
-
}
|
|
1092
|
-
args.push(rewritten);
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
return { args, bindMounts };
|
|
1096
|
-
}
|
|
1097
1123
|
function buildDockerRunArgs(ctx, playwrightArgs, deps) {
|
|
1098
1124
|
const { args: rewrittenArgs, bindMounts } = rewritePlaywrightArgs(playwrightArgs, ctx, deps.workDir, deps.warn);
|
|
1099
1125
|
const args = [
|
|
@@ -1117,7 +1143,8 @@ function buildDockerRunArgs(ctx, playwrightArgs, deps) {
|
|
|
1117
1143
|
args.push("-e", "CRVY_RPRTR_PORTABLE_ARTIFACTS=1", "-e", "TZ=UTC", "-e", "LANG=C.UTF-8", "-e", "LC_ALL=C.UTF-8");
|
|
1118
1144
|
args.push("-e", "PLAYWRIGHT_HTML_OPEN=never");
|
|
1119
1145
|
for (const [key, value] of Object.entries(deps.env)) {
|
|
1120
|
-
|
|
1146
|
+
const upper = key.toUpperCase();
|
|
1147
|
+
if (ENV_DENYLIST.has(upper) || WINDOWS_ENV_NOISE.has(upper) || value === void 0) continue;
|
|
1121
1148
|
args.push("-e", key);
|
|
1122
1149
|
}
|
|
1123
1150
|
if (deps.docker?.extraArgs !== void 0) args.push(...deps.docker.extraArgs);
|
|
@@ -1133,7 +1160,13 @@ function stripCi(env) {
|
|
|
1133
1160
|
return out;
|
|
1134
1161
|
}
|
|
1135
1162
|
function createState(docker) {
|
|
1136
|
-
return {
|
|
1163
|
+
return {
|
|
1164
|
+
available: void 0,
|
|
1165
|
+
prepared: null,
|
|
1166
|
+
image: null,
|
|
1167
|
+
command: docker?.command ?? DEFAULT_CONTAINER_COMMAND,
|
|
1168
|
+
warnedWin32: false
|
|
1169
|
+
};
|
|
1137
1170
|
}
|
|
1138
1171
|
function buildLauncher(state, deps) {
|
|
1139
1172
|
return {
|
|
@@ -1150,11 +1183,13 @@ function buildLauncher(state, deps) {
|
|
|
1150
1183
|
docker: deps.docker,
|
|
1151
1184
|
getPlaywrightVersion: deps.getVersion,
|
|
1152
1185
|
detectAgent: deps.detectAgent,
|
|
1153
|
-
warn: deps.warn
|
|
1186
|
+
warn: deps.warn,
|
|
1187
|
+
platform: deps.platform
|
|
1154
1188
|
},
|
|
1155
1189
|
onProgress
|
|
1156
1190
|
).catch((error) => {
|
|
1157
1191
|
state.prepared = null;
|
|
1192
|
+
state.warnedWin32 = false;
|
|
1158
1193
|
throw error;
|
|
1159
1194
|
});
|
|
1160
1195
|
return state.prepared;
|
|
@@ -1190,6 +1225,7 @@ function createDockerLauncher(options) {
|
|
|
1190
1225
|
getVersion: options.getPlaywrightVersion ?? resolvePlaywrightVersion,
|
|
1191
1226
|
detectAgent: options.detectAgent,
|
|
1192
1227
|
warn: options.warn ?? defaultWarn,
|
|
1228
|
+
platform: options.platform ?? process.platform,
|
|
1193
1229
|
docker: options.docker,
|
|
1194
1230
|
port: options.port
|
|
1195
1231
|
});
|
|
@@ -1209,6 +1245,7 @@ var import_crypto = require("crypto");
|
|
|
1209
1245
|
var import_path3 = require("path");
|
|
1210
1246
|
var DEFAULT_SCREENSHOT_TEMPLATE = "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}";
|
|
1211
1247
|
var WINDOWS_FILESYSTEM_FRIENDLY_LENGTH = 60;
|
|
1248
|
+
var PLAYWRIGHT_SNAPSHOT_NAME_LIMIT = 100;
|
|
1212
1249
|
function isUnsafeFilePathCharacter(character) {
|
|
1213
1250
|
const codePoint = character.codePointAt(0);
|
|
1214
1251
|
return codePoint !== void 0 && (codePoint <= 44 || codePoint >= 46 && codePoint <= 47 || codePoint >= 58 && codePoint <= 64 || codePoint >= 91 && codePoint <= 96 || codePoint >= 123 && codePoint <= 127);
|
|
@@ -1338,7 +1375,11 @@ function reporterTitlesWithoutProjectAndFile(reporterTitlePath2) {
|
|
|
1338
1375
|
return reporterTitlePath2.slice(3).filter((part) => part !== "");
|
|
1339
1376
|
}
|
|
1340
1377
|
function anonymousNameFromTitles(titles, occurrenceIndex) {
|
|
1341
|
-
|
|
1378
|
+
const fullTitleWithoutSpec = `${titles.join(" ")} ${occurrenceIndex}`;
|
|
1379
|
+
return sanitizeFilePathBeforeExtension(
|
|
1380
|
+
`${trimLongString(fullTitleWithoutSpec, PLAYWRIGHT_SNAPSHOT_NAME_LIMIT)}.png`,
|
|
1381
|
+
".png"
|
|
1382
|
+
);
|
|
1342
1383
|
}
|
|
1343
1384
|
function anonymousName(reporterTitlePath2, occurrenceIndex) {
|
|
1344
1385
|
return anonymousNameFromTitles(reporterTitlesWithoutProjectAndFile(reporterTitlePath2), occurrenceIndex);
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-path-resolver.d.ts","sourceRoot":"","sources":["../src/snapshot-path-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"snapshot-path-resolver.d.ts","sourceRoot":"","sources":["../src/snapshot-path-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAU5F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IACtC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,MAAM,CAAA;CAC/C;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7C,QAAQ,CAAC,YAAY,EAAE,SAAS,qBAAqB,EAAE,CAAA;IACvD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAA;IACvC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAA;CAChE;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B;AAeD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAsBlD;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAqC,GAAG,MAAM,CAW1F;AAED,iBAAS,+BAA+B,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAoB,GAAG,MAAM,CAGhG;AAED,iBAAS,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrE;AA0ID,wBAAgB,6BAA6B,CAC3C,iBAAiB,EAAE,SAAS,MAAM,EAAE,EACpC,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CAGf;AAqBD,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,SAAS,qBAAqB,EAAE,EAC9C,iBAAiB,EAAE,SAAS,MAAM,EAAE,GACnC,qBAAqB,EAAE,CASzB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,EAAE,CAK7F;AAED,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,CAAA"}
|