@empiricalrun/playwright-utils 0.27.18 → 0.28.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 +47 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/reporter/empirical-reporter.d.ts +3 -0
- package/dist/reporter/empirical-reporter.d.ts.map +1 -1
- package/dist/reporter/empirical-reporter.js +25 -17
- package/dist/reporter/uploader.d.ts +2 -1
- package/dist/reporter/uploader.d.ts.map +1 -1
- package/dist/reporter/uploader.js +5 -2
- package/dist/reporter/util.d.ts +16 -3
- package/dist/reporter/util.d.ts.map +1 -1
- package/dist/reporter/util.js +71 -26
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.js +7 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @empiricalrun/playwright-utils
|
|
2
2
|
|
|
3
|
+
## 0.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f349076: feat: update summary.json attachment paths to actual urls
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [6b1d98c]
|
|
12
|
+
- Updated dependencies [b6a04f5]
|
|
13
|
+
- Updated dependencies [4cbc287]
|
|
14
|
+
- Updated dependencies [a96a03c]
|
|
15
|
+
- Updated dependencies [df226a5]
|
|
16
|
+
- Updated dependencies [32905df]
|
|
17
|
+
- Updated dependencies [8e3c7a4]
|
|
18
|
+
- Updated dependencies [5b0d43a]
|
|
19
|
+
- Updated dependencies [6ac65ed]
|
|
20
|
+
- Updated dependencies [fc6f97c]
|
|
21
|
+
- Updated dependencies [440e851]
|
|
22
|
+
- Updated dependencies [a23b38f]
|
|
23
|
+
- Updated dependencies [12c69cc]
|
|
24
|
+
- Updated dependencies [5ed01c4]
|
|
25
|
+
- Updated dependencies [e1d01c8]
|
|
26
|
+
- Updated dependencies [450b79a]
|
|
27
|
+
- Updated dependencies [7009d67]
|
|
28
|
+
- Updated dependencies [d570c55]
|
|
29
|
+
- Updated dependencies [622aa35]
|
|
30
|
+
- Updated dependencies [23708d1]
|
|
31
|
+
- Updated dependencies [162e461]
|
|
32
|
+
- Updated dependencies [349003e]
|
|
33
|
+
- Updated dependencies [d5c7696]
|
|
34
|
+
- Updated dependencies [7afa5c1]
|
|
35
|
+
- @empiricalrun/test-gen@0.72.0
|
|
36
|
+
- @empiricalrun/llm@0.20.0
|
|
37
|
+
|
|
38
|
+
## 0.27.19
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- f44505a: fix: smaller responses from run-test tool
|
|
43
|
+
- 001b324: fix: enforce codegen approach for overlay dismissals
|
|
44
|
+
- Updated dependencies [d7f9025]
|
|
45
|
+
- Updated dependencies [f44505a]
|
|
46
|
+
- Updated dependencies [001b324]
|
|
47
|
+
- @empiricalrun/test-gen@0.71.2
|
|
48
|
+
- @empiricalrun/llm@0.19.4
|
|
49
|
+
|
|
3
50
|
## 0.27.18
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAczD,wBAAgB,gBAAgB,IAAI,MAAM,CAazC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAczD,wBAAgB,gBAAgB,IAAI,MAAM,CAazC;AA2CD,eAAO,MAAM,UAAU,EAAE,oBAyBxB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,iBAgBrB,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,9 @@ declare class EmpiricalReporter implements Reporter {
|
|
|
4
4
|
private _uploadBucket;
|
|
5
5
|
private _currentWorkingDir;
|
|
6
6
|
private _willUploadArtifacts;
|
|
7
|
+
private _testResultSourceDir;
|
|
8
|
+
private _baseUrl;
|
|
9
|
+
private _urlPrefix;
|
|
7
10
|
private checkR2Creds;
|
|
8
11
|
constructor();
|
|
9
12
|
private processTestAttachment;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAiBnC,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,oBAAoB,CAG1B;IACF,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,UAAU,CAA2F;IAE7G,OAAO,CAAC,YAAY;;IAyBpB,OAAO,CAAC,qBAAqB,CAuB3B;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAyEtC,KAAK,CAAC,MAAM,EAAE,UAAU;CA+G/B;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -15,6 +15,9 @@ class EmpiricalReporter {
|
|
|
15
15
|
_uploadBucket = "test-report";
|
|
16
16
|
_currentWorkingDir = process.cwd();
|
|
17
17
|
_willUploadArtifacts = false;
|
|
18
|
+
_testResultSourceDir = path_1.default.join(this._currentWorkingDir, "test-results");
|
|
19
|
+
_baseUrl = `https://reports.empirical.run`;
|
|
20
|
+
_urlPrefix = `${this._baseUrl}/${process.env.PROJECT_NAME}/${process.env.TEST_RUN_GITHUB_ACTION_ID}`;
|
|
18
21
|
checkR2Creds() {
|
|
19
22
|
if (!process.env.R2_ACCOUNT_ID ||
|
|
20
23
|
!process.env.R2_ACCESS_KEY_ID ||
|
|
@@ -36,7 +39,6 @@ class EmpiricalReporter {
|
|
|
36
39
|
processTestAttachment = async (attachment) => {
|
|
37
40
|
if (!attachment.path)
|
|
38
41
|
return;
|
|
39
|
-
const testResultSourceDir = path_1.default.join(this._currentWorkingDir, "test-results");
|
|
40
42
|
const exists = await (0, util_1.checkFileExistsAsync)(attachment.path);
|
|
41
43
|
if (exists) {
|
|
42
44
|
logger_1.logger.debug(`[Empirical Reporter] Processing attachment: File exists`);
|
|
@@ -46,10 +48,11 @@ class EmpiricalReporter {
|
|
|
46
48
|
return;
|
|
47
49
|
}
|
|
48
50
|
const uploadTask = (0, uploader_1.createUploadTaskV2)({
|
|
49
|
-
sourceDir:
|
|
51
|
+
sourceDir: this._testResultSourceDir,
|
|
50
52
|
fileList: [attachment.path],
|
|
51
53
|
destinationDir: path_1.default.join(this._destinationDir, "data"),
|
|
52
54
|
uploadBucket: this._uploadBucket,
|
|
55
|
+
baseUrl: this._baseUrl,
|
|
53
56
|
});
|
|
54
57
|
return (0, queue_1.sendTaskToQueue)(uploadTask);
|
|
55
58
|
};
|
|
@@ -126,36 +129,40 @@ class EmpiricalReporter {
|
|
|
126
129
|
}).format(startTime));
|
|
127
130
|
const jsonFilePath = path_1.default.join(this._currentWorkingDir, "summary.json");
|
|
128
131
|
const jsonExists = fs_1.default.existsSync(jsonFilePath);
|
|
129
|
-
if (jsonExists) {
|
|
130
|
-
logger_1.logger.debug("[Empirical Reporter] Uploading JSON file");
|
|
131
|
-
const uploadJsonTask = (0, uploader_1.createUploadTaskV2)({
|
|
132
|
-
sourceDir: this._currentWorkingDir,
|
|
133
|
-
fileList: [jsonFilePath],
|
|
134
|
-
destinationDir: this._destinationDir,
|
|
135
|
-
uploadBucket: this._uploadBucket,
|
|
136
|
-
});
|
|
137
|
-
void (0, queue_1.sendTaskToQueue)(uploadJsonTask);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
logger_1.logger.error(`[Empirical Reporter] summary.json does not exist at: ${jsonFilePath}`);
|
|
141
|
-
}
|
|
142
132
|
const htmlFilePath = path_1.default.join(this._currentWorkingDir, "playwright-report/index.html");
|
|
143
133
|
const htmlExists = await (0, util_1.checkFileExistsAsync)(htmlFilePath);
|
|
144
|
-
if (htmlExists) {
|
|
134
|
+
if (htmlExists && jsonExists) {
|
|
145
135
|
logger_1.logger.debug("[Empirical Reporter] Updating the HTML Zip");
|
|
146
|
-
await (0, util_1.updateHtmlZipFileAttachmentPaths)(jsonFilePath, htmlFilePath);
|
|
136
|
+
await (0, util_1.updateHtmlZipFileAttachmentPaths)(jsonFilePath, htmlFilePath, this._testResultSourceDir);
|
|
147
137
|
logger_1.logger.debug("[Empirical Reporter] Uploading HTML file");
|
|
148
138
|
const uploadHtmlTask = (0, uploader_1.createUploadTaskV2)({
|
|
149
139
|
sourceDir: path_1.default.join(this._currentWorkingDir, "playwright-report"),
|
|
150
140
|
fileList: [htmlFilePath],
|
|
151
141
|
destinationDir: this._destinationDir,
|
|
152
142
|
uploadBucket: this._uploadBucket,
|
|
143
|
+
baseUrl: this._baseUrl,
|
|
153
144
|
});
|
|
154
145
|
void (0, queue_1.sendTaskToQueue)(uploadHtmlTask);
|
|
155
146
|
}
|
|
156
147
|
else {
|
|
157
148
|
logger_1.logger.error(`[Empirical Reporter] playwright-report/index.html does not exist at: ${htmlFilePath}`);
|
|
158
149
|
}
|
|
150
|
+
if (jsonExists) {
|
|
151
|
+
logger_1.logger.debug("[Empirical Reporter] Updating the JSON file");
|
|
152
|
+
await (0, util_1.updateSummaryJsonAttachmentPaths)(jsonFilePath, this._testResultSourceDir, `${this._urlPrefix}/data`);
|
|
153
|
+
logger_1.logger.debug("[Empirical Reporter] Uploading JSON file");
|
|
154
|
+
const uploadJsonTask = (0, uploader_1.createUploadTaskV2)({
|
|
155
|
+
sourceDir: this._currentWorkingDir,
|
|
156
|
+
fileList: [jsonFilePath],
|
|
157
|
+
destinationDir: this._destinationDir,
|
|
158
|
+
uploadBucket: this._uploadBucket,
|
|
159
|
+
baseUrl: this._baseUrl,
|
|
160
|
+
});
|
|
161
|
+
void (0, queue_1.sendTaskToQueue)(uploadJsonTask);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
logger_1.logger.error(`[Empirical Reporter] summary.json does not exist at: ${jsonFilePath}`);
|
|
165
|
+
}
|
|
159
166
|
const traceFilePath = path_1.default.join(this._currentWorkingDir, "playwright-report/trace");
|
|
160
167
|
const traceExists = await (0, util_1.checkFileExistsAsync)(traceFilePath);
|
|
161
168
|
if (traceExists) {
|
|
@@ -164,6 +171,7 @@ class EmpiricalReporter {
|
|
|
164
171
|
sourceDir: traceFilePath,
|
|
165
172
|
destinationDir: path_1.default.join(this._destinationDir, "trace"),
|
|
166
173
|
uploadBucket: this._uploadBucket,
|
|
174
|
+
baseUrl: this._baseUrl,
|
|
167
175
|
});
|
|
168
176
|
void (0, queue_1.sendTaskToQueue)(uploadTraceTask);
|
|
169
177
|
}
|
|
@@ -24,10 +24,11 @@ export declare function createUploadTask({ fileList, outputFolder, relativePath,
|
|
|
24
24
|
* @param {string} params.uploadBucket - The R2 bucket to upload to
|
|
25
25
|
* @returns {AsyncTask} An async task that when executed will upload the files and return a map of file paths to URLs
|
|
26
26
|
*/
|
|
27
|
-
export declare function createUploadTaskV2({ sourceDir, fileList, destinationDir, uploadBucket, }: {
|
|
27
|
+
export declare function createUploadTaskV2({ sourceDir, fileList, destinationDir, uploadBucket, baseUrl, }: {
|
|
28
28
|
sourceDir: string;
|
|
29
29
|
fileList?: string[];
|
|
30
30
|
destinationDir: string;
|
|
31
31
|
uploadBucket: string;
|
|
32
|
+
baseUrl: string;
|
|
32
33
|
}): AsyncTask;
|
|
33
34
|
//# sourceMappingURL=uploader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/reporter/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,2BAA2B,CAAC;AAIrE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/reporter/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,2BAA2B,CAAC;AAIrE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAOpC,wBAAsB,WAAW,CAAC,EAChC,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAwB1B;AAGD,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,YAAY,EACZ,YAAiB,GAClB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,SAAS,CAaZ;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,SAAS,CA8BZ"}
|
|
@@ -9,8 +9,10 @@ exports.createUploadTaskV2 = createUploadTaskV2;
|
|
|
9
9
|
const r2_uploader_1 = require("@empiricalrun/r2-uploader");
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
|
+
// TODO: Remove this once we have migrated to 1.53.X for all repos
|
|
12
13
|
const R2_BUCKET_NAME = "test-report";
|
|
13
14
|
const R2_BASE_URL = "https://reports.empirical.run";
|
|
15
|
+
// TODO: Remove this once we have migrated to 1.53.X for all repos
|
|
14
16
|
async function uploadFiles({ fileList, outputFolder, relativePath, }) {
|
|
15
17
|
if (!process.env.PROJECT_NAME || !process.env.TEST_RUN_GITHUB_ACTION_ID) {
|
|
16
18
|
return;
|
|
@@ -32,6 +34,7 @@ async function uploadFiles({ fileList, outputFolder, relativePath, }) {
|
|
|
32
34
|
logger_1.logger.debug("Finished uploading files:", urls);
|
|
33
35
|
return urls;
|
|
34
36
|
}
|
|
37
|
+
// TODO: Remove this once we have migrated to 1.53.X for all repos
|
|
35
38
|
function createUploadTask({ fileList, outputFolder, relativePath = "", }) {
|
|
36
39
|
return async () => {
|
|
37
40
|
return uploadFiles({
|
|
@@ -60,7 +63,7 @@ function createUploadTask({ fileList, outputFolder, relativePath = "", }) {
|
|
|
60
63
|
* @param {string} params.uploadBucket - The R2 bucket to upload to
|
|
61
64
|
* @returns {AsyncTask} An async task that when executed will upload the files and return a map of file paths to URLs
|
|
62
65
|
*/
|
|
63
|
-
function createUploadTaskV2({ sourceDir, fileList, destinationDir, uploadBucket, }) {
|
|
66
|
+
function createUploadTaskV2({ sourceDir, fileList, destinationDir, uploadBucket, baseUrl, }) {
|
|
64
67
|
return async () => {
|
|
65
68
|
if (!process.env.R2_ACCOUNT_ID ||
|
|
66
69
|
!process.env.R2_ACCESS_KEY_ID ||
|
|
@@ -78,7 +81,7 @@ function createUploadTaskV2({ sourceDir, fileList, destinationDir, uploadBucket,
|
|
|
78
81
|
Object.entries(uploadedFiles).forEach(([filePath]) => {
|
|
79
82
|
// Example: If R2_BASE_URL is "https://r2.example.com" and destinationDir is "test-results/123" and filePath is "screenshot.png"
|
|
80
83
|
// The resulting URL will be: "https://r2.example.com/test-results/123/screenshot.png"
|
|
81
|
-
const fileUrl = new URL(path_1.default.join(destinationDir, filePath),
|
|
84
|
+
const fileUrl = new URL(path_1.default.join(destinationDir, filePath), baseUrl);
|
|
82
85
|
urls[filePath] = fileUrl.toString();
|
|
83
86
|
});
|
|
84
87
|
logger_1.logger.debug("Finished Upload Files");
|
package/dist/reporter/util.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
import { GenericPlaywrightAttachment } from "@empiricalrun/shared-types";
|
|
19
|
-
import { TestCase } from "@playwright/test/reporter";
|
|
19
|
+
import { JSONReport as PlaywrightJSONReport, JSONReportSpec, TestCase } from "@playwright/test/reporter";
|
|
20
20
|
import { TestCaseRunEndEvent } from "./types";
|
|
21
21
|
export declare function getPackageJsonPath(folderPath: string): string;
|
|
22
22
|
export declare function resolveReporterOutputPath(defaultValue: string, configDir: string, configValue: string | undefined): string;
|
|
@@ -36,7 +36,7 @@ export declare function suitesAndProjectForTest(test: TestCase): {
|
|
|
36
36
|
};
|
|
37
37
|
export declare function sendTestCaseUpdateToDashboard(params: TestCaseRunEndEvent): Promise<void>;
|
|
38
38
|
export declare function safelySerialiseJSON(obj: any, keyFilter?: (key: string) => boolean): any;
|
|
39
|
-
export declare function updateHtmlZipFileAttachmentPaths(jsonFilePath: string, htmlFilePath: string): Promise<void>;
|
|
39
|
+
export declare function updateHtmlZipFileAttachmentPaths(jsonFilePath: string, htmlFilePath: string, repoPath: string): Promise<void>;
|
|
40
40
|
/**
|
|
41
41
|
* Replaces media paths in test results with normalized paths from the test attachment map.
|
|
42
42
|
* This function updates the attachments array in each test result with the corresponding
|
|
@@ -51,13 +51,14 @@ export declare function updateHtmlZipFileAttachmentPaths(jsonFilePath: string, h
|
|
|
51
51
|
export declare function replaceMediaPaths(jsonData: any, testAttachmentMap: Map<string, {
|
|
52
52
|
attachments: GenericPlaywrightAttachment[];
|
|
53
53
|
}[]>): void;
|
|
54
|
+
export declare function traverseJsonReportSuites(summaryJson: PlaywrightJSONReport, specFn: (spec: JSONReportSpec) => void): void;
|
|
54
55
|
/**
|
|
55
56
|
* Builds a map from test ID to an array of objects containing attachments for each result (retry).
|
|
56
57
|
* The attachments are normalized to use relative paths starting with 'data/'.
|
|
57
58
|
* @param summaryJsonFilePath Path to the summary JSON file
|
|
58
59
|
* @returns Map<string, { attachments: GenericPlaywrightAttachment[] }[]>
|
|
59
60
|
*/
|
|
60
|
-
export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: string): Map<string, {
|
|
61
|
+
export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: string, repoPath: string, doNotNormalize?: boolean): Map<string, {
|
|
61
62
|
attachments: GenericPlaywrightAttachment[];
|
|
62
63
|
}[]>;
|
|
63
64
|
/**
|
|
@@ -66,4 +67,16 @@ export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: s
|
|
|
66
67
|
* @returns Promise<boolean> - true if the file exists, false otherwise
|
|
67
68
|
*/
|
|
68
69
|
export declare function checkFileExistsAsync(filePath: string): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Updates the attachment paths in the summary JSON file to use remote URLs.
|
|
72
|
+
*
|
|
73
|
+
* This function rewrites all attachment `path` fields in the given Playwright summary JSON file
|
|
74
|
+
* so that they point to remote URLs based on the current `PROJECT_NAME` and `TEST_RUN_GITHUB_ACTION_ID`
|
|
75
|
+
* environment variables.
|
|
76
|
+
*
|
|
77
|
+
* @param filePath - The path to the summary JSON file
|
|
78
|
+
* @returns The updated summary JSON
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
export declare function updateSummaryJsonAttachmentPaths(filePath: string, repoPath: string, urlPrefix: string): Promise<PlaywrightJSONReport | undefined>;
|
|
69
82
|
//# sourceMappingURL=util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EACL,UAAU,IAAI,oBAAoB,EAClC,cAAc,EAId,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAiBnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAI9C,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,mBAAmB,GAC1B,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,iBAuFjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,GAAG,EACb,iBAAiB,EAAE,GAAG,CACpB,MAAM,EACN;IAAE,WAAW,EAAE,2BAA2B,EAAE,CAAA;CAAE,EAAE,CACjD,QA+BF;AAGD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,oBAAoB,EACjC,MAAM,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,QAavC;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,OAAe,GAC9B,GAAG,CAAC,MAAM,EAAE;IAAE,WAAW,EAAE,2BAA2B,EAAE,CAAA;CAAE,EAAE,CAAC,CA4C/D;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,6CAoClB"}
|
package/dist/reporter/util.js
CHANGED
|
@@ -28,8 +28,10 @@ exports.sendTestCaseUpdateToDashboard = sendTestCaseUpdateToDashboard;
|
|
|
28
28
|
exports.safelySerialiseJSON = safelySerialiseJSON;
|
|
29
29
|
exports.updateHtmlZipFileAttachmentPaths = updateHtmlZipFileAttachmentPaths;
|
|
30
30
|
exports.replaceMediaPaths = replaceMediaPaths;
|
|
31
|
+
exports.traverseJsonReportSuites = traverseJsonReportSuites;
|
|
31
32
|
exports.buildTestAttachmentMapFromSummary = buildTestAttachmentMapFromSummary;
|
|
32
33
|
exports.checkFileExistsAsync = checkFileExistsAsync;
|
|
34
|
+
exports.updateSummaryJsonAttachmentPaths = updateSummaryJsonAttachmentPaths;
|
|
33
35
|
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
34
36
|
const async_retry_1 = __importDefault(require("async-retry"));
|
|
35
37
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -171,8 +173,8 @@ async function sendTestCaseUpdateToDashboard(params) {
|
|
|
171
173
|
function safelySerialiseJSON(obj, keyFilter) {
|
|
172
174
|
return JSON.parse(JSON.stringify(obj, (key, value) => (keyFilter?.(key) ? undefined : value)));
|
|
173
175
|
}
|
|
174
|
-
async function updateHtmlZipFileAttachmentPaths(jsonFilePath, htmlFilePath) {
|
|
175
|
-
const testAttachmentMap = buildTestAttachmentMapFromSummary(jsonFilePath);
|
|
176
|
+
async function updateHtmlZipFileAttachmentPaths(jsonFilePath, htmlFilePath, repoPath) {
|
|
177
|
+
const testAttachmentMap = buildTestAttachmentMapFromSummary(jsonFilePath, repoPath);
|
|
176
178
|
let htmlFile;
|
|
177
179
|
try {
|
|
178
180
|
htmlFile = await fs_1.default.promises.readFile(htmlFilePath, "utf8");
|
|
@@ -269,46 +271,53 @@ function replaceMediaPaths(jsonData, testAttachmentMap) {
|
|
|
269
271
|
}
|
|
270
272
|
}
|
|
271
273
|
}
|
|
274
|
+
// Generic suite traversal utility
|
|
275
|
+
function traverseJsonReportSuites(summaryJson, specFn) {
|
|
276
|
+
function recurse(suite) {
|
|
277
|
+
for (const spec of suite.specs || []) {
|
|
278
|
+
specFn(spec);
|
|
279
|
+
}
|
|
280
|
+
for (const childSuite of suite.suites || []) {
|
|
281
|
+
recurse(childSuite);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
for (const suite of summaryJson.suites || []) {
|
|
285
|
+
recurse(suite);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
272
288
|
/**
|
|
273
289
|
* Builds a map from test ID to an array of objects containing attachments for each result (retry).
|
|
274
290
|
* The attachments are normalized to use relative paths starting with 'data/'.
|
|
275
291
|
* @param summaryJsonFilePath Path to the summary JSON file
|
|
276
292
|
* @returns Map<string, { attachments: GenericPlaywrightAttachment[] }[]>
|
|
277
293
|
*/
|
|
278
|
-
function buildTestAttachmentMapFromSummary(summaryJsonFilePath) {
|
|
294
|
+
function buildTestAttachmentMapFromSummary(summaryJsonFilePath, repoPath, doNotNormalize = false) {
|
|
279
295
|
const summaryJson = JSON.parse(fs_1.default.readFileSync(summaryJsonFilePath, "utf8"));
|
|
280
296
|
const testAttachmentMap = new Map();
|
|
281
297
|
function normalizeAttachmentPath(attachment) {
|
|
282
298
|
if (!attachment?.path)
|
|
283
299
|
return attachment;
|
|
284
|
-
const relativePath = path_1.default.relative(
|
|
300
|
+
const relativePath = path_1.default.relative(repoPath, attachment.path);
|
|
285
301
|
attachment.path = path_1.default.join("data", relativePath);
|
|
286
302
|
return attachment;
|
|
287
303
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
const resultAttachments = (test.results || []).map((result) => ({
|
|
297
|
-
attachments: (result.attachments || []).map(normalizeAttachmentPath),
|
|
298
|
-
}));
|
|
299
|
-
testAttachmentMap.set(testId, [
|
|
300
|
-
...(testAttachmentMap.get(testId) || []),
|
|
301
|
-
...resultAttachments,
|
|
302
|
-
]);
|
|
304
|
+
const buildTestAttachmentMap = (spec) => {
|
|
305
|
+
const testId = spec.id;
|
|
306
|
+
for (const test of spec.tests) {
|
|
307
|
+
if (!testId) {
|
|
308
|
+
console.warn("⚠️ Test without testId encountered, skipping.");
|
|
309
|
+
continue;
|
|
303
310
|
}
|
|
311
|
+
const resultAttachments = (test.results || []).map((result) => ({
|
|
312
|
+
attachments: (result.attachments || []).map(doNotNormalize ? (a) => a : normalizeAttachmentPath),
|
|
313
|
+
}));
|
|
314
|
+
testAttachmentMap.set(testId, [
|
|
315
|
+
...(testAttachmentMap.get(testId) || []),
|
|
316
|
+
...resultAttachments,
|
|
317
|
+
]);
|
|
304
318
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
for (const suite of summaryJson.suites || []) {
|
|
310
|
-
processSuite(suite);
|
|
311
|
-
}
|
|
319
|
+
};
|
|
320
|
+
traverseJsonReportSuites(summaryJson, buildTestAttachmentMap);
|
|
312
321
|
return testAttachmentMap;
|
|
313
322
|
}
|
|
314
323
|
/**
|
|
@@ -325,3 +334,39 @@ async function checkFileExistsAsync(filePath) {
|
|
|
325
334
|
return false;
|
|
326
335
|
}
|
|
327
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Updates the attachment paths in the summary JSON file to use remote URLs.
|
|
339
|
+
*
|
|
340
|
+
* This function rewrites all attachment `path` fields in the given Playwright summary JSON file
|
|
341
|
+
* so that they point to remote URLs based on the current `PROJECT_NAME` and `TEST_RUN_GITHUB_ACTION_ID`
|
|
342
|
+
* environment variables.
|
|
343
|
+
*
|
|
344
|
+
* @param filePath - The path to the summary JSON file
|
|
345
|
+
* @returns The updated summary JSON
|
|
346
|
+
*
|
|
347
|
+
*/
|
|
348
|
+
async function updateSummaryJsonAttachmentPaths(filePath, repoPath, urlPrefix) {
|
|
349
|
+
if (!process.env.PROJECT_NAME || !process.env.TEST_RUN_GITHUB_ACTION_ID) {
|
|
350
|
+
console.error("PROJECT_NAME and TEST_RUN_GITHUB_ACTION_ID must be set");
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const summaryJson = JSON.parse(await fs_1.default.promises.readFile(filePath, "utf8"));
|
|
354
|
+
const updateAttachmentPath = (spec) => {
|
|
355
|
+
for (const test of spec.tests) {
|
|
356
|
+
for (const result of test.results || []) {
|
|
357
|
+
if (result.attachments) {
|
|
358
|
+
for (const attachment of result.attachments) {
|
|
359
|
+
if (attachment && attachment.path) {
|
|
360
|
+
const relativePath = path_1.default.relative(repoPath, attachment.path);
|
|
361
|
+
const newPath = `${urlPrefix}/${relativePath}`;
|
|
362
|
+
attachment.path = newPath;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
traverseJsonReportSuites(summaryJson, updateAttachmentPath);
|
|
370
|
+
await fs_1.default.promises.writeFile(filePath, JSON.stringify(summaryJson, null, 2), "utf8");
|
|
371
|
+
return summaryJson;
|
|
372
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAO9C,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,qBAAa,mBAAmB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,iBAAiB,CAIhB;gBAEoB,IAAI,EAAE,IAAI;IAEjC,WAAW;IAMX,GAAG,CACP,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;YA4BF,QAAQ;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAO9C,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,qBAAa,mBAAmB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,iBAAiB,CAIhB;gBAEoB,IAAI,EAAE,IAAI;IAEjC,WAAW;IAMX,GAAG,CACP,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;YA4BF,QAAQ;CAwCvB;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B"}
|
|
@@ -75,6 +75,13 @@ class OverlayDismissAgent {
|
|
|
75
75
|
page: this.page,
|
|
76
76
|
task,
|
|
77
77
|
trace,
|
|
78
|
+
// We don't want to use page.pause approach here because
|
|
79
|
+
// overlay dismissal can kick in during a browser agent tool call
|
|
80
|
+
// and we need app to be able to use page.pause for agent actions.
|
|
81
|
+
// Currently, page.pause does not cleanup properly, causing it to work
|
|
82
|
+
// only once in a particular test run.
|
|
83
|
+
// Ran into this here: https://dash.empirical.run/quizizz-tests/sessions/2825
|
|
84
|
+
prefersElementFromPointCodegen: true,
|
|
78
85
|
});
|
|
79
86
|
this.cachingCandidates.push({
|
|
80
87
|
dom: element?.interceptor,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/playwright-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"author": "Empirical Team <hey@empirical.run>",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@playwright/test": "1.53.
|
|
25
|
+
"@playwright/test": "1.53.2",
|
|
26
26
|
"@types/async-retry": "^1.4.8",
|
|
27
27
|
"@types/authenticator": "^1.1.4",
|
|
28
28
|
"@types/babel__code-frame": "^7.0.6",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"@types/node": "^20.14.9",
|
|
31
31
|
"@types/serve-handler": "^6.1.4",
|
|
32
32
|
"@types/adm-zip": "^0.5.7",
|
|
33
|
-
"playwright-core": "1.53.
|
|
33
|
+
"playwright-core": "1.53.2",
|
|
34
34
|
"serve-handler": "^6.1.6",
|
|
35
|
-
"@empiricalrun/shared-types": "0.
|
|
35
|
+
"@empiricalrun/shared-types": "0.7.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@babel/code-frame": "^7.24.7",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"mailosaur": "^8.6.1",
|
|
44
44
|
"puppeteer-extra-plugin-recaptcha": "^3.6.8",
|
|
45
45
|
"rimraf": "^6.0.1",
|
|
46
|
-
"@empiricalrun/llm": "^0.
|
|
46
|
+
"@empiricalrun/llm": "^0.20.0",
|
|
47
47
|
"@empiricalrun/r2-uploader": "^0.3.9",
|
|
48
|
-
"@empiricalrun/test-gen": "^0.
|
|
48
|
+
"@empiricalrun/test-gen": "^0.72.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"dev": "tsc --build --watch",
|