You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
New OpenSpec change artifacts (proposal, design, specs, tasks — not yet implemented)
Skipped (out of scope): dist/, pnpm-lock.yaml, snapshot auto-generated content
CI checks: could not retrieve (permission denied) — manual verification recommended.
Findings
🔶 Medium — aria-controls broken when menu is not in DOM
File:packages/pluggableWidgets/combobox-web/src/components/ComboboxMenuWrapper.tsx line 52–59; snapshots confirm the issue
Problem: Downshift sets aria-controls="downshift-0-menu" on the combobox input element (confirmed in all three snapshots: aria-controls="downshift-0-menu"). That value references the id="downshift-0-menu" attribute that Downshift injects into the <ul> via getMenuProps. When isOpen is false, the <ul> is now removed from the DOM entirely, so aria-controls points to a non-existent element. Per ARIA spec, aria-controls must reference an element currently present in the DOM, or it is an authoring error. Screen readers (NVDA, JAWS) may either ignore or warn on a broken aria-controls reference, negating the accessibility benefit this PR aims to achieve.
The getMenuProps call was intentionally hoisted out of the conditional render (with a // Always call getMenuProps to satisfy Downshift requirements comment), but the ref that Downshift injects via getMenuProps is never attached to a DOM node when !isOpen. That means the ref is stale (pointing to null) whenever the menu closes and re-opens, which is precisely the scenario suppressRefError: true was added to silence.
Fix options (pick one):
Option A — Keep the <ul> in the DOM but hide it from the accessibility tree when closed:
This preserves the aria-controls target while hiding the empty list from AT when closed.
Option B — Remove aria-controls from the input when closed. This requires passing isOpen into the getInputProps call in SingleSelection.tsx and toggling the attribute. More invasive but semantically correct.
Option A is recommended — it restores the original DOM-always-present pattern for the <ul>, adds aria-hidden when closed (the actual fix for the empty-group problem), and keeps aria-controls intact.
🔶 Medium — E2E assertion uses not.toBeVisible instead of not.toBeInTheDocument
File:packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js line 181
Problem: The test comment says "Verify menu list is not in DOM when closed", but the assertion is:
awaitexpect(menuListClosed).not.toBeVisible();
not.toBeVisible() passes if the element exists in the DOM but is hidden via CSS (e.g. visibility: hidden, display: none, opacity: 0). This test would not catch a regression where the <ul> is rendered but merely hidden — it would still pass, giving a false green. The intent is to verify the element is absent from the DOM.
Fix:
awaitexpect(menuListClosed).toHaveCount(0);// or equivalently:awaitexpect(comboBox.locator(".widget-combobox-menu-list")).not.toBeAttached();
⚠️ Low — Spinner test silently passes when spinner is absent
File:packages/pluggableWidgets/combobox-web/src/__tests__/SingleSelection.spec.tsx line 786–791
Note: The assertion if (spinner) { expect(spinner).not.toHaveAttribute("aria-hidden", "true"); } is wrapped in an if guard that allows the test to pass even when no spinner element is found. If the selector .widget-combobox-spinner changes or the spinner never renders in test conditions, this test does nothing. Consider asserting the spinner exists unconditionally once the loading state is triggered, or at minimum replacing the if with a direct assertion:
Note: The [Unreleased] section only contains an unrelated flex-width fix. This PR changes observable widget behaviour (screen reader output, DOM structure of the menu). Per repo conventions, a changelog entry is expected. Suggest running pnpm -w changelog or manually adding under [Unreleased]:
### Fixed- We fixed an accessibility issue where decorative icons were announced as "image" by screen readers.
- We fixed an accessibility issue where an empty menu structure was exposed to assistive technologies when the combobox was closed.
Positives
The aria-hidden="true" placement on the <span> wrapper (rather than directly on <svg>) is the right approach — it hides both the container and the SVG in a single attribute.
Extracting getMenuProps with a comment explaining the Downshift rules requirement shows good understanding of the library contract.
The new unit tests cover the full matrix of closed/open/empty/loading states and use waitFor correctly for async open transitions.
The OpenSpec design doc's risk/trade-off section proactively flags the aria-controls concern (though the mitigation chosen introduces the issue described above).
The enforce-validation-id-requirement spec is thorough and well-structured for future implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull request type
Bug fix (non-breaking change which fixes an issue)
Description
Fixes two WCAG accessibility violations in the combobox widget.
aria-hidden="true"to DownArrow and ClearButton icon wrappers to prevent "image" announcements<ul>now only renders when open, preventing screen readers from navigating to empty groupsWhat should be covered while testing?
Screen Reader Testing:
Functional Testing: