@element-hq/element-web-playwright-common 1.3.0 → 1.4.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/lib/expect/screenshot.d.ts.map +1 -1
- package/lib/expect/screenshot.js +3 -4
- package/lib/stale-screenshot-reporter.d.ts +19 -0
- package/lib/stale-screenshot-reporter.d.ts.map +1 -0
- package/lib/stale-screenshot-reporter.js +78 -0
- package/lib/testcontainers/synapse.d.ts +2 -2
- package/lib/testcontainers/synapse.d.ts.map +1 -1
- package/package.json +13 -2
- package/src/expect/screenshot.ts +4 -4
- package/src/stale-screenshot-reporter.ts +94 -0
- package/src/testcontainers/synapse.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/expect/screenshot.ts"],"names":[],"mappings":"AAQA,OAAO,EAIH,KAAK,kBAAkB,EACvB,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,qCAAqC,EAC1C,KAAK,iBAAiB,EACzB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/expect/screenshot.ts"],"names":[],"mappings":"AAQA,OAAO,EAIH,KAAK,kBAAkB,EACvB,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,qCAAqC,EAC1C,KAAK,iBAAiB,EACzB,MAAM,kBAAkB,CAAC;AAa1B,MAAM,WAAW,wBAAyB,SAAQ,qCAAqC;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG;IACvB,iBAAiB,EAAE,CACf,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,IAAI,GAAG,OAAO,EACxB,IAAI,EAAE,GAAG,MAAM,MAAM,EACrB,OAAO,CAAC,EAAE,wBAAwB,KACjC,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,MAAM,gDA+BjB,CAAC"}
|
package/lib/expect/screenshot.js
CHANGED
|
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
|
|
8
8
|
import { test, expect as baseExpect, } from "@playwright/test";
|
|
9
9
|
import { sanitizeForFilePath } from "playwright-core/lib/utils";
|
|
10
10
|
import { extname } from "node:path";
|
|
11
|
+
import { ANNOTATION } from "../stale-screenshot-reporter.js";
|
|
11
12
|
// Based on https://github.com/microsoft/playwright/blob/2b77ed4d7aafa85a600caa0b0d101b72c8437eeb/packages/playwright/src/util.ts#L206C8-L210C2
|
|
12
13
|
function sanitizeFilePathBeforeExtension(filePath) {
|
|
13
14
|
const ext = extname(filePath);
|
|
@@ -38,10 +39,8 @@ export const expect = baseExpect.extend({
|
|
|
38
39
|
await baseExpect(receiver).toHaveScreenshot(screenshotName, options);
|
|
39
40
|
await style?.evaluate((tag) => tag.remove());
|
|
40
41
|
testInfo.annotations.push({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// include a path relative to `playwright/snapshots/`
|
|
44
|
-
description: testInfo.snapshotPath(screenshotName).split("/playwright/snapshots/", 2)[1],
|
|
42
|
+
type: ANNOTATION,
|
|
43
|
+
description: testInfo.snapshotPath(screenshotName),
|
|
45
44
|
});
|
|
46
45
|
return { pass: true, message: () => "", name: "toMatchScreenshot" };
|
|
47
46
|
},
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Reporter, type TestCase } from "@playwright/test/reporter";
|
|
2
|
+
import { type FullConfig } from "@playwright/test";
|
|
3
|
+
/**
|
|
4
|
+
* The annotation type used to mark screenshots in tests.
|
|
5
|
+
* `_` prefix hides it from the HTML reporter
|
|
6
|
+
*/
|
|
7
|
+
export declare const ANNOTATION = "_screenshot";
|
|
8
|
+
declare class StaleScreenshotReporter implements Reporter {
|
|
9
|
+
private readonly snapshotRoots;
|
|
10
|
+
private readonly screenshots;
|
|
11
|
+
private failing;
|
|
12
|
+
private success;
|
|
13
|
+
onBegin(config: FullConfig): void;
|
|
14
|
+
onTestEnd(test: TestCase): void;
|
|
15
|
+
private error;
|
|
16
|
+
onExit(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export default StaleScreenshotReporter;
|
|
19
|
+
//# sourceMappingURL=stale-screenshot-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-screenshot-reporter.d.ts","sourceRoot":"","sources":["../src/stale-screenshot-reporter.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,UAAU,gBAAgB,CAAC;AAExC,cAAM,uBAAwB,YAAW,QAAQ;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAQ;IAEhB,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAMjC,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAWtC,OAAO,CAAC,KAAK;IAQA,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAoCvC;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 - 2025 New Vector Ltd.
|
|
3
|
+
Copyright 2024 The Matrix.org Foundation C.I.C.
|
|
4
|
+
|
|
5
|
+
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
6
|
+
Please see LICENSE files in the repository root for full details.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Test reporter which compares the reported screenshots vs those on disk to find stale screenshots
|
|
10
|
+
* Only intended to run from within GitHub Actions
|
|
11
|
+
*/
|
|
12
|
+
import { glob } from "glob";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
/**
|
|
15
|
+
* The annotation type used to mark screenshots in tests.
|
|
16
|
+
* `_` prefix hides it from the HTML reporter
|
|
17
|
+
*/
|
|
18
|
+
export const ANNOTATION = "_screenshot";
|
|
19
|
+
class StaleScreenshotReporter {
|
|
20
|
+
snapshotRoots = new Set();
|
|
21
|
+
screenshots = new Set();
|
|
22
|
+
failing = false;
|
|
23
|
+
success = true;
|
|
24
|
+
onBegin(config) {
|
|
25
|
+
for (const project of config.projects) {
|
|
26
|
+
this.snapshotRoots.add(project.snapshotDir);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
onTestEnd(test) {
|
|
30
|
+
if (!test.ok()) {
|
|
31
|
+
this.failing = true;
|
|
32
|
+
}
|
|
33
|
+
for (const annotation of test.annotations) {
|
|
34
|
+
if (annotation.type === ANNOTATION && annotation.description) {
|
|
35
|
+
this.screenshots.add(annotation.description);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
error(msg, file) {
|
|
40
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
41
|
+
console.log(`::error file=${file}::${msg}`);
|
|
42
|
+
}
|
|
43
|
+
console.error(msg, file);
|
|
44
|
+
this.success = false;
|
|
45
|
+
}
|
|
46
|
+
async onExit() {
|
|
47
|
+
if (this.failing)
|
|
48
|
+
return;
|
|
49
|
+
if (!this.snapshotRoots.size) {
|
|
50
|
+
this.error("No snapshot directories found, did you set the snapshotDir in your Playwright config?", "");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const screenshotFiles = new Set();
|
|
54
|
+
for (const snapshotRoot of this.snapshotRoots) {
|
|
55
|
+
const files = await glob(`**/*.png`, { cwd: snapshotRoot });
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
screenshotFiles.add(path.join(snapshotRoot, file));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const screenshot of screenshotFiles) {
|
|
61
|
+
if (screenshot.split("-").at(-1) !== "linux.png") {
|
|
62
|
+
this.error("Found screenshot belonging to different platform, this should not be checked in", screenshot);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const screenshot of this.screenshots) {
|
|
66
|
+
screenshotFiles.delete(screenshot);
|
|
67
|
+
}
|
|
68
|
+
if (screenshotFiles.size > 0) {
|
|
69
|
+
for (const screenshot of screenshotFiles) {
|
|
70
|
+
this.error("Stale screenshot file", screenshot);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!this.success) {
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export default StaleScreenshotReporter;
|
|
@@ -151,8 +151,8 @@ export type SynapseConfig = typeof DEFAULT_CONFIG;
|
|
|
151
151
|
* Waits for HTTP /health 8008 to 200.
|
|
152
152
|
*/
|
|
153
153
|
export declare class SynapseContainer extends GenericContainer implements HomeserverContainer<SynapseConfig> {
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
protected config: SynapseConfig;
|
|
155
|
+
protected mas?: StartedMatrixAuthenticationServiceContainer;
|
|
156
156
|
constructor(image?: string);
|
|
157
157
|
withConfigField(key: string, value: unknown): this;
|
|
158
158
|
withConfig(config: Partial<SynapseConfig>): this;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synapse.d.ts","sourceRoot":"","sources":["../../src/testcontainers/synapse.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQzE,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,KAAK,2CAA2C,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,GAAG,EAAE,eAAe,EAAa,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA2GV,SAAS,GACT;QACI,aAAa,EAAE,OAAO,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,0BAA0B,EAAE,KAAK,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,eAAe,EAAE,MAAM,CAAC;KAC3B;kBAED,SAAS,GACT;QACI,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/C,4BAA4B,EAAE,OAAO,CAAC;QACtC,kBAAkB,EAAE,MAAM,CAAC;QAC3B,uBAAuB,EAAE,OAAO,CAAC;KACpC;oBAED,SAAS,GACT;QACI,qBAAqB,EAAE,MAAM,CAAC;QAC9B,wBAAwB,EAAE,MAAM,CAAC;QACjC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC;KACrB;;;;;;;;;;;;CAUV,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC;AAElD;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,gBAAiB,YAAW,mBAAmB,CAAC,aAAa,CAAC;IAChG,
|
|
1
|
+
{"version":3,"file":"synapse.d.ts","sourceRoot":"","sources":["../../src/testcontainers/synapse.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@element-hq/element-web-playwright-common",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"license": "SEE LICENSE IN README.md",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -12,7 +12,18 @@
|
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=20.0.0"
|
|
14
14
|
},
|
|
15
|
-
"
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./lib/index.js",
|
|
18
|
+
"require": "./lib/index.js",
|
|
19
|
+
"types": "./lib/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./stale-screenshot-reporter": {
|
|
22
|
+
"import": "./lib/stale-screenshot-reporter.js",
|
|
23
|
+
"require": "./lib/stale-screenshot-reporter.js",
|
|
24
|
+
"types": "./lib/stale-screenshot-reporter.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
16
27
|
"bin": {
|
|
17
28
|
"playwright-screenshots": "playwright-screenshots.sh"
|
|
18
29
|
},
|
package/src/expect/screenshot.ts
CHANGED
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
import { sanitizeForFilePath } from "playwright-core/lib/utils";
|
|
20
20
|
import { extname } from "node:path";
|
|
21
21
|
|
|
22
|
+
import { ANNOTATION } from "../stale-screenshot-reporter.js";
|
|
23
|
+
|
|
22
24
|
// Based on https://github.com/microsoft/playwright/blob/2b77ed4d7aafa85a600caa0b0d101b72c8437eeb/packages/playwright/src/util.ts#L206C8-L210C2
|
|
23
25
|
function sanitizeFilePathBeforeExtension(filePath: string): string {
|
|
24
26
|
const ext = extname(filePath);
|
|
@@ -68,10 +70,8 @@ export const expect = baseExpect.extend<Expectations>({
|
|
|
68
70
|
await style?.evaluate((tag) => tag.remove());
|
|
69
71
|
|
|
70
72
|
testInfo.annotations.push({
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// include a path relative to `playwright/snapshots/`
|
|
74
|
-
description: testInfo.snapshotPath(screenshotName).split("/playwright/snapshots/", 2)[1],
|
|
73
|
+
type: ANNOTATION,
|
|
74
|
+
description: testInfo.snapshotPath(screenshotName),
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
return { pass: true, message: (): string => "", name: "toMatchScreenshot" };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 - 2025 New Vector Ltd.
|
|
3
|
+
Copyright 2024 The Matrix.org Foundation C.I.C.
|
|
4
|
+
|
|
5
|
+
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
6
|
+
Please see LICENSE files in the repository root for full details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Test reporter which compares the reported screenshots vs those on disk to find stale screenshots
|
|
11
|
+
* Only intended to run from within GitHub Actions
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { glob } from "glob";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { type Reporter, type TestCase } from "@playwright/test/reporter";
|
|
17
|
+
import { type FullConfig } from "@playwright/test";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The annotation type used to mark screenshots in tests.
|
|
21
|
+
* `_` prefix hides it from the HTML reporter
|
|
22
|
+
*/
|
|
23
|
+
export const ANNOTATION = "_screenshot";
|
|
24
|
+
|
|
25
|
+
class StaleScreenshotReporter implements Reporter {
|
|
26
|
+
private readonly snapshotRoots = new Set<string>();
|
|
27
|
+
private readonly screenshots = new Set<string>();
|
|
28
|
+
private failing = false;
|
|
29
|
+
private success = true;
|
|
30
|
+
|
|
31
|
+
public onBegin(config: FullConfig): void {
|
|
32
|
+
for (const project of config.projects) {
|
|
33
|
+
this.snapshotRoots.add(project.snapshotDir);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public onTestEnd(test: TestCase): void {
|
|
38
|
+
if (!test.ok()) {
|
|
39
|
+
this.failing = true;
|
|
40
|
+
}
|
|
41
|
+
for (const annotation of test.annotations) {
|
|
42
|
+
if (annotation.type === ANNOTATION && annotation.description) {
|
|
43
|
+
this.screenshots.add(annotation.description);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private error(msg: string, file: string) {
|
|
49
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
50
|
+
console.log(`::error file=${file}::${msg}`);
|
|
51
|
+
}
|
|
52
|
+
console.error(msg, file);
|
|
53
|
+
this.success = false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public async onExit(): Promise<void> {
|
|
57
|
+
if (this.failing) return;
|
|
58
|
+
if (!this.snapshotRoots.size) {
|
|
59
|
+
this.error("No snapshot directories found, did you set the snapshotDir in your Playwright config?", "");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const screenshotFiles = new Set<string>();
|
|
64
|
+
for (const snapshotRoot of this.snapshotRoots) {
|
|
65
|
+
const files = await glob(`**/*.png`, { cwd: snapshotRoot });
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
screenshotFiles.add(path.join(snapshotRoot, file));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const screenshot of screenshotFiles) {
|
|
72
|
+
if (screenshot.split("-").at(-1) !== "linux.png") {
|
|
73
|
+
this.error(
|
|
74
|
+
"Found screenshot belonging to different platform, this should not be checked in",
|
|
75
|
+
screenshot,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const screenshot of this.screenshots) {
|
|
80
|
+
screenshotFiles.delete(screenshot);
|
|
81
|
+
}
|
|
82
|
+
if (screenshotFiles.size > 0) {
|
|
83
|
+
for (const screenshot of screenshotFiles) {
|
|
84
|
+
this.error("Stale screenshot file", screenshot);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!this.success) {
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default StaleScreenshotReporter;
|
|
@@ -188,8 +188,8 @@ export type SynapseConfig = typeof DEFAULT_CONFIG;
|
|
|
188
188
|
* Waits for HTTP /health 8008 to 200.
|
|
189
189
|
*/
|
|
190
190
|
export class SynapseContainer extends GenericContainer implements HomeserverContainer<SynapseConfig> {
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
protected config: SynapseConfig;
|
|
192
|
+
protected mas?: StartedMatrixAuthenticationServiceContainer;
|
|
193
193
|
|
|
194
194
|
public constructor(image = "ghcr.io/element-hq/synapse:develop") {
|
|
195
195
|
super(image);
|