Chromeでも画面全体のキャプチャ―を取得する(Selenium2 WebDriver)


ChromeWebDriverで普通に画面のキャプチャーを取得すると。。。

クロスブラウザテストしたくて、WebDriverでテストを実行したのですが、
ChromeのWebDriverでは画面全体のキャプチャーが取得されません。。。
縦に長―い画面だと一部しかキャプチャ取れないんです。。。

・普通のスクリーンショット取得方法だと。。。

普通のスクリーンショット
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl + "/sample.html");
        driver.switchTo().defaultContent();
        TakesScreenshot ts = (TakesScreenshot) new Augmenter().augment(driver);
        FileUtils.moveFile(ts.getScreenshotAs(OutputType.FILE), new File("c:\\temp\\img-"+ System.currentTimeMillis() +".png"));

・結果

↑↑こんな感じで途中で切れたファイルが保存されちゃいます。これじゃだめだ。怒られる。。

こんな感じで対応しました

WebDriverからJsを実行できるので、
ぐりぐりスクロールさせつつ、
スクリーンショットを撮って、
画像を繋げて保存するようにしました。

サンプルは以下の感じです。

画面全体を撮るスクリーンショット
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl + "/sample.html");
        driver.switchTo().defaultContent();
        TakesScreenshot ts = (TakesScreenshot) new Augmenter().augment(driver);

        //JS実行用のExecuter
        JavascriptExecutor jexec = (JavascriptExecutor) driver;

        //画面サイズで必要なものを取得
        int innerH = Integer.parseInt(String.valueOf(jexec.executeScript("return window.innerHeight")));
        int innerW =Integer.parseInt(String.valueOf(jexec.executeScript("return window.innerWidth")));
        int scrollH = Integer.parseInt(String.valueOf(jexec.executeScript("return document.documentElement.scrollHeight")));

        //イメージを扱うための準備
        BufferedImage img = new BufferedImage(innerW, scrollH, BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();

        //スクロールを行うかの判定
        if(innerH>scrollH){
            BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
            g.drawImage(imageParts, 0, 0, null);
        } else {
            int scrollableH = scrollH;
            int i = 0;

            //スクロールしながらなんどもイメージを結合していく
            while(scrollableH>innerH){
                BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
                g.drawImage(imageParts, 0, innerH*i, null);
                scrollableH=scrollableH - innerH;
                i++;
                jexec.executeScript("window.scrollTo(0,"+innerH*i+")");
            }

            //一番下まで行ったときは、下から埋めるように貼り付け
            BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
            g.drawImage(imageParts, 0, scrollH - innerH, null);
        }

        ImageIO.write(img, "png", new File("c:\\temp\\mergeimg-"+ System.currentTimeMillis() +".png"));

・結果

このようにスクロールされた画像が取得できました!
一番下をいい感じに上書くのがポイントですね。