# História 22 — Acesso no mobile e sem JavaScript

- **Spec:** `tests/22-cms-acesso-mobile.spec.ts`
- **Camadas:** E2E (Playwright + axe) no projeto `cms-mobile` (Pixel 7) + bloco sem JS
- **Dono:** Infraestrutura / Acesso (`Modules\Infraestrutura\Acesso`)
- **Status:** ativa

## Jornada
O administrador percorre as quatro superfícies da P2 no **viewport de toque** — lista de usuários,
lista de perfis, matriz de permissões e perfil próprio — sem overflow horizontal e com **axe** em
cada uma. A célula da matriz mantém alvo ≥ 44 px. Em seguida o mesmo fluxo crítico (criar perfil
pela matriz e excluir) é repetido com **JavaScript desligado**: a matriz é um formulário nativo
(`<form method="post">` + checkboxes) e a confirmação de exclusão usa o **Popover nativo**, então
nada depende de script.

## Critérios de aceite
1. `/usuarios`, `/papeis`, `/papeis/criar` e `/perfil` não estouram o viewport (360 px) e têm `<h1>`
   único no conteúdo.
2. **Axe sem violações A/AA** nas quatro telas no viewport de toque (o axe desktop já cobre as
   mesmas telas em `19`/`20`/`21`).
3. Alvo da matriz ≥ 44 px (2.75rem) no ponteiro grosso.
4. Sem JavaScript: a matriz continua semântica (tabela com `caption`), a ação não declarada segue
   **desabilitada** e criar/excluir perfil funciona pelo formulário e pelo Popover nativos.
5. Cada execução cria e exclui o próprio perfil (`Perfil Mobile E2E <timestamp>`); nenhum outro
   spec depende dele e o lote global roda antes (`dependencies: ['cms-serial']`).

## Evidência
`make check E2E=1` (projeto `cms-mobile`, spec `22-cms-acesso-mobile`) + PHPUnit
`AcessoRolesCmsTest`/`AcessoUsersCmsTest`/`AcessoProfileCmsTest` (contrato de layout e matriz sem JS).

## Observação de dados
O bloco sem JS cria e exclui o perfil na mesma execução (limpeza determinística pela UI). O
`javaScriptEnabled: false` vale só para esse `describe`; o primeiro teste roda com JS para o axe.
