@public-ui/visual-tests 3.0.8-rc.0 → 3.0.8-rc.1
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 +1 -0
- package/package.json +4 -3
- package/playwright.config.js +11 -1
- package/tests/axe-snapshots.spec.js +37 -27
- package/tests/sample-app.routes.js +52 -2
- package/tests/theme-snapshots.spec.js +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,7 @@ Add the following npm scripts to the theme's `package.json`:
|
|
|
56
56
|
- `THEME_EXPERT`: Define the name of the export within the module. (e.g., `export const THEME_NAME = {/**/};`) Defaults to `default`.
|
|
57
57
|
- `KOLIBRI_VISUAL_TESTS_TIMEOUT`: Define the Playwright [test timeout](https://playwright.dev/docs/test-timeouts).
|
|
58
58
|
- `KOLIBRI_VISUAL_TESTS_EXPECT_TIMEOUT`: Define the Playwright [expect timeout](https://playwright.dev/docs/test-timeouts).
|
|
59
|
+
- `KOLIBRI_VISUAL_TESTS_COLOR_SCHEME`: Choose the [CSS color scheme](https://developer.mozilla.org/docs/Web/CSS/@media/prefers-color-scheme) for the browser context. Supported values are `light` (default) and `dark`.
|
|
59
60
|
|
|
60
61
|
Run the tests with `npm test`. The first time, this will create a new folder `snapshots` which is supposed to be committed to the repository.
|
|
61
62
|
In the following runs, new screenshots will be compared to this reference.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@public-ui/visual-tests",
|
|
3
|
-
"version": "3.0.8-rc.
|
|
3
|
+
"version": "3.0.8-rc.1",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
5
|
"homepage": "https://public-ui.github.io",
|
|
6
6
|
"repository": {
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
"kolibri-visual-test": "src/index.js"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"axe-playwright": "
|
|
28
|
+
"@axe-core/playwright": "4.11.0",
|
|
29
|
+
"axe-html-reporter": "2.2.11",
|
|
29
30
|
"portfinder": "1.0.38",
|
|
30
31
|
"serve": "14.2.5",
|
|
31
|
-
"@public-ui/sample-react": "3.0.8-rc.
|
|
32
|
+
"@public-ui/sample-react": "3.0.8-rc.1"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@babel/eslint-parser": "7.28.4",
|
package/playwright.config.js
CHANGED
|
@@ -12,6 +12,16 @@ const EXPECT_TIMEOUT = parseInt(process.env.KOLIBRI_VISUAL_TESTS_EXPECT_TIMEOUT
|
|
|
12
12
|
const BUILD_PATH = process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH ?? '';
|
|
13
13
|
const THEME = (process.env.THEME_EXPORT || 'default').toLocaleLowerCase();
|
|
14
14
|
|
|
15
|
+
const VALID_COLOR_SCHEMES = ['light', 'dark'];
|
|
16
|
+
const colorSchemeInput = process.env.KOLIBRI_VISUAL_TESTS_COLOR_SCHEME;
|
|
17
|
+
const colorSchema = (colorSchemeInput || 'light').toLocaleLowerCase();
|
|
18
|
+
|
|
19
|
+
if (!VALID_COLOR_SCHEMES.includes(colorSchema)) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Environment variable KOLIBRI_VISUAL_TESTS_COLOR_SCHEME must be one of "${VALID_COLOR_SCHEMES.join('", "')}" (received "${colorSchemeInput}").`,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
/**
|
|
16
26
|
* See https://playwright.dev/docs/test-configuration.
|
|
17
27
|
*/
|
|
@@ -68,5 +78,5 @@ export default defineConfig({
|
|
|
68
78
|
url: BASE_URL,
|
|
69
79
|
reuseExistingServer: false,
|
|
70
80
|
},
|
|
71
|
-
snapshotPathTemplate: `{snapshotDir}/theme-${THEME}/{arg}-{projectName}-{platform}{ext}`,
|
|
81
|
+
snapshotPathTemplate: `{snapshotDir}/theme-${THEME}${colorSchema === 'light' ? '' : `-${colorSchema}`}/{arg}-{projectName}-{platform}{ext}`,
|
|
72
82
|
});
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import AxeBuilder from '@axe-core/playwright';
|
|
1
2
|
import { test } from '@playwright/test';
|
|
2
|
-
import
|
|
3
|
-
import { ROUTES } from './sample-app.routes.js';
|
|
3
|
+
import axeHtmlReporter from 'axe-html-reporter';
|
|
4
4
|
import process from 'process';
|
|
5
|
+
import { ROUTES } from './sample-app.routes.js';
|
|
6
|
+
|
|
7
|
+
const { createHtmlReport } = axeHtmlReporter;
|
|
8
|
+
|
|
9
|
+
const AXE_TAGS = ['best-practices', 'wcag2a', 'wcag2aa', 'wcag21aa'];
|
|
5
10
|
|
|
6
11
|
const themeName = (process.env.THEME_EXPORT || 'default').toLocaleLowerCase();
|
|
7
12
|
const rename = (snapshotName) => {
|
|
@@ -25,6 +30,25 @@ const rename = (snapshotName) => {
|
|
|
25
30
|
return result;
|
|
26
31
|
};
|
|
27
32
|
|
|
33
|
+
const sanitizeRouteForReport = (route) => route.replace(/[/?]/g, '-').replace(/^-+/, '') || 'root';
|
|
34
|
+
|
|
35
|
+
const buildReportOptions = (testInfo, route) => ({
|
|
36
|
+
projectKey: `axe-${themeName}`,
|
|
37
|
+
reportFileName: `${sanitizeRouteForReport(route)}.html`,
|
|
38
|
+
outputDirPath: rename(testInfo.outputDir),
|
|
39
|
+
outputDir: `axe-${themeName}`,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const logViolations = (route, violations) => {
|
|
43
|
+
if (!violations?.length) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.warn(`Axe found ${violations.length} violation(s) on ${route}`);
|
|
47
|
+
for (const violation of violations) {
|
|
48
|
+
console.warn(`- ${violation.id}: ${violation.help} (${violation.nodes.length} nodes)`);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
28
52
|
// https://playwright.dev/docs/emulation
|
|
29
53
|
test.use({
|
|
30
54
|
colorScheme: 'light',
|
|
@@ -43,7 +67,6 @@ ROUTES.forEach((options, route) => {
|
|
|
43
67
|
return;
|
|
44
68
|
}
|
|
45
69
|
test(`snapshot for ${route}`, async ({ page }, testInfo) => {
|
|
46
|
-
const outputPath = rename(testInfo.outputDir);
|
|
47
70
|
const hideMenusParam = `${route.includes('?') ? '&' : '?'}hideMenus`;
|
|
48
71
|
await page.goto(`/#${route}${hideMenusParam}`);
|
|
49
72
|
await page.waitForLoadState('networkidle');
|
|
@@ -62,29 +85,16 @@ ROUTES.forEach((options, route) => {
|
|
|
62
85
|
await page.waitForTimeout(options?.snapshot?.waitForTimeout);
|
|
63
86
|
}
|
|
64
87
|
|
|
65
|
-
|
|
66
|
-
await
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
detailedReport: true,
|
|
77
|
-
detailedReportOptions: {
|
|
78
|
-
html: true,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
true, // options?.axe?.skipFailures ?? false,
|
|
82
|
-
'html',
|
|
83
|
-
{
|
|
84
|
-
outputDirPath: outputPath.replace(/\/[^/]+$/, ''),
|
|
85
|
-
outputDir: `axe-${themeName}`,
|
|
86
|
-
reportFileName: `${route.replace(/[/?]/g, '-')}.html`,
|
|
87
|
-
},
|
|
88
|
-
);
|
|
88
|
+
const builder = new AxeBuilder({ page }).withTags(AXE_TAGS);
|
|
89
|
+
const results = await builder.analyze();
|
|
90
|
+
await testInfo.attach('axe-results', {
|
|
91
|
+
body: JSON.stringify(results, null, 2),
|
|
92
|
+
contentType: 'application/json',
|
|
93
|
+
});
|
|
94
|
+
createHtmlReport({
|
|
95
|
+
results,
|
|
96
|
+
options: buildReportOptions(testInfo, route),
|
|
97
|
+
});
|
|
98
|
+
logViolations(route, results.violations);
|
|
89
99
|
});
|
|
90
100
|
});
|
|
@@ -176,6 +176,13 @@ ROUTES.set('card/basic', {
|
|
|
176
176
|
},
|
|
177
177
|
},
|
|
178
178
|
});
|
|
179
|
+
ROUTES.set('card/headlines', {
|
|
180
|
+
snapshot: {
|
|
181
|
+
zoom: {
|
|
182
|
+
skip: true,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
});
|
|
179
186
|
ROUTES.set('combobox/basic?noColumns', {
|
|
180
187
|
snapshot: {
|
|
181
188
|
skip: true,
|
|
@@ -297,7 +304,18 @@ ROUTES.set('icon/basic', {
|
|
|
297
304
|
snapshot: {
|
|
298
305
|
viewportSize: {
|
|
299
306
|
width: 60,
|
|
300
|
-
height:
|
|
307
|
+
height: 200,
|
|
308
|
+
},
|
|
309
|
+
zoom: {
|
|
310
|
+
skip: true,
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
ROUTES.set('icon/font-awesome', {
|
|
315
|
+
snapshot: {
|
|
316
|
+
viewportSize: {
|
|
317
|
+
width: 250,
|
|
318
|
+
height: 345,
|
|
301
319
|
},
|
|
302
320
|
zoom: {
|
|
303
321
|
skip: true,
|
|
@@ -409,6 +427,17 @@ ROUTES.set('input-number/basic?noColumns', {
|
|
|
409
427
|
},
|
|
410
428
|
},
|
|
411
429
|
});
|
|
430
|
+
ROUTES.set('input-number/number-formatter', {
|
|
431
|
+
snapshot: {
|
|
432
|
+
viewportSize: {
|
|
433
|
+
width: 500,
|
|
434
|
+
height: 300,
|
|
435
|
+
},
|
|
436
|
+
zoom: {
|
|
437
|
+
skip: true,
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
});
|
|
412
441
|
ROUTES.set('input-password/basic?noColumns', {
|
|
413
442
|
snapshot: {
|
|
414
443
|
viewportSize: {
|
|
@@ -489,6 +518,17 @@ ROUTES.set('input-text/basic?noColumns', {
|
|
|
489
518
|
},
|
|
490
519
|
},
|
|
491
520
|
});
|
|
521
|
+
ROUTES.set('input-text/text-formatter', {
|
|
522
|
+
snapshot: {
|
|
523
|
+
viewportSize: {
|
|
524
|
+
width: 500,
|
|
525
|
+
height: 690,
|
|
526
|
+
},
|
|
527
|
+
zoom: {
|
|
528
|
+
skip: true,
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
});
|
|
492
532
|
ROUTES.set('kolibri/basic', {
|
|
493
533
|
snapshot: {
|
|
494
534
|
skip: true,
|
|
@@ -572,6 +612,17 @@ ROUTES.set('pagination/basic', {
|
|
|
572
612
|
},
|
|
573
613
|
},
|
|
574
614
|
});
|
|
615
|
+
ROUTES.set('popover-button/basic', {
|
|
616
|
+
snapshot: {
|
|
617
|
+
zoom: {
|
|
618
|
+
skip: true,
|
|
619
|
+
},
|
|
620
|
+
viewportSize: {
|
|
621
|
+
width: 200,
|
|
622
|
+
height: 220,
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
});
|
|
575
626
|
ROUTES.set('progress/basic', {
|
|
576
627
|
snapshot: {
|
|
577
628
|
zoom: {
|
|
@@ -604,7 +655,6 @@ ROUTES.set('select/basic?noColumns', {
|
|
|
604
655
|
});
|
|
605
656
|
ROUTES.set('skip-nav/basic', {
|
|
606
657
|
snapshot: {
|
|
607
|
-
skip: true,
|
|
608
658
|
zoom: {
|
|
609
659
|
skip: true,
|
|
610
660
|
},
|