@empiricalrun/playwright-utils 0.41.1 → 0.43.0
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 +22 -0
- package/dist/config/index.js +8 -8
- package/dist/reporter/empirical-reporter.d.ts.map +1 -1
- package/dist/reporter/empirical-reporter.js +1 -1
- package/dist/reporter/incremental-blob-reporter.d.ts +5 -1
- package/dist/reporter/incremental-blob-reporter.d.ts.map +1 -1
- package/dist/reporter/incremental-blob-reporter.js +77 -17
- package/dist/reporter/util.d.ts +4 -9
- package/dist/reporter/util.d.ts.map +1 -1
- package/dist/reporter/util.js +19 -82
- package/dist/test/coverage.d.ts +9 -0
- package/dist/test/coverage.d.ts.map +1 -0
- package/dist/test/coverage.js +46 -0
- package/dist/test/index.d.ts +2 -2
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +9 -0
- package/dist/test/types.d.ts +3 -0
- package/dist/test/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @empiricalrun/playwright-utils
|
|
2
2
|
|
|
3
|
+
## 0.43.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ab403b8: fix: move json report location to avoid accidental agent commits
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 002127f: feat: add code coverage helper in base fixtures
|
|
12
|
+
|
|
13
|
+
## 0.42.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- c815fc2: feat: use common code to modify html report paths for shard/non-shard
|
|
18
|
+
- d7cdace: feat: added non sharded support to upload partial html and json
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [c815fc2]
|
|
23
|
+
- @empiricalrun/reporter@0.28.0
|
|
24
|
+
|
|
3
25
|
## 0.41.1
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/config/index.js
CHANGED
|
@@ -49,21 +49,21 @@ function getReporters() {
|
|
|
49
49
|
fileName: `report-${process.env.SHARD_INDEX}.zip`,
|
|
50
50
|
},
|
|
51
51
|
],
|
|
52
|
-
...(useIncrementalReporter
|
|
53
|
-
? [
|
|
54
|
-
[
|
|
55
|
-
"./node_modules/@empiricalrun/playwright-utils/dist/reporter/incremental-blob-reporter.js",
|
|
56
|
-
],
|
|
57
|
-
]
|
|
58
|
-
: []),
|
|
59
52
|
]
|
|
60
53
|
: [
|
|
61
|
-
["json", { outputFile: "summary.json" }],
|
|
54
|
+
["json", { outputFile: "playwright-report/summary.json" }],
|
|
62
55
|
["html", { open: "never" }],
|
|
63
56
|
];
|
|
64
57
|
return [
|
|
65
58
|
["list"],
|
|
66
59
|
...middle,
|
|
60
|
+
...(useIncrementalReporter
|
|
61
|
+
? [
|
|
62
|
+
[
|
|
63
|
+
"./node_modules/@empiricalrun/playwright-utils/dist/reporter/incremental-blob-reporter.js",
|
|
64
|
+
],
|
|
65
|
+
]
|
|
66
|
+
: []),
|
|
67
67
|
[
|
|
68
68
|
"./node_modules/@empiricalrun/playwright-utils/dist/reporter/empirical-reporter.js",
|
|
69
69
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAqBnC,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,oBAAoB,CAG1B;IACF,OAAO,CAAC,sBAAsB,CAAuB;IACrD,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,SAAS,CAAyB;;IAM1C,OAAO,CAAC,6BAA6B,CAkCnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAuGtC,KAAK,CAAC,MAAM,EAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAqBnC,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,oBAAoB,CAG1B;IACF,OAAO,CAAC,sBAAsB,CAAuB;IACrD,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,SAAS,CAAyB;;IAM1C,OAAO,CAAC,6BAA6B,CAkCnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAuGtC,KAAK,CAAC,MAAM,EAAE,UAAU;IAkH9B,OAAO,CAAC,gBAAgB;YAoBV,gBAAgB;YAOhB,iBAAiB;CAmChC;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -134,7 +134,7 @@ class EmpiricalReporter {
|
|
|
134
134
|
minute: "2-digit",
|
|
135
135
|
second: "2-digit",
|
|
136
136
|
}).format(startTime));
|
|
137
|
-
const jsonFilePath = path_1.default.join(this._currentWorkingDir, "summary.json");
|
|
137
|
+
const jsonFilePath = path_1.default.join(this._currentWorkingDir, "playwright-report", "summary.json");
|
|
138
138
|
const jsonExists = fs_1.default.existsSync(jsonFilePath);
|
|
139
139
|
const htmlFilePath = path_1.default.join(this._currentWorkingDir, "playwright-report/index.html");
|
|
140
140
|
const htmlExists = await (0, util_1.checkFileExistsAsync)(htmlFilePath);
|
|
@@ -10,6 +10,7 @@ import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult, Tes
|
|
|
10
10
|
export type AttachmentUrlMap = Map<string, string>;
|
|
11
11
|
declare class IncrementalBlobReporter implements Reporter {
|
|
12
12
|
private _currentWorkingDir;
|
|
13
|
+
private _stagingDir;
|
|
13
14
|
private _outputDir;
|
|
14
15
|
private _shardIndex;
|
|
15
16
|
private _totalShards;
|
|
@@ -32,7 +33,9 @@ declare class IncrementalBlobReporter implements Reporter {
|
|
|
32
33
|
private get _zipPath();
|
|
33
34
|
private get _jsonlPath();
|
|
34
35
|
private get _urlsJsonPath();
|
|
35
|
-
private
|
|
36
|
+
private _ensureDirs;
|
|
37
|
+
private _serializePatterns;
|
|
38
|
+
private _embedAttachment;
|
|
36
39
|
private _generateId;
|
|
37
40
|
private _getResultId;
|
|
38
41
|
private _getStepId;
|
|
@@ -47,6 +50,7 @@ declare class IncrementalBlobReporter implements Reporter {
|
|
|
47
50
|
onStepBegin(test: TestCase, result: TestResult, step: TestStep): void;
|
|
48
51
|
onStepEnd(test: TestCase, result: TestResult, step: TestStep): void;
|
|
49
52
|
onEnd(result: FullResult): Promise<void>;
|
|
53
|
+
private _mergeForLocalTest;
|
|
50
54
|
/**
|
|
51
55
|
* Add a single attachment URL mapping
|
|
52
56
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACT,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAUnC;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnD,cAAM,uBAAwB,YAAW,QAAQ;IAC/C,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,WAAW,CAIjB;IACF,OAAO,CAAC,UAAU,CAGhB;IACF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,UAAU,CAAsB;;IAexC,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,oBAAoB;YAOd,eAAe;IAiC7B,OAAO,CAAC,2BAA2B;IA4BnC,OAAO,KAAK,QAAQ,GAKnB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,cAAc;YAQR,SAAS;IAwBvB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IA+E/C,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAerD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAyCnD,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAmBrE,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAsB7D,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAmBhC,kBAAkB;IA2ChC;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5D,aAAa,IAAI,OAAO;CAGzB;AAID,wBAAgB,0BAA0B,IAAI,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,uBAAuB,GAChC,IAAI,CAEN;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getIncrementalBlobReporter = getIncrementalBlobReporter;
|
|
7
7
|
exports.setIncrementalBlobReporterInstance = setIncrementalBlobReporterInstance;
|
|
8
8
|
const zip_1 = require("@empiricalrun/r2-uploader/zip");
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
9
10
|
const crypto_1 = __importDefault(require("crypto"));
|
|
10
11
|
const fs_1 = __importDefault(require("fs"));
|
|
11
12
|
const os_1 = __importDefault(require("os"));
|
|
@@ -14,6 +15,7 @@ const uploader_1 = require("./uploader");
|
|
|
14
15
|
const BLOB_REPORT_VERSION = 2;
|
|
15
16
|
class IncrementalBlobReporter {
|
|
16
17
|
_currentWorkingDir = process.cwd();
|
|
18
|
+
_stagingDir = path_1.default.join(this._currentWorkingDir, "blob-report-incremental", "staging");
|
|
17
19
|
_outputDir = path_1.default.join(this._currentWorkingDir, "blob-report-incremental");
|
|
18
20
|
_shardIndex;
|
|
19
21
|
_totalShards;
|
|
@@ -28,11 +30,14 @@ class IncrementalBlobReporter {
|
|
|
28
30
|
_finalized = false;
|
|
29
31
|
_startTime = Date.now();
|
|
30
32
|
constructor() {
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
+
if (process.env.SHARD_INDEX && process.env.TOTAL_SHARDS) {
|
|
34
|
+
this._shardIndex = Number.parseInt(process.env.SHARD_INDEX, 10);
|
|
35
|
+
this._totalShards = Number.parseInt(process.env.TOTAL_SHARDS, 10);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this._shardIndex = 1;
|
|
39
|
+
this._totalShards = 1;
|
|
33
40
|
}
|
|
34
|
-
this._shardIndex = Number.parseInt(process.env.SHARD_INDEX, 10);
|
|
35
|
-
this._totalShards = Number.parseInt(process.env.TOTAL_SHARDS, 10);
|
|
36
41
|
this._uploader = (0, uploader_1.createUploader)();
|
|
37
42
|
setIncrementalBlobReporterInstance(this);
|
|
38
43
|
this._setupSignalHandler();
|
|
@@ -74,7 +79,10 @@ class IncrementalBlobReporter {
|
|
|
74
79
|
}
|
|
75
80
|
await this._uploader.uploadFile(this._zipPath, `blobs/incremental-report-${this._shardIndex}.zip`);
|
|
76
81
|
await this._uploader.waitForUploads();
|
|
77
|
-
console.log("[IncrementalBlobReporter]
|
|
82
|
+
console.log("[IncrementalBlobReporter] Flush and upload complete on SIGINT");
|
|
83
|
+
if (process.env.LOCAL_TEST === "true") {
|
|
84
|
+
await this._mergeForLocalTest();
|
|
85
|
+
}
|
|
78
86
|
}
|
|
79
87
|
_finalizeReportForInterrupt() {
|
|
80
88
|
if (this._finalized)
|
|
@@ -101,14 +109,36 @@ class IncrementalBlobReporter {
|
|
|
101
109
|
return path_1.default.join(this._outputDir, `incremental-report-${this._shardIndex}.zip`);
|
|
102
110
|
}
|
|
103
111
|
get _jsonlPath() {
|
|
104
|
-
return path_1.default.join(this.
|
|
112
|
+
return path_1.default.join(this._stagingDir, "report.jsonl");
|
|
105
113
|
}
|
|
106
114
|
get _urlsJsonPath() {
|
|
107
|
-
return path_1.default.join(this.
|
|
115
|
+
return path_1.default.join(this._stagingDir, "_empirical_urls.json");
|
|
108
116
|
}
|
|
109
|
-
|
|
117
|
+
_ensureDirs() {
|
|
118
|
+
fs_1.default.mkdirSync(this._stagingDir, { recursive: true });
|
|
110
119
|
fs_1.default.mkdirSync(this._outputDir, { recursive: true });
|
|
111
120
|
}
|
|
121
|
+
_serializePatterns(patterns) {
|
|
122
|
+
const arr = Array.isArray(patterns) ? patterns : [patterns];
|
|
123
|
+
return arr.map((p) => typeof p === "string"
|
|
124
|
+
? { s: p }
|
|
125
|
+
: { r: { source: p.source, flags: p.flags } });
|
|
126
|
+
}
|
|
127
|
+
_embedAttachment(attachmentPath, resultId) {
|
|
128
|
+
if (!attachmentPath || !fs_1.default.existsSync(attachmentPath))
|
|
129
|
+
return null;
|
|
130
|
+
const ext = path_1.default.extname(attachmentPath);
|
|
131
|
+
const uniqueName = `${resultId}-${this._generateId()}${ext}`;
|
|
132
|
+
const destPath = path_1.default.join(this._stagingDir, uniqueName);
|
|
133
|
+
try {
|
|
134
|
+
fs_1.default.copyFileSync(attachmentPath, destPath);
|
|
135
|
+
return uniqueName;
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
console.error(`[IncrementalBlobReporter] Failed to copy attachment ${attachmentPath}:`, err);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
112
142
|
_generateId() {
|
|
113
143
|
return crypto_1.default.randomBytes(16).toString("hex");
|
|
114
144
|
}
|
|
@@ -180,21 +210,21 @@ class IncrementalBlobReporter {
|
|
|
180
210
|
return urlMap;
|
|
181
211
|
}
|
|
182
212
|
async _writeZip() {
|
|
183
|
-
this.
|
|
213
|
+
this._ensureDirs();
|
|
184
214
|
// Write report.jsonl to the output directory
|
|
185
215
|
const jsonlContent = this._reportLines.join("\n") + "\n";
|
|
186
216
|
fs_1.default.writeFileSync(this._jsonlPath, jsonlContent, "utf8");
|
|
187
217
|
// Write _empirical_urls.json with attachment URL mappings
|
|
188
218
|
const urlsJson = this._buildUrlsJson();
|
|
189
219
|
fs_1.default.writeFileSync(this._urlsJsonPath, JSON.stringify(urlsJson, null, 2), "utf8");
|
|
190
|
-
// Create zip from the
|
|
191
|
-
const zipBuffer = await (0, zip_1.createZipFromDirectory)(this.
|
|
220
|
+
// Create zip from the staging directory
|
|
221
|
+
const zipBuffer = await (0, zip_1.createZipFromDirectory)(this._stagingDir);
|
|
192
222
|
fs_1.default.writeFileSync(this._zipPath, zipBuffer);
|
|
193
223
|
console.log(`[IncrementalBlobReporter] Zip updated: ${this._zipPath} (${this._reportLines.length} events, ${this._attachmentUrlMap.size} attachments)`);
|
|
194
224
|
}
|
|
195
225
|
onBegin(config, suite) {
|
|
196
226
|
this._config = config;
|
|
197
|
-
this.
|
|
227
|
+
this._ensureDirs();
|
|
198
228
|
// 1. Emit onBlobReportMetadata (first event)
|
|
199
229
|
const osName = process.platform === "darwin" ? "macOS" : process.platform;
|
|
200
230
|
const osVersion = os_1.default.release();
|
|
@@ -242,12 +272,14 @@ class IncrementalBlobReporter {
|
|
|
242
272
|
repeatEach: project.repeatEach,
|
|
243
273
|
retries: project.retries,
|
|
244
274
|
testDir: project.testDir,
|
|
245
|
-
testIgnore: project.testIgnore,
|
|
246
|
-
testMatch: project.testMatch,
|
|
275
|
+
testIgnore: this._serializePatterns(project.testIgnore),
|
|
276
|
+
testMatch: this._serializePatterns(project.testMatch),
|
|
247
277
|
timeout: project.timeout,
|
|
248
278
|
suites,
|
|
249
|
-
grep: project.grep,
|
|
250
|
-
grepInvert: project.grepInvert
|
|
279
|
+
grep: this._serializePatterns(project.grep),
|
|
280
|
+
grepInvert: project.grepInvert
|
|
281
|
+
? this._serializePatterns(project.grepInvert)
|
|
282
|
+
: [],
|
|
251
283
|
dependencies: project.dependencies,
|
|
252
284
|
snapshotDir: project.snapshotDir,
|
|
253
285
|
use: project.use,
|
|
@@ -275,6 +307,7 @@ class IncrementalBlobReporter {
|
|
|
275
307
|
const resultId = this._getResultId(test.id, result.retry);
|
|
276
308
|
// Emit separate onAttach for each attachment (matching Playwright's blob format)
|
|
277
309
|
for (const attachment of result.attachments) {
|
|
310
|
+
const embeddedPath = this._embedAttachment(attachment.path, resultId);
|
|
278
311
|
this._appendEvent("onAttach", {
|
|
279
312
|
testId: test.id,
|
|
280
313
|
resultId,
|
|
@@ -282,7 +315,7 @@ class IncrementalBlobReporter {
|
|
|
282
315
|
{
|
|
283
316
|
name: attachment.name,
|
|
284
317
|
contentType: attachment.contentType,
|
|
285
|
-
path: attachment.path,
|
|
318
|
+
path: embeddedPath ?? attachment.path,
|
|
286
319
|
},
|
|
287
320
|
],
|
|
288
321
|
});
|
|
@@ -359,6 +392,33 @@ class IncrementalBlobReporter {
|
|
|
359
392
|
await this._writeZip();
|
|
360
393
|
console.log(`[IncrementalBlobReporter] Finished with status: ${result.status}`);
|
|
361
394
|
}
|
|
395
|
+
async _mergeForLocalTest() {
|
|
396
|
+
const htmlOutputDir = path_1.default.join(this._currentWorkingDir, "partial-playwright-report");
|
|
397
|
+
const summaryJsonPath = path_1.default.join(this._currentWorkingDir, "partial-summary.json");
|
|
398
|
+
console.log(`[IncrementalBlobReporter] Running merge report on ${this._outputDir}`);
|
|
399
|
+
try {
|
|
400
|
+
(0, child_process_1.execFileSync)("npx", [
|
|
401
|
+
"playwright",
|
|
402
|
+
"merge-reports",
|
|
403
|
+
this._outputDir,
|
|
404
|
+
"--reporter",
|
|
405
|
+
"html,json",
|
|
406
|
+
], {
|
|
407
|
+
cwd: this._currentWorkingDir,
|
|
408
|
+
env: {
|
|
409
|
+
...process.env,
|
|
410
|
+
PLAYWRIGHT_HTML_OPEN: "never",
|
|
411
|
+
PLAYWRIGHT_HTML_OUTPUT_DIR: htmlOutputDir,
|
|
412
|
+
PLAYWRIGHT_JSON_OUTPUT_NAME: summaryJsonPath,
|
|
413
|
+
},
|
|
414
|
+
stdio: "inherit",
|
|
415
|
+
});
|
|
416
|
+
console.log(`[IncrementalBlobReporter] Merge report completed. HTML: ${htmlOutputDir}, JSON: ${summaryJsonPath}`);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
console.error(`[IncrementalBlobReporter] Merge report failed:`, err);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
362
422
|
/**
|
|
363
423
|
* Add a single attachment URL mapping
|
|
364
424
|
*/
|
package/dist/reporter/util.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { TestAttachmentMap } from "@empiricalrun/reporter";
|
|
2
|
+
import { TestCaseRunEndEventV2 } from "@empiricalrun/shared-types/playwright-utils";
|
|
3
|
+
import { JSONReport as PlaywrightJSONReport, TestCase } from "@playwright/test/reporter";
|
|
3
4
|
export declare function getPackageJsonPath(folderPath: string): string;
|
|
4
5
|
export declare function resolveReporterOutputPath(defaultValue: string, configDir: string, configValue: string | undefined): string;
|
|
5
6
|
export declare function normalizeAndSaveAttachment(outputPath: string, name: string, options?: {
|
|
@@ -30,19 +31,13 @@ export declare function updateHtmlZipFileAttachmentPaths(jsonFilePath: string, h
|
|
|
30
31
|
* objects containing attachments with updated path for each test result
|
|
31
32
|
* @returns void
|
|
32
33
|
*/
|
|
33
|
-
export declare function replaceMediaPaths(jsonData: any, testAttachmentMap: Map<string, {
|
|
34
|
-
attachments: GenericPlaywrightAttachment[];
|
|
35
|
-
}[]>): void;
|
|
36
|
-
export declare function traverseJsonReportSuites(summaryJson: PlaywrightJSONReport, specFn: (spec: JSONReportSpec) => void): void;
|
|
37
34
|
/**
|
|
38
35
|
* Builds a map from test ID to an array of objects containing attachments for each result (retry).
|
|
39
36
|
* The attachments are normalized to use relative paths starting with 'data/'.
|
|
40
37
|
* @param summaryJsonFilePath Path to the summary JSON file
|
|
41
38
|
* @returns Map<string, { attachments: GenericPlaywrightAttachment[] }[]>
|
|
42
39
|
*/
|
|
43
|
-
export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: string, repoPath: string, doNotNormalize?: boolean):
|
|
44
|
-
attachments: GenericPlaywrightAttachment[];
|
|
45
|
-
}[]>;
|
|
40
|
+
export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: string, repoPath: string, doNotNormalize?: boolean): TestAttachmentMap;
|
|
46
41
|
/**
|
|
47
42
|
* Checks asynchronously if a file exists at the given path.
|
|
48
43
|
* @param filePath - The path to the file to check
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAMhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EACL,UAAU,IAAI,oBAAoB,EAElC,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAmBnC,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAmB7D;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,SAAS,UAMhC;AAED,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5E,OAAO,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAyCD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ;;;EAwBrD;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyDf;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GACnC,GAAG,CAIL;AAED,wBAAsB,gCAAgC,CACpD,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,iBAuGjB;AAED;;;;;;;;;;GAUG;AACH;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,OAAe,GAC9B,iBAAiB,CAcnB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,6CA+BlB"}
|
package/dist/reporter/util.js
CHANGED
|
@@ -10,12 +10,11 @@ exports.suitesAndProjectForTest = suitesAndProjectForTest;
|
|
|
10
10
|
exports.sendTestCaseUpdateToDashboard = sendTestCaseUpdateToDashboard;
|
|
11
11
|
exports.safelySerialiseJSON = safelySerialiseJSON;
|
|
12
12
|
exports.updateHtmlZipFileAttachmentPaths = updateHtmlZipFileAttachmentPaths;
|
|
13
|
-
exports.replaceMediaPaths = replaceMediaPaths;
|
|
14
|
-
exports.traverseJsonReportSuites = traverseJsonReportSuites;
|
|
15
13
|
exports.buildTestAttachmentMapFromSummary = buildTestAttachmentMapFromSummary;
|
|
16
14
|
exports.checkFileExistsAsync = checkFileExistsAsync;
|
|
17
15
|
exports.updateSummaryJsonAttachmentPaths = updateSummaryJsonAttachmentPaths;
|
|
18
16
|
const zip_1 = require("@empiricalrun/r2-uploader/zip");
|
|
17
|
+
const reporter_1 = require("@empiricalrun/reporter");
|
|
19
18
|
const async_retry_1 = __importDefault(require("async-retry"));
|
|
20
19
|
const fs_1 = __importDefault(require("fs"));
|
|
21
20
|
const path_1 = __importDefault(require("path"));
|
|
@@ -191,14 +190,14 @@ async function updateHtmlZipFileAttachmentPaths(jsonFilePath, htmlFilePath, repo
|
|
|
191
190
|
try {
|
|
192
191
|
const reportPath = path_1.default.join(tempDir, "report.json");
|
|
193
192
|
const reportData = JSON.parse(await fs_1.default.promises.readFile(reportPath, "utf8"));
|
|
194
|
-
replaceMediaPaths(reportData, testAttachmentMap);
|
|
193
|
+
(0, reporter_1.replaceMediaPaths)(reportData, testAttachmentMap);
|
|
195
194
|
await fs_1.default.promises.writeFile(reportPath, JSON.stringify(reportData, null, 2), "utf8");
|
|
196
195
|
const files = await fs_1.default.promises.readdir(tempDir);
|
|
197
196
|
for (const file of files.filter((f) => f.endsWith(".json") && f !== "report.json")) {
|
|
198
197
|
try {
|
|
199
198
|
const filePath = path_1.default.join(tempDir, file);
|
|
200
199
|
const jsonData = JSON.parse(await fs_1.default.promises.readFile(filePath, "utf8"));
|
|
201
|
-
replaceMediaPaths(jsonData, testAttachmentMap);
|
|
200
|
+
(0, reporter_1.replaceMediaPaths)(jsonData, testAttachmentMap);
|
|
202
201
|
await fs_1.default.promises.writeFile(filePath, JSON.stringify(jsonData, null, 2), "utf8");
|
|
203
202
|
}
|
|
204
203
|
catch (err) {
|
|
@@ -238,48 +237,6 @@ async function updateHtmlZipFileAttachmentPaths(jsonFilePath, htmlFilePath, repo
|
|
|
238
237
|
* objects containing attachments with updated path for each test result
|
|
239
238
|
* @returns void
|
|
240
239
|
*/
|
|
241
|
-
function replaceMediaPaths(jsonData, testAttachmentMap) {
|
|
242
|
-
const testsArray = jsonData.files?.flatMap((f) => f.tests) || jsonData.tests || [];
|
|
243
|
-
if (!testsArray.length) {
|
|
244
|
-
console.warn("⚠️ No test entries found in JSON.");
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
for (const test of testsArray) {
|
|
248
|
-
const testId = test?.testId;
|
|
249
|
-
if (!testId) {
|
|
250
|
-
console.warn("⚠️ Test without testId encountered, skipping.");
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
const mapped = testAttachmentMap.get(testId);
|
|
254
|
-
if (!mapped) {
|
|
255
|
-
console.warn(`⚠️ No mapped attachments found for test: "${testId}"`);
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
// Update each result's attachments directly by index
|
|
259
|
-
for (let i = 0; i < (test.results || []).length; i++) {
|
|
260
|
-
const result = test.results[i];
|
|
261
|
-
const mappedResult = mapped[i];
|
|
262
|
-
if (!result || !mappedResult)
|
|
263
|
-
continue;
|
|
264
|
-
// Overwrite the attachments array directly
|
|
265
|
-
result.attachments = mappedResult.attachments;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
// Generic suite traversal utility
|
|
270
|
-
function traverseJsonReportSuites(summaryJson, specFn) {
|
|
271
|
-
function recurse(suite) {
|
|
272
|
-
for (const spec of suite.specs || []) {
|
|
273
|
-
specFn(spec);
|
|
274
|
-
}
|
|
275
|
-
for (const childSuite of suite.suites || []) {
|
|
276
|
-
recurse(childSuite);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
for (const suite of summaryJson.suites || []) {
|
|
280
|
-
recurse(suite);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
240
|
/**
|
|
284
241
|
* Builds a map from test ID to an array of objects containing attachments for each result (retry).
|
|
285
242
|
* The attachments are normalized to use relative paths starting with 'data/'.
|
|
@@ -288,32 +245,16 @@ function traverseJsonReportSuites(summaryJson, specFn) {
|
|
|
288
245
|
*/
|
|
289
246
|
function buildTestAttachmentMapFromSummary(summaryJsonFilePath, repoPath, doNotNormalize = false) {
|
|
290
247
|
const summaryJson = JSON.parse(fs_1.default.readFileSync(summaryJsonFilePath, "utf8"));
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
for (const test of spec.tests) {
|
|
302
|
-
if (!testId) {
|
|
303
|
-
console.warn("⚠️ Test without testId encountered, skipping.");
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
const resultAttachments = (test.results || []).map((result) => ({
|
|
307
|
-
attachments: (result.attachments || []).map(doNotNormalize ? (a) => a : normalizeAttachmentPath),
|
|
308
|
-
}));
|
|
309
|
-
testAttachmentMap.set(testId, [
|
|
310
|
-
...(testAttachmentMap.get(testId) || []),
|
|
311
|
-
...resultAttachments,
|
|
312
|
-
]);
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
traverseJsonReportSuites(summaryJson, buildTestAttachmentMap);
|
|
316
|
-
return testAttachmentMap;
|
|
248
|
+
return (0, reporter_1.buildTestAttachmentMap)(summaryJson, {
|
|
249
|
+
transformAttachment: doNotNormalize
|
|
250
|
+
? undefined
|
|
251
|
+
: (attachment) => {
|
|
252
|
+
if (!attachment?.path)
|
|
253
|
+
return attachment;
|
|
254
|
+
const relativePath = path_1.default.relative(repoPath, attachment.path);
|
|
255
|
+
return { ...attachment, path: path_1.default.join("data", relativePath) };
|
|
256
|
+
},
|
|
257
|
+
});
|
|
317
258
|
}
|
|
318
259
|
/**
|
|
319
260
|
* Checks asynchronously if a file exists at the given path.
|
|
@@ -346,22 +287,18 @@ async function updateSummaryJsonAttachmentPaths(filePath, repoPath, urlPrefix) {
|
|
|
346
287
|
return;
|
|
347
288
|
}
|
|
348
289
|
const summaryJson = JSON.parse(await fs_1.default.promises.readFile(filePath, "utf8"));
|
|
349
|
-
|
|
290
|
+
(0, reporter_1.traverseJsonReportSuites)(summaryJson, (spec) => {
|
|
350
291
|
for (const test of spec.tests) {
|
|
351
292
|
for (const result of test.results || []) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const newPath = `${urlPrefix}/${relativePath}`;
|
|
357
|
-
attachment.path = newPath;
|
|
358
|
-
}
|
|
293
|
+
for (const attachment of result.attachments || []) {
|
|
294
|
+
if (attachment?.path) {
|
|
295
|
+
const relativePath = path_1.default.relative(repoPath, attachment.path);
|
|
296
|
+
attachment.path = `${urlPrefix}/${relativePath}`;
|
|
359
297
|
}
|
|
360
298
|
}
|
|
361
299
|
}
|
|
362
300
|
}
|
|
363
|
-
};
|
|
364
|
-
traverseJsonReportSuites(summaryJson, updateAttachmentPath);
|
|
301
|
+
});
|
|
365
302
|
await fs_1.default.promises.writeFile(filePath, JSON.stringify(summaryJson, null, 2), "utf8");
|
|
366
303
|
return summaryJson;
|
|
367
304
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BrowserContext } from "@playwright/test";
|
|
2
|
+
export declare function setupCoverageCollection(context: BrowserContext): Promise<string[]>;
|
|
3
|
+
export declare function collectAndAttachCoverage(context: BrowserContext, coverageFiles: string[], testInfo: {
|
|
4
|
+
attach: (name: string, options: {
|
|
5
|
+
path: string;
|
|
6
|
+
contentType: string;
|
|
7
|
+
}) => Promise<void>;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/test/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYvD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,qBAwBpE;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE;IACR,MAAM,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,iBAqBF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setupCoverageCollection = setupCoverageCollection;
|
|
7
|
+
exports.collectAndAttachCoverage = collectAndAttachCoverage;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const istanbulCLIOutput = path_1.default.join(process.cwd(), ".nyc_output");
|
|
11
|
+
function generateCoverageFilename() {
|
|
12
|
+
const timestamp = Date.now();
|
|
13
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
14
|
+
return `coverage_${timestamp}_${random}.json`;
|
|
15
|
+
}
|
|
16
|
+
async function setupCoverageCollection(context) {
|
|
17
|
+
const coverageFiles = [];
|
|
18
|
+
await context.addInitScript(() => window.addEventListener("beforeunload", () => window.collectIstanbulCoverage(JSON.stringify(window.__coverage__))));
|
|
19
|
+
await fs_1.default.promises.mkdir(istanbulCLIOutput, { recursive: true });
|
|
20
|
+
await context.exposeFunction("collectIstanbulCoverage", (coverageJSON) => {
|
|
21
|
+
if (coverageJSON) {
|
|
22
|
+
const filepath = path_1.default.join(istanbulCLIOutput, generateCoverageFilename());
|
|
23
|
+
fs_1.default.writeFileSync(filepath, coverageJSON);
|
|
24
|
+
coverageFiles.push(filepath);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return coverageFiles;
|
|
28
|
+
}
|
|
29
|
+
async function collectAndAttachCoverage(context, coverageFiles, testInfo) {
|
|
30
|
+
for (const page of context.pages()) {
|
|
31
|
+
try {
|
|
32
|
+
await page.evaluate(() => window.collectIstanbulCoverage(JSON.stringify(window.__coverage__)));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Page might be closed or coverage not available
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const filepath of coverageFiles) {
|
|
39
|
+
if (fs_1.default.existsSync(filepath)) {
|
|
40
|
+
await testInfo.attach(path_1.default.basename(filepath), {
|
|
41
|
+
path: filepath,
|
|
42
|
+
contentType: "application/json",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
package/dist/test/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { KVClient } from "../kv";
|
|
|
3
3
|
import { PostgresClient } from "../postgres";
|
|
4
4
|
import { type WebhookMatcherOptions } from "./expect";
|
|
5
5
|
import { injectLocatorHighlightScripts } from "./scripts";
|
|
6
|
-
import {
|
|
6
|
+
import { type BaseTestFixtureOpts } from "./types";
|
|
7
7
|
import { setVideoLabel } from "./video-labels";
|
|
8
8
|
declare global {
|
|
9
9
|
namespace PlaywrightTest {
|
|
@@ -24,6 +24,6 @@ type TestOptions = {
|
|
|
24
24
|
}>;
|
|
25
25
|
saveVideos: void;
|
|
26
26
|
};
|
|
27
|
-
declare const baseTestFixture: (testFn: TestType<PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>, options?:
|
|
27
|
+
declare const baseTestFixture: (testFn: TestType<PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>, options?: BaseTestFixtureOpts) => TestType<PlaywrightTestArgs & PlaywrightTestOptions & TestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
|
28
28
|
export { baseTestFixture, extendExpect, injectLocatorHighlightScripts, setVideoLabel, };
|
|
29
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/test/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,mBAAmB,EAAwB,MAAM,SAAS,CAAC;AACzE,OAAO,EAA8B,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,cAAc,CAAC;QACvB,UAAU,QAAQ,CAAC,CAAC;YAClB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7C,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;SACnE;KACF;CACF;AAED,QAAA,MAAM,YAAY,GAAa,gBAAgB,OAAO,MAAM,0CAG3D,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,yBAAyB,EAAE,CACzB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAYF,QAAA,MAAM,eAAe,GACnB,QAAQ,QAAQ,CACd,kBAAkB,GAAG,qBAAqB,EAC1C,oBAAoB,GAAG,uBAAuB,CAC/C,EACD,UAAS,mBAAoC,uHAqH9C,CAAC;AAEF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,aAAa,GACd,CAAC"}
|
package/dist/test/index.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.setVideoLabel = exports.injectLocatorHighlightScripts = exports.extendEx
|
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const kv_1 = require("../kv");
|
|
9
9
|
const postgres_1 = require("../postgres");
|
|
10
|
+
const coverage_1 = require("./coverage");
|
|
10
11
|
const expect_1 = require("./expect");
|
|
11
12
|
const scripts_1 = require("./scripts");
|
|
12
13
|
Object.defineProperty(exports, "injectLocatorHighlightScripts", { enumerable: true, get: function () { return scripts_1.injectLocatorHighlightScripts; } });
|
|
@@ -26,6 +27,7 @@ const defaultOptions = {
|
|
|
26
27
|
agentCapabilities: true,
|
|
27
28
|
};
|
|
28
29
|
const baseTestFixture = function (testFn, options = defaultOptions) {
|
|
30
|
+
const coverageEnabled = options.collectCoverage ?? false;
|
|
29
31
|
const extendedTestFn = testFn.extend({
|
|
30
32
|
context: async ({ browser }, use, testInfo) => {
|
|
31
33
|
const context = await browser.newContext({
|
|
@@ -36,7 +38,14 @@ const baseTestFixture = function (testFn, options = defaultOptions) {
|
|
|
36
38
|
});
|
|
37
39
|
const pages = [];
|
|
38
40
|
context.on("page", (page) => pages.push(page));
|
|
41
|
+
let coverageFiles = [];
|
|
42
|
+
if (coverageEnabled) {
|
|
43
|
+
coverageFiles = await (0, coverage_1.setupCoverageCollection)(context);
|
|
44
|
+
}
|
|
39
45
|
await use(context);
|
|
46
|
+
if (coverageEnabled) {
|
|
47
|
+
await (0, coverage_1.collectAndAttachCoverage)(context, coverageFiles, testInfo);
|
|
48
|
+
}
|
|
40
49
|
if (!testPages.has(testInfo.testId)) {
|
|
41
50
|
testPages.set(testInfo.testId, []);
|
|
42
51
|
}
|
package/dist/test/types.d.ts
CHANGED
package/dist/test/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/playwright-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"@empiricalrun/cua": "^0.3.0",
|
|
47
47
|
"@empiricalrun/dashboard-client": "^0.2.0",
|
|
48
48
|
"@empiricalrun/llm": "^0.26.0",
|
|
49
|
-
"@empiricalrun/r2-uploader": "^0.9.1"
|
|
49
|
+
"@empiricalrun/r2-uploader": "^0.9.1",
|
|
50
|
+
"@empiricalrun/reporter": "^0.28.0"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"dev": "tsc --build --watch",
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/email.ts","./src/index.ts","./src/kv.ts","./src/logger.ts","./src/mailosaur-client.ts","./src/playwright-extensions.ts","./src/postgres.ts","./src/telemetry.ts","./src/webhook.ts","./src/auth/google.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/config/index.ts","./src/config/proxy.ts","./src/config/devices/types.ts","./src/overlay-tests/cache.spec.ts","./src/overlay-tests/click.spec.ts","./src/overlay-tests/fixtures.ts","./src/overlay-tests/patch.spec.ts","./src/reporter/blob-utils.ts","./src/reporter/empirical-reporter.ts","./src/reporter/failing-line.ts","./src/reporter/incremental-blob-reporter.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/test/constants.ts","./src/test/index.ts","./src/test/types.ts","./src/test/video-labels.ts","./src/test/expect/index.ts","./src/test/expect/types.ts","./src/test/expect/visual.ts","./src/test/expect/webhook.ts","./src/test/scripts/agent-capabilities.ts","./src/test/scripts/index.ts","./src/test/scripts/locator-highlights.ts","./src/test/scripts/locator-vision.ts","./src/test/scripts/mouse-pointer.ts","./src/test/scripts/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts","./src/test/scripts/pw-locator-patch/highlight/click.ts","./src/test/scripts/pw-locator-patch/highlight/expect.ts","./src/test/scripts/pw-locator-patch/highlight/hover.ts","./src/test/scripts/pw-locator-patch/highlight/inner-text.ts","./src/test/scripts/pw-locator-patch/highlight/input-value.ts","./src/test/scripts/pw-locator-patch/highlight/is-checked.ts","./src/test/scripts/pw-locator-patch/highlight/is-disabled.ts","./src/test/scripts/pw-locator-patch/highlight/is-editable.ts","./src/test/scripts/pw-locator-patch/highlight/text-content.ts","./src/test/scripts/pw-locator-patch/utils/index.ts","./src/test/scripts/pw-locator-patch/vision/query.ts"],"version":"5.8.3"}
|
|
1
|
+
{"root":["./src/email.ts","./src/index.ts","./src/kv.ts","./src/logger.ts","./src/mailosaur-client.ts","./src/playwright-extensions.ts","./src/postgres.ts","./src/telemetry.ts","./src/webhook.ts","./src/auth/google.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/config/index.ts","./src/config/proxy.ts","./src/config/devices/types.ts","./src/overlay-tests/cache.spec.ts","./src/overlay-tests/click.spec.ts","./src/overlay-tests/fixtures.ts","./src/overlay-tests/patch.spec.ts","./src/reporter/blob-utils.ts","./src/reporter/empirical-reporter.ts","./src/reporter/failing-line.ts","./src/reporter/incremental-blob-reporter.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/test/constants.ts","./src/test/coverage.ts","./src/test/index.ts","./src/test/types.ts","./src/test/video-labels.ts","./src/test/expect/index.ts","./src/test/expect/types.ts","./src/test/expect/visual.ts","./src/test/expect/webhook.ts","./src/test/scripts/agent-capabilities.ts","./src/test/scripts/index.ts","./src/test/scripts/locator-highlights.ts","./src/test/scripts/locator-vision.ts","./src/test/scripts/mouse-pointer.ts","./src/test/scripts/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts","./src/test/scripts/pw-locator-patch/highlight/click.ts","./src/test/scripts/pw-locator-patch/highlight/expect.ts","./src/test/scripts/pw-locator-patch/highlight/hover.ts","./src/test/scripts/pw-locator-patch/highlight/inner-text.ts","./src/test/scripts/pw-locator-patch/highlight/input-value.ts","./src/test/scripts/pw-locator-patch/highlight/is-checked.ts","./src/test/scripts/pw-locator-patch/highlight/is-disabled.ts","./src/test/scripts/pw-locator-patch/highlight/is-editable.ts","./src/test/scripts/pw-locator-patch/highlight/text-content.ts","./src/test/scripts/pw-locator-patch/utils/index.ts","./src/test/scripts/pw-locator-patch/vision/query.ts"],"version":"5.8.3"}
|