@public-ui/visual-tests 1.7.0-rc.9 → 1.7.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/README.md CHANGED
@@ -36,6 +36,12 @@ In the following runs, new screenshots will be compared to this reference.
36
36
 
37
37
  To update the reference screenshots call `npm run test-update`.
38
38
 
39
+ It's recommended to add the `test-results` folder to the `.gitignore` file:
40
+
41
+ ```bash
42
+ /test-results/
43
+ ```
44
+
39
45
  It's also recommended to automatically run the tests before packing/publishing the module:
40
46
 
41
47
  ```json
package/package.json CHANGED
@@ -1,46 +1,49 @@
1
1
  {
2
- "name": "@public-ui/visual-tests",
3
- "version": "1.7.0-rc.9",
4
- "license": "EUPL-1.2",
5
- "homepage": "https://public-ui.github.io",
6
- "repository": "https://github.com/public-ui/kolibri",
7
- "bugs": {
8
- "url": "https://github.com/public-ui/kolibri/issues",
9
- "email": "kolibri@itzbund.de"
10
- },
11
- "author": {
12
- "name": "Informationstechnikzentrum Bund",
13
- "email": "kolibri@itzbund.de"
14
- },
15
- "type": "module",
16
- "sideEffects": false,
17
- "description": "Provides utility to run visual regression tests for themes.",
18
- "scripts": {
19
- "depcheck": "depcheck --ignores=@public-ui/sample-react,http-server,tslib",
20
- "format": "prettier --check src",
21
- "lint": "eslint src",
22
- "unused": "knip"
23
- },
24
- "bin": {
25
- "kolibri-visual-test": "src/index.js"
26
- },
27
- "dependencies": {
28
- "@playwright/test": "1.37.1",
29
- "@public-ui/sample-react": "1.7.0-rc.9",
30
- "http-server": "14.1.1",
31
- "portfinder": "1.0.32"
32
- },
33
- "devDependencies": {
34
- "@babel/eslint-parser": "7.22.15",
35
- "depcheck": "1.4.6",
36
- "eslint": "8.49.0",
37
- "eslint-plugin-no-loops": "0.3.0",
38
- "knip": "2.24.0",
39
- "prettier": "3.0.3"
40
- },
41
- "files": [
42
- "playwright.config.js",
43
- "src",
44
- "tests"
45
- ]
46
- }
2
+ "name": "@public-ui/visual-tests",
3
+ "version": "1.7.0",
4
+ "license": "EUPL-1.2",
5
+ "homepage": "https://public-ui.github.io",
6
+ "repository": "https://github.com/public-ui/kolibri",
7
+ "bugs": {
8
+ "url": "https://github.com/public-ui/kolibri/issues",
9
+ "email": "kolibri@itzbund.de"
10
+ },
11
+ "author": {
12
+ "name": "Informationstechnikzentrum Bund",
13
+ "email": "kolibri@itzbund.de"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "description": "Provides utility to run visual regression tests for themes.",
18
+ "bin": {
19
+ "kolibri-visual-test": "src/index.js"
20
+ },
21
+ "dependencies": {
22
+ "@playwright/test": "1.38.1",
23
+ "@public-ui/sample-react": "1.7.0",
24
+ "portfinder": "1.0.32",
25
+ "serve": "14.2.1"
26
+ },
27
+ "devDependencies": {
28
+ "@babel/eslint-parser": "7.22.15",
29
+ "@babel/plugin-syntax-import-attributes": "7.22.5",
30
+ "@babel/preset-env": "7.22.20",
31
+ "axe-playwright": "1.2.3",
32
+ "depcheck": "1.4.6",
33
+ "eslint": "8.50.0",
34
+ "eslint-plugin-no-loops": "0.3.0",
35
+ "knip": "2.30.0",
36
+ "prettier": "3.0.3"
37
+ },
38
+ "files": [
39
+ "playwright.config.js",
40
+ "src",
41
+ "tests"
42
+ ],
43
+ "scripts": {
44
+ "depcheck": "depcheck --ignores=@babel/plugin-syntax-import-attributes,@babel/preset-env,@public-ui/sample-react,portfinder,serve",
45
+ "format": "prettier --check src",
46
+ "lint": "eslint src",
47
+ "unused": "knip"
48
+ }
49
+ }
@@ -20,7 +20,7 @@ export default defineConfig({
20
20
  /* Fail the build on CI if you accidentally left test.only in the source code. */
21
21
  forbidOnly: !!process.env.CI,
22
22
  /* Retry on CI only */
23
- retries: 0, // process.env.CI ? 2 : 0,
23
+ retries: process.env.CI ? 2 : 0,
24
24
  /* Opt out of parallel tests on CI. */
25
25
  workers: process.env.CI ? 1 : undefined,
26
26
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
@@ -52,7 +52,7 @@ export default defineConfig({
52
52
 
53
53
  /* Run your local dev server before starting the tests */
54
54
  webServer: {
55
- command: `http-server ${process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH} -p ${PORT}`,
55
+ command: `serve ${process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH} -p ${PORT}`,
56
56
  url: URL,
57
57
  reuseExistingServer: false,
58
58
  },
package/src/index.js CHANGED
@@ -19,11 +19,31 @@ if (!tempDir) {
19
19
  process.env.THEME_MODULE = path.join(process.cwd(), process.env.THEME_MODULE); // Use current working directory (i.e. the theme folder) to complete module path
20
20
  const visualsTestModulePath = fileURLToPath(new URL('..', import.meta.url));
21
21
  const binaryPath = fileURLToPath(new URL('../node_modules/.bin', import.meta.url));
22
+
23
+ let sampleReactPath = '../node_modules/@public-ui/sample-react';
24
+ let backSteps = ``;
25
+ let workingDir = null;
26
+ do {
27
+ const url = new URL(backSteps + sampleReactPath, import.meta.url);
28
+ workingDir = fileURLToPath(url);
29
+ backSteps += `../`;
30
+ } while (!fs.existsSync(workingDir) && path.resolve(process.cwd(), backSteps) !== '/');
31
+
32
+ if (!fs.existsSync(workingDir)) {
33
+ throw new Error('Could not find React Sample App package. Please install it with "npm install @public-ui/sample-react".');
34
+ }
35
+
22
36
  const buildPath = path.join(tempDir, `kolibri-visual-testing-build-${crypto.randomUUID()}`);
37
+ const packageJsonPath = await import(new URL(`${workingDir}/package.json`, import.meta.url), {
38
+ assert: { type: 'json' },
39
+ });
40
+
23
41
  process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH = buildPath;
24
42
 
25
- console.log('Building React Sample App …');
26
- child_process.execFileSync(path.join(binaryPath, 'kolibri-sample-react-test-build'), [buildPath], {
43
+ console.log(`
44
+ Building React Sample App (v${packageJsonPath?.default?.version ?? '#.#.#'}) …`);
45
+ child_process.execFileSync('npm', ['run', 'build', '--', `--output-path=${buildPath}`], {
46
+ cwd: workingDir,
27
47
  encoding: 'utf-8',
28
48
  });
29
49
 
@@ -46,8 +66,15 @@ void (async () => {
46
66
 
47
67
  playwright.on('exit', (code) => {
48
68
  console.log(`Playwright test finished with exit code ${code}.`);
49
- console.log('Cleaning up build folder …');
50
- fs.rmSync(buildPath, { recursive: true, force: true });
69
+
70
+ if (process.env.KOLIBRI_CLEANUP === '0') {
71
+ console.log('Skipping cleanup up build folder.');
72
+ console.log(`You can serve this build with "npx serve ${buildPath}".`);
73
+ } else {
74
+ console.log('Cleaning up build folder …');
75
+ fs.rmSync(buildPath, { recursive: true, force: true });
76
+ console.log('Cleaning up finished successfully.');
77
+ }
51
78
  process.exit(code ?? 1);
52
79
  });
53
80
  })();
@@ -0,0 +1,82 @@
1
+ import { test } from '@playwright/test';
2
+ import { checkA11y, injectAxe } from 'axe-playwright';
3
+ import path from 'path';
4
+ import { ROUTES } from './sample-app.routes.js';
5
+
6
+ const rename = (snapshotName) => {
7
+ const result = snapshotName
8
+
9
+ // Remove browser name from snapshot name
10
+ // .replace('-chromium', '')
11
+ // .replace('-firefox', '')
12
+
13
+ // Remove os name from snapshot name
14
+ // .replace('-darwin', '')
15
+ // .replace('-linux', '')
16
+ // .replace('-windows', '')
17
+
18
+ // Remove test counter from snapshot name
19
+ .replace('-1-', '-')
20
+
21
+ // Make different snapshot folder for different themes
22
+ .replace('theme-snapshots.spec.js', `axe-${process.env.THEME_EXPORT.toLocaleLowerCase()}`)
23
+ .replace('-snapshots', '');
24
+ return result;
25
+ };
26
+
27
+ // https://playwright.dev/docs/emulation
28
+ test.use({
29
+ colorScheme: 'light',
30
+ locale: 'de-DE',
31
+ isMobile: false,
32
+ timezoneId: 'Europe/Berlin',
33
+ viewport: {
34
+ width: 800,
35
+ height: 0,
36
+ },
37
+ });
38
+
39
+ /**
40
+ * @todo stabilize and re-enable test
41
+ */
42
+ const blocklist = [];
43
+
44
+ ROUTES.forEach((options, route) => {
45
+ if (blocklist.includes(route)) {
46
+ return;
47
+ }
48
+ test(`snapshot for ${route}`, async ({ page }, testInfo) => {
49
+ const outputPath = rename(testInfo.outputDir);
50
+ await page.goto(`/#${route}?hideMenus`, { waitUntil: 'networkidle' });
51
+ if (options?.viewportSize) {
52
+ await page.setViewportSize(options.viewportSize);
53
+ }
54
+ if (options?.waitForTimeout) {
55
+ await page.waitForTimeout(options.waitForTimeout);
56
+ }
57
+ await injectAxe(page);
58
+ await checkA11y(
59
+ page,
60
+ undefined,
61
+ {
62
+ axeOptions: {
63
+ runOnly: {
64
+ type: 'tag',
65
+ values: ['best-practices', 'wcag2a', 'wcag2aa', 'wcag21aa'],
66
+ },
67
+ },
68
+ detailedReport: true,
69
+ detailedReportOptions: {
70
+ html: true,
71
+ },
72
+ },
73
+ options?.axe?.skipFailures ?? true,
74
+ 'html',
75
+ {
76
+ outputDirPath: outputPath.replace(/\/[^/]+$/, ''),
77
+ outputDir: `axe-${process.env.THEME_EXPORT.toLocaleLowerCase()}`,
78
+ reportFileName: `${route.replace('/', '-')}.html`,
79
+ },
80
+ );
81
+ });
82
+ });
@@ -1,80 +1,387 @@
1
- export const ROUTES = [
2
- '/handout/basic',
3
- '/abbr/basic',
4
- '/accordion/basic',
5
- '/accordion/header',
6
- '/accordion/headlines',
7
- '/accordion/list',
8
- '/alert/basic',
9
- '/alert/card-msg',
10
- '/alert/html',
11
- '/avatar/basic',
12
- '/badge/basic',
13
- '/badge/button',
14
- '/breadcrumb/basic',
15
- '/button/basic',
16
- '/button/hide-label',
17
- '/button/icons',
18
- '/button/width',
19
- '/button-link/basic',
20
- '/button-link/icons',
21
- '/button-link/image',
22
- '/button-link/target',
23
- '/button-group/basic',
24
- '/card/basic',
25
- '/card/confirm',
26
- '/card/flex',
27
- '/card/selection',
28
- '/details/basic',
29
- '/heading/badge',
30
- '/heading/basic',
31
- '/heading/paragraph',
32
- '/icon/basic',
33
- '/indented-text/basic',
34
- '/input-checkbox/basic',
35
- '/input-color/basic',
36
- '/input-date/basic',
37
- '/input-email/basic',
38
- '/input-file/basic',
39
- '/input-number/basic',
40
- '/input-password/basic',
41
- '/input-password/show-password',
42
- '/input-radio/basic',
43
- '/input-radio/horizontal',
44
- '/input-radio/select',
45
- '/input-range/basic',
46
- '/input-text/basic',
47
- '/input-text/hidden-label',
48
- '/input-text/blur',
49
- '/input-text/focus',
50
- '/link/basic',
51
- '/link/icons',
52
- '/link/image',
53
- '/link/target',
54
- '/link-button/basic',
55
- '/nav/basic',
56
- '/nav/active',
57
- '/nav/aria-current',
58
- '/nav/horizontal',
59
- '/pagination/basic',
60
- '/popover/basic',
61
- '/progress/basic',
62
- '/select/basic',
63
- '/skip-nav/basic',
64
- '/spin/basic',
65
- '/spin/cycle',
66
- '/spin/custom',
67
- '/split-button/basic',
68
- '/table/badge-size',
69
- '/table/render-cell',
70
- '/table/sort-data',
71
- '/textarea/basic',
72
- '/textarea/adjust-height',
73
- '/textarea/disabled',
74
- '/textarea/placeholder',
75
- '/textarea/readonly',
76
- '/textarea/resize',
77
- '/textarea/rows',
78
- '/version/basic',
79
- '/version/context',
80
- ];
1
+ export const ROUTES = new Map();
2
+
3
+ /**
4
+ * Actually we support the following options:
5
+ *
6
+ * Details: https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1
7
+ * - fullPage: boolean (Default: true)
8
+ * - maxDiffPixelRatio: number (Default: undefined)
9
+ * - maxDiffPixels: number (Default: undefined)
10
+ * - threshold: number (Default: undefined)
11
+ * - timeout: number (Default: 0)
12
+ *
13
+ * To set the viewport size, use the following options:
14
+ * - viewportSize: { width, height } (Default: 800x600)
15
+ *
16
+ */
17
+
18
+ ROUTES.set('handout/basic', {
19
+ viewportSize: {
20
+ width: 1920,
21
+ height: 1280,
22
+ },
23
+ waitForTimeout: 500,
24
+ });
25
+ ROUTES.set('abbr/basic', {
26
+ axe: {
27
+ skipFailures: false,
28
+ },
29
+ });
30
+ ROUTES.set('accordion/basic', null);
31
+ ROUTES.set('accordion/header', {
32
+ axe: {
33
+ skipFailures: false,
34
+ },
35
+ });
36
+ ROUTES.set('accordion/headlines', {
37
+ axe: {
38
+ skipFailures: false,
39
+ },
40
+ });
41
+ ROUTES.set('accordion/list', {
42
+ axe: {
43
+ skipFailures: false,
44
+ },
45
+ });
46
+ ROUTES.set('alert/basic', {
47
+ axe: {
48
+ skipFailures: false,
49
+ },
50
+ });
51
+ ROUTES.set('alert/card-msg', {
52
+ axe: {
53
+ skipFailures: false,
54
+ },
55
+ });
56
+ ROUTES.set('alert/html', {
57
+ axe: {
58
+ skipFailures: false,
59
+ },
60
+ });
61
+ ROUTES.set('avatar/basic', {
62
+ axe: {
63
+ skipFailures: false,
64
+ },
65
+ });
66
+ ROUTES.set('badge/basic', null);
67
+ ROUTES.set('badge/button', null);
68
+ ROUTES.set('breadcrumb/basic', {
69
+ axe: {
70
+ skipFailures: false,
71
+ },
72
+ });
73
+ ROUTES.set('button-group/basic', {
74
+ axe: {
75
+ skipFailures: false,
76
+ },
77
+ });
78
+ ROUTES.set('button-link/basic', {
79
+ axe: {
80
+ skipFailures: false,
81
+ },
82
+ });
83
+ ROUTES.set('button-link/icons', {
84
+ axe: {
85
+ skipFailures: false,
86
+ },
87
+ });
88
+ ROUTES.set('button-link/image', {
89
+ axe: {
90
+ skipFailures: false,
91
+ },
92
+ });
93
+ ROUTES.set('button/basic', {
94
+ axe: {
95
+ skipFailures: false,
96
+ },
97
+ });
98
+ ROUTES.set('button/hide-label', {
99
+ axe: {
100
+ skipFailures: false,
101
+ },
102
+ });
103
+ ROUTES.set('button/icons', {
104
+ axe: {
105
+ skipFailures: false,
106
+ },
107
+ });
108
+ ROUTES.set('button/width', {
109
+ axe: {
110
+ skipFailures: false,
111
+ },
112
+ });
113
+ ROUTES.set('card/basic', {
114
+ axe: {
115
+ skipFailures: false,
116
+ },
117
+ });
118
+ ROUTES.set('card/confirm', {
119
+ axe: {
120
+ skipFailures: false,
121
+ },
122
+ });
123
+ ROUTES.set('card/flex', {
124
+ axe: {
125
+ skipFailures: false,
126
+ },
127
+ });
128
+ ROUTES.set('card/selection', {
129
+ axe: {
130
+ skipFailures: false,
131
+ },
132
+ });
133
+ ROUTES.set('details/basic', {
134
+ axe: {
135
+ skipFailures: false,
136
+ },
137
+ });
138
+ ROUTES.set('heading/badge', {
139
+ axe: {
140
+ skipFailures: false,
141
+ },
142
+ });
143
+ ROUTES.set('heading/basic', {
144
+ axe: {
145
+ skipFailures: false,
146
+ },
147
+ });
148
+ ROUTES.set('heading/paragraph', {
149
+ axe: {
150
+ skipFailures: false,
151
+ },
152
+ });
153
+ ROUTES.set('icon/basic', {
154
+ axe: {
155
+ skipFailures: false,
156
+ },
157
+ });
158
+ ROUTES.set('image/basic', {
159
+ axe: {
160
+ skipFailures: false,
161
+ },
162
+ });
163
+ ROUTES.set('indented-text/basic', {
164
+ axe: {
165
+ skipFailures: false,
166
+ },
167
+ });
168
+ ROUTES.set('input-checkbox/basic', null);
169
+ ROUTES.set('input-checkbox/button', null);
170
+ ROUTES.set('input-checkbox/switch', null);
171
+ ROUTES.set('input-color/basic', null);
172
+ ROUTES.set('input-date/basic', null);
173
+ ROUTES.set('input-email/basic', null);
174
+ ROUTES.set('input-file/basic', null);
175
+ ROUTES.set('input-number/basic', null);
176
+ ROUTES.set('input-password/basic', null);
177
+ ROUTES.set('input-password/show-password', null);
178
+ ROUTES.set('input-radio/basic', null);
179
+ ROUTES.set('input-radio/horizontal', null);
180
+ ROUTES.set('input-radio/select', null);
181
+ ROUTES.set('input-range/basic', null);
182
+ ROUTES.set('input-text/basic', null);
183
+ ROUTES.set('input-text/blur', null);
184
+ ROUTES.set('input-text/focus', null);
185
+ ROUTES.set('kolibri/animated', {
186
+ axe: {
187
+ skipFailures: false,
188
+ },
189
+ });
190
+ ROUTES.set('kolibri/basic', {
191
+ axe: {
192
+ skipFailures: false,
193
+ },
194
+ });
195
+ ROUTES.set('kolibri/no-label', {
196
+ axe: {
197
+ skipFailures: false,
198
+ },
199
+ });
200
+ ROUTES.set('link-button/basic', {
201
+ axe: {
202
+ skipFailures: false,
203
+ },
204
+ });
205
+ ROUTES.set('link-group/basic', {
206
+ axe: {
207
+ skipFailures: false,
208
+ },
209
+ });
210
+ ROUTES.set('link-group/horizontal', {
211
+ axe: {
212
+ skipFailures: false,
213
+ },
214
+ });
215
+ ROUTES.set('link/basic', {
216
+ axe: {
217
+ skipFailures: false,
218
+ },
219
+ });
220
+ ROUTES.set('link/icons', {
221
+ axe: {
222
+ skipFailures: false,
223
+ },
224
+ });
225
+ ROUTES.set('link/image', {
226
+ axe: {
227
+ skipFailures: false,
228
+ },
229
+ });
230
+ ROUTES.set('link/target', {
231
+ axe: {
232
+ skipFailures: false,
233
+ },
234
+ });
235
+ ROUTES.set('logo/basic', {
236
+ axe: {
237
+ skipFailures: false,
238
+ },
239
+ });
240
+ ROUTES.set('modal/basic', {
241
+ axe: {
242
+ skipFailures: false,
243
+ },
244
+ });
245
+ ROUTES.set('nav/active', {
246
+ axe: {
247
+ skipFailures: false,
248
+ },
249
+ });
250
+ ROUTES.set('nav/aria-current', {
251
+ axe: {
252
+ skipFailures: false,
253
+ },
254
+ });
255
+ ROUTES.set('nav/basic', null);
256
+ ROUTES.set('nav/horizontal', {
257
+ axe: {
258
+ skipFailures: false,
259
+ },
260
+ });
261
+ ROUTES.set('pagination/basic', {
262
+ axe: {
263
+ skipFailures: false,
264
+ },
265
+ });
266
+ ROUTES.set('popover/basic', {
267
+ axe: {
268
+ skipFailures: false,
269
+ },
270
+ });
271
+ ROUTES.set('progress/basic', {
272
+ axe: {
273
+ skipFailures: false,
274
+ },
275
+ });
276
+ ROUTES.set('quote/basic', {
277
+ axe: {
278
+ skipFailures: false,
279
+ },
280
+ });
281
+ ROUTES.set('quote/block', {
282
+ axe: {
283
+ skipFailures: false,
284
+ },
285
+ });
286
+ ROUTES.set('select/basic', null);
287
+ ROUTES.set('skip-nav/basic', {
288
+ axe: {
289
+ skipFailures: false,
290
+ },
291
+ });
292
+ ROUTES.set('spin/basic', {
293
+ axe: {
294
+ skipFailures: false,
295
+ },
296
+ });
297
+ ROUTES.set('spin/custom', {
298
+ axe: {
299
+ skipFailures: false,
300
+ },
301
+ });
302
+ ROUTES.set('spin/cycle', {
303
+ axe: {
304
+ skipFailures: false,
305
+ },
306
+ });
307
+ ROUTES.set('split-button/basic', {
308
+ axe: {
309
+ skipFailures: false,
310
+ },
311
+ });
312
+ ROUTES.set('table/badge-size', {
313
+ axe: {
314
+ skipFailures: false,
315
+ },
316
+ });
317
+ ROUTES.set('table/render-cell', {
318
+ axe: {
319
+ skipFailures: false,
320
+ },
321
+ });
322
+ ROUTES.set('table/sort-data', {
323
+ axe: {
324
+ skipFailures: false,
325
+ },
326
+ });
327
+ ROUTES.set('tabs/basic', {
328
+ axe: {
329
+ skipFailures: false,
330
+ },
331
+ });
332
+ ROUTES.set('tabs/icons-only', {
333
+ axe: {
334
+ skipFailures: false,
335
+ },
336
+ });
337
+ ROUTES.set('textarea/adjust-height', {
338
+ axe: {
339
+ skipFailures: false,
340
+ },
341
+ });
342
+ ROUTES.set('textarea/basic', null);
343
+ ROUTES.set('textarea/disabled', {
344
+ axe: {
345
+ skipFailures: false,
346
+ },
347
+ });
348
+ ROUTES.set('textarea/placeholder', {
349
+ axe: {
350
+ skipFailures: false,
351
+ },
352
+ });
353
+ ROUTES.set('textarea/readonly', {
354
+ axe: {
355
+ skipFailures: false,
356
+ },
357
+ });
358
+ ROUTES.set('textarea/resize', {
359
+ axe: {
360
+ skipFailures: false,
361
+ },
362
+ });
363
+ ROUTES.set('textarea/rows', {
364
+ axe: {
365
+ skipFailures: false,
366
+ },
367
+ });
368
+ ROUTES.set('textarea/with-counter', {
369
+ axe: {
370
+ skipFailures: false,
371
+ },
372
+ });
373
+ ROUTES.set('toast/basic', {
374
+ axe: {
375
+ skipFailures: false,
376
+ },
377
+ });
378
+ ROUTES.set('version/basic', {
379
+ axe: {
380
+ skipFailures: false,
381
+ },
382
+ });
383
+ ROUTES.set('version/context', {
384
+ axe: {
385
+ skipFailures: false,
386
+ },
387
+ });
@@ -4,6 +4,7 @@ import { ROUTES } from './sample-app.routes.js';
4
4
  // https://github.com/microsoft/playwright/issues/7575#issuecomment-1288164474
5
5
  export const configureSnapshotPath =
6
6
  () =>
7
+ // eslint-disable-next-line no-empty-pattern
7
8
  ({}, testInfo) => {
8
9
  const originalSnapshotPath = testInfo.snapshotPath;
9
10
  testInfo.snapshotPath = (snapshotName) => {
@@ -15,33 +16,55 @@ export const configureSnapshotPath =
15
16
  // .replace('-firefox', '')
16
17
 
17
18
  // Remove os name from snapshot name
18
- .replace('-darwin', '')
19
- .replace('-linux', '')
20
- .replace('-windows', '')
19
+ // .replace('-darwin', '')
20
+ // .replace('-linux', '')
21
+ // .replace('-windows', '')
21
22
 
22
23
  // Remove test counter from snapshot name
23
- .replace('-1-', '-');
24
+ .replace('-1-', '-')
25
+
26
+ // Make different snapshot folder for different themes
27
+ .replace('theme-snapshots.spec.js', `theme-${process.env.THEME_EXPORT.toLocaleLowerCase()}`)
28
+ .replace('-snapshots', '');
24
29
  return result;
25
30
  };
26
31
  };
27
32
 
28
33
  test.beforeEach(configureSnapshotPath());
29
34
 
35
+ // https://playwright.dev/docs/emulation
36
+ test.use({
37
+ colorScheme: 'light',
38
+ locale: 'de-DE',
39
+ isMobile: false,
40
+ timezoneId: 'Europe/Berlin',
41
+ viewport: {
42
+ width: 800,
43
+ height: 0,
44
+ },
45
+ });
46
+
30
47
  /**
31
48
  * @todo stabilize and re-enable test
32
49
  */
33
50
  const blocklist = [];
34
51
 
35
- ROUTES.filter((route) => !blocklist.includes(route)).forEach((route) => {
52
+ ROUTES.forEach((options, route) => {
53
+ if (blocklist.includes(route)) {
54
+ return;
55
+ }
36
56
  test(`snapshot for ${route}`, async ({ page }) => {
37
57
  await page.goto(`/#${route}?hideMenus`, { waitUntil: 'networkidle' });
38
- await page.setViewportSize({
39
- width: 1920,
40
- height: 1280,
41
- });
58
+ if (options?.viewportSize) {
59
+ await page.setViewportSize(options.viewportSize);
60
+ }
61
+ if (options?.waitForTimeout) {
62
+ await page.waitForTimeout(options.waitForTimeout);
63
+ }
42
64
  await expect(page).toHaveScreenshot({
43
- // fullPage: true,
44
- maxDiffPixelRatio: 0.03,
65
+ fullPage: true,
66
+ maxDiffPixelRatio: 0.025,
67
+ ...options,
45
68
  });
46
69
  });
47
70
  });