<p><strong>Meta Description:</strong> Aprenda a testar acessibilidade: WCAG 2.1, ARIA, screen readers, testes automatizados e manuais para garantir que seu site é acessível a todos.</p>

<hr>
<h2>O Que é Acessibilidade?</h2>

<p>Acessibilidade web garante que pessoas com deficiências podem usar websites. No Brasil, a <strong>Lei Brasileira de Inclusão (Lei 13.146/2015)</strong> exige acessibilidade em sites públicos e de empresas.</p>

<h3>Por Que Importa?</h3>

<ul><li><strong>Inclusão</strong>: 15{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} da população tem algum tipo de deficiência</li><ol><li><strong>Legal</strong>: Conformidade com LGPD e leis</li>
<li><strong>SEO</strong>: Sites acessíveis rankeiam melhor</li>
<li><strong>UX</strong>: Boas práticas beneficiam todos</li>
</ol>
<hr>
<h2>WCAG 2.1 - 4 Princípios</h2>

<h3>1. Perceivable (Perceptível)</h3>

<pre><code><!-- Imagens com alt text -->
<img src="logo.png" alt="Empresa X - Página inicial">

<p><!-- Vídeos com legendas --><br><video><br>  <track kind="subtitles" src="legendas.vtt" srclang="pt" label="Português"><br></video></p>

<p><!-- Contrast adequado --><br><br>  .text {<br>    color: #1a1a1a;        /<em> Pior: #767676 = 4.5:1 em fundo branco </em>/<br>    background: #ffffff;   /<em> Melhor: #1a1a1a = 21:1 em fundo branco </em>/<br>  }<br><br></code></pre></p>

<h3>2. Operable (Operável)</h3>

<pre><code><!-- Navegação por teclado -->
<nav>
  <a href="#main" class="skip-link">Pular para conteúdo principal</a>
  <a href="#menu">Menu</a>
  <a href="#search">Busca</a>
</nav>

<p><br>.skip-link {<br>  position: absolute;<br>  top: -40px;<br>  left: 0;<br>  background: #000;<br>  color: #fff;<br>  padding: 8px;<br>  z-index: 100;<br>}<br>.skip-link:focus {<br>  top: 0;<br>}<br></p>

<p><!-- Focus visível --><br>:focus {<br>  outline: 3px solid #005fcc;<br>  outline-offset: 2px;<br>}<br></code></pre></p>

<h3>3. Understandable (Compreensível)</h3>

<pre><code><!-- Labels em inputs -->
<label for="email">Email</label>

<span id="email-hint">Formato: usuario@dominio.com</span>

<p><!-- Erros claros --><br><div class="error" role="alert"><br>  <span id="password-error">Senha deve ter:</span><br>  <ul aria-labelledby="password-error"><br>    <li id="error-length">Mínimo 8 caracteres</li><br>    <li id="error-number">Pelo menos 1 número</li><br>  </ul><br></div><br></code></pre></p>

<h3>4. Robust (Robusto)</h3>

<pre><code><!-- HTML semântico -->
<header role="banner">
  <nav role="navigation" aria-label="Menu principal">
  <main role="main">
  <article role="article">
  <aside role="complementary">
  <footer role="contentinfo">
</code></pre>

<hr>
<h2>ARIA - Accessible Rich Internet Applications</h2>

<h3>Roles</h3>

<pre><code><!-- Landmarks -->
<header role="banner">
<nav role="navigation">
<main role="main">
<aside role="complementary">
<footer role="contentinfo">

<p><!-- Widgets --><br><button role="button" aria-expanded="false"><br><div role="menu" aria-label="Menu"><br><div role="menuitem"><br><div role="tablist"><br><div role="tab"><br><div role="tabpanel"><br><div role="dialog" aria-labelledby="dialog-title"><br></code></pre></p>

<h3>Estados e Propriedades</h3>

<pre><code><!-- Expanded/Collapsed -->
<button aria-expanded="false" aria-controls="menu-content">
<div id="menu-content" hidden>

<p><!-- Selected --><br><br></p>

<p><!-- Disabled --><br><button></p>

<p><!-- Live Regions --><br><div aria-live="polite">Notificação</div><br><div aria-live="assertive">Erro</div><br><div><br></code></pre></p>

<hr>
<h2>Testes Automatizados</h2>

<h3>axe-core</h3>

<pre><code>// Playwright + axe
const { test, expect } = require('@playwright/test');
const AxeBuilder = require('@axe-core/playwright').default;

<p>test('accessibility on login page', async ({ page }) =&gt; {<br>  await page.goto('/login');</p>

<p>const accessibilityScanResults = await new AxeBuilder({ page })<br>    .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])<br>    .analyze();</p>

<p>// Log violations<br>  if (accessibilityScanResults.violations.length &gt; 0) {<br>    console.log('Violations found:');<br>    accessibilityScanResults.violations.forEach(v =&gt; {<br>      console.log(<code>  - ${v.id}: ${v.description}</code>);<br>    });<br>  }</p>

<p>// Fail if critical violations<br>  const critical = accessibilityScanResults.violations.filter(<br>    v =&gt; v.impact === 'critical'<br>  );<br>  expect(critical.length, <code>${critical.length} critical violations</code>).toBe(0);<br>});<br></code></pre></p>

<pre><code># pytest + axe
import pytest
from playwright.sync_api import Page

<p>def test_accessibility(page: Page):<br>    page.goto('/login')</p>

<p>results = page.run_axe()</p>

<p>critical_violations = [<br>        v for v in results['violations']<br>        if v['impact'] in ['critical', 'serious']<br>    ]</p>

<p>assert len(critical_violations) == 0, (<br>        f"Found {len(critical_violations)} critical accessibility violations"<br>    )<br></code></pre></p>

<h3>Lighthouse CI</h3>

<pre><code># .github/workflows/a11y.yml
name: Accessibility Tests

<p>on: [push, pull_request]</p>

<p>jobs:<br>  accessibility:<br>    runs-on: ubuntu-latest<br>    steps:<br>      - uses: actions/checkout@v4</p>

<p>- name: Run Lighthouse CI<br>        uses: treosh/lighthouse-ci-action@v10<br>        with:<br>          urls: |<br>            https://example.com/<br>            https://example.com/login<br>          budgetPath: ./lighthouse-budget.json<br>          uploadArtifacts: true<br>          temporaryPublicStorage: true</p>

<p># lighthouse-budget.json<br>{<br>  "ci": {<br>    "collect": {<br>      "startServerCommand": "npm run start",<br>      "url": [<br>        "http://localhost:8080/"<br>      ]<br>    },<br>    "assert": {<br>      "assertions": {<br>        "categories:accessibility": ["error", {"minScore": 0.9}]<br>      }<br>    }<br>  }<br>}<br></code></pre></p>

<hr>
<h2>Testes Manuais</h2>

<h3>Checklist de Testes Manuais</h3>

<pre><code># Accessibility Testing Checklist

<h2>Navegação por Teclado</h2><ol><li>[ ] Tab percorre todos os elementos interativos</li>
<li>[ ] ordem de foco faz sentido</li>
<li>[ ] Focus é sempre visível</li>
<li>[ ] Links úteis no topo (skip link)</li>
<li>[ ] ESC fecha modais</li>
<li>[ ] Enter ativa botões e links</li>
</ol>
<h2>Imagens</h2><ol><li>[ ] Todas imagens têm alt text</li>
<li>[ ] Alt text descreve conteúdo/função</li>
<li>[ ] Imagens decorativas têm alt=""</li>
<li>[ ] Textos em imagens evitados</li>
</ol>
<h2>Contrastes</h2><ol><li>[ ] Texto normal: 4.5:1 mínimo</li>
<li>[ ] Texto grande (18pt+): 3:1 mínimo</li>
<li>[ ] Gráficos: 3:1</li>
</ol>
<h2>Formulários</h2><ol><li>[ ] Labels associados a inputs</li>
<li>[ ] Erros descritos claramente</li>
<li>[ ] Campos obrigatórios marcados</li>
<li>[ ] Autocomplete quando aplicável</li>
</ol>
<h2>Semântica</h2><ol><li>[ ] Cabeçalhos em ordem (h1 &gt; h2 &gt; h3)</li>
<li>[ ] Listas usam <ul>/<ol></li>
<li>[ ] Tabelas têm headers</li>
<li>[ ] Landmarks definidos</li>
</ol>
<h2>ARIA</h2><ol><li>[ ] ARIA usado quando HTML não é suficiente</li>
<li>[ ] ARIA não sobrepõe semântica nativa</li>
<li>[ ] Live regions atualizam corretamente</li>
</ol></code></pre>

<h3>Screen Reader Testing</h3>

<pre><code># Screen Reader Testing

<h2>VoiceOver (macOS)</h2><ol><li>Cmd + F5: Ativar VoiceOver</li>
<li>Tab/Cmd + Option + Setas: Navegar</li>
<li>Cmd + Option + U: Rotor</li>
</ol>
<h2>NVDA (Windows)</h2><ol><li>Insert + D: Ler documento</li>
<li>Tab: Próximo elemento</li>
<li>Insert + Espaço: Modo foco</li>
</ol>
<h2>Verificar:</h2><ol><li>[ ] Ordem de leitura faz sentido</li>
<li>[ ] Imagens descritas</li>
<li>[ ] Links têm contexto</li>
<li>[ ] Formulários etiquetados</li>
<li>[ ] Tabelas fazem sentido</li>
<li>[ ] Headings navegáveis</li></ol></ul>
</code></pre>

<hr>
<h2>Ferramentas</h2>

<figure class="wp-block-table"><table>
<tr><th>Ferramenta</th><th>Tipo</th><th>Custo</th></tr>
<tr><td><strong>axe DevTools</strong></td><td>Browser Extension</td><td>Grátis</td></tr>
<tr><td><strong>WAVE</strong></td><td>Browser Extension</td><td>Grátis</td></tr>
<tr><td><strong>Lighthouse</strong></td><td>DevTools/CLI</td><td>Grátis</td></tr>
<tr><td><strong>AXE-core</strong></td><td>Library</td><td>Grátis</td></tr>
<tr><td><strong>SiteImprove</strong></td><td>SaaS</td><td>Pago</td></tr>
<tr><td><strong>Deque aXe</strong></td><td>Enterprise</td><td>Pago</td></tr>
<tr><td><strong>Tenon.io</strong></td><td>API</td><td>Pago</td></tr>
</table></figure>

<hr>
<h2>Conclusão</h2>

<p>Acessibilidade é fundamental para inclusão. As chaves são:<br><ol><li><strong>Semântica primeiro</strong> - Use HTML correto</li><br><li><strong>Teste automatizado</strong> - Capture issues rapidamente</li><br><li><strong>Teste manual</strong> - Screen readers e teclado</li><br><li><strong>WCAG compliance</strong> - Atingir nível AA mínimo</li><br><li><strong>Continuous testing</strong> - Integre ao CI/CD</li></ol></p>