lørdag 26. januar 2008

Using Selenium for getting a full image of a page.


The last few weeks I've been working on and off on a patch to acquire complete images of websites using Selenium-rc, now it is done.



The patch builds on the work done by Robert Zimmermann, but takes it a few steps further, creating two new selenium commands:


  1. initScreenshots creates a calibration image that is used to define the area that will be saved into the image.

  2. You can then navigate to the spot where you want to take a picture, and then call getFullScreenshot to get a full image.


Both commands maximize the window and getFullScreenshot also takes multiple screenshots of the page (while scrolling it) and then merges these together.



You can see a sample image taken of http://www.nytimes.com/ here (firefox) . I'm having a smal problem getting IE to do proper scrolling, but that should be fixable.



Compiling and running it yourself



I've attached the patches to bug #395. As a further help, you can find ready compiled jars for testing here: http://folk.uio.no/tarjeih/selenium/. You need to compile your tests using the selenium-java-client-driver-0.9.3-SNAPSHOT.jar file.



To run the server, you need to increase the amount of heap space to be able to merge the images. Here's the commandline I use to run this on windows:

java -Xmx256m -jar "Z:\selenium-server-0.9.3-SNAPSHOT-standalone.jar" -multiWindow


Further work


The basic patch is fairly clean, although some of the merge tests depend on quite a few images and also contains some Unixims, mainly that it saves files to /tmp.

Sample tests:










import java.awt.image.BufferedImage;

import java.io.File;

import javax.imageio.ImageIO;

import junit.framework.TestCase;

import com.thoughtworks.selenium.DefaultSelenium;

import com.thoughtworks.selenium.Selenium;



public class TestRemoteFullImage extends TestCase {

  private Selenium selenium;

  public void testRemoteImage() throws Exception {

  String url = "http://www.nytimes.com/";  

  selenium = new DefaultSelenium("wintest"4444"*firefox", url);

        selenium.start();

        System.out.println(selenium.initScreenshots());

        selenium.open(url);

        selenium.waitForPageToLoad("20000");

        BufferedImage rendImage = selenium.getFullScreenshot("png");

        File file = new File("/tmp/imresult.png");

        assertNotNull(rendImage);

        ImageIO.write(rendImage, "png", file);

  }

  public void testRemoteImageOnIE() throws Exception {

    String url = "http://www.nytimes.com/";

    selenium = new DefaultSelenium("wintest"4444"*iexplore", url);

        selenium.start();

        System.out.println(selenium.initScreenshots());



        selenium.open(url);

        selenium.waitForPageToLoad("20000");

        BufferedImage rendImage = selenium.getFullScreenshot("png");

        File file = new File("/tmp/iexporeresult.png");

        assertNotNull(rendImage);

        ImageIO.write(rendImage, "png", file);



  }

}









Java2html




fredag 11. januar 2008

Selenuim now has captureImage()

I just noticed over the holidays that Selenium has got support for retrieving images of a browser. It is still a patch though, but I've given it a spin and it works quite well. I'm now trying to extend it to capture the whole "page" not the part shown by the browsers viewport. More on that in a later post. Here's the basic code I use to get a picture:


import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import junit.framework.TestCase;

public class SimpleScreenshotTest extends TestCase {
private Selenium selenium;

public void setUp() throws Exception {
String url = "http://www.google.com";
// browsers:
//selenium = new DefaultSelenium("wintest", 4444, "*iexplore", url);
selenium = new DefaultSelenium("wintest", 4444, "*firefox", url);
selenium.start();
}

protected void tearDown() throws Exception {
selenium.stop();
}

/**
* The normal google test, just with a screenshot twist.
*/

public void testGoogle() throws Throwable {
selenium.open("http://www.google.com/webhp?hl=en");

assertEquals("Google", selenium.getTitle());

/* use maximize window to be able to get as much of the viewport as possible. */
selenium.windowMaximize();
selenium.waitForPageToLoad("5000");
// note: getScreenshot does not validate the inputparameters.
RenderedImage rendImage = selenium.getScreenshot("png");
if (rendImage == null) {
fail("Rendered image null!");
}
File file = new File("/tmp/newimage-.png");
ImageIO.write(rendImage, "png", file);
}


The next thing now will be to look into creating shots of the whole page.

If someone needs help building Selenium with the patch, post to the comments and I'll do a quick writeup of how to compile selenium-rc.