test(campaign): reforça e2e da barra inferior mobile após /simplify

- pina paddingTop >= 10px (pt-2.5) e cobre viewport 320px — o aceite da
  intenção promete rótulos legíveis em qualquer largura mobile.
This commit is contained in:
Francisco Solla 2026-08-08 18:45:42 -03:00
parent eb94a81ebc
commit f3d2f46a58
2 changed files with 33 additions and 21 deletions

View file

@ -64,7 +64,7 @@ N/A — chrome de navegação, sem dados hexibidos (a intenção já declara que
- **Risco:** rótulo 10px quebra acessibilidade percebida. **Mitigação:** é o tamanho do canvas aprovado; rótulos continuam `font-medium`, ícone `size-5` inalterado, alvo de toque pleno; nenhum rótulo some.
- **Risco:** `nowrap` + fonte pequena ainda estoura em viewport 320px. **Mitigação:** 10px "Atualizações" ≈ 66px em célula ≥64px (320px/5); o teste e2e novo pina a não-sobreposição em 390px (viewport do suite) e valida `fontSize`; se 320px for exigido depois, é outro item.
- **Risco:** mudança quebra o FAB. **Mitigação:** FAB test (y < nav.y) já cobre; barra cresce ~6px, `bottom-[7rem]` sobra.
- **Risco:** mudança quebra o FAB. **Mitigação:** FAB test (y < nav.y) já cobre; barra cresce ~10px, `bottom-[7rem]` sobra.
## Aceite de engenharia

View file

@ -127,29 +127,41 @@ test.describe('Mobile bottom nav (B164)', () => {
await page.goto('/campanha')
const bottomNav = page.locator('[aria-label="Navegação principal"]')
await expect(bottomNav).toBeVisible()
// A small breathing gap between the item content and the bar's top border.
const paddingTop = await bottomNav.evaluate((el) => parseFloat(getComputedStyle(el).paddingTop))
expect(paddingTop).toBeGreaterThanOrEqual(8)
const expectLabelsLegible = async () => {
await expect(bottomNav).toBeVisible()
// Labels render smaller than the original text-xs (12px).
const labels = bottomNav.locator('a > span, button > span')
await expect(labels).toHaveCount(5)
const sizes = await labels.evaluateAll((els) =>
els.map((el) => parseFloat(getComputedStyle(el).fontSize)),
)
for (const fontSize of sizes) expect(fontSize).toBeLessThan(12)
// A small breathing gap between the item content and the bar's top edge
// (pt-2.5 computes to 10px).
const paddingTop = await bottomNav.evaluate((el) =>
parseFloat(getComputedStyle(el).paddingTop),
)
expect(paddingTop).toBeGreaterThanOrEqual(10)
// Adjacent labels must not overlap horizontally on a mobile viewport.
const boxes = await labels.evaluateAll((els) =>
els.map((el) => {
const rect = el.getBoundingClientRect()
return { left: rect.left, right: rect.right }
}),
)
for (let i = 1; i < boxes.length; i++) {
expect(boxes[i].left).toBeGreaterThanOrEqual(boxes[i - 1].right - 0.5)
// Labels render smaller than the original text-xs (12px).
const labels = bottomNav.locator('a > span, button > span')
await expect(labels).toHaveCount(5)
const sizes = await labels.evaluateAll((els) =>
els.map((el) => parseFloat(getComputedStyle(el).fontSize)),
)
for (const fontSize of sizes) expect(fontSize).toBeLessThan(12)
// Adjacent labels must not overlap horizontally on a mobile viewport.
const boxes = await labels.evaluateAll((els) =>
els.map((el) => {
const rect = el.getBoundingClientRect()
return { left: rect.left, right: rect.right }
}),
)
for (let i = 1; i < boxes.length; i++) {
expect(boxes[i].left).toBeGreaterThanOrEqual(boxes[i - 1].right - 0.5)
}
}
// Default narrow phone (390px) and an extra-narrow one — the acceptance
// promises readable labels on "any mobile viewport", so cover both.
await expectLabelsLegible()
await page.setViewportSize({ width: 320, height: 640 })
await expectLabelsLegible()
})
})