I had been facing problems with the ‘capture screen-shot’ functionality in the remote webdriver implementation. There are many blogs on the web that try to address this problem, but I was unable to find any solution to the problem I was facing. Finally, I found a solution, and here is what I did. I hope this will will help those stuck in a similar situation. I request you to kindly provide your feedback if it works for you, and also if it doesn’t.
Issue:
‘Capture screen-shot’ functionality works well with selenium2 standard implementation or webdriver implementation. When you try to do to the same with remote webdriver implementation, the ‘capture screen-shot’ functionality throws Class Cast Exception [java.lang.ClassCastException: org.openqa.selenium.remote.RemoteWebDriver cannot be cast to org.openqa.selenium.TakesScreenshot].
Reason:
The RemoteWebDriver class not implements TakesScreenshot interface.
Resolution:
One nice feature of the remote webdriver is that exceptions often have an attached screenshot, encoded as a Base64 PNG. In order to get this screenshot, you need to write code similar to:
if (e.getCause() instanceof ScreenshotException) {
String base64Str =
((ScreenshotException) e.getCause()).getBase64EncodedScreenshot();
…
}
This will provide you a screenshot when the WebdriverException exception occurs during action or event on browser. But what if you want to capture screenshot at particular step?
First, I tried unusual quick fix by utilizing WebdriverException. It worked for me, but it is not a standard way for sure. One more issue with the extracted screenshot from webdriver exception is, that it corresponds to the visible screen/desktop so sometimes the screenshot became meaningless when it does not contain the browser screen.
After analyzing the issue in greater detail I came up with a more standard solution. The main reason why screenshot in remote webdriver implementation is not supported is that the RemoteWebDriver class does not implement TakesScreenshot interface. So I created MyCustomRemoteWebDriver by extending RemoteWebDriver and implementing TakesScreenshot interface.
public
class MyCustomRemoteWebDriver extends RemoteWebDriver implements TakesScreenshot {
…
}
Finally I used MyCustomRemoteWebDriver in my implementation instead of standard RemoteWebDriver and it worked for capturing screenshot in the usual way!