최신 웹 앱 자동화를 해본 분이라면 이런 상황, 한 번쯤 겪어봤을 거예요. Selenium으로 테스트 코드를 짜서 버튼을 눌렀는데, 아무 반응이 없죠. 나중에 알고 보니 버튼이 화면에 안 보이거나, 스크롤을 내려야만 더 많은 상품이 뜨는 구조였던 겁니다. 요즘처럼 콘텐츠가 실시간으로 바뀌고, 무한 스크롤이 적용된 웹페이지에서는 실제 사용자가 보는 화면을 테스트가 제대로 따라가야 절반은 성공한 셈이죠. 오랜 기간 웹 자동화를 해오면서 느낀 건, Selenium에서 스크롤을 제대로 다루는 게 단순한 옵션이 아니라, 신뢰할 수 있는 자동화와 불안정한 테스트를 가르는 핵심이라는 점입니다.
이번 글에서는 Selenium에서 스크롤이 왜 중요한지, 지연 로딩 리스트부터 고정 헤더까지 다양한 상황에서 쓸 수 있는 스크롤 노하우, 그리고 같은 도구로 워크플로우를 훨씬 빠르게 만드는 방법까지 실전 팁을 아낌없이 공유합니다. 실용적인 코드 예시와 브라우저별 주의점, 그리고 현장에서 얻은 노하우까지 담았으니, 이제 테스트 때문에 머리 아플 일 없이 결과에만 집중해보세요.
Selenium에서 스크롤의 기본 이해하기
그럼 Selenium에서 '스크롤'이란 뭘까요? 웹 자동화에서는 브라우저 화면(뷰포트)을 프로그래밍으로 위, 아래, 좌, 우 또는 특정 요소까지 이동시켜서 원하는 콘텐츠가 실제로 화면에 보이게 만드는 작업을 말합니다. Selenium WebDriver는 기본적으로 자동 스크롤을 지원하지 않기 때문에, 화면 밖에 있는 요소를 클릭하려 하면 ElementNotInteractableException 오류가 뜰 수 있습니다(). 그래서 믿을 수 있는 UI 테스트 자동화를 하려면 정확한 스크롤 제어가 필수입니다.
Selenium에서 주로 쓰는 스크롤 방식은 아래와 같습니다:
- 수직 스크롤: 페이지를 위아래로 움직여 더 많은 콘텐츠를 보여줌
- 수평 스크롤: 넓은 테이블이나 캐러셀 등에서 사용
- 특정 요소로 스크롤:
scrollIntoView로 원하는 요소를 화면에 노출 - 픽셀 단위 스크롤: 지정한 픽셀만큼 뷰포트를 이동(점진적 스크롤에 유용)
- 페이지 맨 위/아래로 이동: 한 번에 페이지 시작 또는 끝으로 이동
이런 스크롤이 왜 중요할까요? 요즘 웹페이지는 무한 스크롤 피드, '더 보기' 버튼, 고정 헤더, 지연 로딩 이미지 등 동적 요소가 넘쳐납니다. 테스트가 스크롤을 못 하면 UI의 절반도 제대로 확인 못 해서 버그를 놓치거나, 엉뚱한 이유로 테스트가 실패할 수 있습니다().
자주 겪는 문제들:
- 요소를 찾았다고 해서 항상 화면에 보이거나 클릭 가능한 건 아님
.click()이나.sendKeys()같은 액션이 자동으로 스크롤을 해주지 않음- 고정 헤더가 스크롤 후에도 요소를 가릴 수 있음
- 무한 스크롤 페이지는 반복적이고 점진적인 스크롤이 필요함
아래는 요소를 화면에 보이게 스크롤하는 Java 예시입니다:
1((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
이렇게 하면 해당 요소가 뷰포트 상단에 노출되어 'element not interactable' 오류를 막을 수 있습니다.
Selenium에서 효율적인 스크롤이 웹 테스트에 중요한 이유
현실적으로, 요즘 웹앱 대부분은 스크롤해야만 나타나는 동적 콘텐츠에 의존합니다. 최근 통계에 따르면 이고, 실제로는 이보다 훨씬 많을 거예요. Selenium 테스트에서 스크롤을 안 하면, 앱의 상당 부분을 놓치게 됩니다.
스크롤이 꼭 필요한 대표 상황:
- 무한/지연 로딩 리스트: 소셜 피드, 상품 그리드, SaaS 대시보드 등
- '더 보기' 버튼: 이커머스, 뉴스, 디렉터리 사이트
- 숨겨진 버튼/링크: 스크롤해야만 나타나는 요소
- 고정 헤더: 스크롤 위치에 따라 요소를 가릴 수 있음
- 대형 테이블/캐러셀: 수평 또는 컨테이너 내부 스크롤 필요
| 테스트 시나리오 | 스크롤이 필요한 이유 |
|---|---|
| 무한 콘텐츠 피드(예: 소셜 미디어) | 스크롤할 때마다 새 게시물이 로드됨. 모든 항목을 확인하려면 반복 스크롤 필요. |
| '더 보기' 페이지네이션 | 추가 항목이 스크롤/클릭 전까지 DOM에 없음. |
| 지연 로딩 이미지 | 스크롤해야 이미지를 로드하므로, 모든 이미지가 정상적으로 표시되는지 확인 필요. |
| 고정 헤더가 콘텐츠를 가림 | 스크롤 후에도 헤더에 가려질 수 있어, 위치 조정이 필요함. |
| 대형 스크롤 테이블/캐러셀 | 한 번에 일부만 보이므로, 모든 행/항목을 확인하려면 스크롤 필요. |
효과:
- 테스트 커버리지 향상: 로드 시점에 보이는 UI뿐 아니라 전체 요소를 검증
- 수작업 감소: 테스트 분할이나 수동 스크롤 없이 자동화 가능
- 신뢰성 향상: '요소를 찾을 수 없음' 또는 '비활성화' 오류 감소
예를 들어, 한 번에 20개씩만 상품이 보이는 이커머스 사이트에서 스크롤 없이 테스트하면 전체 상품의 20%만 검증하게 됩니다. 효율적인 스크롤은 더 많은 버그를 빠르게 잡을 수 있게 해줍니다.

Selenium 스크롤링 기법 비교: 다양한 방법 한눈에 보기
Selenium에는 'scrollDown()' 같은 단일 명령어는 없지만, 여러 가지 방식으로 스크롤을 구현할 수 있습니다. 주요 방법을 정리하면 다음과 같습니다:
| 방법 | 브라우저 지원 | 난이도 | 적합한 상황 |
|---|---|---|---|
| Actions API (Wheel input) | Chrome, Edge (Selenium 4) | 중간 | 요소 또는 오프셋 기준 정밀 스크롤 |
| JavaScriptExecutor | 모든 브라우저 | 쉬움 | 요소, 픽셀, 페이지 끝 등 다양한 스크롤 |
| 키보드 입력(Page Down 등) | 모든 브라우저 | 쉬움 | 실제 사용자 키 입력 시뮬레이션 |
| 요소 내부 스크롤 | 모든 브라우저 | 중간 | 테이블, 캐러셀 등 컨테이너 내부 스크롤 |
요소로 스크롤 & 픽셀 단위 스크롤
특정 요소로 스크롤:
정확히 보고 싶은 요소가 있을 때 가장 적합합니다.
1js.executeScript("arguments[0].scrollIntoView();", webElement);
또는 Selenium 4 Actions API(Chrome/Edge):
1new Actions(driver).scrollToElement(element).perform();
픽셀 단위 스크롤:
점진적 스크롤이나 위치 미세 조정에 유용합니다.
1js.executeScript("window.scrollBy(0, 350)", "");
양수는 아래로, 음수는 위로 스크롤합니다.
언제 어떤 방법을 쓸까?
- 정밀성과 신뢰성을 원하면 요소로 스크롤을 우선 사용
- 점진적 로딩, 패럴럭스 효과 등에는 픽셀 단위 스크롤 활용
페이지 맨 위/아래로 스크롤 & 무한 스크롤 처리
페이지 맨 아래로 스크롤:
1js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
페이지 맨 위로 스크롤:
1js.executeScript("window.scrollTo(0, 0)");
무한 스크롤 처리:
반복문을 사용해 스크롤, 새 콘텐츠 로드 대기, 더 이상 로드가 없으면 종료합니다.
1long lastHeight = (Long) js.executeScript("return document.body.scrollHeight");
2while (true) {
3 js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
4 Thread.sleep(2000); // 실제 테스트에서는 명시적 대기 사용 권장
5 long newHeight = (Long) js.executeScript("return document.body.scrollHeight;");
6 if (newHeight == lastHeight) break;
7 lastHeight = newHeight;
8}
이 패턴을 사용하면 실제 사용자처럼 모든 콘텐츠를 로드할 수 있습니다().
Selenium에서 execute_script로 커스텀 스크롤 구현하기
기본적인 스크롤을 넘어서는 상황에서는 JavaScript의 execute_script가 정말 유용합니다. 예를 들어:
- 단계별로 스크롤해 실제 사용자처럼 부드럽게 이동
- 스크롤 후 콘텐츠 로드 대기
- 특정 컨테이너(테이블, 캐러셀 등) 내부 스크롤
- 고정 헤더, 동적 요소 등 특수 상황 처리
예시: 단계별 부드러운 스크롤
1for i in range(10):
2 driver.execute_script("window.scrollBy(0, 500);")
3 time.sleep(0.5)
예시: 스크롤 후 콘텐츠 로드 대기
1js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
2WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
3wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("new_element")));
베스트 프랙티스:
- 스크롤 후에는 항상 명시적 대기로 새 콘텐츠 로드 확인
scrollIntoView사용 시{block: "center"}옵션으로 가시성 향상- 하드코딩된 sleep 대신 실제 콘텐츠 변화에 맞춘 대기 사용
- 컨테이너 내부는
element.scrollTop = ...또는element.scrollBy(...)로 제어
브라우저별 Selenium 스크롤 최적화 팁
브라우저마다 스크롤 동작이 조금씩 다를 수 있습니다:
- Chrome/Edge: Actions API와 JavaScript 모두 완벽 지원
- Firefox: JS 지원은 좋으나, Actions API는 일부만 지원(부드러운 스크롤은 추가 조정 필요)
- Safari: Actions API 스크롤 미지원, JavaScript만 사용 가능()
- 헤드리스 모드: 윈도우 크기 설정 필수, 그렇지 않으면 스크롤이 비정상 동작할 수 있음
팁:
- 모든 대상 브라우저에서 스크롤 로직을 미리 테스트
- JS 스크롤을 범용 백업 방법으로 활용
- 고정 헤더가 있다면 몇 픽셀 더 스크롤하거나 커스텀 JS로 겹침 방지
- 헤드리스 모드에서는
driver.manage().window().setSize(...)로 윈도우 크기 고정
Thunderbit: Selenium 테스트 개발을 가속화하는 스마트 스크래핑
이제 비장의 무기를 소개할 차례입니다: . Selenium이 브라우저 조작에 강하다면, 실제로 데이터를 추출해야 할 때는 Thunderbit가 진짜 빛을 발합니다. 특히 스크롤이 많거나 동적 콘텐츠가 많은 페이지에서 Thunderbit의 진가가 드러나죠.
Thunderbit가 Selenium을 보완하는 방법:
- 무한 스크롤 페이지도 데이터 완전 추출: Thunderbit의 AI가 스크롤, 페이지네이션, 구조화된 데이터(상품명, 가격, 이미지 등)를 클릭 몇 번으로 수집
- 테스트용 기준 데이터 생성: Thunderbit로 UI의 모든 예상 데이터를 빠르게 수집, Selenium 테스트에서 실제 UI와 비교 검증
- 테스트 개발 속도 향상: 'AI 필드 추천' 기능으로 셀렉터와 구조를 쉽게 파악, Selenium locator 작성이 쉬워짐
예시 워크플로우:
- Thunderbit로 동적 이커머스 페이지의 모든 상품을 스크래핑(자동 스크롤 및 추출)
- 데이터를 Google Sheets 또는 CSV로 내보내기
- Selenium 테스트에서 페이지를 스크롤하며 보이는 상품 정보를 수집, Thunderbit 데이터셋과 비교
- 모든 상품이 정상적으로 로드되고 누락 없이 표시되는지 검증
이 조합을 활용하면 불안정한 스크래핑 코드 작성에 시간을 낭비하지 않고, 진짜 중요한 검증에 집중할 수 있습니다. Thunderbit의 및 예약 스크래핑 기능은 대규모 동적 사이트에 특히 유용합니다.
실전 예제: Selenium 테스트에서 효율적인 스크롤 적용하기
이제 실제로 활용할 수 있는 시나리오와 코드를 살펴보겠습니다:
1. 대형 테이블 스크롤하기
별도의 스크롤 바가 있는 데이터 그리드가 있다고 가정해봅니다:
1WebElement table = driver.findElement(By.id("data-table"));
2js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight", table);
테이블 맨 아래까지 스크롤합니다. 각 행을 확인하려면 반복적으로 스크롤하면 됩니다.
2. 무한 스크롤 피드 탐색
1prev_count = 0
2while True:
3 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
4 time.sleep(2)
5 posts = driver.find_elements(By.CSS_SELECTOR, ".post")
6 if len(posts) == prev_count:
7 break
8 prev_count = len(posts)
새 게시물이 더 이상 로드되지 않을 때까지 모든 게시물을 불러옵니다.
3. 지연 로딩 이미지 검증
1List<WebElement> images = driver.findElements(By.tagName("img"));
2for (WebElement img : images) {
3 if ("lazy".equals(img.getAttribute("loading"))) {
4 js.executeScript("arguments[0].scrollIntoView(true);", img);
5 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
6 wait.until(d -> (Boolean) ((JavascriptExecutor)d).executeScript("return arguments[0].complete && arguments[0].naturalWidth > 0;", img));
7 Assert.assertTrue((Integer) js.executeScript("return arguments[0].naturalWidth;", img) > 0);
8 }
9}
각 지연 로딩 이미지를 화면에 노출시키고, 정상적으로 로드됐는지 확인합니다.
4. 캐러셀에서 수평 스크롤
1WebElement carousel = driver.findElement(By.className("carousel"));
2js.executeScript("arguments[0].scrollBy(300, 0);", carousel);
캐러셀을 오른쪽으로 300px 이동합니다.
5. 콘텐츠 로드 실패 감지
스크롤 후에는 명시적 대기로 새 콘텐츠나 로딩 스피너를 확인하세요. 타임아웃이 발생하면 상태를 기록하고 실패로 처리합니다.
단계별 가이드: Selenium에서 효율적인 스크롤 구현하기
실행 가능한 체크리스트를 정리했습니다:
- 스크롤 필요성 파악: 콘텐츠가 숨겨져 있거나, 지연 로딩/페이지네이션 구조인지 확인
- 요소 존재 확인: 명시적 대기로 요소가 DOM에 있는지 체크
- 적합한 스크롤 방식 선택:
- 정밀한 위치는 요소로 스크롤
- 점진적 로딩은 픽셀 단위 스크롤
- 무한 스크롤은 반복문 활용
- 스크롤 구현: 상황에 맞게 JavaScript 또는 Actions API 사용
- 스크롤 후 동기화: 새 콘텐츠 로드 대기(고정 sleep 대신 명시적 대기)
- 콘텐츠 검증: 스크롤 후 요소가 보이고, 로드됐으며, 상호작용 가능한지 확인
- 브라우저 최적화: 모든 대상 브라우저에서 테스트, JS를 백업 방법으로 활용
- Thunderbit 연동: 대용량 데이터 사전 추출 또는 검증에 Thunderbit 활용
- 불필요한 스크롤 최소화: 꼭 필요한 만큼만 스크롤
- 로직 문서화: 각 스크롤 방식 선택 이유를 주석으로 남기기
| 단계 | 핵심 액션 |
|---|---|
| 필요성 파악 | 이 시나리오에 스크롤이 필요한가? |
| 요소 존재 확인 | DOM에 요소가 있는지 대기 |
| 방식 선택 | 요소, 픽셀, 반복, 컨테이너 스크롤 중 선택 |
| 구현 | JS/Actions/키 입력 등 적합한 방법 사용 |
| 동기화 | 스크롤 후 콘텐츠 로드 대기 |
| 검증 | 가시성 및 정확성 검증 |
| 브라우저 최적화 | Chrome, Firefox, Edge, Safari 등에서 테스트 |
| Thunderbit 연동 | 데이터 추출/검증에 활용 |
| 최소화 | 불필요한 스크롤 방지 |
| 문서화 | 접근 방식 주석 및 설명 |
결론 & 핵심 요약
Selenium에서 효율적인 스크롤은 현대 웹 테스트 자동화의 핵심입니다. 동적 콘텐츠와 무한 스크롤이 일상화된 환경에서, 실제 사용자처럼 스크롤해야만 UI를 제대로 검증할 수 있습니다. 가장 중요한 포인트는 다음과 같습니다:
- 목적 있는 스크롤: 언제, 어디서 스크롤이 필요한지 명확히 파악
- 적합한 도구 사용: 정밀한 위치는 요소 스크롤, 유연성은 JavaScript, 네이티브 동작은 Actions API(지원 브라우저 한정)
- 동기화 및 검증: 스크롤 후 콘텐츠 로드 대기, 가시성과 정확성까지 꼼꼼히 확인
- 브라우저별 최적화: 모든 브라우저에서 스크롤 로직 테스트, JS를 범용 백업으로 활용
- Thunderbit 활용: 와 Selenium을 결합해 스크롤이 많은 동적 페이지에서도 데이터 추출과 검증을 빠르게 처리
Selenium 테스트를 한 단계 업그레이드하고 싶다면, Thunderbit의 으로 더 똑똑하고 빠른 테스트 개발을 경험해보세요. 더 많은 자동화 팁이 궁금하다면 에서 심층 가이드와 튜토리얼을 확인할 수 있습니다.
즐거운 스크롤링 하시고, 여러분의 테스트가 항상 원하는 결과를 찾길 응원합니다.
자주 묻는 질문(FAQ)
1. Selenium이 DOM에 있는 요소와 상호작용하지 못하는 이유는 뭔가요?
Selenium은 자동으로 요소를 화면에 보이게 스크롤하지 않습니다. 요소가 화면 밖에 있으면 ElementNotInteractableException이 발생할 수 있으니, 스크롤 액션으로 요소를 노출시킨 후 상호작용하세요.
2. Selenium에서 무한 스크롤 페이지는 어떻게 처리하나요?
반복문을 사용해 페이지 맨 아래로 스크롤, 새 콘텐츠 로드 대기, 더 이상 로드가 없으면 종료하는 방식이 가장 효과적입니다. 고정 sleep 대신 실제 콘텐츠 변화에 맞춘 명시적 대기를 사용하세요.
3. 모든 브라우저에서 스크롤 코드를 호환시키려면?
JavaScript의 execute_script가 가장 범용적입니다. Actions API는 Chrome/Edge에서 잘 동작하지만, Safari나 구버전 Firefox에서는 지원이 제한될 수 있으니, 모든 대상 브라우저에서 테스트하세요.
4. 메인 페이지가 아닌 컨테이너나 테이블 내부도 스크롤할 수 있나요?
네! JavaScript로 컨테이너 요소의 scrollTop 또는 scrollBy를 설정하면 됩니다. 예: js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight", tableElement);
5. Thunderbit가 Selenium 테스트 자동화에 어떻게 도움이 되나요?
Thunderbit의 AI 기반 스크래핑은 무한 스크롤이나 동적 페이지에서도 모든 데이터를 추출해 Selenium 테스트의 기준 데이터로 활용할 수 있습니다. 덕분에 UI 검증이 쉬워지고, 복잡한 데이터 사이트에서도 테스트 개발 속도가 빨라집니다.
Selenium, 웹 스크래핑, 자동화 베스트 프랙티스에 대해 더 알고 싶다면 를 참고하세요.