From 5b72a916e4c71a882839dd484583b8bc349a0a5c Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 22 Jul 2025 15:21:02 -0700 Subject: [PATCH] (HACK WEEK 2025) A11y admin test helper (#2937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 🤖 add a11y audit test helper config * chore: 🤖 remove report files * refactor: 💡 remove console.log * Apply PR feedback * Delete the flag --server when running a11y tests --------- Co-authored-by: Lisbet Alvarez --- ui/admin/.gitignore | 3 +++ ui/admin/config/environment.js | 15 ++++------- ui/admin/package.json | 4 ++- ui/admin/testem.js | 14 ++++++++-- ui/admin/tests/test-helper.js | 49 ++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 13 deletions(-) diff --git a/ui/admin/.gitignore b/ui/admin/.gitignore index 4133a3873..6aee20f80 100644 --- a/ui/admin/.gitignore +++ b/ui/admin/.gitignore @@ -18,3 +18,6 @@ # broccoli-debug /DEBUG/ + +# a11y audit +/ember-a11y-report/ \ No newline at end of file diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 8109948a9..209cc4684 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -14,6 +14,7 @@ const { const APP_NAME = process.env.APP_NAME || 'Boundary'; const API_HOST = process.env.API_HOST || ''; +const ENABLE_A11Y_AUDIT = process.env.ENABLE_A11Y_AUDIT || false; const clone = (obj) => v8.deserialize(v8.serialize(obj)); @@ -157,16 +158,6 @@ module.exports = function (environment) { ? JSON.parse(process.env.ENABLE_MIRAGE) : true; - ENV['ember-a11y-testing'] = { - componentOptions: { - axeOptions: { - checks: { - 'color-contrast': { options: { noScroll: true } }, - }, - }, - }, - }; - // Default edition in development ENV.features.defaultEdition = 'enterprise'; // Enable development-only features @@ -178,6 +169,8 @@ module.exports = function (environment) { ENV.features.featureEditions.enterprise[feature] = true; ENV.features.featureEditions.hcp[feature] = true; }); + + ENV.ENABLE_A11Y_AUDIT = ENABLE_A11Y_AUDIT; } if (environment === 'test') { @@ -197,6 +190,8 @@ module.exports = function (environment) { ENV.oidcPollingTimeoutSeconds = 0; ENV.enableConfirmService = false; + + ENV.ENABLE_A11Y_AUDIT = ENABLE_A11Y_AUDIT; } if (environment === 'production') { diff --git a/ui/admin/package.json b/ui/admin/package.json index 0c77c8ede..659229907 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -30,7 +30,9 @@ "format:sass": "prettier --write app/**/*.scss", "start": "ember serve", "clean:coverage": "rm -rf coverage_* || true", - "test": "pnpm clean:coverage && concurrently \"npm:test:*\" --names \"test:\" && pnpm test:finalize", + "test": "pnpm clean:coverage && pnpm test:ember && pnpm test:finalize", + "test-a11y": "ENABLE_A11Y_AUDIT=true ember test", + "test-a11y:dark": "COLOR_THEME=dark pnpm test-a11y", "test:ember": "COVERAGE=true ember exam --test-port 0 --split=4 --parallel=1 --random", "test:finalize": "ember coverage-merge && pnpm clean:coverage" }, diff --git a/ui/admin/testem.js b/ui/admin/testem.js index d0d33ce78..552b07b13 100644 --- a/ui/admin/testem.js +++ b/ui/admin/testem.js @@ -3,6 +3,14 @@ * SPDX-License-Identifier: BUSL-1.1 */ +const COLOR_THEME = process.env.COLOR_THEME ?? 'light'; + +if (!['dark', 'light'].includes(COLOR_THEME)) { + throw new Error( + `Only values of "dark" and "light" are allowed for environment variable COLOR_THEME`, + ); +} + module.exports = { test_page: 'tests/index.html?hidepassed', disable_watching: true, @@ -12,8 +20,10 @@ module.exports = { browser_args: { Chrome: { all: [ - process.env.DARK_MODE ? '--enable-features=WebContentsForceDark' : null, - process.env.DARK_MODE ? '--force-dark-mode' : null, + COLOR_THEME === 'dark' + ? '--enable-features=WebContentsForceDark' + : null, + COLOR_THEME === 'dark' ? '--force-dark-mode' : '--force-light-mode', ].filter(Boolean), ci: [ // --no-sandbox is needed when running Chrome inside a container diff --git a/ui/admin/tests/test-helper.js b/ui/admin/tests/test-helper.js index 94408dcec..c1fc1e66a 100644 --- a/ui/admin/tests/test-helper.js +++ b/ui/admin/tests/test-helper.js @@ -9,9 +9,58 @@ import * as QUnit from 'qunit'; import { setApplication } from '@ember/test-helpers'; import { setup } from 'qunit-dom'; import start from 'ember-exam/test-support/start'; +import { + DEFAULT_A11Y_TEST_HELPER_NAMES, + setRunOptions, + setupGlobalA11yHooks, + setupQUnitA11yAuditToggle, + shouldForceAudit, + setEnableA11yAudit, + useMiddlewareReporter, + setupMiddlewareReporter, +} from 'ember-a11y-testing/test-support'; setApplication(Application.create(config.APP)); +setupGlobalA11yHooks(() => true, { + helpers: [ + ...DEFAULT_A11Y_TEST_HELPER_NAMES, + 'fillIn', + 'render', + 'tab', + 'focus', + 'select', + ], +}); + +setupQUnitA11yAuditToggle(QUnit); + +setRunOptions({ + runOnly: { + type: 'tag', + values: [ + 'wcag2a', + 'wcag2aa', + 'wcag21a', + 'wcag21aa', + 'wcag22aa', + 'best-practice', + ], + }, + include: [['#ember-testing-container']], + exclude: [['.flight-sprite-container']], +}); + +if (shouldForceAudit()) { + setEnableA11yAudit(true); +} + +// Note, as a convenience, useMiddlewareReporter automatically forces audits, thus explicitly specifying the enableA11yAudit query param or the ENABLE_A11Y_AUDIT environment variable is unnecessary. +if (useMiddlewareReporter()) { + // Only runs if `enableA11yMiddlewareReporter` is set in URL + setupMiddlewareReporter(); +} + setup(QUnit.assert); start();