대부분의 접근성 테스트는 사이트의 한 가지 버전, 즉 팀이 매일 만들고 들여다보는 버전에서만 이루어진다. 보통은 영어로 되어 있고 보통은 사무실에서 확인한다. 하지만 시장이 열 개 넘게 있는 사이트는 사실상 열 개 넘는 사이트나 마찬가지다. 번역은 텍스트 길이와 줄바꿈을 바꾸고, 현지 팀은 자체 배너와 양식을 추가하며, 나라마다 다른 컴포넌트가 나타나고, 베를린이나 도쿄의 방문자가 받는 버전은 한 번도 테스트되지 않았을 수도 있다.
우리는 이것이 실제로 얼마나 중요한지 알고 싶었다. 그래서 23개의 대형 다국가 웹사이트를 선정하여 각국 내부에서 미국, 독일, 프랑스, 일본 버전을 불러온 뒤 동일한 자동화 접근성 감사를 모두 실행했다. 이 가이드는 우리가 발견한 내용, 사용한 코드, 그리고 시장을 고려한 테스트를 여러분의 프로세스에 구축하는 방법을 소개한다.
핵심 요약
- 여러분이 테스트하는 버전이 모든 사람이 받는 버전은 아니다. 결과가 안정적이었던 20개 사이트 중 5개는 현지화된 버전에서 미국 버전에는 전혀 나타나지 않았던 유형의 접근성 결함을 최소 한 가지 이상 가지고 있었다.
- 그 차이는 구체적이었다. 회원가입 양식의 라벨 없는 생년월일 필드, 라벨 없는 검색창, 텍스트 대체 수단이 없는 이미지, 이름 없는 버튼, 대비가 기준을 통과하지 못한 텍스트 등이다.
- 페이지는 방문 간에도 변하므로 먼저 노이즈를 측정해야 한다. 23개 사이트 중 3개는 몇 분 간격으로 동일한 미국 페이지를 두 번 불러왔을 때 서로 다른 결과를 보였다.
- 자동화된 규칙은 문제의 일부만 잡아낸다. 이를 시장별 회귀 테스트망으로 취급하고, 보조 기술을 사용한 수동 테스트를 함께 유지해야 한다.
- EU에서는 2025년 6월 28일부터 유럽 접근성법(European Accessibility Act)이 전자상거래를 포함한 많은 소비자 서비스에 적용되고 있어, 모든 시장 버전이 컴플라이언스 대상에 포함된다.
하나의 버전만으로는 충분하지 않은 이유
시장마다 접근성에 영향을 줄 수 있는 여러 요소가 달라진다.
- 텍스트. 독일어 단어는 길고, 일본어 텍스트는 다른 글꼴과 줄바꿈 방식을 사용하며, 번역된 라벨은 누락되거나 중복되거나 비어 있을 수 있다.
- 컴포넌트. 동의 배너, 쿠키 벽, 연령 확인, 통화 및 국가 선택기, 현지 결제 위젯, 지역 프로모션은 일부 시장에서만 나타나는 경우가 많다.
- 콘텐츠. 현지 마케팅 팀이 자체 이미지와 캠페인을 게시하며, 때로는 메인 디자인 시스템 밖에서 게시하고, 대체 텍스트가 가장 먼저 누락되는 요소다.
- 전달 방식. 일부 사이트는 지역별로 다른 빌드, 도메인, 콘텐츠 관리 인스턴스를 제공한다.
이러한 버전이 어떻게 보이는지는 방문자가 어디에 있는지에 달려 있다. 미국 사무실에서 독일 페이지를 불러오는 테스트는 리디렉션을 당하거나, 다른 동의 흐름을 보거나, 지역 컴포넌트의 미국 버전을 보게 될 수 있다. 독일 사용자가 받는 것을 테스트하려면, 테스트가 독일에 있는 방문자로서 실행되어야 한다.
테스트 방법
우리는 홈페이지의 미국 영어, 독일어, 프랑스어, 일본어 버전을 게시하는 대형 웹사이트들을 선정했으며, URL은 각 사이트 자체의 hreflang 주석에서 가져왔다. 2026년 10월 4일, 우리는 해당 국가와 일치하는 Shifter 종료 지점을 통해 Chromium에서 각 버전을 불러왔으며, 브라우저의 언어와 시간대는 뉴욕(미국), 베를린, 파리, 도쿄에 맞춰 설정했다. 클라이언트 측 렌더링과 동의 배너를 위해 5초를 기다린 뒤, WCAG 2 Level A 및 AA 규칙을 적용한 axe-core 4.13을 실행했다.
처음 시작한 25개 사이트 중 2개는 모든 시장에서 차단 페이지를 반환하여 제외되었고, 23개가 남았다. 노이즈를 측정하기 위해 모든 미국 페이지를 두 번씩 감사했다. 23개 사이트 중 3개는 이 두 번의 미국 실행 사이에 서로 다른 결과를 보였는데, 보통 순환 배너나 무작위로 로드되는 콘텐츠 때문이었으므로, 시장 간 비교 시에는 이 세 사이트를 제외했다.
발견한 내용
| 측정 항목 | 미국, 첫 번째 실행 | 미국, 두 번째 실행 | 독일 | 프랑스 | 일본 |
|---|---|---|---|---|---|
| 23개 사이트 전체의 위반 사례 수 | 158 | 165 | 174 | 168 | 161 |
| 감지된 위반이 없는 사이트 수 | 6 | 5 | 3 | 3 | 5 |
| 페이지당 평균 위반 유형 수 | 1.6 | 1.7 | 1.8 | 1.8 | 1.7 |
현지화된 버전은 모든 측정 항목에서 약간 더 나쁜 결과를 보였지만, 이 수준에서의 차이는 실행 간 노이즈에 가깝다. 더 명확한 신호는 어떤 문제가 어디에서 나타났는가에 있다. 미국 결과가 안정적이었던 20개 사이트 중 5개는 미국의 두 실행 어디에도 나타나지 않았던 유형의 결함을 현지화된 버전에서 최소 한 가지 이상 가지고 있었다.
| 사이트 유형 | 미국 외에서만 발견된 결함 | 시장 |
|---|---|---|
| 게임 플랫폼 | 접근 가능한 이름이 없는 회원가입 생년월일 필드(일, 월, 연) | 독일, 프랑스, 일본 |
| 웹사이트 빌더 | 라벨이 없는 메인 검색 필드 | 독일, 프랑스, 일본 |
| 보안 소프트웨어 공급업체 | 유효하지 않은 ARIA 속성을 가진 통화 선택기, 텍스트 대체 수단이 없는 프로모션 이미지, 이름 없는 동영상 재생 버튼 | 독일, 프랑스, 일본 |
| 전자상거래 플랫폼 | 접근 가능한 이름이 없는 버튼 | 독일, 프랑스 |
| 오픈소스 프로젝트 사이트 | 색상 대비 기준을 통과하지 못한 푸터 텍스트 | 독일, 프랑스, 일본 |
이 중 몇 가지는 수치가 보여주는 것보다 더 중요하다. 스크린 리더 사용자는 날짜 필드에 이름이 없는 회원가입 양식을 완료할 수 없고, “편집 텍스트”로만 안내되는 검색창을 사용할 수 없다. 이는 미국 페이지만 테스트하는 팀에게는 계속 보이지 않는 유형의 결함이다.
92건의 감사 전체에서 가장 흔한 결함은 색상 대비로, 43개 페이지에서 발견되었으며, 그 다음은 접근 가능한 이름이 없는 버튼과 텍스트 대체 수단이 없는 이미지였다.
코드
아래 모듈은 한 시장의 방문자가 보게 될 방식 그대로 한 페이지를 감사하며, 차단 페이지나 오류 페이지를 표시하여 그것이 의도한 페이지로 잘못 오인되지 않도록 한다. Playwright와 axe-core가 필요하다.
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const AXE_SOURCE = readFileSync(require.resolve('axe-core/axe.min.js'), 'utf8');
// Audit one page as a visitor in one market would see it: the browser's locale and time zone match the
// market, and the browser itself runs through an exit in that country.
export async function auditPage(browser, url, { locale, timezoneId }) {
const context = await browser.newContext({ locale, timezoneId });
const page = await context.newPage();
try {
const response = await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
await page.waitForTimeout(5000); // let client-side rendering and consent banners appear
await page.evaluate(AXE_SOURCE); // evaluate, not a script tag, so the page's CSP cannot block it
const result = await page.evaluate(() =>
window.axe.run(document, { runOnly: ['wcag2a', 'wcag2aa'], resultTypes: ['violations'] }));
const lang = await page.evaluate(() => document.documentElement.getAttribute('lang'));
const status = response ? response.status() : null;
return {
url,
finalUrl: page.url(),
status,
blocked: status === null || status >= 400, // a block or error page, not the page you meant to audit
title: await page.title(),
lang,
violations: result.violations.map((v) => ({ id: v.id, impact: v.impact, nodes: v.nodes.length })),
};
} finally {
await context.close();
}
}
그리고 특정 시장을 위해 실행할 때는, 해당 국가의 종료 지점을 거치도록 브라우저를 라우팅한다.
import { chromium } from 'playwright';
import { auditPage } from './audit.mjs';
// One browser per market, running through an exit in that country.
const browser = await chromium.launch({
proxy: {
server: 'http://p.shifter.io:443',
username: `${process.env.SHIFTER_PROXY_USER}-country-de`,
password: process.env.SHIFTER_PROXY_PASS,
},
});
const result = await auditPage(browser, 'https://shifter.io/de', { locale: 'de-DE', timezoneId: 'Europe/Berlin' });
console.log(result.status, result.blocked, result.lang, result.violations);
await browser.close();
우리 자체의 독일 홈페이지에 대해 실행한 결과, 위반 사항이 보고되지 않았다.
이것을 만들면서 얻은 두 가지 교훈이 코드에 담겨 있다. blocked 플래그가 존재하는 이유는 첫 번째 실행에서 차단 페이지를 감사했기 때문이다. 두 사이트가 모든 종료 지점을 거부했고, 그 차단 페이지는 그럴듯해 보이는 결과를 만들어냈는데, 그중에는 미국 영어로 선언된 페이지가 있었고 우리는 잠시 그것을 잘못 라벨링된 독일 페이지로 착각했다. 그리고 axe는 스크립트 태그가 아니라 evaluate로 주입되는데, 일부 사이트의 엄격한 콘텐츠 보안 정책(Content Security Policy)이 주입된 스크립트를 거부하기 때문이다.
프로세스에 구축하기
- 판매하는 모든 시장을 그 시장에서 감사하라. 프록시 지역, 시간대, 로케일 일치시키기에서 설명한 대로 각 국가의 종료 지점을 사용하고 언어와 시간대를 맞춰서, 감사가 현지 방문자와 동일한 동의 흐름, 리디렉션, 지역 컴포넌트를 보도록 하라.
- 버전 목록은 사이트 자체에서 찾아라. Hreflang 주석은 모든 시장 버전을 나열하므로, 시장이 추가되어도 감사 목록을 최신 상태로 유지할 수 있다.
- 차이를 신뢰하기 전에 노이즈를 측정하라. 같은 페이지를 두 번 감사하고, 동일한 실행 사이에서도 나타나는 변화는 노이즈로 취급하라.
- 올바른 페이지를 감사했는지 확인하라. 상태 코드, 제목, 최종 URL을 기록하고, 차단 페이지, 오류 페이지, 다른 시장으로의 리디렉션은 제외하라. 우리의 봇 차단 스택 조회에서는 상태 코드 하나만으로는 오해를 불러일으킬 수 있는 이유를 설명한다.
- 기본 버전과 비교하라. 팀이 테스트하는 버전에는 없고 특정 시장 버전에만 존재하는 결함을 보고하라. 아무도 본 적 없는 것이 바로 그런 결함이기 때문이다.
- 일정에 따라 실행하라. 현지 캠페인과 배너는 매주 바뀌며, 변경 감지 원칙은 접근성에도 적용된다.
- 사람을 프로세스에 계속 포함시켜라. W3C는 도구가 모든 접근성 요구사항을 확인할 수는 없으며 사람의 판단이 필요하다고 명시하고 있다. 자동화된 감사는 회귀를 찾아낼 뿐, 사이트가 접근성을 갖췄다는 것을 증명하지는 않는다.
지금 이것이 중요한 이유
많은 국가에서 공공 부문 웹사이트에 대한 접근성은 오랫동안 법적 요구사항이었다. EU에서는 2025년 6월 28일부터 유럽 접근성법이 전자상거래를 포함한 정해진 소비자 제품 및 서비스에 적용되고 있으며, 이를 충족하기 위해 사용되는 유럽 조화 표준은 WCAG를 기반으로 한다. 유럽 전역에서 판매하는 기업의 경우, 각 국가 버전의 사이트가 이러한 요구사항을 충족해야 하는 대상에 포함되며, 개발자가 들여다보는 버전 하나만 해당되는 것이 아니다. 이는 일반적인 정보이며 법률 자문이 아니다. 여러분의 각 시장에 적용되는 규정은 법률 자문을 통해 확인하라.
결론
접근성은 보통 한 곳에서 테스트되어 여러 곳으로 배포된다. 23개 다국가 사이트에 대한 우리의 감사에서, 결과가 안정적이었던 사이트 중 4분의 1은 미국 외에서만 존재하는 결함, 즉 라벨 없는 회원가입 필드부터 텍스트 대체 수단이 없는 이미지까지 다양한 결함을 가지고 있었다.
각 시장 버전을 현지 방문자가 보는 방식 그대로 테스트하고, 실제 차이를 노이즈와 구분하며, 팀이 이미 확인하는 버전과 비교하라. 시장당 몇 분의 자동화 작업만으로, 그곳의 사용자들이 줄곧 겪어 온 문제를 찾아낼 수 있다.
출처 및 참고자료
- Deque, axe-core, 버전 4.13, 감사에 사용됨.
- W3C Web Accessibility Initiative, Selecting web accessibility evaluation tools.
- Noerr, Accessibility in e-commerce: new obligations for online shop operators starting from June 2025.
- 위 코드를 사용하여 2026년 10월 4일 Shifter가 실행한 감사.