Selenium for vb.net

Selenium HQHave you found a need to automate a process with just a web UI available? Where there’s no API, repetitive task can take ages and be most destructive on the patience of a programmer that knows most things can be automated.

There is an option though.. It’s called Selenium (I was informed by my friend at thedaytodayjava.com)

Selenium allows you to simulate a “human” browsing any html webpage and perform actions.

This a quite long article. If you want a shorter version, I came across this article.

Preperations

You’ll want the following dll’s referenced in your app:

nmock.dll
nunit.core.dll
nunit.framwork.dll
ThoughtWorks.Selenium.Core.dll
ThoughtWorks.Selenium.IntegrationTests.dll
ThoughtWorks.Selenium.UnitTests.dll

(You might not need some of these, but I’m not going to retrace my steps. Let my know if you want to correct me =)

Download Selenium RC from http://seleniumhq.org/download/

In the zip file you’ll find the folder selenium-dotnet-client-driver-*.*.* that should contain all you need, dll-wise.
The selenium-server-*.*.* folder contains the selenium-server.jar file to run on Java SE (Update: JRE).

As you are a .NET geek, the .jar file might seem strange. Running this file on Java will actually initiate the server in which your application will interact with the browser.

..All done with the worst. Now you’ll need the Selenium IDE for Firefox. Grab it here.

With the plugin installed to Firefox you may activate it, record and do some stuff on a web page. Your actions are recorded step by step. Explore it, click links, type in textboxes and submit, Selenium will record it all. When your done you get some html-like formatted log which you can replay.

Getting to it

To make it real powerful you’ll want to use this in your code.. Selenium provides several export options.

Export your Selenium recording and place it in your program.

An export might look like this

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;

namespace SeleniumTests
{
	[TestFixture]
	public class seleniumDemoCsharp
	{
		private ISelenium selenium;
		private StringBuilder verificationErrors;

		[SetUp]
		public void SetupTest()
		{
			selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://www.google.no/");
			selenium.Start();
			verificationErrors = new StringBuilder();
		}

		[TearDown]
		public void TeardownTest()
		{
			try
			{
				selenium.Stop();
			}
			catch (Exception)
			{
				// Ignore errors if unable to close the browser
			}
			Assert.AreEqual("", verificationErrors.ToString());
		}

		[Test]
		public void TheSeleniumDemoCsharpTest()
		{
			selenium.Open("/");
			selenium.Type("q", "Selenium IDE");
			selenium.Click("btnG");
			selenium.Click("//ol[@id='rso']/li[1]/h3/a[1]/em");
		}
	}
}

Yes, it will only export to C#. Rewrite it or translate to vb.net using you favorite conversion tool.

In our example we end up with something like this

Imports System
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports NUnit.Framework
Imports Selenium

Namespace SeleniumTests
  <TestFixture()> _
  Public Class seleniumDemoCsharp

    Private selenium As ISelenium
    Private verificationErrors As StringBuilder

    <SetUp()> _
    Public Sub SetupTest()
      selenium = New DefaultSelenium("localhost", 4444, "*chrome", "http://www.google.no/")
      selenium.Start()
      verificationErrors = New StringBuilder()
    End Sub

    <TearDown()> _
    Public Sub TeardownTest()
      Try
        selenium.[Stop]()
        Catch generatedExceptionName As Exception
        ' Ignore errors if unable to close the browser
      End Try
      Assert.AreEqual("", verificationErrors.ToString())
    End Sub

    <Test()> _
    Public Sub TheSeleniumDemoCsharpTest()
      selenium.Open("/")
      selenium.Type("q", "Selenium IDE")
      selenium.Click("btnG")
    End Sub
  End Class
End Namespace

As you might have guessed, in the example above I’ve cruised to google.no, typed “Selenium IDE” and clicked the Search button.

Creating something useful

Lets say you want to search for different terms and save an image of the page (Warning! Google don’t like such automated systems.. This is just an example).

In your application you can replace the strings you’ve searched for and enumerate a list of different values you’d like to automate:

Imports System
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports NUnit.Framework
Imports Selenium

Namespace SeleniumTests

  <TestFixture()> _
  Public Class seleniumDemoCsharp

    Private selenium As ISelenium
    Private verificationErrors As StringBuilder

    <SetUp()> _
    Public Sub SetupTest()
      selenium = New DefaultSelenium("localhost", 4444, "*chrome", "http://www.google.no/")
      selenium.Start()
      verificationErrors = New StringBuilder()
    End Sub

    <TearDown()> _
    Public Sub TeardownTest()
      Try
        selenium.[Stop]()
      Catch generatedExceptionName As Exception
        ' Ignore errors if unable to close the browser
      End Try
      Assert.AreEqual("", verificationErrors.ToString())
    End Sub

    <Test()> _
    Public Sub CaptureResults(ByVal SearchTerm As String)
      selenium.Open("/")
      selenium.Type("q", SearchTerm)
      selenium.Click("btnG")
      selenium.WaitForPageToLoad("30000")
      If selenium.IsTextPresent("jorno.org") Then
        selenium.CaptureEntirePageScreenshot("C:\GoogleResultImages\" & SearchTerm.Replace(" ", "-") & ".jpg")
      Else
        Throw New Exception("Epic fail!")
      End If
    End Sub

    Public Sub Main()
      Dim arrTerms as new string(){"Selenium", "Webhosting", "Nine Inch Nails rules"}
      For i as integer = 0 to (arrTerms.Length - 1)
        CaptureResults(arrTerms(i))
      Next
    End Sub

  End Class
End Namespace

On line 38 you might have noticed we’ve put in WaitForPageToLoad. This will cause selenium to wait for 30000 MS before it times out. Not very useful in this example, but could prove useful in other scenarios if the site doesn’t repond in time.

Line 39 checks if the result page contains the text “jorno.org”. An error is thrown if not. A rather unstable application =)

On line 40 we store the result page as an image. The term “Nine Inch Nails rules” results would be found as an image at C:\GoogleResultImages\NineInchNailsrules.jpg if “jorno.org” is present on the result page (unlikely).

There are large amounts of functions to selenium which we haven’t touched in this article and you can imagine to possibilities for integrating selenium. It is widely used for unit-testing. Integrated with systems like hudson it’s a great way to test your builds and save a lot of testing time on your web-UIs.

Conclusion

This trick can help you save ALOT of time. It has done for me:

We desperately needed to extract large amounts of data from a rather old fashioned service provider with no functioning API, just a terrible web-UI. The solution became integration of selenium to a windows application. If it weren’t for this solution we would spend several months solving our problem..

  1. Thanks for posting this, it’s a good idea for automation.

    Selenium is also fantastic for automated testing of your UI, too.

    I think there is a little mistake on line 36, though – shouldn’t the “Selenium IDE” be replaced by SearchTerm?

  2. @Greg L
    Thank you sir, silly mistake =)

  1. No trackbacks yet.