@crvy/rprtr 0.1.2 → 0.1.4
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 +28 -0
- package/README.md +8 -0
- package/dist/{chunk-RJEAJDMQ.js → chunk-KLGJSEKV.js} +13 -4
- package/dist/{chunk-KFXC7QDV.js → chunk-WRMHUY5A.js} +30 -8
- package/dist/cli.js +2 -2
- package/dist/index.css +3 -0
- package/dist/index.js +9 -3
- package/dist/path-utils.d.ts +3 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/report-state.d.ts.map +1 -1
- package/dist/report-utils.d.ts.map +1 -1
- package/dist/reporter.cjs +69 -39
- package/dist/reporter.d.ts +4 -0
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +17 -3
- package/dist/schemas.d.ts +10 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/server/artifact-routes.d.ts.map +1 -1
- package/dist/server.cjs +81 -52
- package/dist/server.js +2 -2
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,34 @@ 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.1.4] - 2026-06-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **path-utils:** Add cross-platform absolute path helpers
|
|
13
|
+
- **server:** Log diagnostic when /file URL cannot resolve on host OS
|
|
14
|
+
|
|
15
|
+
### Documentation
|
|
16
|
+
|
|
17
|
+
- **plans:** Cross-OS path handling and stale actual URL on passing rerun
|
|
18
|
+
- Document cross-OS artifact loading limitations
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **report-utils:** Route Windows-style absolute paths to /file on any host
|
|
23
|
+
- **server:** Check pre-resolve path for foreign-OS diagnostic
|
|
24
|
+
- **report-state:** Drop stale comparison actual URL on passed reruns
|
|
25
|
+
- **report-state:** Strip stale actual/diff when preserving baseline-only images
|
|
26
|
+
|
|
27
|
+
### Testing
|
|
28
|
+
|
|
29
|
+
- **path-utils:** Cover forward-slash UNC form
|
|
30
|
+
- **server-routes:** Cover baseline enrichment after failed→passed progression
|
|
31
|
+
## [0.1.3] - 2026-06-18
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **reporter:** Resolve browser label for Playwright's default project
|
|
8
36
|
## [0.1.2] - 2026-06-08
|
|
9
37
|
|
|
10
38
|
### Added
|
package/README.md
CHANGED
|
@@ -113,6 +113,14 @@ Approval routing uses the same resolver, but it reads its resolver settings from
|
|
|
113
113
|
|
|
114
114
|
When the server is running, Crvy Rprtr also refreshes the UI after report JSON or screenshot artifacts change on disk.
|
|
115
115
|
|
|
116
|
+
## Cross-OS Artifact Loading
|
|
117
|
+
|
|
118
|
+
Crvy Rprtr stores image URLs exactly as the reporter that produced them saw them. In live mode (server running during the test run), failure artifacts are referenced by absolute path under `/file/<encoded>`; in CI/offline mode, attachments are copied into `screenshots/` and referenced by relative path under `/screenshots/`.
|
|
119
|
+
|
|
120
|
+
If you generate a report on one operating system and then open it on another (for example, downloading a Windows CI runner's `report.json` onto a macOS laptop), absolute-path `/file/...` URLs cannot resolve: the file is not on your filesystem. Crvy Rprtr logs a single diagnostic line per such request and returns 404. The `/screenshots/...` and `/baseline/...` URLs remain portable because they resolve through the server's `screenshotDir` or snapshot resolver.
|
|
121
|
+
|
|
122
|
+
For fully portable artifact loading across operating systems, run the reporter in CI mode (`ci: true`) and ship the `screenshots/` directory alongside the report JSON.
|
|
123
|
+
|
|
116
124
|
## Programmatic API
|
|
117
125
|
|
|
118
126
|
```ts
|
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
applyTestEndEvent,
|
|
12
12
|
createMutableReportState,
|
|
13
13
|
finalizeRunEvent,
|
|
14
|
+
isForeignAbsolutePath,
|
|
14
15
|
resolveBaselineTargets,
|
|
15
16
|
safeParse
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WRMHUY5A.js";
|
|
17
18
|
|
|
18
19
|
// src/server/app.ts
|
|
19
20
|
import { dirname as dirname3, join as join3 } from "path";
|
|
@@ -210,14 +211,21 @@ async function realpathOrNull(path) {
|
|
|
210
211
|
}
|
|
211
212
|
async function handleFile(ctx, req) {
|
|
212
213
|
const notFound = () => new Response("Not Found", { status: 404 });
|
|
214
|
+
let rawDecoded;
|
|
213
215
|
let decodedPath;
|
|
214
216
|
try {
|
|
215
|
-
|
|
217
|
+
rawDecoded = decodeURIComponent(new URL(req.url).pathname.slice("/file/".length));
|
|
218
|
+
decodedPath = resolve2(rawDecoded);
|
|
216
219
|
} catch {
|
|
217
220
|
return notFound();
|
|
218
221
|
}
|
|
219
222
|
const realTarget = await realpathOrNull(decodedPath);
|
|
220
223
|
if (realTarget === null) {
|
|
224
|
+
if (isForeignAbsolutePath(rawDecoded, process.platform)) {
|
|
225
|
+
console.warn(
|
|
226
|
+
`[Crvy Rprtr] /file request resolved to a foreign-OS absolute path that cannot be served on ${process.platform}: ${rawDecoded}`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
221
229
|
return notFound();
|
|
222
230
|
}
|
|
223
231
|
const realRoots = (await Promise.all((ctx.artifactRoots ?? []).map((root) => realpathOrNull(resolve2(root))))).filter(
|
|
@@ -235,7 +243,8 @@ async function handleFile(ctx, req) {
|
|
|
235
243
|
}
|
|
236
244
|
function reporterTitlePath(test) {
|
|
237
245
|
const testFile = test.location?.file;
|
|
238
|
-
|
|
246
|
+
const projectName = test.projectName ?? test.browser;
|
|
247
|
+
return ["", projectName, testFile ?? "", ...test.titlePath, test.title];
|
|
239
248
|
}
|
|
240
249
|
function resolveBaselineSnapshotPath(routing, test, retry, imageName) {
|
|
241
250
|
const testFile = test.location?.file;
|
|
@@ -251,7 +260,7 @@ function resolveBaselineSnapshotPath(routing, test, retry, imageName) {
|
|
|
251
260
|
configDir: routing.configDir,
|
|
252
261
|
testDir: routing.playwrightTestDir ?? dirname2(testFile),
|
|
253
262
|
snapshotDir: routing.playwrightSnapshotDir ?? dirname2(testFile),
|
|
254
|
-
projectName: test.browser,
|
|
263
|
+
projectName: test.projectName ?? test.browser,
|
|
255
264
|
snapshotSuffix: process.platform,
|
|
256
265
|
snapshotPathTemplate: routing.playwrightSnapshotPathTemplate,
|
|
257
266
|
toHaveScreenshotPathTemplate: routing.playwrightToHaveScreenshotPathTemplate
|
|
@@ -216,6 +216,7 @@ var TestDataSchema = z.object({
|
|
|
216
216
|
id: z.string(),
|
|
217
217
|
titlePath: z.array(z.string()),
|
|
218
218
|
browser: z.string(),
|
|
219
|
+
projectName: z.string().optional(),
|
|
219
220
|
title: z.string(),
|
|
220
221
|
skip: z.union([z.boolean(), z.string()]).optional(),
|
|
221
222
|
retries: z.number().optional(),
|
|
@@ -267,6 +268,7 @@ var TestBeginDataSchema = z.object({
|
|
|
267
268
|
title: z.string(),
|
|
268
269
|
titlePath: z.array(z.string()),
|
|
269
270
|
browser: z.string(),
|
|
271
|
+
projectName: z.string().optional(),
|
|
270
272
|
location: LocationSchema
|
|
271
273
|
});
|
|
272
274
|
var TestEndDataSchema = z.object({
|
|
@@ -339,8 +341,26 @@ function safeParse(schema, data) {
|
|
|
339
341
|
return null;
|
|
340
342
|
}
|
|
341
343
|
|
|
344
|
+
// src/path-utils.ts
|
|
345
|
+
var posixAbsolutePattern = /^\//u;
|
|
346
|
+
var windowsDrivePattern = /^[A-Za-z]:[\\/]/u;
|
|
347
|
+
var windowsUncPattern = /^[\\/][\\/]/u;
|
|
348
|
+
function isPosixAbsolutePath(p) {
|
|
349
|
+
return posixAbsolutePattern.test(p);
|
|
350
|
+
}
|
|
351
|
+
function isWindowsAbsolutePath(p) {
|
|
352
|
+
return windowsDrivePattern.test(p) || windowsUncPattern.test(p);
|
|
353
|
+
}
|
|
354
|
+
function isAnyAbsolutePath(p) {
|
|
355
|
+
return isPosixAbsolutePath(p) || isWindowsAbsolutePath(p);
|
|
356
|
+
}
|
|
357
|
+
function isForeignAbsolutePath(p, hostPlatform) {
|
|
358
|
+
if (!isAnyAbsolutePath(p)) return false;
|
|
359
|
+
if (hostPlatform === "win32") return !isWindowsAbsolutePath(p);
|
|
360
|
+
return !isPosixAbsolutePath(p);
|
|
361
|
+
}
|
|
362
|
+
|
|
342
363
|
// src/report-utils.ts
|
|
343
|
-
import { isAbsolute } from "path";
|
|
344
364
|
function normalizeScreenshotsBaseUrl(baseUrl) {
|
|
345
365
|
return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
346
366
|
}
|
|
@@ -385,7 +405,7 @@ function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/")
|
|
|
385
405
|
const role = match[2];
|
|
386
406
|
if (baseName === null || baseName === void 0 || role === null || role === void 0) continue;
|
|
387
407
|
images[baseName] ??= {};
|
|
388
|
-
const url =
|
|
408
|
+
const url = isAnyAbsolutePath(attachment.path) ? `/file/${encodeURIComponent(attachment.path)}` : `${baseUrl}${attachment.path}`;
|
|
389
409
|
const img = images[baseName];
|
|
390
410
|
if (img !== null && img !== void 0) {
|
|
391
411
|
if (role === "actual") img.actual = url;
|
|
@@ -420,9 +440,6 @@ function isCurrentArtifact(image) {
|
|
|
420
440
|
}
|
|
421
441
|
function isReusablePassingImage(image) {
|
|
422
442
|
const source = image.source ?? classifyImage(image);
|
|
423
|
-
if (source === "comparison") {
|
|
424
|
-
return image.actual !== void 0 && image.diff === void 0;
|
|
425
|
-
}
|
|
426
443
|
return source === "baseline-only";
|
|
427
444
|
}
|
|
428
445
|
function hasReusablePassingImages(images) {
|
|
@@ -443,8 +460,8 @@ function preservePreviousPassingImages(test, status, images) {
|
|
|
443
460
|
return {
|
|
444
461
|
...currentImages,
|
|
445
462
|
[name]: {
|
|
446
|
-
|
|
447
|
-
source:
|
|
463
|
+
expect: previousImage.expect,
|
|
464
|
+
source: "baseline-only"
|
|
448
465
|
}
|
|
449
466
|
};
|
|
450
467
|
}, images);
|
|
@@ -465,12 +482,16 @@ function createMutableReportState(screenshotDir = "./screenshots") {
|
|
|
465
482
|
};
|
|
466
483
|
}
|
|
467
484
|
function applyTestBeginEvent(state, data) {
|
|
468
|
-
const { id, title, titlePath, browser, location } = data;
|
|
485
|
+
const { id, title, titlePath, browser, projectName, location } = data;
|
|
469
486
|
state.currentRunIds.add(id);
|
|
470
487
|
state.reportData.tests[id] ??= {
|
|
471
488
|
id,
|
|
472
489
|
titlePath: titlePath ?? [],
|
|
473
490
|
browser: browser ?? "",
|
|
491
|
+
// Older reporters sent the raw project name in `browser` and had no
|
|
492
|
+
// `projectName` field. Preserve that value for snapshot path resolution
|
|
493
|
+
// when loading data produced by such reporters.
|
|
494
|
+
projectName: projectName ?? browser ?? "",
|
|
474
495
|
title: title ?? "",
|
|
475
496
|
location,
|
|
476
497
|
status: "running"
|
|
@@ -528,6 +549,7 @@ function finalizeRunEvent(state) {
|
|
|
528
549
|
}
|
|
529
550
|
|
|
530
551
|
export {
|
|
552
|
+
isForeignAbsolutePath,
|
|
531
553
|
createMutableReportState,
|
|
532
554
|
applyTestBeginEvent,
|
|
533
555
|
applyTestEndEvent,
|
package/dist/cli.js
CHANGED
package/dist/index.css
CHANGED
package/dist/index.js
CHANGED
|
@@ -19368,6 +19368,7 @@ var TestDataSchema = external_exports.object({
|
|
|
19368
19368
|
id: external_exports.string(),
|
|
19369
19369
|
titlePath: external_exports.array(external_exports.string()),
|
|
19370
19370
|
browser: external_exports.string(),
|
|
19371
|
+
projectName: external_exports.string().optional(),
|
|
19371
19372
|
title: external_exports.string(),
|
|
19372
19373
|
skip: external_exports.union([external_exports.boolean(), external_exports.string()]).optional(),
|
|
19373
19374
|
retries: external_exports.number().optional(),
|
|
@@ -19419,6 +19420,7 @@ var TestBeginDataSchema = external_exports.object({
|
|
|
19419
19420
|
title: external_exports.string(),
|
|
19420
19421
|
titlePath: external_exports.array(external_exports.string()),
|
|
19421
19422
|
browser: external_exports.string(),
|
|
19423
|
+
projectName: external_exports.string().optional(),
|
|
19422
19424
|
location: LocationSchema
|
|
19423
19425
|
});
|
|
19424
19426
|
var TestEndDataSchema = external_exports.object({
|
|
@@ -19618,6 +19620,10 @@ function hasScreenshots(item) {
|
|
|
19618
19620
|
}
|
|
19619
19621
|
|
|
19620
19622
|
// src/client/helpers/path.ts
|
|
19623
|
+
var DEFAULT_BROWSER_KEY = "default";
|
|
19624
|
+
function browserKeyFor(browser) {
|
|
19625
|
+
return browser === "" ? DEFAULT_BROWSER_KEY : browser;
|
|
19626
|
+
}
|
|
19621
19627
|
function getTestPath(test) {
|
|
19622
19628
|
return [...test.titlePath, test.title, test.browser].filter(isDefined);
|
|
19623
19629
|
}
|
|
@@ -19676,7 +19682,7 @@ function treeifyTests(testsById) {
|
|
|
19676
19682
|
Object.values(testsById).forEach((test) => {
|
|
19677
19683
|
if (test === void 0) return;
|
|
19678
19684
|
const titlePath = test.titlePath ?? [];
|
|
19679
|
-
const browser = test.browser ?? "";
|
|
19685
|
+
const browser = browserKeyFor(test.browser ?? "");
|
|
19680
19686
|
const title = test.title;
|
|
19681
19687
|
const pathParts = [...titlePath, title, browser].filter((p) => p !== void 0 && p !== "");
|
|
19682
19688
|
const [browserName, ...testPathParts] = pathParts.reverse();
|
|
@@ -19863,8 +19869,8 @@ function collectTestsById(suite) {
|
|
|
19863
19869
|
function pathTokensFor(test) {
|
|
19864
19870
|
const titlePath = test.titlePath ?? [];
|
|
19865
19871
|
const title = test.title;
|
|
19866
|
-
|
|
19867
|
-
|
|
19872
|
+
if (title === void 0 || title === "") return null;
|
|
19873
|
+
const browser = browserKeyFor(test.browser ?? "");
|
|
19868
19874
|
const pathParts = [...titlePath, title, browser].filter((p) => p !== void 0 && p !== "");
|
|
19869
19875
|
const reversed = pathParts.reverse();
|
|
19870
19876
|
const browserKey = reversed[0];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAYA,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,QAAQ,GAAG,OAAO,CAIvF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-state.d.ts","sourceRoot":"","sources":["../src/report-state.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAU,QAAQ,EAAc,MAAM,YAAY,CAAA;AAE9D,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,iBAAiB,CAAA;IAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,KAAK,sBAAsB,GAAG,WAAW,GAAG;IAC1C,kBAAkB,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CACtD,CAAA;
|
|
1
|
+
{"version":3,"file":"report-state.d.ts","sourceRoot":"","sources":["../src/report-state.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAU,QAAQ,EAAc,MAAM,YAAY,CAAA;AAE9D,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,iBAAiB,CAAA;IAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,KAAK,sBAAsB,GAAG,WAAW,GAAG;IAC1C,kBAAkB,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CACtD,CAAA;AAqDD,wBAAgB,wBAAwB,CAAC,aAAa,SAAkB,GAAG,kBAAkB,CAW5F;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa,GAAG,QAAQ,CAiB5F;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,sBAAsB,EAC5B,OAAO,GAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,kBAAkB,GAAG,IAAI,CAyC3B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAa/G"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-utils.d.ts","sourceRoot":"","sources":["../src/report-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report-utils.d.ts","sourceRoot":"","sources":["../src/report-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAMhE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAUzD;AASD,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,kBAAkB,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,GAC/D,SAAS,MAAM,EAAE,CAEnB;AAED,wBAAgB,sBAAsB,CACpC,kBAAkB,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,GAC/D,SAAS,qBAAqB,EAAE,GAAG,SAAS,CAE9C;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACvC,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASjC;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,UAAU,EAAE,EACzB,kBAAkB,SAAkB,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkCjC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAWrF"}
|
package/dist/reporter.cjs
CHANGED
|
@@ -36,7 +36,7 @@ __export(reporter_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(reporter_exports);
|
|
37
37
|
var import_fs = require("fs");
|
|
38
38
|
var import_promises3 = require("fs/promises");
|
|
39
|
-
var
|
|
39
|
+
var import_path4 = require("path");
|
|
40
40
|
var import_p_limit2 = __toESM(require("p-limit"), 1);
|
|
41
41
|
|
|
42
42
|
// src/ci.ts
|
|
@@ -56,16 +56,29 @@ var logError = (...args) => {
|
|
|
56
56
|
|
|
57
57
|
// src/reporter-artifact-ops.ts
|
|
58
58
|
var import_promises2 = require("fs/promises");
|
|
59
|
-
var
|
|
59
|
+
var import_path2 = require("path");
|
|
60
60
|
var import_p_limit = __toESM(require("p-limit"), 1);
|
|
61
61
|
|
|
62
62
|
// src/report-artifact.ts
|
|
63
63
|
var import_promises = require("fs/promises");
|
|
64
|
-
var
|
|
64
|
+
var import_path = require("path");
|
|
65
65
|
var import_url = require("url");
|
|
66
66
|
|
|
67
|
+
// src/path-utils.ts
|
|
68
|
+
var posixAbsolutePattern = /^\//u;
|
|
69
|
+
var windowsDrivePattern = /^[A-Za-z]:[\\/]/u;
|
|
70
|
+
var windowsUncPattern = /^[\\/][\\/]/u;
|
|
71
|
+
function isPosixAbsolutePath(p) {
|
|
72
|
+
return posixAbsolutePattern.test(p);
|
|
73
|
+
}
|
|
74
|
+
function isWindowsAbsolutePath(p) {
|
|
75
|
+
return windowsDrivePattern.test(p) || windowsUncPattern.test(p);
|
|
76
|
+
}
|
|
77
|
+
function isAnyAbsolutePath(p) {
|
|
78
|
+
return isPosixAbsolutePath(p) || isWindowsAbsolutePath(p);
|
|
79
|
+
}
|
|
80
|
+
|
|
67
81
|
// src/report-utils.ts
|
|
68
|
-
var import_path = require("path");
|
|
69
82
|
function normalizeScreenshotsBaseUrl(baseUrl) {
|
|
70
83
|
return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
71
84
|
}
|
|
@@ -110,7 +123,7 @@ function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/")
|
|
|
110
123
|
const role = match[2];
|
|
111
124
|
if (baseName === null || baseName === void 0 || role === null || role === void 0) continue;
|
|
112
125
|
images[baseName] ??= {};
|
|
113
|
-
const url = (
|
|
126
|
+
const url = isAnyAbsolutePath(attachment.path) ? `/file/${encodeURIComponent(attachment.path)}` : `${baseUrl}${attachment.path}`;
|
|
114
127
|
const img = images[baseName];
|
|
115
128
|
if (img !== null && img !== void 0) {
|
|
116
129
|
if (role === "actual") img.actual = url;
|
|
@@ -145,9 +158,6 @@ function isCurrentArtifact(image) {
|
|
|
145
158
|
}
|
|
146
159
|
function isReusablePassingImage(image) {
|
|
147
160
|
const source = image.source ?? classifyImage(image);
|
|
148
|
-
if (source === "comparison") {
|
|
149
|
-
return image.actual !== void 0 && image.diff === void 0;
|
|
150
|
-
}
|
|
151
161
|
return source === "baseline-only";
|
|
152
162
|
}
|
|
153
163
|
function hasReusablePassingImages(images) {
|
|
@@ -168,8 +178,8 @@ function preservePreviousPassingImages(test, status, images) {
|
|
|
168
178
|
return {
|
|
169
179
|
...currentImages,
|
|
170
180
|
[name]: {
|
|
171
|
-
|
|
172
|
-
source:
|
|
181
|
+
expect: previousImage.expect,
|
|
182
|
+
source: "baseline-only"
|
|
173
183
|
}
|
|
174
184
|
};
|
|
175
185
|
}, images);
|
|
@@ -190,12 +200,16 @@ function createMutableReportState(screenshotDir = "./screenshots") {
|
|
|
190
200
|
};
|
|
191
201
|
}
|
|
192
202
|
function applyTestBeginEvent(state, data) {
|
|
193
|
-
const { id, title, titlePath, browser, location } = data;
|
|
203
|
+
const { id, title, titlePath, browser, projectName, location } = data;
|
|
194
204
|
state.currentRunIds.add(id);
|
|
195
205
|
state.reportData.tests[id] ??= {
|
|
196
206
|
id,
|
|
197
207
|
titlePath: titlePath ?? [],
|
|
198
208
|
browser: browser ?? "",
|
|
209
|
+
// Older reporters sent the raw project name in `browser` and had no
|
|
210
|
+
// `projectName` field. Preserve that value for snapshot path resolution
|
|
211
|
+
// when loading data produced by such reporters.
|
|
212
|
+
projectName: projectName ?? browser ?? "",
|
|
199
213
|
title: title ?? "",
|
|
200
214
|
location,
|
|
201
215
|
status: "running"
|
|
@@ -299,6 +313,7 @@ var TestDataSchema = import_zod.z.object({
|
|
|
299
313
|
id: import_zod.z.string(),
|
|
300
314
|
titlePath: import_zod.z.array(import_zod.z.string()),
|
|
301
315
|
browser: import_zod.z.string(),
|
|
316
|
+
projectName: import_zod.z.string().optional(),
|
|
302
317
|
title: import_zod.z.string(),
|
|
303
318
|
skip: import_zod.z.union([import_zod.z.boolean(), import_zod.z.string()]).optional(),
|
|
304
319
|
retries: import_zod.z.number().optional(),
|
|
@@ -350,6 +365,7 @@ var TestBeginDataSchema = import_zod.z.object({
|
|
|
350
365
|
title: import_zod.z.string(),
|
|
351
366
|
titlePath: import_zod.z.array(import_zod.z.string()),
|
|
352
367
|
browser: import_zod.z.string(),
|
|
368
|
+
projectName: import_zod.z.string().optional(),
|
|
353
369
|
location: LocationSchema
|
|
354
370
|
});
|
|
355
371
|
var TestEndDataSchema = import_zod.z.object({
|
|
@@ -427,7 +443,7 @@ var import_meta = { url: require("url").pathToFileURL(__filename).href };
|
|
|
427
443
|
var DEFAULT_REPORT_HTML_PATH = "./crvy-rprtr.html";
|
|
428
444
|
var STATIC_ARTIFACT_APPROVAL_MESSAGE = "This artifact is read-only. Open it with the Crvy Rprtr server to approve screenshots.";
|
|
429
445
|
function toBrowserPath(pathValue) {
|
|
430
|
-
const normalized = pathValue.split(
|
|
446
|
+
const normalized = pathValue.split(import_path.sep).join("/");
|
|
431
447
|
if (normalized === "") return ".";
|
|
432
448
|
if (normalized.startsWith(".")) return normalized;
|
|
433
449
|
return `./${normalized}`;
|
|
@@ -463,11 +479,11 @@ function renderArtifactHtml(template, bootstrapData, stylesheet, script) {
|
|
|
463
479
|
);
|
|
464
480
|
}
|
|
465
481
|
async function getPackagedAssetPath(fileName) {
|
|
466
|
-
const currentDir = (0,
|
|
467
|
-
const candidates = [currentDir, (0,
|
|
482
|
+
const currentDir = (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
483
|
+
const candidates = [currentDir, (0, import_path.resolve)(currentDir, "../dist")];
|
|
468
484
|
const resolvedCandidates = await Promise.all(
|
|
469
485
|
candidates.map(async (candidate) => {
|
|
470
|
-
const assetPath = (0,
|
|
486
|
+
const assetPath = (0, import_path.resolve)(candidate, fileName);
|
|
471
487
|
try {
|
|
472
488
|
await (0, import_promises.access)(assetPath);
|
|
473
489
|
return assetPath;
|
|
@@ -485,7 +501,7 @@ async function getPackagedAssetPath(fileName) {
|
|
|
485
501
|
);
|
|
486
502
|
}
|
|
487
503
|
function buildStaticBootstrapData(events, screenshotDir, htmlPath) {
|
|
488
|
-
const screenshotBaseUrl = toBrowserDirPath((0,
|
|
504
|
+
const screenshotBaseUrl = toBrowserDirPath((0, import_path.relative)((0, import_path.dirname)(htmlPath), (0, import_path.resolve)(screenshotDir)));
|
|
489
505
|
const state = createMutableReportState(screenshotDir);
|
|
490
506
|
for (const event of events) {
|
|
491
507
|
switch (event.type) {
|
|
@@ -524,13 +540,13 @@ function buildStaticBootstrapData(events, screenshotDir, htmlPath) {
|
|
|
524
540
|
return parsedBootstrapData;
|
|
525
541
|
}
|
|
526
542
|
async function writeReportArtifact(options) {
|
|
527
|
-
const reportHtmlPath = (0,
|
|
543
|
+
const reportHtmlPath = (0, import_path.resolve)(options.reportHtmlPath ?? DEFAULT_REPORT_HTML_PATH);
|
|
528
544
|
const [indexHtmlPath, indexJsPath, indexCssPath] = await Promise.all([
|
|
529
545
|
getPackagedAssetPath("index.html"),
|
|
530
546
|
getPackagedAssetPath("index.js"),
|
|
531
547
|
getPackagedAssetPath("index.css")
|
|
532
548
|
]);
|
|
533
|
-
await (0, import_promises.mkdir)((0,
|
|
549
|
+
await (0, import_promises.mkdir)((0, import_path.dirname)(reportHtmlPath), { recursive: true });
|
|
534
550
|
const [template, script, stylesheet] = await Promise.all([
|
|
535
551
|
(0, import_promises.readFile)(indexHtmlPath, "utf8"),
|
|
536
552
|
(0, import_promises.readFile)(indexJsPath, "utf8"),
|
|
@@ -563,9 +579,9 @@ function sanitizeId(id) {
|
|
|
563
579
|
async function copyResolvedBaseline(safeTestId, testScreenshotDir, target, savedAttachments) {
|
|
564
580
|
const attachmentName = `${target.attachmentBaseName}-expected.png`;
|
|
565
581
|
const artifactPath = safeArtifactPath(attachmentName);
|
|
566
|
-
const destPath = (0,
|
|
582
|
+
const destPath = (0, import_path2.join)(testScreenshotDir, artifactPath);
|
|
567
583
|
try {
|
|
568
|
-
await (0, import_promises2.mkdir)((0,
|
|
584
|
+
await (0, import_promises2.mkdir)((0, import_path2.dirname)(destPath), { recursive: true });
|
|
569
585
|
await (0, import_promises2.copyFile)(target.snapshotPath, destPath);
|
|
570
586
|
savedAttachments.push({ name: attachmentName, path: `${safeTestId}/${artifactPath}`, contentType: "image/png" });
|
|
571
587
|
log(`[CrvyRprtr] Attached baseline: ${target.snapshotPath}`);
|
|
@@ -575,7 +591,7 @@ async function copyResolvedBaseline(safeTestId, testScreenshotDir, target, saved
|
|
|
575
591
|
async function saveAttachments(screenshotDir, testId, result) {
|
|
576
592
|
const savedAttachments = [];
|
|
577
593
|
const safeTestId = sanitizeId(testId);
|
|
578
|
-
const testScreenshotDir = (0,
|
|
594
|
+
const testScreenshotDir = (0, import_path2.join)(screenshotDir, safeTestId);
|
|
579
595
|
const limit = (0, import_p_limit.default)(MAX_CONCURRENT_FILE_OPS);
|
|
580
596
|
await Promise.all(
|
|
581
597
|
result.attachments.filter(
|
|
@@ -584,8 +600,8 @@ async function saveAttachments(screenshotDir, testId, result) {
|
|
|
584
600
|
(attachment) => limit(async () => {
|
|
585
601
|
try {
|
|
586
602
|
const artifactPath = safeArtifactPath(attachment.name);
|
|
587
|
-
const destPath = (0,
|
|
588
|
-
await (0, import_promises2.mkdir)((0,
|
|
603
|
+
const destPath = (0, import_path2.join)(testScreenshotDir, artifactPath);
|
|
604
|
+
await (0, import_promises2.mkdir)((0, import_path2.dirname)(destPath), { recursive: true });
|
|
589
605
|
await (0, import_promises2.copyFile)(attachment.path, destPath);
|
|
590
606
|
savedAttachments.push({
|
|
591
607
|
name: attachment.name,
|
|
@@ -715,7 +731,7 @@ function extractScreenshotDeclarations(steps) {
|
|
|
715
731
|
|
|
716
732
|
// src/snapshot-path-resolver.ts
|
|
717
733
|
var import_crypto = require("crypto");
|
|
718
|
-
var
|
|
734
|
+
var import_path3 = require("path");
|
|
719
735
|
var DEFAULT_SCREENSHOT_TEMPLATE = "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}";
|
|
720
736
|
var WINDOWS_FILESYSTEM_FRIENDLY_LENGTH = 60;
|
|
721
737
|
function isUnsafeFilePathCharacter(character) {
|
|
@@ -750,16 +766,16 @@ function trimLongString(value, length = WINDOWS_FILESYSTEM_FRIENDLY_LENGTH) {
|
|
|
750
766
|
const end = length - middle.length - start;
|
|
751
767
|
return value.slice(0, start) + middle + value.slice(-end);
|
|
752
768
|
}
|
|
753
|
-
function sanitizeFilePathBeforeExtension(filePath, extension = (0,
|
|
769
|
+
function sanitizeFilePathBeforeExtension(filePath, extension = (0, import_path3.extname)(filePath)) {
|
|
754
770
|
const base = filePath.slice(0, filePath.length - extension.length);
|
|
755
771
|
return sanitizeForFilePath(base) + extension;
|
|
756
772
|
}
|
|
757
773
|
function addSuffixToFilePath(filePath, suffix) {
|
|
758
|
-
const extension = (0,
|
|
774
|
+
const extension = (0, import_path3.extname)(filePath);
|
|
759
775
|
return filePath.slice(0, filePath.length - extension.length) + suffix + extension;
|
|
760
776
|
}
|
|
761
777
|
function normalizedSnapshotDir(config) {
|
|
762
|
-
return (0,
|
|
778
|
+
return (0, import_path3.resolve)(config.configDir, config.snapshotDir);
|
|
763
779
|
}
|
|
764
780
|
function templateValue(template, token, value) {
|
|
765
781
|
return template.replace(
|
|
@@ -769,8 +785,8 @@ function templateValue(template, token, value) {
|
|
|
769
785
|
}
|
|
770
786
|
function applyTemplate(input, nameArgument, extension) {
|
|
771
787
|
const template = input.config.toHaveScreenshotPathTemplate ?? input.config.snapshotPathTemplate ?? DEFAULT_SCREENSHOT_TEMPLATE;
|
|
772
|
-
const relativeTestFilePath = (0,
|
|
773
|
-
const parsed = (0,
|
|
788
|
+
const relativeTestFilePath = (0, import_path3.relative)(input.config.testDir, input.testFile);
|
|
789
|
+
const parsed = (0, import_path3.parse)(relativeTestFilePath);
|
|
774
790
|
const tokens = [
|
|
775
791
|
["testDir", input.config.testDir],
|
|
776
792
|
["snapshotDir", normalizedSnapshotDir(input.config)],
|
|
@@ -788,16 +804,16 @@ function applyTemplate(input, nameArgument, extension) {
|
|
|
788
804
|
(currentTemplate, [token, value]) => templateValue(currentTemplate, token, value),
|
|
789
805
|
template
|
|
790
806
|
);
|
|
791
|
-
return (0,
|
|
807
|
+
return (0, import_path3.resolve)(input.config.configDir, snapshotPath);
|
|
792
808
|
}
|
|
793
|
-
function removeExtension(filePath, extension = (0,
|
|
809
|
+
function removeExtension(filePath, extension = (0, import_path3.extname)(filePath)) {
|
|
794
810
|
return filePath.slice(0, filePath.length - extension.length);
|
|
795
811
|
}
|
|
796
812
|
function snapshotNameParts(declaredName) {
|
|
797
|
-
const extension = (0,
|
|
813
|
+
const extension = (0, import_path3.extname)(declaredName) || ".png";
|
|
798
814
|
return {
|
|
799
815
|
extension,
|
|
800
|
-
filePath: (0,
|
|
816
|
+
filePath: (0, import_path3.extname)(declaredName) === "" ? `${declaredName}${extension}` : declaredName
|
|
801
817
|
};
|
|
802
818
|
}
|
|
803
819
|
function filePathForOccurrence(filePath, occurrenceIndex) {
|
|
@@ -821,7 +837,7 @@ function resolveStringCallTarget(input, declaration) {
|
|
|
821
837
|
function resolveArrayCallTarget(input, declaration) {
|
|
822
838
|
const { extension, filePath } = snapshotNameParts(declaration.declaredName);
|
|
823
839
|
const occurrenceFilePath = filePathForOccurrence(filePath, declaration.occurrenceIndex);
|
|
824
|
-
const nameArgument = (0,
|
|
840
|
+
const nameArgument = (0, import_path3.join)((0, import_path3.dirname)(occurrenceFilePath), (0, import_path3.basename)(occurrenceFilePath, extension));
|
|
825
841
|
return createResolvedBaselineTarget(input, declaration, nameArgument, extension);
|
|
826
842
|
}
|
|
827
843
|
function resolveNamedTarget(input, declaration) {
|
|
@@ -863,7 +879,7 @@ function resolveTarget(input, declaration) {
|
|
|
863
879
|
case "unnamed": {
|
|
864
880
|
const anonymousFileName = anonymousName(input.reporterTitlePath, declaration.occurrenceIndex);
|
|
865
881
|
const extension = ".png";
|
|
866
|
-
const nameArgument = (0,
|
|
882
|
+
const nameArgument = (0, import_path3.join)((0, import_path3.dirname)(anonymousFileName), (0, import_path3.basename)(anonymousFileName, extension));
|
|
867
883
|
return createResolvedBaselineTarget(input, declaration, nameArgument, extension);
|
|
868
884
|
}
|
|
869
885
|
}
|
|
@@ -915,7 +931,7 @@ var CrvyRprtr = class {
|
|
|
915
931
|
if (this.ci) this.isOfflineMode = true;
|
|
916
932
|
}
|
|
917
933
|
async onBegin(config, suite) {
|
|
918
|
-
this.configDir = config.configFile === void 0 ? config.rootDir : (0,
|
|
934
|
+
this.configDir = config.configFile === void 0 ? config.rootDir : (0, import_path4.dirname)(config.configFile);
|
|
919
935
|
log(`[CrvyRprtr] Starting run with ${suite.allTests().length} tests`);
|
|
920
936
|
await (0, import_promises3.mkdir)(this.screenshotDir, { recursive: true });
|
|
921
937
|
if (!this.ci) {
|
|
@@ -975,10 +991,23 @@ var CrvyRprtr = class {
|
|
|
975
991
|
titlePath.unshift(suite.title);
|
|
976
992
|
return titlePath;
|
|
977
993
|
}
|
|
994
|
+
/** Resolves a non-empty browser label for UI display, falling back to the
|
|
995
|
+
* configured browser engine since the raw project `name` is `""` for the
|
|
996
|
+
* default project and devices spread `defaultBrowserType` into `use`. */
|
|
997
|
+
resolveBrowserLabel(project) {
|
|
998
|
+
const name = project?.name;
|
|
999
|
+
if (name !== void 0 && name !== "") return name;
|
|
1000
|
+
const browserName = project?.use?.browserName;
|
|
1001
|
+
if (browserName !== void 0) return browserName;
|
|
1002
|
+
const defaultBrowserType = project?.use?.defaultBrowserType;
|
|
1003
|
+
if (defaultBrowserType !== void 0) return defaultBrowserType;
|
|
1004
|
+
return "chromium";
|
|
1005
|
+
}
|
|
978
1006
|
reporterTitlePath(test) {
|
|
979
|
-
return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "
|
|
1007
|
+
return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "", test.location.file, ...this.describeTitlePath(test), test.title];
|
|
980
1008
|
}
|
|
981
1009
|
onTestBegin(test) {
|
|
1010
|
+
const project = test.parent.project();
|
|
982
1011
|
this.testMetadata.set(test.id, {
|
|
983
1012
|
reporterTitlePath: this.reporterTitlePath(test)
|
|
984
1013
|
});
|
|
@@ -988,7 +1017,8 @@ var CrvyRprtr = class {
|
|
|
988
1017
|
id: test.id,
|
|
989
1018
|
title: test.title,
|
|
990
1019
|
titlePath: this.describeTitlePath(test),
|
|
991
|
-
browser:
|
|
1020
|
+
browser: this.resolveBrowserLabel(project),
|
|
1021
|
+
projectName: project?.name ?? "",
|
|
992
1022
|
location: { file: test.location.file, line: test.location.line }
|
|
993
1023
|
}
|
|
994
1024
|
});
|
|
@@ -1050,7 +1080,7 @@ var CrvyRprtr = class {
|
|
|
1050
1080
|
async copyBaselinesForTargets(testId, status, resolvedTargets, savedAttachments) {
|
|
1051
1081
|
if (status !== "passed" || resolvedTargets.length === 0) return;
|
|
1052
1082
|
const safeTestId = sanitizeId(testId);
|
|
1053
|
-
const testScreenshotDir = (0,
|
|
1083
|
+
const testScreenshotDir = (0, import_path4.join)(this.screenshotDir, safeTestId);
|
|
1054
1084
|
const limit = (0, import_p_limit2.default)(5);
|
|
1055
1085
|
await Promise.all(
|
|
1056
1086
|
resolvedTargets.map(
|
package/dist/reporter.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export declare class CrvyRprtr implements Reporter {
|
|
|
24
24
|
private enableOfflineMode;
|
|
25
25
|
private sendRegister;
|
|
26
26
|
private describeTitlePath;
|
|
27
|
+
/** Resolves a non-empty browser label for UI display, falling back to the
|
|
28
|
+
* configured browser engine since the raw project `name` is `""` for the
|
|
29
|
+
* default project and devices spread `defaultBrowserType` into `use`. */
|
|
30
|
+
private resolveBrowserLabel;
|
|
27
31
|
private reporterTitlePath;
|
|
28
32
|
onTestBegin(test: TestCase): void;
|
|
29
33
|
onTestEnd(test: TestCase, result: TestResult): void;
|
package/dist/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,UAAU,EAEV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAA;AAalC,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,uBAAuB,CAAA;AAS9B,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,qBAAa,SAAU,YAAW,QAAQ;IACxC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,YAAY,CAAqD;IACzE,OAAO,CAAC,qBAAqB,CAAC,CAAQ;IACtC,OAAO,CAAC,8BAA8B,CAAC,CAAQ;IAC/C,OAAO,CAAC,sCAAsC,CAAC,CAAQ;IACvD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAgC;gBAE5C,OAAO,GAAE,gBAAqB;IAapC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,OAAO,CAAC,OAAO;IA6Bf,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,iBAAiB;IAOzB;;6EAEyE;IACzE,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,iBAAiB;IAOzB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAkBjC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAmCnD,OAAO,CAAC,aAAa;YAqBP,uBAAuB;IAgB/B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC9C,OAAO,CAAC,IAAI;CAUb;AAED,eAAe,SAAS,CAAA"}
|
package/dist/reporter.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveBaselineTargets,
|
|
10
10
|
safeParse,
|
|
11
11
|
withResolvedVisualNames
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WRMHUY5A.js";
|
|
13
13
|
|
|
14
14
|
// src/reporter.ts
|
|
15
15
|
import { existsSync } from "fs";
|
|
@@ -421,10 +421,23 @@ var CrvyRprtr = class {
|
|
|
421
421
|
titlePath.unshift(suite.title);
|
|
422
422
|
return titlePath;
|
|
423
423
|
}
|
|
424
|
+
/** Resolves a non-empty browser label for UI display, falling back to the
|
|
425
|
+
* configured browser engine since the raw project `name` is `""` for the
|
|
426
|
+
* default project and devices spread `defaultBrowserType` into `use`. */
|
|
427
|
+
resolveBrowserLabel(project) {
|
|
428
|
+
const name = project?.name;
|
|
429
|
+
if (name !== void 0 && name !== "") return name;
|
|
430
|
+
const browserName = project?.use?.browserName;
|
|
431
|
+
if (browserName !== void 0) return browserName;
|
|
432
|
+
const defaultBrowserType = project?.use?.defaultBrowserType;
|
|
433
|
+
if (defaultBrowserType !== void 0) return defaultBrowserType;
|
|
434
|
+
return "chromium";
|
|
435
|
+
}
|
|
424
436
|
reporterTitlePath(test) {
|
|
425
|
-
return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "
|
|
437
|
+
return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "", test.location.file, ...this.describeTitlePath(test), test.title];
|
|
426
438
|
}
|
|
427
439
|
onTestBegin(test) {
|
|
440
|
+
const project = test.parent.project();
|
|
428
441
|
this.testMetadata.set(test.id, {
|
|
429
442
|
reporterTitlePath: this.reporterTitlePath(test)
|
|
430
443
|
});
|
|
@@ -434,7 +447,8 @@ var CrvyRprtr = class {
|
|
|
434
447
|
id: test.id,
|
|
435
448
|
title: test.title,
|
|
436
449
|
titlePath: this.describeTitlePath(test),
|
|
437
|
-
browser:
|
|
450
|
+
browser: this.resolveBrowserLabel(project),
|
|
451
|
+
projectName: project?.name ?? "",
|
|
438
452
|
location: { file: test.location.file, line: test.location.line }
|
|
439
453
|
}
|
|
440
454
|
});
|
package/dist/schemas.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ export declare const TestDataSchema: z.ZodObject<{
|
|
|
93
93
|
id: z.ZodString;
|
|
94
94
|
titlePath: z.ZodArray<z.ZodString>;
|
|
95
95
|
browser: z.ZodString;
|
|
96
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
96
97
|
title: z.ZodString;
|
|
97
98
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
98
99
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -153,6 +154,7 @@ export declare const CrvyRprtrTestSchema: z.ZodObject<{
|
|
|
153
154
|
id: z.ZodString;
|
|
154
155
|
titlePath: z.ZodArray<z.ZodString>;
|
|
155
156
|
browser: z.ZodString;
|
|
157
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
156
158
|
title: z.ZodString;
|
|
157
159
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
158
160
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -238,6 +240,7 @@ export declare const WebSocketMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
238
240
|
id: z.ZodString;
|
|
239
241
|
titlePath: z.ZodArray<z.ZodString>;
|
|
240
242
|
browser: z.ZodString;
|
|
243
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
241
244
|
title: z.ZodString;
|
|
242
245
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
243
246
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -299,6 +302,7 @@ export declare const WebSocketMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
299
302
|
id: z.ZodString;
|
|
300
303
|
titlePath: z.ZodArray<z.ZodString>;
|
|
301
304
|
browser: z.ZodString;
|
|
305
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
302
306
|
title: z.ZodString;
|
|
303
307
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
304
308
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -371,6 +375,7 @@ export declare const WebSocketMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
371
375
|
id: z.ZodString;
|
|
372
376
|
titlePath: z.ZodArray<z.ZodString>;
|
|
373
377
|
browser: z.ZodString;
|
|
378
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
374
379
|
title: z.ZodString;
|
|
375
380
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
376
381
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -438,6 +443,7 @@ export declare const TestBeginDataSchema: z.ZodObject<{
|
|
|
438
443
|
title: z.ZodString;
|
|
439
444
|
titlePath: z.ZodArray<z.ZodString>;
|
|
440
445
|
browser: z.ZodString;
|
|
446
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
441
447
|
location: z.ZodObject<{
|
|
442
448
|
file: z.ZodString;
|
|
443
449
|
line: z.ZodNumber;
|
|
@@ -493,6 +499,7 @@ export declare const ReportDataSchema: z.ZodObject<{
|
|
|
493
499
|
id: z.ZodString;
|
|
494
500
|
titlePath: z.ZodArray<z.ZodString>;
|
|
495
501
|
browser: z.ZodString;
|
|
502
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
496
503
|
title: z.ZodString;
|
|
497
504
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
498
505
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -558,6 +565,7 @@ export declare const LoadedReportDataSchema: z.ZodObject<{
|
|
|
558
565
|
id: z.ZodString;
|
|
559
566
|
titlePath: z.ZodArray<z.ZodString>;
|
|
560
567
|
browser: z.ZodString;
|
|
568
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
561
569
|
title: z.ZodString;
|
|
562
570
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
563
571
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -654,6 +662,7 @@ export declare const ReportApiResponseSchema: z.ZodObject<{
|
|
|
654
662
|
id: z.ZodString;
|
|
655
663
|
titlePath: z.ZodArray<z.ZodString>;
|
|
656
664
|
browser: z.ZodString;
|
|
665
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
657
666
|
title: z.ZodString;
|
|
658
667
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
659
668
|
retries: z.ZodOptional<z.ZodNumber>;
|
|
@@ -718,6 +727,7 @@ export declare const ClientBootstrapDataSchema: z.ZodObject<{
|
|
|
718
727
|
id: z.ZodString;
|
|
719
728
|
titlePath: z.ZodArray<z.ZodString>;
|
|
720
729
|
browser: z.ZodString;
|
|
730
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
721
731
|
title: z.ZodString;
|
|
722
732
|
skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
723
733
|
retries: z.ZodOptional<z.ZodNumber>;
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,cAAc;;;iBAGzB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAErD,eAAO,MAAM,kBAAkB;;;;EAA2D,CAAA;AAE1F,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAG7D,eAAO,MAAM,YAAY;;;;;;;;;;iBAMvB,CAAA;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEjD,eAAO,MAAM,2BAA2B;;;;;;;;;;2BAatC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAG/E,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAGzD,eAAO,MAAM,gBAAgB;;;;;;;;EAAyF,CAAA;AAEtH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,eAAO,MAAM,sBAAsB;;;;EAA2C,CAAA;AAE9E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAGrE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO3B,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAGzD,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-routes.d.ts","sourceRoot":"","sources":["../../src/server/artifact-routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"artifact-routes.d.ts","sourceRoot":"","sources":["../../src/server/artifact-routes.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAWhD,wBAAsB,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyCpF;AAYD,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAA;AAE9D,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAyBf;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmCxF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAQhH"}
|
package/dist/server.cjs
CHANGED
|
@@ -35,16 +35,34 @@ __export(server_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(server_exports);
|
|
36
36
|
|
|
37
37
|
// src/server/app.ts
|
|
38
|
-
var
|
|
38
|
+
var import_path7 = require("path");
|
|
39
39
|
var import_url = require("url");
|
|
40
40
|
var import_p_limit = __toESM(require("p-limit"), 1);
|
|
41
41
|
|
|
42
42
|
// src/offline-reports.ts
|
|
43
43
|
var import_promises = require("fs/promises");
|
|
44
|
-
var
|
|
44
|
+
var import_path = require("path");
|
|
45
|
+
|
|
46
|
+
// src/path-utils.ts
|
|
47
|
+
var posixAbsolutePattern = /^\//u;
|
|
48
|
+
var windowsDrivePattern = /^[A-Za-z]:[\\/]/u;
|
|
49
|
+
var windowsUncPattern = /^[\\/][\\/]/u;
|
|
50
|
+
function isPosixAbsolutePath(p) {
|
|
51
|
+
return posixAbsolutePattern.test(p);
|
|
52
|
+
}
|
|
53
|
+
function isWindowsAbsolutePath(p) {
|
|
54
|
+
return windowsDrivePattern.test(p) || windowsUncPattern.test(p);
|
|
55
|
+
}
|
|
56
|
+
function isAnyAbsolutePath(p) {
|
|
57
|
+
return isPosixAbsolutePath(p) || isWindowsAbsolutePath(p);
|
|
58
|
+
}
|
|
59
|
+
function isForeignAbsolutePath(p, hostPlatform) {
|
|
60
|
+
if (!isAnyAbsolutePath(p)) return false;
|
|
61
|
+
if (hostPlatform === "win32") return !isWindowsAbsolutePath(p);
|
|
62
|
+
return !isPosixAbsolutePath(p);
|
|
63
|
+
}
|
|
45
64
|
|
|
46
65
|
// src/report-utils.ts
|
|
47
|
-
var import_path = require("path");
|
|
48
66
|
function normalizeScreenshotsBaseUrl(baseUrl) {
|
|
49
67
|
return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
50
68
|
}
|
|
@@ -89,7 +107,7 @@ function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/")
|
|
|
89
107
|
const role = match[2];
|
|
90
108
|
if (baseName === null || baseName === void 0 || role === null || role === void 0) continue;
|
|
91
109
|
images[baseName] ??= {};
|
|
92
|
-
const url = (
|
|
110
|
+
const url = isAnyAbsolutePath(attachment.path) ? `/file/${encodeURIComponent(attachment.path)}` : `${baseUrl}${attachment.path}`;
|
|
93
111
|
const img = images[baseName];
|
|
94
112
|
if (img !== null && img !== void 0) {
|
|
95
113
|
if (role === "actual") img.actual = url;
|
|
@@ -124,9 +142,6 @@ function isCurrentArtifact(image) {
|
|
|
124
142
|
}
|
|
125
143
|
function isReusablePassingImage(image) {
|
|
126
144
|
const source = image.source ?? classifyImage(image);
|
|
127
|
-
if (source === "comparison") {
|
|
128
|
-
return image.actual !== void 0 && image.diff === void 0;
|
|
129
|
-
}
|
|
130
145
|
return source === "baseline-only";
|
|
131
146
|
}
|
|
132
147
|
function hasReusablePassingImages(images) {
|
|
@@ -147,8 +162,8 @@ function preservePreviousPassingImages(test, status, images) {
|
|
|
147
162
|
return {
|
|
148
163
|
...currentImages,
|
|
149
164
|
[name]: {
|
|
150
|
-
|
|
151
|
-
source:
|
|
165
|
+
expect: previousImage.expect,
|
|
166
|
+
source: "baseline-only"
|
|
152
167
|
}
|
|
153
168
|
};
|
|
154
169
|
}, images);
|
|
@@ -169,12 +184,16 @@ function createMutableReportState(screenshotDir = "./screenshots") {
|
|
|
169
184
|
};
|
|
170
185
|
}
|
|
171
186
|
function applyTestBeginEvent(state, data) {
|
|
172
|
-
const { id, title, titlePath, browser, location } = data;
|
|
187
|
+
const { id, title, titlePath, browser, projectName, location } = data;
|
|
173
188
|
state.currentRunIds.add(id);
|
|
174
189
|
state.reportData.tests[id] ??= {
|
|
175
190
|
id,
|
|
176
191
|
titlePath: titlePath ?? [],
|
|
177
192
|
browser: browser ?? "",
|
|
193
|
+
// Older reporters sent the raw project name in `browser` and had no
|
|
194
|
+
// `projectName` field. Preserve that value for snapshot path resolution
|
|
195
|
+
// when loading data produced by such reporters.
|
|
196
|
+
projectName: projectName ?? browser ?? "",
|
|
178
197
|
title: title ?? "",
|
|
179
198
|
location,
|
|
180
199
|
status: "running"
|
|
@@ -278,6 +297,7 @@ var TestDataSchema = import_zod.z.object({
|
|
|
278
297
|
id: import_zod.z.string(),
|
|
279
298
|
titlePath: import_zod.z.array(import_zod.z.string()),
|
|
280
299
|
browser: import_zod.z.string(),
|
|
300
|
+
projectName: import_zod.z.string().optional(),
|
|
281
301
|
title: import_zod.z.string(),
|
|
282
302
|
skip: import_zod.z.union([import_zod.z.boolean(), import_zod.z.string()]).optional(),
|
|
283
303
|
retries: import_zod.z.number().optional(),
|
|
@@ -329,6 +349,7 @@ var TestBeginDataSchema = import_zod.z.object({
|
|
|
329
349
|
title: import_zod.z.string(),
|
|
330
350
|
titlePath: import_zod.z.array(import_zod.z.string()),
|
|
331
351
|
browser: import_zod.z.string(),
|
|
352
|
+
projectName: import_zod.z.string().optional(),
|
|
332
353
|
location: LocationSchema
|
|
333
354
|
});
|
|
334
355
|
var TestEndDataSchema = import_zod.z.object({
|
|
@@ -406,7 +427,7 @@ var OFFLINE_REPORT_FILE_PATTERN = /^crvy-rprtr(?:-\d+)?\.json$/;
|
|
|
406
427
|
async function findOfflineReportPaths(searchDir) {
|
|
407
428
|
try {
|
|
408
429
|
const entries = await (0, import_promises.readdir)(searchDir);
|
|
409
|
-
return entries.filter((entry) => OFFLINE_REPORT_FILE_PATTERN.test(entry)).sort((left, right) => left.localeCompare(right)).map((entry) => (0,
|
|
430
|
+
return entries.filter((entry) => OFFLINE_REPORT_FILE_PATTERN.test(entry)).sort((left, right) => left.localeCompare(right)).map((entry) => (0, import_path.join)(searchDir, entry));
|
|
410
431
|
} catch (error) {
|
|
411
432
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
412
433
|
return [];
|
|
@@ -458,7 +479,7 @@ function mergeOfflineReportsIntoTests(existingTests, offlineReports, options = {
|
|
|
458
479
|
|
|
459
480
|
// src/server/file-utils.ts
|
|
460
481
|
var import_promises2 = require("fs/promises");
|
|
461
|
-
var
|
|
482
|
+
var import_path2 = require("path");
|
|
462
483
|
function isFileNotFound(error) {
|
|
463
484
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
464
485
|
}
|
|
@@ -499,16 +520,16 @@ async function readJsonFile(filePath) {
|
|
|
499
520
|
}
|
|
500
521
|
}
|
|
501
522
|
async function writeJsonFile(filePath, value) {
|
|
502
|
-
await (0, import_promises2.mkdir)((0,
|
|
523
|
+
await (0, import_promises2.mkdir)((0, import_path2.dirname)(filePath), { recursive: true });
|
|
503
524
|
await (0, import_promises2.writeFile)(filePath, `${JSON.stringify(value, null, 2)}
|
|
504
525
|
`);
|
|
505
526
|
}
|
|
506
527
|
async function copyFilePortable(sourcePath, destinationPath) {
|
|
507
|
-
await (0, import_promises2.mkdir)((0,
|
|
528
|
+
await (0, import_promises2.mkdir)((0, import_path2.dirname)(destinationPath), { recursive: true });
|
|
508
529
|
await (0, import_promises2.copyFile)(sourcePath, destinationPath);
|
|
509
530
|
}
|
|
510
531
|
function inferContentType(filePath) {
|
|
511
|
-
switch ((0,
|
|
532
|
+
switch ((0, import_path2.extname)(filePath).toLowerCase()) {
|
|
512
533
|
case ".css":
|
|
513
534
|
return "text/css";
|
|
514
535
|
case ".gif":
|
|
@@ -557,11 +578,11 @@ var import_fs2 = require("fs");
|
|
|
557
578
|
// src/server/artifact-routes.ts
|
|
558
579
|
var import_fs = require("fs");
|
|
559
580
|
var import_promises3 = require("fs/promises");
|
|
560
|
-
var
|
|
581
|
+
var import_path5 = require("path");
|
|
561
582
|
|
|
562
583
|
// src/snapshot-path-resolver.ts
|
|
563
584
|
var import_crypto = require("crypto");
|
|
564
|
-
var
|
|
585
|
+
var import_path3 = require("path");
|
|
565
586
|
var DEFAULT_SCREENSHOT_TEMPLATE = "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}";
|
|
566
587
|
var WINDOWS_FILESYSTEM_FRIENDLY_LENGTH = 60;
|
|
567
588
|
function isUnsafeFilePathCharacter(character) {
|
|
@@ -596,16 +617,16 @@ function trimLongString(value, length = WINDOWS_FILESYSTEM_FRIENDLY_LENGTH) {
|
|
|
596
617
|
const end = length - middle.length - start;
|
|
597
618
|
return value.slice(0, start) + middle + value.slice(-end);
|
|
598
619
|
}
|
|
599
|
-
function sanitizeFilePathBeforeExtension(filePath, extension = (0,
|
|
620
|
+
function sanitizeFilePathBeforeExtension(filePath, extension = (0, import_path3.extname)(filePath)) {
|
|
600
621
|
const base = filePath.slice(0, filePath.length - extension.length);
|
|
601
622
|
return sanitizeForFilePath(base) + extension;
|
|
602
623
|
}
|
|
603
624
|
function addSuffixToFilePath(filePath, suffix) {
|
|
604
|
-
const extension = (0,
|
|
625
|
+
const extension = (0, import_path3.extname)(filePath);
|
|
605
626
|
return filePath.slice(0, filePath.length - extension.length) + suffix + extension;
|
|
606
627
|
}
|
|
607
628
|
function normalizedSnapshotDir(config) {
|
|
608
|
-
return (0,
|
|
629
|
+
return (0, import_path3.resolve)(config.configDir, config.snapshotDir);
|
|
609
630
|
}
|
|
610
631
|
function templateValue(template, token, value) {
|
|
611
632
|
return template.replace(
|
|
@@ -615,8 +636,8 @@ function templateValue(template, token, value) {
|
|
|
615
636
|
}
|
|
616
637
|
function applyTemplate(input, nameArgument, extension) {
|
|
617
638
|
const template = input.config.toHaveScreenshotPathTemplate ?? input.config.snapshotPathTemplate ?? DEFAULT_SCREENSHOT_TEMPLATE;
|
|
618
|
-
const relativeTestFilePath = (0,
|
|
619
|
-
const parsed = (0,
|
|
639
|
+
const relativeTestFilePath = (0, import_path3.relative)(input.config.testDir, input.testFile);
|
|
640
|
+
const parsed = (0, import_path3.parse)(relativeTestFilePath);
|
|
620
641
|
const tokens = [
|
|
621
642
|
["testDir", input.config.testDir],
|
|
622
643
|
["snapshotDir", normalizedSnapshotDir(input.config)],
|
|
@@ -634,16 +655,16 @@ function applyTemplate(input, nameArgument, extension) {
|
|
|
634
655
|
(currentTemplate, [token, value]) => templateValue(currentTemplate, token, value),
|
|
635
656
|
template
|
|
636
657
|
);
|
|
637
|
-
return (0,
|
|
658
|
+
return (0, import_path3.resolve)(input.config.configDir, snapshotPath);
|
|
638
659
|
}
|
|
639
|
-
function removeExtension(filePath, extension = (0,
|
|
660
|
+
function removeExtension(filePath, extension = (0, import_path3.extname)(filePath)) {
|
|
640
661
|
return filePath.slice(0, filePath.length - extension.length);
|
|
641
662
|
}
|
|
642
663
|
function snapshotNameParts(declaredName) {
|
|
643
|
-
const extension = (0,
|
|
664
|
+
const extension = (0, import_path3.extname)(declaredName) || ".png";
|
|
644
665
|
return {
|
|
645
666
|
extension,
|
|
646
|
-
filePath: (0,
|
|
667
|
+
filePath: (0, import_path3.extname)(declaredName) === "" ? `${declaredName}${extension}` : declaredName
|
|
647
668
|
};
|
|
648
669
|
}
|
|
649
670
|
function filePathForOccurrence(filePath, occurrenceIndex) {
|
|
@@ -667,7 +688,7 @@ function resolveStringCallTarget(input, declaration) {
|
|
|
667
688
|
function resolveArrayCallTarget(input, declaration) {
|
|
668
689
|
const { extension, filePath } = snapshotNameParts(declaration.declaredName);
|
|
669
690
|
const occurrenceFilePath = filePathForOccurrence(filePath, declaration.occurrenceIndex);
|
|
670
|
-
const nameArgument = (0,
|
|
691
|
+
const nameArgument = (0, import_path3.join)((0, import_path3.dirname)(occurrenceFilePath), (0, import_path3.basename)(occurrenceFilePath, extension));
|
|
671
692
|
return createResolvedBaselineTarget(input, declaration, nameArgument, extension);
|
|
672
693
|
}
|
|
673
694
|
function resolveNamedTarget(input, declaration) {
|
|
@@ -705,7 +726,7 @@ function resolveTarget(input, declaration) {
|
|
|
705
726
|
case "unnamed": {
|
|
706
727
|
const anonymousFileName = anonymousName(input.reporterTitlePath, declaration.occurrenceIndex);
|
|
707
728
|
const extension = ".png";
|
|
708
|
-
const nameArgument = (0,
|
|
729
|
+
const nameArgument = (0, import_path3.join)((0, import_path3.dirname)(anonymousFileName), (0, import_path3.basename)(anonymousFileName, extension));
|
|
709
730
|
return createResolvedBaselineTarget(input, declaration, nameArgument, extension);
|
|
710
731
|
}
|
|
711
732
|
}
|
|
@@ -718,7 +739,7 @@ function resolveBaselineTargets(input) {
|
|
|
718
739
|
}
|
|
719
740
|
|
|
720
741
|
// src/server/utils.ts
|
|
721
|
-
var
|
|
742
|
+
var import_path4 = require("path");
|
|
722
743
|
var LIVE_UPDATES_WEBSOCKET_PATH = "/";
|
|
723
744
|
function broadcastToBrowsers(wsClients, msg) {
|
|
724
745
|
const payload = JSON.stringify(msg);
|
|
@@ -730,10 +751,10 @@ function isWebSocketUpgradeRequest(req) {
|
|
|
730
751
|
return new URL(req.url).pathname === LIVE_UPDATES_WEBSOCKET_PATH && req.headers.get("upgrade")?.toLowerCase() === "websocket";
|
|
731
752
|
}
|
|
732
753
|
function isPathWithinRoots(target, roots) {
|
|
733
|
-
const resolvedTarget = (0,
|
|
754
|
+
const resolvedTarget = (0, import_path4.resolve)(target);
|
|
734
755
|
return roots.some((root) => {
|
|
735
|
-
const rel = (0,
|
|
736
|
-
return rel === "" || !rel.startsWith(`..${
|
|
756
|
+
const rel = (0, import_path4.relative)((0, import_path4.resolve)(root), resolvedTarget);
|
|
757
|
+
return rel === "" || !rel.startsWith(`..${import_path4.sep}`) && rel !== ".." && !(0, import_path4.isAbsolute)(rel);
|
|
737
758
|
});
|
|
738
759
|
}
|
|
739
760
|
|
|
@@ -747,17 +768,24 @@ async function realpathOrNull(path) {
|
|
|
747
768
|
}
|
|
748
769
|
async function handleFile(ctx, req) {
|
|
749
770
|
const notFound = () => new Response("Not Found", { status: 404 });
|
|
771
|
+
let rawDecoded;
|
|
750
772
|
let decodedPath;
|
|
751
773
|
try {
|
|
752
|
-
|
|
774
|
+
rawDecoded = decodeURIComponent(new URL(req.url).pathname.slice("/file/".length));
|
|
775
|
+
decodedPath = (0, import_path5.resolve)(rawDecoded);
|
|
753
776
|
} catch {
|
|
754
777
|
return notFound();
|
|
755
778
|
}
|
|
756
779
|
const realTarget = await realpathOrNull(decodedPath);
|
|
757
780
|
if (realTarget === null) {
|
|
781
|
+
if (isForeignAbsolutePath(rawDecoded, process.platform)) {
|
|
782
|
+
console.warn(
|
|
783
|
+
`[Crvy Rprtr] /file request resolved to a foreign-OS absolute path that cannot be served on ${process.platform}: ${rawDecoded}`
|
|
784
|
+
);
|
|
785
|
+
}
|
|
758
786
|
return notFound();
|
|
759
787
|
}
|
|
760
|
-
const realRoots = (await Promise.all((ctx.artifactRoots ?? []).map((root) => realpathOrNull((0,
|
|
788
|
+
const realRoots = (await Promise.all((ctx.artifactRoots ?? []).map((root) => realpathOrNull((0, import_path5.resolve)(root))))).filter(
|
|
761
789
|
(root) => root !== null
|
|
762
790
|
);
|
|
763
791
|
if (!isPathWithinRoots(realTarget, realRoots)) {
|
|
@@ -772,7 +800,8 @@ async function handleFile(ctx, req) {
|
|
|
772
800
|
}
|
|
773
801
|
function reporterTitlePath(test) {
|
|
774
802
|
const testFile = test.location?.file;
|
|
775
|
-
|
|
803
|
+
const projectName = test.projectName ?? test.browser;
|
|
804
|
+
return ["", projectName, testFile ?? "", ...test.titlePath, test.title];
|
|
776
805
|
}
|
|
777
806
|
function resolveBaselineSnapshotPath(routing, test, retry, imageName) {
|
|
778
807
|
const testFile = test.location?.file;
|
|
@@ -786,9 +815,9 @@ function resolveBaselineSnapshotPath(routing, test, retry, imageName) {
|
|
|
786
815
|
declarations: [declaration],
|
|
787
816
|
config: {
|
|
788
817
|
configDir: routing.configDir,
|
|
789
|
-
testDir: routing.playwrightTestDir ?? (0,
|
|
790
|
-
snapshotDir: routing.playwrightSnapshotDir ?? (0,
|
|
791
|
-
projectName: test.browser,
|
|
818
|
+
testDir: routing.playwrightTestDir ?? (0, import_path5.dirname)(testFile),
|
|
819
|
+
snapshotDir: routing.playwrightSnapshotDir ?? (0, import_path5.dirname)(testFile),
|
|
820
|
+
projectName: test.projectName ?? test.browser,
|
|
792
821
|
snapshotSuffix: process.platform,
|
|
793
822
|
snapshotPathTemplate: routing.playwrightSnapshotPathTemplate,
|
|
794
823
|
toHaveScreenshotPathTemplate: routing.playwrightToHaveScreenshotPathTemplate
|
|
@@ -946,9 +975,9 @@ function handleRegister(ctx, data) {
|
|
|
946
975
|
}
|
|
947
976
|
|
|
948
977
|
// src/server/routes.ts
|
|
949
|
-
var
|
|
978
|
+
var import_path6 = require("path");
|
|
950
979
|
async function handleRoot(ctx) {
|
|
951
|
-
const html = await respondWithFile((0,
|
|
980
|
+
const html = await respondWithFile((0, import_path6.join)(ctx.staticDir, "index.html"), "text/html");
|
|
952
981
|
return html ?? new Response("Not Found", { status: 404 });
|
|
953
982
|
}
|
|
954
983
|
async function handleAppCss() {
|
|
@@ -968,7 +997,7 @@ function handleApiReport(ctx) {
|
|
|
968
997
|
var APPROVAL_TARGET_ERROR = "Could not resolve approval target";
|
|
969
998
|
function actualPathFromUrl(ctx, actualUrl) {
|
|
970
999
|
if (actualUrl.startsWith("/screenshots/")) {
|
|
971
|
-
return (0,
|
|
1000
|
+
return (0, import_path6.join)(ctx.reportData.screenshotDir, actualUrl.slice("/screenshots/".length));
|
|
972
1001
|
}
|
|
973
1002
|
if (actualUrl.startsWith("/file/")) {
|
|
974
1003
|
return decodeURIComponent(actualUrl.slice("/file/".length));
|
|
@@ -1090,7 +1119,7 @@ async function handleScreenshots(ctx, req) {
|
|
|
1090
1119
|
}
|
|
1091
1120
|
async function handleDist(ctx, req) {
|
|
1092
1121
|
const path = new URL(req.url).pathname.slice("/dist/".length);
|
|
1093
|
-
const filePath = (0,
|
|
1122
|
+
const filePath = (0, import_path6.join)(ctx.staticDir, path);
|
|
1094
1123
|
const contentType = filePath.endsWith(".css") ? "text/css" : filePath.endsWith(".js") ? "application/javascript" : filePath.endsWith(".svelte") ? "text/plain" : "application/octet-stream";
|
|
1095
1124
|
const file = await respondWithFile(filePath, contentType);
|
|
1096
1125
|
return file ?? new Response("Not Found", { status: 404 });
|
|
@@ -1253,19 +1282,19 @@ function createWebSocketMessageHandler(getHandlerContext) {
|
|
|
1253
1282
|
};
|
|
1254
1283
|
}
|
|
1255
1284
|
async function resolveStaticDir(staticDir) {
|
|
1256
|
-
const currentDir = (0,
|
|
1285
|
+
const currentDir = (0, import_path7.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
1257
1286
|
const candidates = staticDir === void 0 ? [
|
|
1258
1287
|
currentDir,
|
|
1259
|
-
(0,
|
|
1260
|
-
(0,
|
|
1261
|
-
(0,
|
|
1262
|
-
(0,
|
|
1263
|
-
(0,
|
|
1264
|
-
] : [staticDir, (0,
|
|
1288
|
+
(0, import_path7.join)(currentDir, "dist"),
|
|
1289
|
+
(0, import_path7.join)(currentDir, "..", "dist"),
|
|
1290
|
+
(0, import_path7.join)(currentDir, "..", "..", "dist"),
|
|
1291
|
+
(0, import_path7.join)(currentDir, ".."),
|
|
1292
|
+
(0, import_path7.join)(currentDir, "..", "..")
|
|
1293
|
+
] : [staticDir, (0, import_path7.join)(staticDir, "dist")];
|
|
1265
1294
|
const resolvedCandidates = await Promise.all(
|
|
1266
1295
|
candidates.map(async (candidate) => ({
|
|
1267
1296
|
candidate,
|
|
1268
|
-
exists: await fileExists((0,
|
|
1297
|
+
exists: await fileExists((0, import_path7.join)(candidate, "index.html"))
|
|
1269
1298
|
}))
|
|
1270
1299
|
);
|
|
1271
1300
|
const resolved = resolvedCandidates.find(({ exists }) => exists);
|
|
@@ -1276,9 +1305,9 @@ async function resolveStaticDir(staticDir) {
|
|
|
1276
1305
|
}
|
|
1277
1306
|
async function resolveReportPath(reportPath) {
|
|
1278
1307
|
if (await isDirectory(reportPath)) {
|
|
1279
|
-
return { reportFile: (0,
|
|
1308
|
+
return { reportFile: (0, import_path7.join)(reportPath, "report.json"), offlineReportDir: reportPath };
|
|
1280
1309
|
}
|
|
1281
|
-
return { reportFile: reportPath, offlineReportDir: (0,
|
|
1310
|
+
return { reportFile: reportPath, offlineReportDir: (0, import_path7.dirname)(reportPath) };
|
|
1282
1311
|
}
|
|
1283
1312
|
function createRoutesContext(reportData, staticDir, saveReport, options) {
|
|
1284
1313
|
const artifactRoots = [reportData.screenshotDir, options.outputDir, options.playwrightSnapshotDir].filter(
|
package/dist/server.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -30,6 +30,13 @@ export interface TestData {
|
|
|
30
30
|
id: string;
|
|
31
31
|
titlePath: string[];
|
|
32
32
|
browser: string;
|
|
33
|
+
/**
|
|
34
|
+
* Raw Playwright project name. Used for snapshot path resolution so the
|
|
35
|
+
* resolver matches what Playwright itself used when storing baselines
|
|
36
|
+
* (empty string for the implicit default project). Undefined for data
|
|
37
|
+
* produced by older reporters; consumers fall back to `browser`.
|
|
38
|
+
*/
|
|
39
|
+
projectName?: string;
|
|
33
40
|
title: string;
|
|
34
41
|
skip?: boolean | string;
|
|
35
42
|
retries?: number;
|
|
@@ -87,6 +94,7 @@ export interface TestBeginMessage {
|
|
|
87
94
|
title: string;
|
|
88
95
|
titlePath: string[];
|
|
89
96
|
browser: string;
|
|
97
|
+
projectName?: string;
|
|
90
98
|
location: Location;
|
|
91
99
|
};
|
|
92
100
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|