Shadow DOM 정복하기: 자동화 테스터를 위한 가이드
Source: November 30, 2025 · 3 min read
🌑 “Shadow” 문제
Shadow DOM은 JavaScript, CSS, 템플릿을 캡슐화하는 웹 표준입니다. 컴포넌트 작성자는 구현 세부 사항을 문서의 나머지 부분으로부터 숨길 수 있습니다.
- 개발자에게는 훌륭합니다.
- 자동화 테스터에게는 악몽입니다.
표준 CSS/XPath 선택자는 Shadow Boundary를 통과할 수 없습니다.
🤯 테스트 담당자에게 왜 고통인가요?
-
보이지 않음
표준 WebDriver 명령으로는 shadow root 내부를 볼 수 없습니다. -
지루한 탐색
요소에 접근하려면 다음을 수행해야 합니다:- shadow host 찾기
- JavaScript를 통해 shadow root 가져오기
- 그 root 안에서 검색하기
중첩된 shadow root가 있으면 이 과정을 재귀적으로 반복합니다.
-
발견의 지옥
- DevTools가 실제 경로를 숨기는 경우가 많습니다.
- 이벤트 재지정(event retargeting) 때문에 shadow root 내부를 클릭해도 호스트 요소를 클릭한 것으로 표시됩니다.
Save 버튼을 클릭했지만 DevTools에서는 호스트 컨테이너를 클릭한 것으로 나타납니다.
혼란스럽고, 느리며, 오류가 발생하기 쉽습니다.
🔮 Lumos ShadowDOM 소개
이를 해결하기 위해 Lumos ShadowDOM이라는 Python 패키지를 만들었습니다. 이 패키지는 Shadow DOM 상호작용을 일반 Selenium처럼 사용할 수 있게 해 줍니다. 일반 자동화와 캡슐화된 DOM 구조 사이의 격차를 메워 줍니다.
🧠 해결 방법
솔루션은 두 가지 핵심 구성 요소로 이루어져 있습니다:
1. WebDriver 몽키 패치
패키지는 Selenium WebDriver에 새로운 메서드를 추가합니다:
driver.find_shadow("host > nested-host > target")
다음 작업을 처리합니다:
- JavaScript 실행
- 재귀적인 Shadow 탐색
- Shadow root 추출
- 중첩 조회
모두 하나의 깔끔한 API로 제공됩니다.
2. 스마트 디스커버리 도구
DevTools 내부에서 event.composedPath()를 사용해 shadow boundary를 우회하고 root → element 전체 경로를 얻습니다. 그런 다음 이 경로를 가장 짧고 안정적인 CSS 선택자로 변환합니다.
⚙️ 사용 방법
패키지를 설치합니다:
pip install lumos-shadowdom
테스트 스크립트에서 사용합니다:
from selenium import webdriver
import lumos_shadowdom # This activates the extension
driver = webdriver.Chrome()
driver.get("https://example.com/shadow-dom-app")
# Instead of 15 lines of JS:
driver.find_shadow("my-app > settings-panel > #save-btn").click()
# Or use smart text search:
element = driver.find_shadow_text("Save Changes")
element.click()
✅ 결론
Shadow DOM이 자동화 작업을 늦추게 해서는 안 됩니다. Lumos ShadowDOM 같은 도구를 사용하면 복잡한 다단계 탐색이 한 줄의 가독성 높은 코드로 바뀝니다. 이를 통해 DOM 구조와 싸우는 대신 애플리케이션 로직 테스트에 집중할 수 있습니다.
자동화는 효율성을 위한 것이지 좌절을 위한 것이 아닙니다 — Shadow DOM도 예외는 아닙니다.