당신의 코딩 에이전트가 화면을 고쳤다고 보고한다. Playwright 로 스크린샷도 찍었고, scrollWidth > clientWidth 로 가로 넘침도 0 이라고 한다. 그런데 사람이 열어 보면 쇼핑몰 장바구니 카드의 할인 내역이 카드 오른쪽 빈 여백으로 삐져나와 있다. 또는 상품 카드에 마우스를 올리면 커서가 손가락과 화살표 사이를 깜빡이는데, 에이전트는 "재현되지 않는다"고 한다. 둘 다 레이아웃 회귀 검사를 눈으로 하거나, 문서 전체를 재는 검사로 한 탓이다 — scrollWidth 검사는 이런 넘침을 못 잡는다.
화면이 맞는지는 무엇으로 판정하나
화면이 맞게 놓였는지는 눈이 아니라 페이지 안에서 잰 숫자로 판정하고, 그 숫자는 그 요소가 지켜야 할 기준 — 들어 있어야 할 카드의 경계, 실제 크기, 마우스 아래에 와야 할 요소 — 에 대 본다. 에이전트는 스크린샷을 봐도 몇 픽셀 차이를 못 가리고, 사람도 카드 안쪽만 보게 된다. 브라우저는 모든 요소의 자리를 이미 알고 있다. 그걸 묻기만 하면 된다.
왜 scrollWidth 검사는 넘침을 놓치나
scrollWidth > clientWidth 는 문서(또는 그 상자)가 가로로 스크롤되는가를 묻는다. 카드는 화면 가운데 좁게 놓이고 양옆이 비어 있는 데스크톱 화면에서, 카드 밖으로 새어 나간 글자는 그 빈 여백 안에 떨어진다. 문서 폭은 그대로라 검사는 0 을 낸다. 그러니 "넘침 0" 은 "아무것도 제자리를 벗어나지 않았다"가 아니라 "페이지가 스크롤바를 만들지 않았다"는 뜻일 뿐이다.
요소마다 무엇에 대 봐야 하나
요소마다 getBoundingClientRect()(MDN)로 상자를 받아, 문서가 아니라 그 요소가 속한 기준과 비교한다.
- 본문 컨테이너 밖으로 나간 요소
- 가장 가까운 카드(또는 패널) 밖으로 나간 요소
- 글자 잘림 — 글자 요소 자신의
scrollWidth > clientWidth(MDN) - 형제 글자 상자끼리의 겹침
- 접힌 블록(아코디언·더 보기)은 모두 펼친 상태로 다시 돌린다 — 접힌 채로는 숨은 줄이 검사에 안 들어온다
에이전트에게 줄 지침은 이렇게 쓴다.
레이아웃을 바꾼 뒤에는 스크린샷 판단으로 끝내지 말 것.
모든 보이는 요소의 getBoundingClientRect() 를 (1) 본문 컨테이너,
(2) 가장 가까운 카드와 비교해 밖으로 나간 것, 글자가 잘린 것,
글자 상자가 겹친 것을 목록으로 출력한다. 접힌 블록은 모두 펼친 뒤에 잰다.
데스크톱·모바일 폭 둘 다 돌리고, 목록이 비어야 통과다.
마우스가 무엇을 가리키는지는 어떻게 재나
hover 깜빡임은 스크린샷에 안 찍힌다. 대신 그 자리에서 브라우저가 어느 요소를 고르는지를 센다. document.elementFromPoint(x, y)(MDN)는 그 좌표의 히트 테스트 결과를 돌려준다. 제목 위에 격자로 수십 점을 찍어 전부 제목 요소(또는 그 자식)가 나오는지 센다. 섞여 나오면 깜빡임의 원인이 거기 있다.
CSS 3D(transform-style: preserve-3d)로 살짝 기울인 카드 더미가 흔한 예다. 앞의 글자 요소와 뒤의 판이 정확히 같은 깊이에 있으면 브라우저가 좌표마다 다른 쪽을 집는다. backface-visibility 나 평면화로는 안 고쳐지고, 앞 요소를 translateZ(1px) 로 띄워 깊이를 갈라야 한다. 고쳤는지도 같은 격자 검사로 확인한다.
그림·농도처럼 숫자가 없어 보이는 것은 어떻게 하나
먹 번짐의 농도, 그림자의 세기, 아이콘의 굵기처럼 "보기 좋은가"의 문제도 숫자로 바꿀 수 있다. 목업이 캔버스에서 스스로 값을 읽어 캡션에 찍게 한다.
- 캔버스의 픽셀을
getImageData로 읽어 덮인 비율(%), 알파 최댓값, 반지름(px)을 계산한다 - 그 값을 시안마다 캡션에 찍고, 좋다고 합의한 범위는 색으로 표시한다
- 비교 시안은 실제 크기(1:1) 로 건다. 축소해 걸면 다른 그림을 고르게 된다
- 사용자의 말("안 보인다", "너무 진하다")을 그 숫자에 맞대어 다음 값을 정한다
이렇게 하면 "안 보인다"가 "덮임 3%, 목표 8~15%"가 되고, 한 번에 고쳐진다. 단, 카메라가 움직이는 연출처럼 시간에 따라 변하는 것은 정지 프레임 목업으로 판단하지 않는다. 장마다 시점이 달라 끊김으로만 읽힌다. 그런 것은 실제 화면 안에서 개발용 스위치 뒤에 만들어 움직이는 채로 본다.
우리가 겪은 일
- 카드 밖 넘침(웹 계산기): 데스크톱 결과 카드의 공제 내역이 카드 밖 빈 여백으로 새는 것을 스크린샷 QA 가 여러 차례 놓쳤다.
scrollWidth검사는 계속 0 이었다. 요소 상자를 카드·컨테이너와 비교하는 검사로 바꾸고서야 잡혔고, 그 과정에서 CSS 다단(columns)이 Chrome 에서 열을 하나 더 만들던 것도 드러나 grid 로 바꿨다. - hover 깜빡임(3D 카드 더미): 기울인 카드 제목에 마우스를 올리면 커서와 밑줄이 깜빡였다. 원인은 같은 깊이의 두 요소였고,
translateZ(1px)뒤 제목 위 격자의elementFromPoint가 전부 제목을 가리키는지 세어 닫았다. - 붓 농도 조율(캔버스 목업): 에이전트가 결과를 눈으로 못 보는 채 농도·굵기를 추측으로 고치다 두세 번 빗나갔다. 목업이 덮임 %·알파 최댓값·반지름을 캡션에 찍게 하자 사용자의 말과 숫자가 맞물려 한 번에 맞았다.
확인 목록
- 검사가 묻는 것이 "문서가 스크롤되나"인지 "요소가 제자리에 있나"인지 구분했다
- 요소마다 기준 경계(컨테이너·카드)를 정했다
- 접힌 블록을 펼치고, 두 가지 화면 폭에서 돌렸다
- hover·클릭 문제는
elementFromPoint격자로 셌다 - 시각 시안에는 측정값 캡션과 1:1 크기가 있다
- 움직이는 연출은 실제 화면에서 움직이는 채로 봤다