#이미 고친 블로그를 다시 열었다
블로그의 읽기 화면과 목차, 복사, 그래프 개선은 이미 main에 병합돼 있었다. 이전 기록에는 데스크톱과 모바일에서 직접 본 화면도 있었다. 이번에는 그 개선을 처음부터 다시 만드는 대신 빠진 조건을 확인했다.
실제 화면은 Ego Lite에서 열었고 자동 접근성 검사는 브라우저에 주입한 axe-core로 실행했다. 앱에 검사 라이브러리를 배포한 것은 아니다. 테마를 바꾸고, 영어로 전환하고, 화면을 더 좁혔다. 마우스 대신 Tab으로 이동했다. 평소 쓰는 한 가지 조합에서는 잘 보이지 않던 문제가 나왔다.
그래프의 연결 목록은 색만으로 링크를 구분하고 있었다. 필터를 적용하면 선택되지 않은 노드의 글자가 너무 흐려졌다. 에피소드 검색창에는 기록 검색이라는 이름이 붙어 있었고, 영어 화면의 홈 링크도 접근성 이름은 한국어였다.
#흐리게 만든 글자도 읽어야 했다
그래프는 선택한 항목을 강조하려고 나머지 요소의 투명도를 낮췄다. 그런데 연결선과 노드에 같은 값을 적용하면서, 노드 안의 글자까지 배경에 묻혔다.
선과 글자를 나눠 봤다. 연결선의 opacity는 0.12로 유지하고, 노드만 0.7로 바꿨다. 필터와 포커스 상태 16조건에서 글자 최소 대비는 라이트 5.21:1, 다크 7.58:1로 확인됐다. 배치나 글꼴을 바꾸지 않아도 읽기 어려웠던 부분을 고칠 수 있었다.
연결 목록의 링크에는 기본 밑줄을 넣었다. 검색창과 홈 링크의 이름은 현재 화면의 언어와 용도에 맞췄다. 수정한 조건마다 브라우저에서 다시 확인했다.
#violations 말고 incomplete도 열어봤다
화면을 돌며 얻은 자동 검사 결과에는 violations가 0으로 나왔다. 그런데 axe 결과에는 도구가 판정을 끝내지 못한 incomplete 항목도 있었다. 그 내용을 열어보니 에피소드 목록의 시대별 제목 연결이 끊겨 있었다.
원인은 공백이 들어간 ID였다. 화면에 제목 글자는 보였지만, aria-labelledby가 가리키는 대상을 제대로 찾지 못했다. 눈으로 제목을 읽는 것과 보조 기술이 그 제목을 찾는 것은 달랐다.
먼저 서버 렌더링 결과에서 참조가 끊기는 회귀 테스트를 추가하고 실패를 확인했다. 새 ID 규칙을 만들 필요는 없었다. 이미 사용하던 eraKey를 section과 제목 ID에 함께 썼다. 테스트를 통과시킨 뒤 최종 실행본의 해당 화면을 12조건으로 다시 확인했다. 시대별 제목 참조가 모두 연결됐고, 관련 ARIA 검사에서도 incomplete와 violations가 남지 않았다.
수정한 JSX의 연결은 짧았다. 같은 키를 section의 참조와 h2의 ID에 쓰는 것이 전부였다.
<section aria-labelledby={eraKey(group.era)}>
<h2 id={eraKey(group.era)}>{group.era}</h2>
</section>
회귀 테스트는 Node.js의 node:test에서 React의 renderToStaticMarkup으로 목록을 렌더링했다. 생성한 제목 ID가 중복되지 않고 공백이 없는지, aria-labelledby의 각 참조가 실제 제목 ID를 찾는지 검사했다. 브라우저를 열기 전에 끊어진 참조를 잡고, 브라우저에서는 최종 DOM의 접근성 결과를 다시 확인하는 방식이었다.
axe의 violations와 incomplete는 결과 배열도 따로다. axe-core API 문서에 설명된 대로, 판정을 끝내지 못한 결과는 추가 확인이 필요하다. 이번에는 그 배열 안의 노드를 열어 참조 오류를 찾았다.
자동 검사 0건은 그 검사에서 오류를 보고하지 않았다는 결과였다. 판정하지 못한 항목까지 확인했다는 뜻으로 읽으면 이 문제를 놓쳤을 것이다.
#검사 숫자를 합치지 않았다
이번에는 확인 조건을 넓게 잡았다. 10화면에 화면 너비 1280·390·360, 한·영, 라이트·다크를 조합해 120조건을 확인했다. 가로 넘침은 없었다. 이 중 1280 너비에서는 자동 접근성 검사를 40회 실행했다.
키보드 이동도 따로 봤다. 10화면에서 Tab을 347회 눌러 포커스가 빠지거나 보이지 않는 곳이 있는지 확인했다. 스킵 링크, 언어 메뉴, 검색 초기화, 목차, 그래프 이동도 확인했다.
다만 이 숫자들이 전부 같은 실행본에서 나온 것은 아니다. 화면 행렬과 키보드 이동은 해당 검증 단계의 기록이다. 마지막 ARIA 수정 뒤에는 영향을 받는 화면의 12조건과 회귀 테스트를 다시 검사했다. 앞서 통과한 모든 화면을 마지막 코드에서 다시 봤다고 적지 않았다.
#다섯 가지 수정과 남은 검사
이번에 확인한 문제 다섯 가지는 수정했다. 최종 테스트 55개, 타입 검사, ESLint, production build가 통과했다. 블로그 변경 9개 파일은 2102acc1b로 커밋한 뒤 main에 병합했다. 운영 배포는 하지 않았다.
접근성과 디자인 전체를 완료로 표시하지는 않았다. VoiceOver와 NVDA 실사용, 전체 SVG 비텍스트 대비, 글자 확대, OS 클립보드와 인쇄 대화상자는 확인이 남아 있다. 운영 화면도 이번 검증에 포함하지 않았다.
전체 화면의 디자인 판정에는 선택된 이미지 청사진과 항목별 비교가 필요하다. 이번에는 그 입력이 없어서 청사진 일치율 95%를 계산하지 않았고, 전체 디자인 gate도 gap으로 남겼다. 실제 전후 화면으로 수정 효과를 확인한 것과 전체 디자인을 통과시킨 것은 범위가 다르다.
화면 90장을 검수했는데 빠진 화면이 있었다에서는 검수 목록에서 빠진 화면을 찾았다. 이번에는 검사 결과 안에서 아직 판단하지 못한 항목을 찾았다. 다음 검증을 시작할 때는 통과 개수보다 그 목록부터 열어볼 생각이다.