Selenium 화면 녹화 구현 방법

UI 자동화는 불안정성이 높아 실행 중단이나 테스트 실패가 자주 발생합니다. 이를 해결하기 위한 일반적인 방법은 다음과 같습니다.

  1. 상세 로그 기록
  2. 오류 발생 시 스크린샷 저장
  3. Pytest 캐시 메커니즘(성공/실패한 케이스 기록)
  4. 자동 재시도 메커니즘(예: pytest-rerunfailures)
  5. 테스트 실행 동영상 녹화

테스트 실행 동영상 녹화는 가장 직관적인 방식으로, 실시간 조작 상황을 확인할 수 있습니다. Saucelabs와 같은 여러 클라우드 플랫폼에서 이 기능을 제공합니다.
하지만 Selenium 자체에는 이런 기능이 없습니다. ffmpeg 같은 타사 소프트웨어를 이용한 동기식 화면 녹화 외에도, 별도 스레드를 생성해 지속적으로 스크린샷을 찍고 이를 GIF로 합성하는 방법이 있습니다.
구체적인 방법은 다음과 같습니다.

실시간 스크린샷

  1. 반복 스크린샷 함수 capture 작성
def capture(driver):
    count = 0
    while True:
        file_path = os.path.join(image_dir, f'{count}.png')
        try:
            driver.save_screenshot(file_path)
        except:
            return
        count += 1

WebDriver 인터페이스의 스크린샷 명령 실행 속도 제한으로, 각 반복마다 sleep을 할 필요가 없습니다.

  1. 웹 조작 시 스레드 시작
image_dir = 'screenshots'  # 임시 이미지 디렉토리
driver = webdriver.Chrome()

thread = threading.Thread(target=capture, args=(driver,))  # 새 스레드 생성
thread.start()  # 스크린샷 스레드 시작

driver.get('https://www.google.com')
driver.find_element('name', 'q').send_keys('Selenium recording')
driver.find_element('name', 'btnK').click()
time.sleep(1)
driver.get('https://www.github.com')
driver.back()
time.sleep(2)
driver.quit()
  1. 이미지를 GIF로 합성

Pillow 설치 필요: pip install pillow

image_files = os.listdir(image_dir)  # 디렉토리 내 모든 이미지 나열
image_files.sort(key=lambda x: int(x[:-4]))  # 파일명으로 정렬

first_image = Image.open(os.path.join(image_dir, image_files[0]))  # 첫 번째 이미지 객체
rest_images = [Image.open(os.path.join(image_dir, img)) for img in image_files[1:]]  # 나머지 이미지 객체들

first_image.save("recording.gif", append_images=rest_images,
               duration=300,  # 각 이미지 전환 시간(밀리초)
               save_all=True)  # 합성 저장, 반복 재생을 위해 loop=0 추가 가능

전체 코드

from selenium import webdriver
import threading
import os
import time
from PIL import Image


def clean_directory(path):
    """디렉토리 생성 또는 비우기"""
    if not os.path.isdir(path):
        os.mkdir(path)
    else:
        [os.remove(os.path.join(path, file)) for file in os.listdir(path)]


def capture(driver, save_path):
    """반복 스크린샷 함수"""
    count = 0
    clean_directory(save_path)
    while True:
        file_path = os.path.join(save_path, f'{count}.png')
        try:
            driver.save_screenshot(file_path)
        except:
            return
        count += 1


# Selenium 조작
image_dir = 'screenshots'
driver = webdriver.Chrome()

capture_thread = threading.Thread(target=capture, args=(driver, image_dir))
capture_thread.start()

driver.get('https://www.google.com')
driver.find_element('name', 'q').send_keys('Selenium recording test')
driver.find_element('name', 'btnK').click()
time.sleep(1)
driver.get('https://www.github.com')
driver.back()
time.sleep(2)
driver.quit()

# 이미지를 GIF로 합성
image_files = os.listdir(image_dir)
image_files.sort(key=lambda x: int(x[:-4]))

first_image = Image.open(os.path.join(image_dir, image_files[0]))
rest_images = [Image.open(os.path.join(image_dir, img)) for img in image_files[1:]]

first_image.save("recording.gif", append_images=rest_images,
               duration=300,
               save_all=True)

최종 결과는 슬라이드쇼와 유사합니다.

태그: selenium pillow GIF recording webdriver Python threading

7월 17일 19:12에 게시됨