Using WebDriver with CSharp

You can read my previous post if you’re interested in the background to this post. What follows is a step-by-step guide for using WebDriver from C# test code.

Preparation

What you’ll need:

  • IKVM.NET.  I used version 0.40.0.1 and the download was called ikvmbin-0.40.0.1.zip
  • WebDriver “all”.  The download will be called something like webdriver-all-7376.zip

Once you’ve downloaded them, extract the two ZIPs on to your computer.

Recompile WebDriver from Java to .NET

Open up a command window and change directory to the directory where you extracted the WebDriver files.

Run the following from the command prompt (all on one line):

path\to\ikvm\bin\ikvmc.exe -out:webdriver-all.dll -target:library *.jar

The above line uses ikvmc.exe to recompile the WebDriver Java code into managed .NET classes.  The managed .NET classes are placed in the webdriver-all.dll assembly.

When I run ikvmc.exe it spits out about 1200 lines of warning messages!  However everything seems to work fine regardless.  I wouldn’t worry too much about the warning messages, but if anyone has the time, it’s worth digging into them (first thing to try would be to replace *.jar in the ikvmc.exe command line with a space separated list of all the WebDriver .jar files – with the files ordered so that every .jar file appears in the list after all the .jar files its dependent on).  Some of the warning messages like duplicate class name… and skipping class…class is already available in referenced assembly… are harmless.

Using WebDriver from a Visual Studio Project

Open Visual Studio 2008 and create a new C# Console Application project  called WebDriverAndCSharp.

Right click the project in Solution Explorer and add a references to the following DLLs:

  • The webdriver-all.dll that you created above
  • All the DLLs in the bin directory that you extracted from the IKVM.NET download – except don’t add a reference to the ikvm-native.dll file
References after adding webdriver-all.dll and IKVM.NET DLLs

Adding ikvm-native.dll to the Project

IKVM.NET also depends on a native (non-managed) DLL called ikvm-native.dll.  You can’t add ikvm-native.dll as a project reference due to a limitation of Visual Studio.  Instead you need to add a link to the ikvm-native.dll file by doing the following:

  1. Right click the project in Solution Explorer and click Add\Existing Item…
  2. In the Add Existing Item dialog box that appears:
    1. Select Executable Files (*.exe; *.dll; *.ocx) in the drop down list of file types
    2. Browse to the directory where you extracted the IKVM.NET download
    3. Select the ikvm-native.dll file in the bin subdirectory
    4. Click the down arrow next to the Add button (don’t actually click the Add button) and select Add As Link

Next, right click ikvm-native.dll in the Solution Explorer and click properties. Change the Build Action to None and set Copy to Output Directory to Copy Always.

Amended propeties for ikvm-native.dll

Amended properties for ikvm-native.dll

Adding the Example Code

Open the Program.cs file and replace its contents with the following:

namespace WebDriverAndCSharp
{
  using org.openqa.selenium;
  using org.openqa.selenium.firefox;
  using org.openqa.selenium.htmlunit;
  using org.openqa.selenium.ie;

  public class Program
  {
    public static void Main(string[] args)
    {
      SearchTheWeb(new HtmlUnitDriver());
      SearchTheWeb(new FirefoxDriver());
      SearchTheWeb(new InternetExplorerDriver());
      SearchTheWeb(new ChromeDriver());
      `
      System.Console.Out.WriteLine("Press ENTER to exit");
      System.Console.In.ReadLine();
    }

    public static void SearchTheWeb(WebDriver driver)
    {
      // And now use this to visit Google
      driver.get("http://www.google.com");

      // Find the text input element by its name
      WebElement element = driver.findElement(By.name("q"));

      // Enter something to search for
      element.sendKeys("Cheese!");

      // Now submit the form. WebDriver will find
      // the form for us from the element
      element.submit();

      // Check the title of the page
      System.Console.Out.WriteLine(
        "Page title is: " + driver.getTitle());

      driver.quit();
    }
  }
}

The C# code above is a translation of the Java-based WebDriver example code given on the WebDriver’s Getting Started page.

Running the Example

Press F5 to launch the console app you’ve created.  If all goes well, after a few seconds you should see a Firefox window open and perform a search on Google for “Cheese!”.  You should then see Internet Explorer do the same.  When the app has finished – assuming nothing went wrong – the console app should look like this:

Page title is: Cheese! - Google Search
Page title is: Cheese! - Google Search
Page title is: Cheese! - Google Search
Press ENTER to exit

Now press the ENTER key to exit the console app. The console app should then close. If it doesn’t, then part of WebDriver may not have closed down cleanly – a problem which I’ve only encountered with Google Chrome (you’ll notice that Chrome is missing from the code example above).

If Something Went Wrong

When you run the example, if you get an exception message saying “The type initializer for ‘com.sun.jna.Native’ threw an exception”, check the build output folder for your project (normally in the directory “bin\Debug” under the directory with your *.csproj file in it) and confirm you can see a file called ikvm-native.dll.  If the DLL isn’t there, take a look back in this posting at the section called Adding ikvm-native.dll to the Project and check you’ve followed all the steps there.  If that doesn’t work for you, another way to get the DLL into your build output directory is to do the following:

  1. Right click the project in Solution Explorer and click Properties.
  2. On the left, click the Build Events tab.
  3. Paste the following into the Post-build event command line textbox.  Make sure you replace path\to with the full path to where  you extracted ikvm-native.dll to (when you extracted the IKVM.NET ZIP file).
copy /y path\to\ikvm-native.dll $(TargetDir)

Following these steps will ensure that the ikvm-native.dll DLL is copied to your build output folder everytime you build the project.

Browser Support

So far I’ve only tested a small fraction of WebDriver’s functionality from C#.  I’ll need to use it for a week or two to really get a feel for how stable WebDriver is when running under IKVM.NET.  However initial impressions suggest that WebDriver with C# works fine with the following browsers:

  • HtmlUnit
  • Firefox
  • Internet Explorer

Google Chrome

I encountered an issue getting Google Chrome working: WebDriver leaves the Google Chrome browser open when the ChromeDriver is closed.  This leads to the console app not terminating properly. It’s a shame because other than that, Chrome seems to work well with WebDriver + .NET.

If you want to try Chrome for yourself, make sure you switch your Chrome browser over to either the beta or dev streams and that your Chrome version is 4.0.206.*+.  I found Google’s Channel Changer app very helpful.

See the WebDriver page on the ChromeDriver for more information on using Chrome with WebDriver.

Update: Daniel Wagner-Hall on the WebDriver discussion group has kindly helped me out with getting ChromeDriver working.  Turns out I should have used driver.quit() instead of driver.close().  I’ve updated the example above to use driver.quit() (see the WebDrive discussion group for more).  With the change, Chrome nolonger stops the console app from finishing.  However I am still seeing Chrome outputting the wrong page title on the console app – unlike the other drivers.

7 comments

  1. @Jake Thanks. Do you get an exception message saying “The type initializer for ‘com.sun.jna.Native’ threw an exception”? If you do, check the ikvm-native.dll assembly has appeared in your build output folder (probably “.\bin\Debug”). I’ve checked and not having that IKVM.NET assembly in your build folder would cause the exception I mentioned and it would only affect InternetExplorerDriver. Hope that helps.

    Try the “Instead you need to add a link to the ikvm-native.dll file by doing the following” bit in the post above and that’ll probably sort it for you. Let me know if it doesn’t fix it. I’ll add a bit extra to the post covering the exception message

  2. Hi Simon,

    Just wanted to say many-thanks for taking the time to put this article together. Found it very-very useful and have managed to get this working really well in VB.NET with no fuss.

    Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *