diff --git a/apps/web/src/components/filters/FilterBar.test.tsx b/apps/web/src/components/filters/FilterBar.test.tsx
index 53a659b..8b077c4 100644
--- a/apps/web/src/components/filters/FilterBar.test.tsx
+++ b/apps/web/src/components/filters/FilterBar.test.tsx
@@ -132,4 +132,70 @@ describe("FilterBar", (): void => {
// Should show 3 active filters (2 statuses + 1 priority)
expect(screen.getByText(/3/)).toBeInTheDocument();
});
+
+ describe("accessibility (CQ-WEB-11)", (): void => {
+ it("should have aria-label on search input", (): void => {
+ render();
+ const searchInput = screen.getByRole("textbox", { name: /search tasks/i });
+ expect(searchInput).toBeInTheDocument();
+ });
+
+ it("should have aria-label on date inputs", (): void => {
+ render();
+ expect(screen.getByLabelText(/filter from date/i)).toBeInTheDocument();
+ expect(screen.getByLabelText(/filter to date/i)).toBeInTheDocument();
+ });
+
+ it("should have aria-labels on status filter buttons", (): void => {
+ render();
+ expect(screen.getByRole("button", { name: /status filter/i })).toBeInTheDocument();
+ });
+
+ it("should have aria-labels on priority filter buttons", (): void => {
+ render();
+ expect(screen.getByRole("button", { name: /priority filter/i })).toBeInTheDocument();
+ });
+
+ it("should have id and htmlFor associations on status checkboxes", async (): Promise => {
+ const user = userEvent.setup();
+ render();
+
+ // Open status dropdown
+ await user.click(screen.getByRole("button", { name: /status filter/i }));
+
+ // Verify specific status checkboxes have proper id attributes
+ const notStartedCheckbox = screen.getByLabelText(/filter by status: not started/i);
+ expect(notStartedCheckbox).toHaveAttribute("id", "status-filter-NOT_STARTED");
+
+ const inProgressCheckbox = screen.getByLabelText(/filter by status: in progress/i);
+ expect(inProgressCheckbox).toHaveAttribute("id", "status-filter-IN_PROGRESS");
+
+ const completedCheckbox = screen.getByLabelText(/filter by status: completed/i);
+ expect(completedCheckbox).toHaveAttribute("id", "status-filter-COMPLETED");
+ });
+
+ it("should have id and htmlFor associations on priority checkboxes", async (): Promise => {
+ const user = userEvent.setup();
+ render();
+
+ // Open priority dropdown
+ await user.click(screen.getByRole("button", { name: /priority filter/i }));
+
+ // Verify specific priority checkboxes have proper id attributes
+ const lowCheckbox = screen.getByLabelText(/filter by priority: low/i);
+ expect(lowCheckbox).toHaveAttribute("id", "priority-filter-LOW");
+
+ const mediumCheckbox = screen.getByLabelText(/filter by priority: medium/i);
+ expect(mediumCheckbox).toHaveAttribute("id", "priority-filter-MEDIUM");
+
+ const highCheckbox = screen.getByLabelText(/filter by priority: high/i);
+ expect(highCheckbox).toHaveAttribute("id", "priority-filter-HIGH");
+ });
+
+ it("should have aria-label on clear filters button", (): void => {
+ const filtersWithSearch = { search: "test" };
+ render();
+ expect(screen.getByRole("button", { name: /clear filters/i })).toBeInTheDocument();
+ });
+ });
});
diff --git a/apps/web/src/components/filters/FilterBar.tsx b/apps/web/src/components/filters/FilterBar.tsx
index 981060d..ccb541c 100644
--- a/apps/web/src/components/filters/FilterBar.tsx
+++ b/apps/web/src/components/filters/FilterBar.tsx
@@ -112,6 +112,7 @@ export function FilterBar({
{
setSearchValue(e.target.value);
@@ -141,14 +142,17 @@ export function FilterBar({
{Object.values(TaskStatus).map((status) => (