@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 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.0",
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": "2.2.2",
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.0"
32
+ "@public-ui/sample-react": "3.0.8-rc.1"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@babel/eslint-parser": "7.28.4",
@@ -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 { checkA11y, injectAxe } from 'axe-playwright';
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
- await injectAxe(page);
66
- await checkA11y(
67
- page,
68
- undefined,
69
- {
70
- axeOptions: {
71
- runOnly: {
72
- type: 'tag',
73
- values: ['best-practices', 'wcag2a', 'wcag2aa', 'wcag21aa'],
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: 80,
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
  },
@@ -1,4 +1,4 @@
1
- import { test, expect } from '@playwright/test';
1
+ import { expect, test } from '@playwright/test';
2
2
  import { ROUTES } from './sample-app.routes.js';
3
3
 
4
4
  // https://playwright.dev/docs/emulation