Capybara와 Selenium으로 스크린샷 자동화하기
지난주 AppSignal 업데이트에는 모든 화면에 적용된 새로운 인터페이스 디자인이 포함되어 있었습니다. 이는 홈페이지의 모든 스크린샷을 앱의 현재 상태에 맞게 다시 촬영해야 한다는 의미이기도 했습니다. 이 작업에 필요한 방대한 수작업을 줄이기 위해 우리는 프로세스 자동화를 결심했습니다.
다행히 곧 Selenium으로 스크린샷을 촬영할 수 있다는 사실이 떠올랐습니다. 우리는 이미 기능 테스트(feature test)에서 Capybara를 통해 Selenium을 폭넓게 사용하고 있었기 때문에, 새로운 도구를 추가하지 않고도 이 작업을 자동화할 수 있을지 조사해 보기로 했습니다. 몇 가지 실험 끝에 이 계획이 충분히 실현 가능하다는 것을 확인했습니다.
간단한 스크린샷 API
스크린샷을 찍는 API는 매우 직관적입니다. 브라우저 창을 원하는 크기로 설정하고, 페이지에 접속한 뒤 스크린샷을 저장하기만 하면 됩니다.
require 'capybara'
Capybara.default_driver = :selenium
page.driver.browser.manage.window.resize_to(1600, 1200)
visit 'https://appsignal.com'
page.save_screenshot(file)이 코드를 실행하면 지정된 위치에 PNG 파일이 생성됩니다.
Retina 스크린샷의 문제점
다만 Retina(레티나) 스크린샷을 원한다면 주의할 점이 있습니다. Chrome 드라이버는 Retina 해상도의 스크린샷을 만들 수 있지만, 화면에 실제로 보이는 영역만 촬영합니다. 반면 Firefox 드라이버는 전체 페이지를 촬영할 수 있지만 Retina 해상도로는 출력되지 않습니다. 게다가 팀원 모두가 Retina 디스플레이를 사용하는 것도 아니라서, 어차피 일부 팀원은 고해상도 스크린샷을 만들 수 없는 상황이었습니다.
여러 차례 검색한 끝에, chrism이 공개한 Gist에서 해결책을 찾았습니다. 이 영리한 트릭을 활용하면 Firefox에게 스크린샷을 찍기 직전에 페이지를 일반 크기의 두 배로 확대하도록 지시할 수 있습니다.
page.driver.execute_script('
body = document.getElementsByTagName("body")[0];
body.style["transform-origin"] = "top left";
body.style["transform"] = "scale(2)";
')이미지 크롭과 최적화
전체 페이지의 Retina 스크린샷을 확보했다면, 다음 단계는 ImageMagick에 포함된 convert CLI 도구를 사용해 원하는 크기로 이미지를 잘라내는 것입니다.
`convert #{file} -crop #{1600 * 2}x#{ 800 * 2}+0+0 #{to_file}`크기 값을 두 배로 입력해야 하는데, 그 이유는 ImageMagick이 해당 이미지가 Retina 이미지라는 사실을 알지 못하기 때문입니다. ImageMagick 입장에서는 단순히 3200×1600픽셀짜리 이미지일 뿐입니다. to_file은 에셋(assets) 폴더 안의 최종 파일 경로를 직접 가리킵니다.
마지막으로 pngquant를 사용해 파일 용량을 최적화합니다. 일반적인 스크린샷 하나가 220kB에서 250kB에 달하기 때문에, 용량 최적화는 필수적입니다.
`pngquant --force --output #{to_file} #{to_file}`Rakefile로 재사용성 높이기
이것으로 전 과정이 끝났습니다. 우리는 위 명령들을 기반으로 Rakefile을 작성했고, 디자인 변경이 생길 때마다 언제든 다시 실행할 수 있도록 만들었습니다. 전체 코드가 담긴 Gist도 공개해 두었으니 참고하시기 바랍니다.
이 프로세스를 자동화한 덕분에 이미 상당한 시간을 절약했으며, 앞으로도 개발 흐름을 유지하는 데 큰 도움이 될 것입니다. Tour 페이지 등에서 선명한 Retina 화질의 결과물을 직접 확인해 보세요!