dotnetco.de

Example how to use Selenium with Visual Studio and Visual Basic.NET

(The code in this example is Visual Basic.net but could of course be easily transferred into C#). So we have set up Selenium (as described here) and followed some general tips (as described here). Now it’s time to write our first unit test in Visual Studio using Visual Basic.net and Selenium. We will do a rather simple test but it covers several aspects of web testing. We will write a test to check whether a link to our current domain dotnet-developer.de is returned as first result from bing when we search for “dotnet-developer.de”. So we have to write a webtest with these steps:

  1. Go to Bing.com
  2. Enter “dotnet-developer.de” into the search box
  3. Start search by pressing ENTER or clicking the Search-Button
  4. Check the first result returned by Bing.com

Helpful tools are Firefox and Firebug. Of course you could write the texts also without these tools but you will see that they will help you a lot, so I recommend to use them.

You could watch a video about the final result on Youtube at http://www.youtube.com/user/dotnetdeveloperde:

Open Bing Homepage

The first step is then to navigate to bing.com so first line of code is:

driver.Navigate.GoToUrl(HomePageURL)

Enter search text into textbox

Now we want to enter “dotnet-developer.de” into the searchbox. So we need to find out details about the searchbox. Therefore we start Firefox and manually go to “http://www.bing.com” and inspect the homepage within firebug. Click on Firebugs “Inspect”-Icon and select the Searchbox. The corresponding HTML-Code is now marked in Firebug.

In the second line of Firebug use your right mouse-button and click on the leftmost element, in current case it’s “input#sb…..sq_qbox” (when you move the mouse on the items you might notice that Firebug marks there position within the web page). On the right-click menu select “Copy XPath”.

Now the following value is copied: //*[@id=”sb_form_q”] So in current case we got an ID, in other cases you get an Xpath like this: /html/body/table/tbody/tr/td/div/div[6]/div[2]/form/div

Both is fine, but if you have an ID I’d prefer to use the ID rather than the XPath because XPath changes if the design of the page changes but ID will still be the same until the field is renamed (which might appear only in rare cases). Now we need to click in this field from Selenium. First we need to get a handle to it:

Dim SearchBox As IWebElement SearchBox = GetWebElement(driver, By.Id("sb_form_q"), 10)

 

So we have a handle to the search box. Now we want to enter some text:

SearchBox.SendKeys("dotnet-developer.de")

Start the search

As the text is inserted we now want to start the search. This could be done in several ways, e.g. press enter:

SearchBox.SendKeys(Keys.Enter)

 

Or we could grab the “Search”-Button and click it. So we click again the “Inspect” button in Firebug (as described above) and get the XPath for the button:

SearchButton = GetWebElement(driver, By.Id("sb_form_go"), 10) SearchButton.Click()

So after calling one of these 2 methods Bing should display a result page.

Check Result page

Now we do the same manually in our Firefox instance. So got to http://www.bing.com,  enter “dotnet-developer.de” and start the search.

For the test we want to check the first result returned by Bing. So get a reference to it as already described above using Firebugs “Inspect” icon and get the XPath for the first link. It should be like this:

/html/body/div/div/div[2]/div[3]/div/div/div[2]/div/div/div/ul/li/div/div/div/h3/a. So we get the web element as usual but we will see that the XPath depends on whether Bing e.g. displays adverts or not. For example when we use Bing to search for “Microsoft” we will get this XPath:

/html/body/div/div/div[2]/div[3]/div/div/div[2]/div/div/div[2]/ul/li/div/div/div/h3/a. See the difference? So using the proposed XPath might work now but will fail if Microsoft starts displaying ads for the search term. Anyway, it would be fine if you use this command:

FirstResult = GetWebElement(driver, By.XPath("/html/body/div/div/div[2]/div[3]/div/div/div[2]/div/div/div[2]/ul/li/div/div/div/h3/a"), 10)

But let’s try to make it work regardless of their ads. Having a closer look at the source code shows that Bing returns the search result in an unordered list of class “sb_results”.

So the better approach would be to start at list “sb_results” instead of the beginning of the document. Using XPath this is rather easy (If you are not familiar with Xpath you might start with the Wikipedia Article).

Default XPath:

/html/body/div/div/div[2]/div[3]/div/div/div[2]/div/div/div/ul/li/div/div/div/h3/a

New Xpath:

//ul[@class=’sb_results’]/li/div/div/div/h3/a

So we now have a handle to the first link in the Resultlist. Again we have several options. First we could check the text. It is available in WebElements property “Text”:

Dim Expected As String = "dotnet-developer.de | Tips for vb.net,…" Assert.AreEqual(Expected, FirstResult.Text, "Subject is not correct")

Of course this works fine, but only if the subject of dotnet-developer.de is not changed. So of course it would be better to check for the link, not for the text.

When we have a look at the source code of the Bing result page we see the structure of the first link looks like this:

<a h=”ID=SERP,5082.1″ href=”http://www.dotnet-developer.de/”><strong>dotnet-developer.de</strong> | Tips for vb.net,…</a>

As usual, the anchor has a ‘href’ attribute. Each Selenium Webelement has a method ‘GetAttribute’ where we could specify the attribute to be retrieved. So in current case we want to check attribute ‘href’:

Dim expected As String = "http://www.dotnet-developer.de" Assert.AreEqual(expected, FirstResult.GetAttribute("href"), "URL is not correct!")

 

 

Done!

Here is the full source code:

Imports System.Text
Imports OpenQA.Selenium
Imports OpenQA.Selenium.Firefox
Imports OpenQA.Selenium.Support.UI


<TestClass()>
Public Class UnitTest1
Private testContextInstance As TestContext


'''<summary>
'''Gets or sets the test context which provides
'''information about and functionality for the current test run.
'''</summary>
Public Property TestContext() As TestContext
Get
   Return testContextInstance
End Get
Set(ByVal value As TestContext)
   testContextInstance = Value
End Set
End Property


Public driver As IWebDriver
Const HomePageURL As String = "http://www.bing.com/"


<TestInitialize()>
Public Sub Initialization()
   driver = New FirefoxDriver
End Sub


<TestCleanup()>
Public Sub Termination()
   driver.Quit()
End Sub


<TestMethod()>
Public Sub TestMethod1()
   Dim SearchBox As IWebElement
   Dim FirstResult As IWebElement


   'Go to Bing Homepage
   driver.Navigate.GoToUrl(HomePageURL)


   'Get Handle for Searchbox
   SearchBox = GetWebElement(driver, By.Id("sb_form_q"), 10)


   'Enter Search Text
   SearchBox.SendKeys("dotnet-developer.de")
   
   'Different ways to start the search
   'Method 1: Press ENTER
   SearchBox.SendKeys(Keys.Enter)


   'Method 2: Grab Search-Button and click it
   'Dim SearchButton As IWebElement
   'SearchButton = GetWebElement(driver, By.Id("sb_form_go"), 10)
   'SearchButton.Click()


   'Now get the first result returned by Bing search
   FirstResult = GetWebElement(driver, By.XPath("//ul[@class='sb_results']/li/div/div/div/h3/a"), 10)


   'Method 1: Compare the subject
   Dim ExpectedText As String = "dotnet-developer.de | Tips for vb.net,…"
   Assert.AreEqual(ExpectedText, FirstResult.Text, "Subject is not correct")


   'Method 2: Compare the link
   Dim ExpectedURL As String = "http://www.dotnet-developer.de/"
   Assert.AreEqual(ExpectedURL, FirstResult.GetAttribute("href"), "URL is not correct!")
End Sub


''' <summary>
''' Retrieve Web Element using default driver and default timeout
''' </summary>
''' <param name="definition">Definition of the WebElement to grab</param>
''' <returns></returns>
''' <remarks></remarks>
Private Overloads Function GetWebElement(ByVal definition As OpenQA.Selenium.By) As IWebElement
   Const DefaultTimeout As Integer = 10
    Return GetWebElement(definition, DefaultTimeout)
End Function


''' <summary>
''' Retrieve Web Element using default driver
''' </summary>
''' <param name="definition">Definition of the WebElement to grab</param>
''' <param name="timeoutSeconds">Seconds to wait until a timeout is thrown</param>
''' <returns></returns>
''' <remarks></remarks>
Private Overloads Function GetWebelement(ByVal definition As OpenQA.Selenium.By, ByVal timeoutSeconds As Integer) As IWebElement
   Return GetWebelement(driver, definition, timeoutSeconds)
End Function


''' <summary>
''' Waits until the given element is enabled and visible
''' </summary>
''' <param name="webDriver"></param>
''' <param name="definition"></param>
''' <param name="seconds"></param>
''' <returns></returns>
''' <remarks>Needs to wait for .displayed because for e.g. in a collapsed Treeview all nodes are available but not visible 
''' if the parent node is collapsed and therefore the following error would appear:
''' OpenQA.Selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
''' </remarks>
Private Overloads Function GetWebElement(ByVal webDriver As IWebDriver, ByVal definition As OpenQA.Selenium.By, ByVal seconds As Integer) As IWebElement
   Dim wait As New WebDriverWait(webDriver, TimeSpan.FromSeconds(seconds))
   wait.Until(Function(d)
      Return d.FindElement(definition).Enabled And d.FindElement(definition).Displayed
   End Function)
   GetWebElement = webDriver.FindElement(definition)
End Function
End Class

 

Leave a Comment