Reputation: 24291
I would like an automated web tests suite based on Selenium RC to take screenshots of pages when some errors are encountered. The test suite is a part of the continuous integration process and technically is executed by CruiseControl running as a Windows service.
The selenium.captureScreenshot()
method is called to trigger the actual screenshot. I've registered a JUnit RunListener
to call it on any test failure.
The problem is the screenshots are just blank files - PNG files totally black. The dimensions are 1440x900.
When manually running the same tests from Eclipse the screenshots are OK (althought they are screenshots of the whole desktop not the browser window, but that's a different story and a minor issue). So I guess the cause of the problem is the Selenium being run as a Windows service.
How can I have the screenshots of pages taken when exceptions in Selenium tests happen?
The software used:
Upvotes: 12
Views: 9852
Reputation: 210
An alternative solution to your RunListener approach:
Enclose your test in a try-catch block and do the screenshot in the catch block, that's what i always do.
Example java code:
public void testEnterFormFields()
try {
enterFormFields();
} catch(SeleniumException e) {
//do screenshot, logging, dumping, stacktracing or whatever here
}
}
You could catch Throwable or Exception as well, if your coding rules allow it, but it makes sense to catch the specific Exception one by one. This approach produces a bit more clutter in your code but it will help you a lot in case of failure analysis. You can tailor your exception handling to the type of error. You maybe want to capture other informations in case of an AssertionError than in case of a SeleniumException.
Upvotes: -1
Reputation: 4356
I don't know how cruise control will execute GUI tests, but i recently implemented a screenshot mechanism myself and what i learned was that the components you're drawing have to be in a window or some other root element. "unrooted" elements will just not paint properly and result in black images most of the time.
So if cruise control or your unit tests are using some magic to not properly display the gui elements, you might want to add them to a dummy JFrame before painting.
Upvotes: 1
Reputation: 24291
Looks like there's a completely different answer. The Windows service (managed by TanukiSoftware Java Service Wrapper) was started with wrapper.ntservice.interactive
set to false
. Setting it to true
has helped. Eventually the screenshots contain real screen content.
Consult the wrapper.ntservice.interactive
for details. The analysis of the wrapper code leads to [SERVICE_INTERACTIVE_PROCESS
](http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx) flag being set when starting the Windows service.
Upvotes: 5
Reputation: 1384
I have come accross the issue with CaptureScreenshot generating black images when running under a windows service.
Using CaptureEntirePageScreenshot as recommended by Dave Hunt is working consistently for me.
Upvotes: 1
Reputation: 8223
What browser are you running these tests in? If it's Firefox I'd recommend the captureEntirePageScreenshot to capture the entire canvas - not just what's in view (rather than the screen) and captureEntirePageScreenshotToString if you're working remotely and want to save the files locally.
Not sure if it will help with your issue, but as it uses an add-on to Firefox it might be worth a try.
Upvotes: 3
Reputation: 8388
Reading a little more on this, it could be something to do with your windows service needing extra security permissions. Going back to Windows NT 3.5/4 services had restricted access to the application desktop (required for screenshots) and I'd guess their security restrictions continue to this day.
This thread about services on the java.net forums may provide the clues you need to get it working.
Upvotes: 2
Reputation: 3843
Here is some code for taking pics using Selenium and the Java Robot class:
public void takeAScreenShotOfTheApp() {
Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenBounds = new Rectangle(0, 0, screenDim.width, screenDim.height);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenBounds);
File screenshotFile = new File("target" + File.separator
+ "image" + System.currentTimeMillis() + ".png");
ImageIO.write(image, "png", screenshotFile);
}
It is taken from this site
Upvotes: 0