Testes automatizados e auditoria manual para garantir acessibilidade web

Testes automatizados e auditoria manual para garantir acessibilidade web
“A acessibilidade não é um recurso opcional; é a base de uma experiência digital verdadeiramente inclusiva.”
A construção de interfaces que atendam a todas as pessoas vai muito além de aplicar algumas regras de estilo. É preciso adotar uma cultura de desenvolvimento que combine testes automatizados, auditoria manual e boas práticas de código. Neste artigo, vamos explorar passo a passo como integrar essas práticas ao seu fluxo de trabalho, garantindo conformidade com as diretrizes WCAG 2.2 e proporcionando uma experiência fluida para usuários de leitores de tela, navegação por teclado e outras tecnologias assistivas.
1. Por que combinar testes automatizados e auditoria manual?
| Aspecto | Testes Automatizados | Auditoria Manual |
|---|---|---|
| Velocidade | Executa milhares de verificações em segundos | Demanda tempo, mas foca em nuances |
| Cobertura | Detecta problemas de markup, contraste, atributos ARIA faltantes | Avalia fluxo de navegação, linguagem, contexto |
| Consistência | Repete o mesmo conjunto de regras em todas as builds | Adapta-se a mudanças de design e conteúdo |
| Feedback | Integração direta em CI/CD, bloqueia merges | Relatórios qualitativos, recomendações de usabilidade |
A combinação permite que você identifique rapidamente falhas técnicas (por exemplo, falta de alt em imagens) e, ao mesmo tempo, avalie a experiência real do usuário, como a ordem de foco ou a clareza de mensagens de erro.
2. Configurando o ambiente de testes automatizados
2.1 Ferramentas recomendadas
- axe-core (npm) – biblioteca JavaScript que roda no navegador ou em Node.
- Pa11y – CLI que gera relatórios de conformidade.
- Lighthouse – auditoria integrada ao Chrome DevTools, inclui métricas de acessibilidade.
- Storybook Accessibility Addon – valida componentes UI isolados.
2.2 Exemplo: Integração do axe-core com Jest
Instale as dependências:
npm install --save-dev jest axe-core @axe-core/webdriverjs selenium-webdriver
Crie o teste accessibility.test.js:
// accessibility.test.js
const {Builder, By} = require('selenium-webdriver');
const axe = require('axe-core');
describe('Acessibilidade da página principal', () => {
let driver;
beforeAll(async () => {
driver = await new Builder().forBrowser('chrome').build();
await driver.get('http://localhost:3000');
});
afterAll(async () => {
await driver.quit();
});
test('não deve ter violações de acessibilidade', async () => {
const source = await driver.getPageSource();
const results = await driver.executeAsyncScript((cb) => {
axe.run((err, result) => {
if (err) cb(err);
else cb(result);
});
});
// Falha se houver qualquer violação
expect(results.violations).toHaveLength(0);
});
});
Dica: Execute esse teste em seu pipeline de CI/CD. Se o número de violações for maior que zero, o build falha, garantindo que nenhum código novo quebre a acessibilidade.
2.3 Testando contraste de cores com Pa11y
npm install -g pa11y
pa11y http://localhost:3000 --reporter json > relatorio-acessibilidade.json
O JSON gerado contém linhas como:
{
"code": "WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail",
"type": "error",
"message": "Insufficient color contrast (foreground: #777777, background: #FFFFFF).",
"context": "<p style=\"color:#777777;\">..."
}
Use esses dados para corrigir contrastes críticos antes do próximo deploy.
3. Boas práticas de markup e ARIA
3.1 Estrutura semântica
- Use
,,,epara delimitar regiões. - Evite puro para componentes interativos; prefira
,ou.3.2 ARIA landmarks
<body><header role="banner"> <h1>Minha Aplicação</h1> </header>
<nav role="navigation" aria-label="Menu principal"> <ul> <li><a href="/dashboard">Dashboard</a></li> <li><a href="/relatorios">Relatórios</a></li> </ul> </nav>
<main role="main"> <!-- Conteúdo principal --> </main>
<footer role="contentinfo"> © 2026 Minha Empresa </footer> </body>
Os landmarks permitem que leitores de tela pulem rapidamente para áreas importantes.
3.3 Controle de foco
Um dos erros mais comuns é perder o foco ao abrir modais ou menus. O código abaixo cria um focus trap simples em JavaScript:
<!-- Modal --><div id="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title" hidden> <h2 id="modal-title">Confirmar ação</h2> <p>Deseja realmente excluir este item?</p> <button id="confirmBtn">Confirmar</button> <button id="cancelBtn">Cancelar</button> </div>
<button id="openModal">Abrir modal</button>
// focus-trap.jsconst modal = document.getElementById('modal'); const openBtn = document.getElementById('openModal'); const focusableEls = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'; let firstFocusable, lastFocusable;
function openModal() { modal.hidden = false; const focusables = modal.querySelectorAll(focusableEls); firstFocusable = focusables[0]; lastFocusable = focusables[focusables.length - 1]; firstFocusable.focus(); }
function closeModal() { modal.hidden = true; openBtn.focus(); }
openBtn.addEventListener('click', openModal); modal.addEventListener('keydown', (e) => { if (e.key !== 'Tab') return;
if (e.shiftKey) { // Shift + Tab if (document.activeElement === firstFocusable) { e.preventDefault(); lastFocusable.focus(); } } else { // Tab if (document.activeElement === lastFocusable) { e.preventDefault(); firstFocusable.focus(); } } });
document.getElementById('cancelBtn').addEventListener('click', closeModal); document.getElementById('confirmBtn').addEventListener('click', () => { // ação de confirmação closeModal(); });
Esse script garante que, enquanto o modal estiver aberto, o foco circule apenas dentro dele, evitando que usuários de teclado fiquem presos no conteúdo de fundo.
4. Auditoria manual: checklist essencial
Mesmo com ferramentas, a visita humana continua indispensável. Use a checklist abaixo em cada release:
Item Como validar Ferramentas auxiliares Leitura de tela Navegue usando NVDA (Windows) ou VoiceOver (macOS). Verifique se as informações são anunciadas na ordem correta. NVDA, VoiceOver Navegação por teclado Use Tab,Shift+Tab,EntereEsc. Certifique‑se de que todos os controles são acessíveis e que não há focus traps inesperados.Chrome DevTools (Focus outline) Contraste Verifique manualmente com a extensão WCAG Contrast Checker ou com o relatório do Pa11y. WCAG Contrast Checker Textos alternativos Passe o mouse sobre imagens e veja se o atributo altdescreve o conteúdo.Inspect Element Tamanho de toque Em dispositivos móveis, teste se alvos têm ao menos 44 × 44 px. Chrome DevTools (Device Mode) Mensagens de erro Submeta formulários com campos vazios e confirme se as mensagens são claras e associadas ao campo ( aria-describedby).Formulário de teste 4.1 Exemplo de mensagem de erro acessível
<form id="loginForm" novalidate><label for="email">E‑mail</label> <input type="email" id="email" name="email" required aria-describedby="emailError"> <div id="emailError" class="error" hidden>Por favor, informe um e‑mail válido.</div>
<label for="senha">Senha</label> <input type="password" id="senha" name="senha" required aria-describedby="senhaError"> <div id="senhaError" class="error" hidden>Campo obrigatório.</div>
<button type="submit">Entrar</button> </form>
// validação simplesdocument.getElementById('loginForm').addEventListener('submit', (e) => { const email = document.getElementById('email'); const senha = document.getElementById('senha'); let valid = true;
if (!email.checkValidity()) { document.getElementById('emailError').hidden = false; email.focus(); valid = false; } else { document.getElementById('emailError').hidden = true; }
if (!senha.checkValidity()) { document.getElementById('senhaError').hidden = false; if (valid) senha.focus(); valid = false; } else { document.getElementById('senhaError').hidden = true; }
if (!valid) e.preventDefault(); });
A associação via
aria-describedbygarante que leitores de tela leiam a mensagem de erro imediatamente após o
Artigos relacionados
Análise de DadosWeb Inclusiva: Implementando WCAG, ARIA e Testes de Conformidade
AdminDescubra como tornar suas aplicações web verdadeiramente inclusivas aplicando as diretrizes WCAG 2.1, atributos ARIA, ferramentas de análise automática e testes de usabilidade. O guia traz conceitos, boas práticas e código funcional para desenvolv...
Ler artigo →
Análise de DadosAnálise de Dados Avançada
Luis CubaAprenda sobre as últimas tecnologias e ferramentas de análise de dados para melhorar sua capacidade de tomar decisões informadas
Ler artigo →
Análise de DadosLakehouses Open Source: A Nova Era da Análise de Dados
Luis CubaExplore a arquitetura Lakehouse open source, combinando o melhor de Data Lakes e Data Warehouses. Descubra como ferramentas como Apache Iceberg, Delta Lake e Apache Hudi transformam a análise de dados.
Ler artigo →