Geb で長いページの完全なスクリーンショット画像を保存する

まとめ

背景

  • Geb には任意の時点でブラウザの表示内容を png 画像に保存できる ScreenShotReporter が付属している
  • 取得できる内容は WebDriver の実装に依存している
  • たいていの WebDriver 実装は viewport つまりウインドウに表示している部分しか取得しないようになっている
    • viewport を広げるためウインドウサイズを調整するのもいいけど根本的な対応にはならない

検討

  • WebDriver の viewport を移動してページ全体のスクリーンショットを取得できるライブラリ aShot がよさそうだった
  • Geb のレポーターとして実装すれば実現できそう

実現方法

こんな感じのレポータークラスを用意した。

package com.example
 
import geb.report.ReportState
import geb.report.ScreenshotReporter
import ru.yandex.qatools.ashot.AShot
import ru.yandex.qatools.ashot.shooting.ShootingStrategies
import ru.yandex.qatools.ashot.util.ImageTool
 
/**
 * 全画面のスクリーンショットを取得する操作を提供するレポートクラス。
 */
class WholePageScreenShotReporter extends ScreenshotReporter {
 
    def scrollTimeout = 1000
 
    @Override
    void writeReport(ReportState reportState) {
 
        def screenShot = new AShot()
            .shootingStrategy(ShootingStrategies.viewportPasting(scrollTimeout))
            .takeScreenshot(reportState.browser?.augmentedDriver);
 
        def file = super.saveScreenshotPngBytes(reportState.outputDir, reportState.label, ImageTool.toByteArray(screenShot))
        super.notifyListeners(reportState, [file])
    }
}

GebConfig.groovy では次のようにレポーターを設定する。 PageSourceReporter は Geb に同梱されているレポーターで、 html をそのまま保存する。

reporter = new CompositeReporter(
    new PageSourceReporter(),
    new WholePageScreenShotReporter(),
)

Maven の依存関係も追加しておく。

<dependency>
    <groupId>ru.yandex.qatools.ashot</groupId>
    <artifactId>ashot</artifactId>
    <version>1.5.4</version>
</dependency>