From 085b97f9465cd6dcebe75b1c6722645771b4e533 Mon Sep 17 00:00:00 2001 From: yogeshwaran-c Date: Thu, 30 Apr 2026 17:27:52 +0530 Subject: [PATCH] fix(a11y): add aria-label to operations filter input The filter-by-tag input in the operations panel only had a placeholder attribute, which is not exposed as an accessible name to assistive technologies. Screen readers announced the input as an unlabeled text field, failing WCAG 4.1.2 (Name, Role, Value) and 1.3.1 (Info and Relationships). Add an aria-label="Filter by tag" matching the existing placeholder so the input has a stable accessible name regardless of whether a value is present. The placeholder is preserved for sighted users. Covered by a Jest unit test on FilterContainer and a Cypress e2e spec under test/e2e-cypress/e2e/a11y/filter-input.cy.js. --- src/core/containers/filter.jsx | 2 +- test/e2e-cypress/e2e/a11y/filter-input.cy.js | 17 +++++++++++++++++ test/unit/components/filter.jsx | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/e2e-cypress/e2e/a11y/filter-input.cy.js diff --git a/src/core/containers/filter.jsx b/src/core/containers/filter.jsx index 440b1ac4ad9..2a2d4980fce 100644 --- a/src/core/containers/filter.jsx +++ b/src/core/containers/filter.jsx @@ -32,7 +32,7 @@ export default class FilterContainer extends React.Component { {filter === false ? null :
- diff --git a/test/e2e-cypress/e2e/a11y/filter-input.cy.js b/test/e2e-cypress/e2e/a11y/filter-input.cy.js new file mode 100644 index 00000000000..a2c222b6f18 --- /dev/null +++ b/test/e2e-cypress/e2e/a11y/filter-input.cy.js @@ -0,0 +1,17 @@ +describe("Filter input accessibility", () => { + describe("with filter enabled", () => { + it("should expose an accessible name via aria-label on the filter input", () => { + cy.visit("/?url=/documents/petstore.swagger.yaml&filter=true") + .get(".operation-filter-input") + .should("exist") + .should("have.attr", "aria-label", "Filter by tag") + }) + + it("should still render the visual placeholder for sighted users", () => { + cy.visit("/?url=/documents/petstore.swagger.yaml&filter=true") + .get(".operation-filter-input") + .should("exist") + .should("have.attr", "placeholder", "Filter by tag") + }) + }) +}) diff --git a/test/unit/components/filter.jsx b/test/unit/components/filter.jsx index caa85f0f4a7..b36999efdf7 100644 --- a/test/unit/components/filter.jsx +++ b/test/unit/components/filter.jsx @@ -44,4 +44,20 @@ describe("", function(){ const renderedColInsideFilter = wrapper.find(Col) expect(renderedColInsideFilter.length).toEqual(0) }) + + it("exposes an accessible name on the filter input via aria-label", function(){ + + // Given + let props = {...mockedProps} + props.layoutSelectors = {...mockedProps.specSelectors} + props.layoutSelectors.currentFilter = function() {return true} + + // When + let wrapper = mount() + + // Then + const input = wrapper.find("input.operation-filter-input") + expect(input.length).toEqual(1) + expect(input.prop("aria-label")).toEqual("Filter by tag") + }) })