From ad7f06de87c48387224fd95a4a6c9b87bf6ce2f1 Mon Sep 17 00:00:00 2001 From: Nikol Georgieva Date: Mon, 5 Oct 2026 14:10:27 +0300 Subject: [PATCH] harmonia template: axe-core checks the generated pages against WCAG 2.1 AA, red on serious/critical (#7645) The Harmonia templates carry ARIA where the component library put it, but nothing checked it: no axe-core, pa11y or Lighthouse anywhere, so every generated page was one template edit away from a regression no one saw. AccessibilityHarmoniaIT generates and publishes an intent application and scans its manage list, manage form, document page, read-only preview and Inbox with axe-core (Deque's Selenium binding, on the Chrome the Selenide ITs already drive), WCAG 2.1 A/AA rules, in both colour schemes. Every page's result and a count per impact go to target/failsafe-reports/axe/, which the IT jobs upload; a serious or critical violation fails it. It also asserts what axe cannot see: the status step indicator announces the active step, and the line dialog returns focus to the button that opened it. HarmoniaAccessibilityMarkupIT guards the rules on markup no intent application renders: a sortable header sorts through a button, every step trigger binds aria-current. Template fixes the first report and the issue's list surfaced: - the column-resize grip (a focusable role=separator) announced aria-valuenow only once focused - required from the start (critical); - the document's "your step" strip put muted text on its primary tint (4.32:1) - now foreground; - the perspective list sorted on a click on the - a real button now, with aria-sort; - both status step indicators (document page, BPM task form) bind aria-current="step"; Harmonia marks the active step visually only. Reviewed, no change: inputs carry bound labels (the label rule finds nothing), Harmonia's dialog traps and returns focus itself, and the 194 role="presentation" are all on decorative svg icons, none on table markup. Not enforced: contrast against Harmonia 3.1.2's own --primary (white on it 3.67:1 light / 4.43:1 dark, it as dark-mode link text 4.26:1 - one token cannot pass both) - a node-level exemption, so every other contrast failure still fails the test; it is fixed in codbex/harmonia. The Playwright app-test runner (npm/test, published in @aerokit/sdk) gets the same check as an a11y flow with @axe-core/playwright (optional peer): report-only by default, APPTEST_A11Y=strict to fail. Verified: AccessibilityHarmoniaIT and HarmoniaAccessibilityMarkupIT green, red with the form labels' for= binding removed ([critical] label on #f_Name, #f_Email, #f_Vip); HarmoniaContractIT, HarmoniaListColumnsIT, HarmoniaHierarchyTreeTableIT, I18nKeyCoverageIT, HarmoniaTaskFormLayoutIT, ShellRuntimeVintageIT, IntentEmissionCoverageIT green; formatter:validate with the cache wiped. The npm a11y flow was syntax-checked, not run. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../META-INF/dirigible/modules/package.json | 6 +- .../application-core/shell/js/app.js | 3 + .../document/document-view.html.template | 6 +- .../ui/perspective/list/page.js.template | 5 + .../ui/perspective/list/view.html.template | 7 +- .../ui/index.html.template | 3 +- npm/test/README.md | 11 +- npm/test/package.json | 8 +- npm/test/src/flows/a11y.js | 86 +++++ npm/test/src/index.js | 2 + pom.xml | 14 + tests/tests-integrations/pom.xml | 5 + .../api/HarmoniaAccessibilityMarkupIT.java | 75 ++++ .../ui/tests/AccessibilityHarmoniaIT.java | 338 ++++++++++++++++++ .../AccessibilityHarmoniaIT/app.intent | 50 +++ 15 files changed, 610 insertions(+), 9 deletions(-) create mode 100644 npm/test/src/flows/a11y.js create mode 100644 tests/tests-integrations/src/main/java/org/eclipse/dirigible/integration/tests/api/HarmoniaAccessibilityMarkupIT.java create mode 100644 tests/tests-integrations/src/main/java/org/eclipse/dirigible/integration/tests/ui/tests/AccessibilityHarmoniaIT.java create mode 100644 tests/tests-integrations/src/main/resources/AccessibilityHarmoniaIT/app.intent diff --git a/components/api/api-modules-javascript/src/main/resources/META-INF/dirigible/modules/package.json b/components/api/api-modules-javascript/src/main/resources/META-INF/dirigible/modules/package.json index f4cad7cfb13..2f89e8e6e97 100644 --- a/components/api/api-modules-javascript/src/main/resources/META-INF/dirigible/modules/package.json +++ b/components/api/api-modules-javascript/src/main/resources/META-INF/dirigible/modules/package.json @@ -59,11 +59,15 @@ } }, "peerDependencies": { - "@playwright/test": ">=1.45" + "@playwright/test": ">=1.45", + "@axe-core/playwright": ">=4.10" }, "peerDependenciesMeta": { "@playwright/test": { "optional": true + }, + "@axe-core/playwright": { + "optional": true } } } diff --git a/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/js/app.js b/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/js/app.js index 6fbc992c2d6..b283b997afb 100644 --- a/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/js/app.js +++ b/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/js/app.js @@ -373,6 +373,9 @@ App.listColumns = { resize(width + (event.key === 'ArrowRight' ? step : -step)); }); th.appendChild(grip); + // aria-valuenow is required on a focusable separator from the start, not only once it has + // been focused (#7645); focus and every resize keep it current. + announce(); }, // Is the element's text wider than its content box? scrollWidth alone rounds a sub-pixel overflow diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template index 5cd031a11d7..4e91ccf81dd 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template @@ -126,7 +126,8 @@
- + +