본문으로 건너뛰기

8.2 Visual, accessibility test

Screenshot comparison은 layout, style 회귀를 찾고 accessibility test는 semantic rule 위반을 찾습니다. 둘 다 기능 assertion을 대체하지 않습니다.

await expect(page).toHaveScreenshot('todo-list.png', {
animations: 'disabled',
mask: [page.getByTestId('current-time')],
});

Screenshot baseline은 OS, browser, font, rendering 환경에 민감합니다. CI의 고정 image에서 생성, 비교하고 변경된 pixel을 제품 변경과 noise로 구분해 review합니다.

접근성은 @axe-core/playwright 같은 도구를 연결할 수 있습니다.

import AxeBuilder from '@axe-core/playwright';

const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);

자동 rule은 keyboard flow, screen reader 경험, content 의미를 모두 보장하지 않습니다. getByRole locator, focus 이동, keyboard navigation test와 수동 검토를 결합합니다.

Baseline update와 accessibility 예외에는 reviewer, 이유, 만료일을 둡니다. 무조건 snapshot을 갱신하거나 violation을 전역 제외하면 quality gate가 사라집니다.

참고: Visual comparisons, Accessibility testing

Visual과 accessibility를 같이 보는 이유

Pixel이 같아도 accessible name이 사라질 수 있고, ARIA tree가 같아도 overlay로 button이 가려질 수 있습니다. DOM assertion, visual comparison, ARIA snapshot, axe, manual keyboard test는 서로 다른 결함을 찾습니다.

Gate 분리

  • PR: 핵심 component visual, targeted ARIA assertion
  • Nightly: 넓은 visual matrix, 전체 axe scan
  • Release: baseline diff human approval, known issue delta 확인

Known issue fingerprint

Axe result 전체를 snapshot하면 DOM detail 때문에 흔들립니다. Rule ID와 target만 정규화해 기존 위반이 늘지 않았는지 확인하고, owner와 만료일을 관리합니다.

실습

  1. Button label 제거가 visual과 ARIA에 각각 어떻게 보이는지 확인합니다.
  2. Padding change가 ARIA snapshot에는 영향이 없음을 확인합니다.
  3. Dynamic timestamp를 Clock으로 고정한 visual test를 만듭니다.
  4. Automated scan이 놓치는 keyboard focus order를 수동 점검합니다.