Claude Skills Guide

Claude Code Keyboard Navigation Testing Guide

Keyboard navigation testing ensures your web applications remain accessible to users who rely on keyboards instead of pointing devices. This guide covers practical testing strategies using Claude Code skills, test frameworks, and automation patterns that integrate smoothly into your development workflow.

Why Keyboard Navigation Testing Matters

Users with motor disabilities, power users who prefer keyboard efficiency, and screen reader users all depend on proper keyboard navigation. Beyond accessibility compliance with WCAG 2.1 AA standards, testing keyboard flows catches regression bugs that break tab order, focus management, and keyboard shortcuts.

Core Testing Strategies

Manual Testing Fundamentals

Before automating, establish baseline manual testing. Check these critical paths:

Automated Testing with Playwright

The webapp-testing skill provides excellent tooling for keyboard navigation automation. Here’s a test pattern:

import { test, expect } from '@playwright/test';

test('keyboard navigation flows correctly', async ({ page }) => {
  await page.goto('/');
  
  // Start from first interactive element
  await page.keyboard.press('Tab');
  await expect(page.locator(':focus')).toHaveAttribute('data-testid', 'menu-button');
  
  // Navigate through menu items
  await page.keyboard.press('ArrowDown');
  await expect(page.locator(':focus')).toHaveText('Option One');
  
  // Activate with Enter
  await page.keyboard.press('Enter');
  await expect(page.locator('#panel')).toBeVisible();
});

Focus Management Testing

Proper focus management prevents users from losing context. Test these scenarios:

test('modal focus management', async ({ page }) => {
  await page.click('#open-modal');
  
  // Focus should move to modal
  await expect(page.locator('.modal')).toBeFocused();
  
  // Tab should cycle within modal
  const focusableElements = page.locator('.modal button, .modal input');
  await page.keyboard.press('Tab');
  await expect(focusableElements.first()).toBeFocused();
  
  // Escape should close and return focus
  await page.keyboard.press('Escape');
  await expect(page.locator('#open-modal')).toBeFocused();
});

Integration with Claude Code Skills

Using tdd Skill for Test-Driven Development

The tdd skill helps structure your keyboard navigation tests properly:

/tdd create keyboard navigation test suite for modal component with focus trap tests

This generates a test file with proper structure:

describe('Modal Keyboard Navigation', () => {
  beforeEach(async ({ page }) => {
    await page.goto('/modal');
  });

  it('traps focus within modal', async ({ page }) => {
    // Implementation here
  });

  it('returns focus on close', async ({ page }) => {
    // Implementation here
  });
});

Automating with frontend-design Skill

The frontend-design skill includes accessibility patterns:

/frontend-design add keyboard navigation patterns to my navigation component

This adds ARIA attributes and keyboard handlers:

// Generated pattern includes:
nav.addEventListener('keydown', (e) => {
  const items = [...nav.querySelectorAll('[role="menuitem"]')];
  const index = items.indexOf(document.activeElement);
  
  switch(e.key) {
    case 'ArrowDown':
      e.preventDefault();
      items[(index + 1) % items.length].focus();
      break;
    case 'ArrowUp':
      e.preventDefault();
      items[(index - 1 + items.length) % items.length].focus();
      break;
  }
});

Continuous Integration

Add keyboard navigation tests to your CI pipeline:

# .github/workflows/accessibility.yml
name: Accessibility Tests
on: [push, pull_request]

jobs:
  keyboard-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test tests/keyboard-navigation.spec.ts

Common Pitfalls

Missing Focusable Elements

Divs and spans with click handlers aren’t focusable by default. Add tabindex="0" or use semantic elements:

<!-- Wrong -->
<div onclick="openMenu()">Menu</div>

<!-- Correct -->
<button onclick="openMenu()">Menu</button>
<!-- or -->
<div tabindex="0" role="button" onclick="openMenu()">Menu</div>

Focus Loss After Dynamic Updates

Single-page applications often lose focus when DOM updates. Use the superpower skill to audit focus management:

/superpower check for focus loss issues in my React app

Visual Regression Testing

Combine keyboard navigation tests with visual regression using the screenshot-testing approach:

test('keyboard focus visual states', async ({ page }) => {
  await page.goto('/form');
  
  const inputs = page.locator('input');
  const count = await inputs.count();
  
  for (let i = 0; i < count; i++) {
    await page.keyboard.press('Tab');
    await expect(page.locator(':focus')).toHaveScreenshot(
      `focus-state-${i}.png`
    );
  }
});

Test Coverage Checklist

Create a test checklist covering these keyboard scenarios:

Scenario Test Method
Tab order Sequential Tab presses
Skip links Tab from page start
Dropdown navigation Arrow key navigation
Modal traps Tab cycling
Shortcut conflicts Key press combinations
Form validation Tab through errors

Conclusion

Keyboard navigation testing protects accessibility while improving usability for all users. Automate regression tests with Playwright, integrate with Claude Code skills like tdd and frontend-design, and maintain coverage through CI pipelines. Regular testing catches issues early and ensures your applications remain navigable by keyboard.

Built by theluckystrike — More at zovo.one