---
type: Task
status: AI Gen TODO
category: QA
isAgentGenerated: "true"
---

# Test: Accessibility — Keyboard Navigation

## Description

Verify that the Build Calculator and Database pages are navigable and operable using only the keyboard, with proper ARIA roles, focus indicators, and tab order.

## Rationale

The Build Calculator's hotkey viewer is inherently keyboard-centric (Q, W, E, R hotkeys add entities to the build order), but the **filter dropdowns, clear button, timing inputs, and option toggles** must also be reachable and activatable via keyboard (`Tab`, `Enter`, `Space`, arrow keys). A screen-reader user should be able to:
- Tab through the filter selects and timing inputs in logical order.
- Change a select value using arrow keys.
- Activate the "Clear Build Order" button with Enter or Space.
- See a visible focus ring on every interactive element.

No existing test verifies any of these accessibility requirements.

## Playwright Feature

This test uses **`page.evaluate()`** and **`page.accessibility.snapshot()`** (the Accessibility Tree API) to inspect ARIA attributes, plus **keyboard-based interaction** (Tab, Enter, arrow keys) to test the entire flow without a mouse.

### Approach

#### Tab Order Test

```js
// Starting at the top of the Build Calculator page
await page.keyboard.press('Tab');          // First focusable element
const focused1 = page.locator(':focus');
// Assert focused on the Faction select
await expect(focused1).toBeVisible();

await page.keyboard.press('Tab');          // Move to Immortal select
// Assert focus moved correctly
```

#### ARIA Snapshot Test

```js
const snapshot = await page.accessibility.snapshot();
// Verify the hotkey viewer container has role="application" or role="group"
// Verify selects have role="combobox" or role="listbox"
// Verify buttons have accessible names
```

#### Screen-Reader Logic Test

Verify that a filter select's `aria-label` or associated `<label>` text matches the visible label ("Faction", "Immortal"), using `page.locator('select').getAttribute('aria-label')`.

### What to Assert

- Every `<select>` has an associated `<label>` or an `aria-label` attribute.
- Every button in the hotkey viewer has an `aria-label` derived from the hotkey + entity name (e.g., "Q — Acropolis").
- The timeline's interactive items have a `role="listbox"` or `role="grid"`.
- Toast notifications have `role="alert"` or `aria-live="polite"` so screen readers announce them.
- No element has a `tabindex` greater than 0 (custom tab order) unless intentional.
- The "Clear Build Order" button is keyboard-reachable and activatable.

### Tools

Playwright uses the **Chromium Accessibility Tree** via `page.accessibility.snapshot()`, which mirrors what a Chromevox screen reader would expose. This is *not* a substitute for testing with a real screen reader, but it catches the most common ARIA violations at low cost.
