How to take a screenshot using webdrvier with C#

3,808 views
Skip to first unread message

Moises Siles

unread,
Aug 13, 2011, 10:56:57 PM8/13/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
Hi guys, 

What is the right way to take a screenshot using webdriver and C# with Firefox 3.6 and IE8?

I found this code in the link below but it is not working



            Screenshot ss = ((ITakesScreenshot)webDriver).GetScreenshot();   // I got the error here

            //Use it as you want now
            string screenshot = ss.AsBase64EncodedString;
            byte[] screenshotAsByteArray = ss.AsByteArray;
            ss.SaveAsFile("c://test", ImageFormat.Png); //use any of the built in image formating
            ss.ToString();//same as string screenshot = ss.AsBase64EncodedString;


Thanks

Daniel Wagner-Hall

unread,
Aug 13, 2011, 11:15:40 PM8/13/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
What error are you getting? Can we have a stack trace?

Are you using a RemoteWebDriver?

> --
> You received this message because you are subscribed to the Google Groups
> "webdriver" group.
> To post to this group, send email to webd...@googlegroups.com.
> To unsubscribe from this group, send email to
> webdriver+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/webdriver?hl=en.
>

Moises Siles

unread,
Aug 14, 2011, 11:06:10 AM8/14/11
to seleniu...@googlegroups.com
Yep, I'm using webdriver and this is the error

Unable to cast object of type 'OpenQA.Selenium.Remote.RemoteWebDriver' to type 'OpenQA.Selenium.ITakesScreenshot'.


--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To post to this group, send email to seleniu...@googlegroups.com.
To unsubscribe from this group, send email to selenium-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/selenium-users?hl=en.


Jim Evans

unread,
Aug 14, 2011, 11:35:44 AM8/14/11
to Selenium Users
No, that's exactly right. RemoteWebDriver doesn't implement
ITakesScreenshot, because all subclasses thereof may not support
taking screenshots. You could make an argument that IWebDriver should
support screenshots, and throw an exception if the concrete
implementation doesn't support it, but that's an API issue and as such
affects more than just the .NET bindings, so you'd need to get
consensus from the designers of the API. In the meantime, you can
subclass RemoteWebDriver and implement ITakesScreenshot yourself. For
a demonstration of this, look at the project source code at the
implementation of InternetExplorerDriver, FirefoxDriver, or
ChromeDriver.

On Aug 14, 11:06 am, Moises Siles <moises.si...@gmail.com> wrote:
> Yep, I'm using webdriver and this is the error
>
> Unable to cast object of type 'OpenQA.Selenium.Remote.RemoteWebDriver' to
> type 'OpenQA.Selenium.ITakesScreenshot'.
>
> On Sat, Aug 13, 2011 at 9:15 PM, Daniel Wagner-Hall <dawag...@gmail.com>wrote:
>
>
>
> > What error are you getting? Can we have a stack trace?
>
> > Are you using a RemoteWebDriver?
>
> > On 13 August 2011 19:56, Moises Siles <moises.si...@gmail.com> wrote:
> > > Hi guys,
> > > What is the right way to take a screenshot using webdriver and C# with
> > > Firefox 3.6 and IE8?
> > > I found this code in the link below but it is not working
>
> >http://stackoverflow.com/questions/3346017/best-way-to-take-screensho...

Moises Siles

unread,
Aug 14, 2011, 12:09:09 PM8/14/11
to seleniu...@googlegroups.com, webd...@googlegroups.com
thanks for the clarification Jim, so, where should I start take a look trying to implement the screenshot as well..... Do you have a link or specific sections that I have to take a look in the code

Thanks

Jim Evans

unread,
Aug 14, 2011, 1:40:07 PM8/14/11
to Selenium Users
Any of the implementations of the specific browser drivers would have
an example of ITakesScreenshot. It should be fairly obvious looking at
the source for those classes. However, to more explicitly point you to
the source files you'd want to look at, see below.

Firefox: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver/Firefox/FirefoxDriver.cs
Chrome: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver/Chrome/ChromeDriver.cs
IE: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver/IE/InternetExplorerDriver.cs

On Aug 14, 12:09 pm, Moises Siles <moises.si...@gmail.com> wrote:
> thanks for the clarification Jim, so, where should I start take a look
> trying to implement the screenshot as well..... Do you have a link or
> specific sections that I have to take a look in the code
>
> Thanks
>

Moises Siles

unread,
Aug 15, 2011, 12:27:09 AM8/15/11
to seleniu...@googlegroups.com, webd...@googlegroups.com
Thanks Jim for your time and help

Regards

Moises Siles

unread,
Aug 17, 2011, 10:47:00 AM8/17/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
Yes Kumar, that should work fine for the FirefoxDriver, but we are talking about the RemoteWebdriver

On Wed, Aug 17, 2011 at 12:53 AM, Harish Kumar <harishb...@gmail.com> wrote:
I have used your code and successfully taken screen shots of web pages using C#.

            IWebDriver driver = new FirefoxDriver();

            driver.Navigate().GoToUrl("http://www.google.com");

            Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
            string screenshot = ss.AsBase64EncodedString;
            byte[] screenshotAsByteArray = ss.AsByteArray;
            


actually you have to add:
using System.Drawing;
using System.Drawing.Imaging;


also, you have to write the extension with filename.
ss.SaveAsFile("c://test.png", ImageFormat.Png);
Thank You

HARISH KUMAR

Krishnan Mahadevan

unread,
Aug 17, 2011, 11:08:22 AM8/17/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
Following is how we managed to get this done in Java :

public class MyScreenShotRemoteWebDriver extends RemoteWebDriver implements TakesScreenshot {
    public MyScreenShotRemoteWebDriver (URL url, DesiredCapabilities capabilities) {
        super(url, capabilities);
    }
    public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
            return target.convertFromBase64Png(execute(DriverCommand.SCREENSHOT).getValue().toString());
    }

}
 //here ssWebDriver is of type MyScreenShotRemoteWebDriver 
 String ss = ssWebDriver.getScreenshotAs(OutputType.BASE64);
byte[] decodeBuffer = Base64.decodeBase64(ss.getBytes());

once you have the bytes, you could write them into an outputstream 

Hope that helps

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

Moises Siles

unread,
Aug 17, 2011, 11:31:14 AM8/17/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
Thanks Krishnan,

So far that is what I have..... My problem is initializing the webdriver var, because I have something like this

  public static IWebDriver webDriver { get; set; }

   [SetUp]
        public static void LaunchBrowser()
        {
            try
            {
                Browser = ConfigurationManager.AppSettings["Browser"].ToString();
                //DesiredCapabilities desiredCapabilities;
                var remoteAddress = new Uri(ConfigurationManager.AppSettings["RemoteAddress"].ToString());

                switch (Browser.ToString())
                {
                    case "Firefox":
                        webDriver = new FirefoxDriver();
                        break;
                    case "iexplorer":
                        webDriver = new InternetExplorerDriver();
                        break;

                    case "remoteFirefox":
                        desiredCapabilities = DesiredCapabilities.Firefox();
                        //webDriver = new RemoteWebDriver(remoteAddress, desiredCapabilities);
                        webDriver = new ScreenShotRemoteWebDriver(remoteAddress, desiredCapabilities);

                        break;
                    case "remoteInternet":
                        desiredCapabilities = DesiredCapabilities.InternetExplorer();
                        webDriver = new ScreenShotRemoteWebDriver(remoteAddress, desiredCapabilities);
                        break;

                    default:
                        throw new Exception("Can't find the Browser: " + Browser);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

The problem is in this line webDriver = new ScreenShotRemoteWebDriver(remoteAddress, desiredCapabilities); ,  it is working fine, the only problem is that I can't call the method GetScreenshot that I have defined in the ScreeShotRemoteWebdriver class, I know that this issue is because the webDriver variable is of Type IWebDriver and it should be ScreeShotRemoteWebdriver, but if I change the webDriver type, how can I solve the or how should I work with the other drivers that I have in the switch...... I'm not sure if I'm doing wrong initializing all the drivers in that way(Take a look in the switch section)

Regards

Krishnan Mahadevan

unread,
Aug 17, 2011, 11:45:47 AM8/17/11
to webd...@googlegroups.com, seleniu...@googlegroups.com
Umm, I get what you are talking about. But if webDriver is being assigned an object of type ScreenShotRemoteWebDriver() I am guessing that you should be able to explicitly cast it back to its type and then use it.[Since ScreenshotRemoteWebdriver extends RemoteWebDriver which inturn implements WebDriver interface)

i.e., something like ((ScreenShotRemoteWebDriver)webDriver).getScreenshotAs()

You could check if webDriver is an instance of type ScreenShotRemoteWebDriver before you do this cast, just to be on the safer side and not kick off ClassCastExceptions 

Would that work ?

Just a point that I thought I would bring up although its not related to the conversation in this thread.
If there is no specific reason as to why you would want to switch between FFDriver, IEDriver and RemoteWebDriver, I would stick to RemoteWebDriver all the time, and for local runs, just stick to spawning a local hub and then having the RemoteWebDriver run against it.
That would keep things fairly simple and you wouldnt have to worry about webDriver being assigned an instance of type FFDriver or IEDriver or RemoteWebDriver.it would all the time be ScreenShotRemoteWebDriver (which basically extends RemoteWebDriver)

You can refer to : https://gist.github.com/1106183 wherein I wrote up a sample, which basically shows you how to spawn a local Grid via your code (intended for local runs)

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"



Moises Siles

unread,
Aug 17, 2011, 12:28:02 PM8/17/11
to seleniu...@googlegroups.com, webd...@googlegroups.com
Thanks guys, I really appreciate all your help, it is working now.... Thanks Jim for your patience with me :P and for your answers

@Krishnan, 
Answering your other question basically when I started I used to use only the 
RemoteWebdriver, right now I have to use the local drivers and sometimes I 
have to use the Remote one. But I agree with you, if I want to run the scripts 
locally I can start the hub and still using the RemoteWebdriver

Also I'm not sure if this is true, but I feel that my scripts runs faster 
using the local Drivers instead of the RemoteWebdriver......

Regards
Reply all
Reply to author
Forward
0 new messages