モダンな Selenium でスクリーンキャプチャ/スクリーンショット (Screen capture / Screen shot)方法
先日、Selenium でキャプチャ取る方法を聞かれたのでまとめる。
ぐぐってもモダンな方法が出てこないので。
結論を言うと、Selenium RC 0.9.2 (Core にも入ってた) から導入された、captureScreenshot を使うか、導入時期不明だけど、最新の Selenium 1.0 Beta 2 には入っている captureEntirePageScreenshot を使う。関連する API として、RC の Java Client には captureEntirePageScreenshotToString などもあるので興味のある人は、doc を見ると良い。
captureScreenshot と captureEntirePageScreenshot の違いはデスクトップ全体をキャプチャするか、テストしているページだけをキャプチャするかの違い。
captureEntirePageScreenshot のほうがテストしているページだけキャプチャできるので、良いように思えるが若干の制限がある。
Browser Luncher が *iexplore ではキャプチャできない。ちなみに、Selenium 1.0 Beta 2 のときに「*iexplore」の扱いが変更になった点に注意。デフォルトが Internet Explorer in HTA mode になった。
http://clearspace.openqa.org/community/selenium/blog/2009/01/13/selenium-rc-beta-2-goodies-and-gotchas
IE で、captureEntirePageScreenshot を動かしたいときは、まず、IE に、snapsIE (http://snapsie.sourceforge.net/)という selenium 用に開発されてる ie で screen capture を撮るライブラリをアタッチする。僕の環境では以下の通りで実行できた。実行できない人は上記サイトを参考に。
で、non HTA mode である *iexploreproxy で Selenium RC Client を起動してキャプチャを撮る。
具体的なコードとしては、例えば Java であれば 以下のような Selenium RC Clinet (+ JUnit4) のコードで行う。Path に関しては色々ためしたのだが、captureScreenshotはファイル名だけ書くと Selenium RC Server 側の起動ディレクトリ以下にファイルをキャプチャしてくれる。captureEntirePageScreenshot は絶対パスでないとダメ。この辺りは、マルチプラットフォームでテストするときには、ポイントになりそう。
余談だが、モダンでない capture 方法として、Java だったら、java.awt.Robot を使ってキャプチャを行うという方法もある。
GoogleJavaTest.java
import com.thoughtworks.selenium.*; import org.junit.Test; import org.junit.After; import org.junit.Before; import static org.junit.Assert.*; public class GoogleJavaTest { private Selenium browser; @Before public void setUp() { browser = new DefaultSelenium("localhost", 4444, "*iexploreproxy", "http://www.google.com"); // (1) browser.start(); } @Test public void testGoogle() { try { browser.open("http://www.google.com/webhp?hl=en"); browser.type("q", "hello world"); browser.click("btnG"); browser.waitForPageToLoad("5000"); assertEquals("hello worl - Google Search", browser.getTitle()); } catch (AssertionError ex) { browser.captureEntirePageScreenshot("C://tmp/errorTestGoogleEntire.png", ""); // (2) browser.captureScreenshot("C://tmp/errorTestGoogle.png"); // (3) throw ex; } } @After public void tearDown() { browser.stop(); } }
ruby の場合は以下の通りで実行できる。また、試してないが、RSpec のほうには、capture_html_snapshot という現在の html 全体を取得できそうなメソッドがあった。
require "test/unit" require "selenium/client" class GoogleTest < Test::Unit::TestCase attr_reader :browser def setup @browser = Selenium::Client::Driver.new "localhost", 4444, "*firefox", "http://www.google.com", 10000 browser.start_new_browser_session end def teardown browser.close_current_browser_session end def test_page_search begin browser.open "/" assert_equal "Google", browser.title browser.type "q", "hello world" browser.click "btnG", :wait_for => :page assert_equal "hello worl - Google Search", browser.title rescue Test::Unit::AssertionFailedError => e browser.capture_entire_page_screenshot "C://tmp/errorTestGoogleEntire.png", "" browser.capture_screenshot "C://tmp/errorTestGoogle.png" raise e end end end
TODO:Mac OS X や Linux 系でも試す。
一応、HTML Selence でも上記動くと思うので、Selenium IDE でも captureScreenShot のコマンドを使えばできると思う。後で試す。