Skip to content

fix(a11y): admin and auth pages accessibility - #13998

Merged
viktoravelino merged 11 commits into
release-1.12.0from
fix/admin-auth-pages-a11y
Jul 21, 2026
Merged

fix(a11y): admin and auth pages accessibility#13998
viktoravelino merged 11 commits into
release-1.12.0from
fix/admin-auth-pages-a11y

Conversation

@viktoravelino

@viktoravelino viktoravelino commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Brings the auth surfaces and the /admin user-management page to WCAG 2.1 A/AA, verified with the IBM Equal Access (accessibility-checker) engine plus keyboard/focus interaction tests. Same approach used for /settings/api-keys (LE-1720 / #13953) and /assets/files (#13987).

Covers LE-1760 (/login/admin) and LE-1761 (/admin).

Fixes

/login, /signup — already clean; added regression coverage.

/login/admin

  • Wrapped content in a <main> landmark (fixes skip_main_exists + aria_content_in_landmark).
  • Bound the username/password inputs to state so the placeholder overlay clears once text is entered.

/admin

  • Wrapped the page in a <main> landmark.
  • Accessible names for the search input, active/superuser toggles, row edit/delete icon buttons, and the back button.
  • Made the clear-search control a real focusable <button> (was a <div onClick> — WCAG 2.1.1) + keyboard test.
  • Constrained the active/superuser toggle focus ring to the checkbox.

New User modal

  • Fixed label associations (explicit htmlFor on the is_active/is_superuser checkboxes; label_ref_valid).
  • Password / confirm-password fields: replaced the hand-rolled <input> (which stuffed the visibility toggle into the label, mispositioning the eye icon and leaving it keyboard-inoperable) with the shared InputComponent password primitive used by login/signup — eye toggle now sits inside the input, is keyboard operable, and exposes aria-label + aria-pressed. Validation moved to the getRequiredFieldError pattern.

Previously-baselined debt — now fixed (baselines removed)

The three admin IBM baselines are deleted; the underlying violations are resolved:

  • aria_descendant_valid (active/superuser toggles): the toggles nested a role="checkbox" indicator inside the confirmation dialog-trigger <button>. Converted them to proper toggle buttons — aria-label + aria-pressed threaded through ConfirmationModal.TriggerBaseModal.Trigger → the Radix DialogTrigger button — and made the inner CheckBoxDiv presentational (aria-hidden, no role) via a new presentational prop.
  • target_spacing_sufficient (row edit/delete icons): each icon trigger is now wrapped to a ≥24×24 CSS-px target, satisfying WCAG 2.5.8 (≥24px targets are exempt from the spacing requirement).

Dark-mode coverage + contrast fix

  • Every auth state now runs in both light and dark (matrix over states × themes), and a dark-mode New User modal scan was added. Previously only one dark scan existed per surface.
  • This surfaced a real, pre-existing bug: dark-mode form error text (.field-invalid / .label-invalid) was only ~3.9:1 contrast — below the WCAG AA 4.5:1 minimum. Fixed by pointing those classes at the brighter --accent-red-foreground in dark mode (light mode unchanged; app-wide improvement for every dark-mode form error).

i18n

Keys admin.backButton and admin.clearSearch added to all 7 locale files.

Validation

cd src/frontend
RUN_A11Y=true RUN_A11Y_ASSERT=true npx playwright test tests/a11y/auth-pages.a11y.spec.ts tests/a11y/admin-page.a11y.spec.ts --project=chromium
npx jest src/components/ui/__tests__/checkbox.a11y.test.tsx
  • Both a11y specs green in light and dark (0 violations, no baselines).
  • New-user modal password fix verified in the live app (eye toggle inside the input).

Tickets

- Wrap /login/admin and /admin content in a <main> landmark
- Add accessible names to admin controls: search, clear, active/superuser
  toggles, row edit/delete, back button
- Fix New User modal label associations (explicit htmlFor on checkbox fields)
- Bind /login/admin username/password inputs so the placeholder overlay
  clears once text is entered
- Constrain the active/superuser toggle focus ring to the checkbox instead
  of spanning the full cell
- Make the clear-search control a real focusable button (was a div onClick)
- Add /admin and /login/admin a11y specs, IBM baselines for remaining
  framework-level debt, and a clear-search keyboard test
- Add i18n keys admin.backButton and admin.clearSearch across all locales
- Move baselineFolder to tests/a11y/baselines
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 165757f1-b04e-498a-8bfc-d5a72d183581

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds accessibility improvements to the admin area: aria-label support on checkboxes and admin page controls, semantic markup changes (div-to-main, div-to-button), controlled login inputs, htmlFor label associations, new locale strings, accessibility Playwright tests, corresponding a11y baseline JSON files, an achecker config path update, and regenerated secrets baseline entries.

Changes

Admin Page Accessibility Enhancements

Layer / File(s) Summary
CheckBoxDiv aria-label support
src/frontend/src/components/ui/checkbox.tsx
Adds an optional aria-label prop to CheckBoxDiv, applied to the rendered checkbox div.
Admin page semantic markup and aria-labels
src/frontend/src/pages/AdminPage/index.tsx
Wraps content in <main>, converts clear-search div to button, adds computed aria-labels to checkboxes, edit/delete icons, and search input.
Admin login page semantics and controlled inputs
src/frontend/src/pages/AdminPage/LoginPage/index.tsx
Changes wrapper to <main>, makes username/password inputs controlled via state value.
User management modal label associations
src/frontend/src/modals/userManagementModal/index.tsx
Adds htmlFor attributes linking Form.Label elements to is_active and is_superuser inputs.
New admin locale strings
src/frontend/src/locales/de.json, en.json, es.json, fr.json, ja.json, pt.json, zh-Hans.json
Adds admin.backButton and admin.clearSearch translation keys across all locales.
Secrets baseline regeneration
.secrets.baseline
Updates hashed_secret/line_number entries for changed locale files and refreshes generated_at.

Estimated code review effort: 2 (Simple) | ~15 minutes

Accessibility Test Suite and Baselines

Layer / File(s) Summary
Achecker baseline folder config
src/frontend/.achecker.yml
Repoints baselineFolder from tests/baselines to tests/a11y/baselines.
Admin page accessibility test suite
src/frontend/tests/a11y/admin-page.a11y.spec.ts
Adds helpers for animation/theme control, login, and navigation, plus tests scanning admin page, new user modal, dark mode, and clear-search keyboard operability.
Admin login accessibility tests
src/frontend/tests/a11y/auth-pages.a11y.spec.ts
Adds tests for empty admin login accessibility and admin login error toast accessibility.
New a11y baseline JSON files
src/frontend/tests/a11y/baselines/chromium__admin-new-user-modal.json, chromium__admin-page-dark.json, chromium__admin-page-empty.json
Adds baseline files documenting tracked known accessibility violations for the admin new-user modal, dark mode, and empty state.

Estimated code review effort: 2 (Simple) | ~15 minutes

Suggested labels: lgtm

Suggested reviewers: keval718

🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (8 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test Coverage For New Implementations ✅ Passed Added Playwright a11y/regression specs and checkbox a11y coverage that exercise the new landmarks, labels, keyboard behavior, and controlled inputs.
Test Quality And Coverage ✅ Passed New Playwright a11y specs cover admin/auth flows, keyboard behavior, and modal scans; checkbox has RTL/axe coverage and tests follow project patterns.
Test File Naming And Structure ✅ Passed New Playwright a11y specs live under src/frontend/tests/a11y, use the repo’s .spec.ts convention, and have descriptive, structured tests with helpers.
Excessive Mock Usage Warning ✅ Passed Mocks are limited to external auth/theme setup in Playwright flows; core UI behavior is exercised directly, and the checkbox a11y test uses no mocks.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main accessibility improvements on admin and auth pages.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/admin-auth-pages-a11y

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug Something isn't working label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/frontend/tests/a11y/admin-page.a11y.spec.ts (1)

5-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract disableAnimations to a shared utility.

This function is duplicated verbatim in auth-pages.a11y.spec.ts (lines 16–30). Extract it to a shared module (e.g., alongside the existing ../utils/ helpers) and import from both specs to keep a11y test setup DRY.

♻️ Suggested extraction
-async function disableAnimations(page: LangflowPage) {
-  await page.addStyleTag({
-    content: `
-      *,
-      *::before,
-      *::after {
-        animation-duration: 0s !important;
-        animation-delay: 0s !important;
-        transition-duration: 0s !important;
-        transition-delay: 0s !important;
-        scroll-behavior: auto !important;
-      }
-    `,
-  });
-}
+// In a shared file, e.g. src/frontend/tests/a11y/utils.ts
+export async function disableAnimations(page: LangflowPage) {
+  await page.addStyleTag({
+    content: `
+      *,
+      *::before,
+      *::after {
+        animation-duration: 0s !important;
+        animation-delay: 0s !important;
+        transition-duration: 0s !important;
+        transition-delay: 0s !important;
+        scroll-behavior: auto !important;
+      }
+    `,
+  });
+}

Then in both spec files:

+import { disableAnimations } from "./utils";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/tests/a11y/admin-page.a11y.spec.ts` around lines 5 - 19, The
disableAnimations helper is duplicated across a11y specs, so extract it into a
shared utility under the existing utils helpers and import it from both test
files. Move the shared implementation of disableAnimations(page: LangflowPage)
into the common module, then update admin-page.a11y.spec.ts and
auth-pages.a11y.spec.ts to use that shared helper so the animation-disabling
setup stays DRY and consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/frontend/tests/a11y/admin-page.a11y.spec.ts`:
- Around line 5-19: The disableAnimations helper is duplicated across a11y
specs, so extract it into a shared utility under the existing utils helpers and
import it from both test files. Move the shared implementation of
disableAnimations(page: LangflowPage) into the common module, then update
admin-page.a11y.spec.ts and auth-pages.a11y.spec.ts to use that shared helper so
the animation-disabling setup stays DRY and consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7b39f236-7013-46df-b7c8-22e1eefcf4fe

📥 Commits

Reviewing files that changed from the base of the PR and between 6ea7dc0 and d302542.

📒 Files selected for processing (18)
  • .secrets.baseline
  • src/frontend/.achecker.yml
  • src/frontend/src/components/ui/checkbox.tsx
  • src/frontend/src/locales/de.json
  • src/frontend/src/locales/en.json
  • src/frontend/src/locales/es.json
  • src/frontend/src/locales/fr.json
  • src/frontend/src/locales/ja.json
  • src/frontend/src/locales/pt.json
  • src/frontend/src/locales/zh-Hans.json
  • src/frontend/src/modals/userManagementModal/index.tsx
  • src/frontend/src/pages/AdminPage/LoginPage/index.tsx
  • src/frontend/src/pages/AdminPage/index.tsx
  • src/frontend/tests/a11y/admin-page.a11y.spec.ts
  • src/frontend/tests/a11y/auth-pages.a11y.spec.ts
  • src/frontend/tests/a11y/baselines/chromium__admin-new-user-modal.json
  • src/frontend/tests/a11y/baselines/chromium__admin-page-dark.json
  • src/frontend/tests/a11y/baselines/chromium__admin-page-empty.json

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 46%
46.53% (65637/141043) 70.22% (9149/13029) 44.95% (1505/3348)

Unit Test Results

Tests Skipped Failures Errors Time
5372 0 💤 0 ❌ 0 🔥 18m 40s ⏱️

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 30.76923% with 144 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release-1.12.0@7157a10). Learn more about missing BASE report.

Files with missing lines Patch % Lines
.../frontend/src/modals/userManagementModal/index.tsx 33.62% 77 Missing ⚠️
src/frontend/src/pages/AdminPage/index.tsx 3.70% 52 Missing ⚠️
...rc/frontend/src/modals/confirmationModal/index.tsx 37.50% 5 Missing ⚠️
...c/frontend/src/pages/AdminPage/LoginPage/index.tsx 16.66% 5 Missing ⚠️
src/frontend/src/types/components/index.ts 0.00% 5 Missing ⚠️

❌ Your patch check has failed because the patch coverage (30.76%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##             release-1.12.0   #13998   +/-   ##
=================================================
  Coverage                  ?   60.36%           
=================================================
  Files                     ?     2344           
  Lines                     ?   230134           
  Branches                  ?    34796           
=================================================
  Hits                      ?   138910           
  Misses                    ?    89619           
  Partials                  ?     1605           
Flag Coverage Δ
frontend 59.49% <30.76%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/frontend/src/components/ui/checkbox.tsx 73.75% <100.00%> (ø)
src/frontend/src/modals/baseModal/index.tsx 91.34% <100.00%> (ø)
...rc/frontend/src/modals/confirmationModal/index.tsx 53.40% <37.50%> (ø)
...c/frontend/src/pages/AdminPage/LoginPage/index.tsx 42.10% <16.66%> (ø)
src/frontend/src/types/components/index.ts 0.00% <0.00%> (ø)
src/frontend/src/pages/AdminPage/index.tsx 25.30% <3.70%> (ø)
.../frontend/src/modals/userManagementModal/index.tsx 35.96% <33.62%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 10, 2026
…dd dark scans

Resolve the a11y debt that was previously baselined for the /admin page and
harden the auth surfaces:

- Toggle controls (active/superuser): convert to proper toggle buttons
  (aria-label + aria-pressed threaded to the trigger) and render the inner
  CheckBoxDiv as presentational, so a checkbox role is no longer nested inside
  an interactive button (IBM aria_descendant_valid, WCAG 1.3.1/4.1.2).
- Row action icons (edit/delete): size each trigger to >=24x24 CSS px so they
  meet WCAG 2.5.8 target size and no longer trip target_spacing_sufficient.
- Delete all three admin IBM baselines now that the violations are fixed.

- New User modal: the password/confirm fields hand-rolled a raw input with the
  visibility toggle stuffed into the label. Replace with the shared
  InputComponent password primitive (eye toggle inside the input, keyboard
  operable, aria-label + aria-pressed), matching the login/signup surfaces;
  move validation to the getRequiredFieldError pattern.

- Dark-mode coverage: run every auth state in both light and dark and add a
  dark new-user-modal scan. This surfaced insufficient error-text contrast in
  dark mode (~3.9:1); fix .field-invalid/.label-invalid to use the brighter
  accent-red so form errors meet WCAG AA 4.5:1.
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 10, 2026

@Cristhianzl Cristhianzl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Jul 10, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 10, 2026
InputComponent lost the name attribute that Radix Form.Control asChild
previously injected, breaking Playwright selectors input[name=password]
and input[name=confirmpassword] in the New User modal.
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
…uth-pages-a11y

# Conflicts:
#	.secrets.baseline
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@viktoravelino
viktoravelino added this pull request to the merge queue Jul 14, 2026
@viktoravelino viktoravelino self-assigned this Jul 14, 2026
@viktoravelino
viktoravelino removed this pull request from the merge queue due to a manual request Jul 14, 2026
@viktoravelino viktoravelino added the DO NOT MERGE Don't Merge this PR label Jul 14, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 14, 2026
@erichare
erichare deleted the branch release-1.12.0 July 15, 2026 18:36
@erichare erichare closed this Jul 15, 2026
@erichare erichare reopened this Jul 15, 2026
@viktoravelino
viktoravelino changed the base branch from release-1.11.0 to release-1.12.0 July 21, 2026 17:32
@viktoravelino viktoravelino removed the DO NOT MERGE Don't Merge this PR label Jul 21, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 21, 2026
@viktoravelino
viktoravelino merged commit 3c39c0d into release-1.12.0 Jul 21, 2026
11 of 12 checks passed
@viktoravelino
viktoravelino deleted the fix/admin-auth-pages-a11y branch July 21, 2026 17:37
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants