TestDriven.Me

I hope to spend some time discussing testing with VB.NET. I don't think of myself as an expert, but I have had some experience and certainly some opinions. I will try to share some of those opinions along with some information and hopefully generate some discussion so that we all can improve our skills a bit.
Watin API Reference - DIVS

This method is used to make visible the collection of DIV tags on a web page.  DIV elements contain a host of properties to help manipulate the information therein.

 

Example of Usage

 

This example utilizes the main.html page that is distributed with WatiN to highlight some of the methods available with the DIV class.

 



    ''' <summary>
    ''' Test behavior of DIVs
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/main.html"
    ''' </remarks>
    <Test()> _
        Public Sub TestDivs()
        Dim aDIV As Div
        Dim aBoolean As Boolean = False
        Dim aString As String = ""
 
        Using ie As IE = New IE(currentURL)
 
            For Each aDIV In ie.Divs
                If aDIV.Text.Contains("Contains text in DIV") Then
                    aBoolean = True
                    Assert.IsTrue(aDIV.Tables.Length > 0, "DIV did not contain any tables.")
                    Exit For 'Found DIV in question, no need to look at the rest of them.
                End If
            Next
 
            Assert.IsTrue(aBoolean, "Div did not contain expected text.")
 
        End Using
 
    End Sub

 

This test shows the most common use of the DIVS method, which is finding a DIV that does not have a known ID.  Each DIV tag on the page is examined to match some known aspect (normally text) to locate the correct DIV, and then the DIV itself can expose the remainder of its properties for testing.

Contents: Table of Contents Previous Page: WatiN API Reference - Div Next Page: working on it

 

Posted Friday, September 26, 2008 2:06 PM by ddodgen | with no comments

WatiN API Reference - DIV

This method is used to make visible elements contained within a DIV tag on a web page.  It contains a host of properties to help manipulate the information therein.

 

Example of Usage

 

This example utilizes the main.html page that is distributed with WatiN to highlight some of the methods available with the DIV class.

 

    ''' <summary>
    ''' Test behavior of DIV
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/main.html"
    ''' </remarks>
    <Test()> _
        Public Sub TestDiv()
        Dim aDIV As Div
        Dim aBoolean As Boolean = False
 
        Using ie As IE = New IE(currentURL)
 
            aDIV = ie.Div(Find.ById("divid")) 
            Assert.IsTrue(aDIV.Text.Contains("Contains text in DIV"), "Div did not contain expected text.")
 
            Assert.IsTrue(aDIV.Tables.Length > 0, "Div did not contain a table.")
            Assert.IsTrue(aDIV.Tables(0).TableRows.Length > 0, "Div table had no rows.")
            Assert.IsTrue(aDIV.Tables(0).TableRows.Length = 2, "Div table did not have 2 rows.")
 
            aString = aDIV.Tables(0).TableRows(0).TableCells(0).Text
            Assert.IsTrue(aString = "Contains text in DIV", "Cell did not contain expected text.")
 
            Assert.IsTrue(aDIV.Tables(0).TableRows(1).Text.Contains("Test label before:"), "Text not found in table row.")
            Assert.IsTrue(aDIV.Tables(0).TableRows(1).TableCells(0).Text.Contains("Test label before:"), "Text not found in table cell.")
 
            aBoolean = aDIV.Tables(0).TableRows(1).TableCells(0).CheckBoxes(0).Checked
            aDIV.Tables(0).TableRows(1).TableCells(0).CheckBoxes(0).Checked = Not aBoolean
            Assert.IsFalse(aBoolean = aDIV.Tables(0).TableRows(1).TableCells(0).CheckBoxes(0).Checked, "Checkbox not changed.")
 
        End Using
 
    End Sub

 


 

This test is pretty self-explanatory and requires little additional comment.  Once the DIV is located and placed within a local variable (not required, but makes the syntax shorter on subsequent usage), the various elements within the DIV are proven to exist.  The value of the checkbox is changed at the end of the test to demonstrate that this is possible.

 

The primary use of the DIV is to work with elements that cannot be located via the normal means available to the individual controls.  For example:  The text contained in the first row is not within an ASP.NET control, so it can only be examined by digging down into the table.

 

Contents: Table of Contents Previous Page: WatiN API Reference - Dispose Next Page: WatiN API Reference - Divs

 

Posted Tuesday, August 26, 2008 10:26 AM by ddodgen | 1 comment(s)

WatiN API Reference - Dispose

 

This method is used to release resources no longer needed by the current instance of the browser.  Normally, you can omit this statement since it is called internally by the IE instance when it closes itself.

 

Once Dispose is called, the IE instance is no longer valid and cannot be used.  The only valid method to call on the IE instance after Dispose is Close.

Example of Usage


    ''' <summary>
    ''' Determine dispose will affect the current instance of IE.
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/Default.aspx"
    ''' OKButton is a Private Const = "OKButton"
    ''' </remarks>
    <Test()> _
    Public Sub TestDispose()
        Dim ErrorFlag As Boolean = False
 
        Try
            Dim ie As IE = New IE(currentURL)
 
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "The page did not contain expected text.")
            ie.Dispose()
 
            'This should produce an error after IE instance is closed.
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "Error was not caused when disposed.")
 
        Catch ex As Exception
            ErrorFlag = True
            Assert.IsTrue(ex.Message.Contains("Could not find"), "Did not produce the expected error.")
        End Try
 
        Assert.IsTrue(ErrorFlag, "Error was not caused after dispose.")
 
        ErrorFlag = False
        Try
            Dim ie As IE = New IE(currentURL)
 
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "The second page did not contain expected text.")
            ie.Dispose()
            ie.Close()
 
        Catch ex As Exception
            ErrorFlag = True
            Assert.IsTrue(ex.Message.Contains("Could not find"), "Close should not produce an error.")
        End Try
 
        Assert.IsFalse(ErrorFlag, "Error was caused by close after dispose.")
 
        Using ie As IE = New IE(currentURL)
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "The page did not contain expected button with using.")
        End Using
 
    End Sub

 


 

This test shows that the Dispose statement effectively closes the current instance of the browser, because the next statement that uses the IE instance causes an error to be thrown.  This could also have been checked for by using the attribute on the test for expected error, but I wanted to do some other processing afterwards, which would not have been possible using the attribute.

 

Note:  Deliberately causing an exception so you can catch it and examine it, is normally very bad practice.  You will notice how long this test takes to run as Visual Studio tries gamely to find the IE instance.  I only did it here to demonstrate that nothing can be accessed from the IE instance after it is closed.

 

An even more important item to note in this test is the final stage, where the Using statement is employed.  Using has several advantages over Dim; it ensures the proper disposal of resources, closed is not even needed, less typing, clearer syntax.  You should always utilize the Using syntax when system resources are involved, such as data objects or files, to ensure proper disposal when no longer needed.

 

Contents: Table of Contents Previous Page: WatiN API Reference - DialogWatcher Next Page: WatiN API Reference - Div

 

Posted Wednesday, August 20, 2008 2:16 PM by ddodgen | with no comments

WatiN API - DialogWatcher

The dialog watcher class is used to handle javascript and other dialogs.  The IE instance can have a dialog watcher which can have dialog handlers assigned to it to assist in processing pop up dialogs.

Example of Usage

 

This is a rework of the TestAddDialogHander2 test that was introduced earlier:

 

    ''' <summary>
    ''' Ensure that an alert dialog will be handled and
    ''' closed properly.
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/popup.html"
    ''' HelloButton is a Private Const = "hello"
    ''' </remarks>
    <Test()> _
    Public Sub TestAddDialogHandler2Plus()
 
        Using ie As IE = New IE(currentURL)
            Dim myHandler As New AlertAndConfirmDialogHandler
            Dim myWatcher As New DialogWatcher(ie.ProcessID)
 
            myWatcher.Add(myHandler)
 
            ie.Button(HelloButton).ClickNoWait()
            Assert.IsTrue(myWatcher.Count > 0, "There should be a hello dialog open at this point.")
 
            ie.WaitForComplete()
        End Using
 
    End Sub

 


 

The dialog watcher is created from the IE instance and is therefore already assigned to it.  A handler is added to process the javascript popup and the button is clicked to display the dialog.

 

Another way of using the dialog watcher is presented next:

 

    ''' <summary>
    ''' Ensure that an alert dialog will be handled and
    ''' closed properly.
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/popup.html"
    ''' HelloButton is a Private Const = "hello"
    ''' </remarks>
    <Test()> _
    Public Sub TestAddDialogHandler2Plus2()
 
        Using ie As IE = New IE(currentURL)
            Dim myHandler As New AlertAndConfirmDialogHandler
            Dim myWatcher As DialogWatcher
 
            myWatcher = ie.DialogWatcher
            myWatcher.Add(myHandler)
 
            ie.Button(HelloButton).ClickNoWait()
            Assert.IsTrue(myWatcher.Count > 0, "There should be a hello dialog open at this point.")
 
            ie.WaitForComplete()
        End Using
 
    End Sub

 


 

Here the dialog watcher is not created from the IE instance, so it must be specifically assigned.

Contents: Table of Contents Previous Page: WatiN API Reference - ContainsText Next Page: WatiN API Reference - Dispose

 

Posted Monday, August 11, 2008 2:16 PM by ddodgen | with no comments

WatiN API Reference - ContainsText

This method is used to determine if the web page has specific text being displayed.  The text to be found must be in the HTML or a label control, but cannot be located within a textbox, button or other control.

Example of Usage

 

This is the simplest usage of the method:

 

    ''' <summary>
    ''' Test behavior of ContainsText
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/main.html"
    ''' </remarks>
    <Test()> _
        Public Sub TestContainsText()
 
        Using ie As IE = New IE(currentURL)
 
            Assert.IsTrue(ie.ContainsText("Contains text in DIV"), "Page did not contain expected text.")
 
        End Using
 
    End Sub

 

The page is examined for specified text.  Frequently this is used to determine the result of some other action, such as looking for a message expected to be displayed.

 

This next test demonstrates that just because it can be seen, does not mean it is “contained”, or in other words, text in some controls will not be returned in the ContainsText method.  The controls themselves must be examined.

 

    ''' <summary>
    ''' Test behavior of ContainsText
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/main.html"
    ''' </remarks>
    <Test()> _
        Public Sub TestContainsText2()
 
        Using ie As IE = New IE(currentURL)
 
            ie.TextField(Find.ByName("textinput1")).Value = "TestContainsText"
            ie.TextField(Find.ById("Textarea1")).Value = "TextAreaText"
 
            Assert.IsFalse(ie.ContainsText("TestContainsText"), "Textbox found when not expected.")
            Assert.IsTrue(ie.TextField(Find.ById("name")).Value = "TestContainsText", "Text field did not contain expected text.")
 
            Assert.IsFalse(ie.ContainsText("Show allert"), "Button found when not expected.")
            Assert.IsTrue(ie.Button(Find.ById("helloid")).Text = "Show allert", "Button did not show expected text.")
 
            Assert.IsTrue(ie.ContainsText("Test label before"), "Label did not contain expected text.")
 
            Assert.IsTrue(ie.ContainsText("TextAreaText"), "Text area did not contain expected text.")
 
            Assert.IsTrue(ie.ContainsText("First Listitem"), "List item did not contain expected text.")
 
        End Using
 
    End Sub

 


This test shows how the different controls behave in relation to ContainsText calls. Controls that will return text to ContainsText include HTML controls such as TD, label controls, lists, and text areas.  Controls that will not return text to ContainsText include buttons and textboxes.

 

Contents: Table of Contents Previous Page: WatiN API Reference - Close Next Page: WatiN API Reference - DialogWatcher

 

Posted Thursday, July 31, 2008 2:45 PM by ddodgen | with no comments

WatiN API Reference - Close

This method is used to close the current instance of the browser.  If you want to leave the browser open at the end of the test, you can omit this statement.  This will allow you to examine the contents of the browser, but you will have to close it yourself.  If you are running more than one test at a time, this can be somewhat aggravating, and fortunately is unnecessary just to see what the browser contains, since you can always capture a screen shot instead.

Example of Usage

 

    ''' <summary>
    ''' Determine if the current instance of IE will close properly.
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/Default.aspx"
    ''' OKButton is a Private Const = "OKButton"
    ''' </remarks>
    <Test()> _
    Public Sub TestClose()
        Dim ErrorFlag As Boolean = False
 
        Try
            Dim ie As IE = New IE(currentURL)
 
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "The page did not contain expected text.")
            ie.Close()
 
            'This should produce an error after IE instance is closed.
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "Error was not caused when closed.")
 
        Catch ex As Exception
            ErrorFlag = True
            Assert.IsTrue(ex.Message.Contains("Could not find"), "Did not produce the expected error.")
        End Try
 
        Assert.IsTrue(ErrorFlag, "Error was not caused after close.")
 
        Using ie As IE = New IE(currentURL)
            Assert.IsTrue(ie.Button(New Regex(OKButton)).Text = "OK", "The page did not contain expected button with using.")
        End Using
 
    End Sub

 


 

This test shows that the Close statement disposes of the current instance of the browser, because the next statement that uses the IE instance causes an error to be thrown.  This could also have been checked for by using the attribute on the test for expected error, but I wanted to do some other processing afterwards, which would not have been possible using the attribute.

 

Note:  Deliberately causing an exception so you can catch it and examine it, is normally very bad practice.  You will notice how long this test takes to run as Visual Studio tries gamely to find the IE instance.  I only did it here to demonstrate that nothing can be accessed from the IE instance after it is closed.

 

An even more important item to note in this test is the second stage, where the Using statement is employed.  (Yes it was hard not to say “used” here.)  Using has several advantages over Dim; it ensures the proper disposal of resources, closed is not even needed, less typing, clearer syntax.  You should always utilize the Using syntax when system resources are involved, such as data objects or files, to ensure proper disposal when no longer needed.

Contents: Table of Contents Previous Page: WatiN API Reference - ClearCookies  Next Page: WatiN API Reference - ContainsText

 

Posted Monday, July 14, 2008 10:29 AM by ddodgen | with no comments

WatiN API - ClearCookies

I could not get this method to work as expected for me.

 

It is designed to clear cookies for either a specific web site or all cookies depending on whether you pass a web site URL as its parameter.  When I tried it in the below test, it failed because of no security access to clear the cookie data in IE7.  Since I did not want to modify system access because that did not seem proper for testing, I just decided that clearing cookies would probably not be that important.

 

Example of Usage

 

    ''' <summary>
    ''' Ensure that browser cookies do not affect
    ''' the results of clicking the OK Button.
    ''' </summary>
    ''' <remarks>
    ''' currentURL is a Private Const =
    ''' "http://localhost:3587/Default.aspx"
    ''' OKButton is a Private Const = "OKButton"
    ''' MessageTextBox is a Private Const = "MessageTextBox"
    ''' </remarks>
    <Test()> _
        Public Sub TestClearCookies()
        Dim StringValue As String = ""
 
        Using ie As IE = New IE(currentURL)
 
 
            'Method ONE - Fully specify find criteria
            ie.Button(Find.ById(New Regex(OKButton))).Click()
            Assert.IsTrue(ie.TextField(Find.ById(New Regex(MessageTextBox))).Text.Contains("OK"), "TestButtons did not find OK in the textbox after OK button clicked.")
            ie.CaptureWebPageToFile("c:\temp\step1.jpg")
 
            ie.SetCookie("http://google.com", "test=Cookie Test")
            ie.TextField(Find.ById(New Regex(MessageTextBox))).Value = "Test"
            ie.CaptureWebPageToFile("c:\temp\step2.jpg")
            Assert.IsTrue(ie.TextField(Find.ById(New Regex(MessageTextBox))).Text.Equals("Test"), "Textfield did not reset.")
 
            StringValue = ie.GetCookie("http://google.com", "test")
            ie.TextField(Find.ById(New Regex(MessageTextBox))).Value = StringValue
            ie.CaptureWebPageToFile("c:\temp\step3.jpg")
 
            ie.TextField(Find.ById(New Regex(MessageTextBox))).Value = "Test"
            ie.CaptureWebPageToFile("c:\temp\step4.jpg")
            ie.ClearCookies("http://google.com")
            ie.SetCookie("http://google.com", "test=")
 
            StringValue = ie.GetCookie("http://google.com", "test")
            ie.TextField(Find.ById(New Regex(MessageTextBox))).Value = StringValue
            ie.CaptureWebPageToFile("c:\temp\step5.jpg")
 
 
            Assert.IsTrue(ie.TextField(Find.ById(New Regex(MessageTextBox))).Text.Equals("test"), "Cookie data remained when should have been cleared.")
 
        End Using
 
    End Sub

 


 

This test will fail on the line with ClearCookies, because WatiN does not have access to delete cookies.  If you comment out the ClearCookies command, you can change the data manually by setting the cookie to an empty string and the test will pass.

 

Contents: Table of Contents Previous Page: WatiN API Reference - ClearCache Next Page: WatiN API Reference - Close

 

Posted Thursday, July 03, 2008 9:53 AM by ddodgen | with no comments

WatiN API Reference - ClearCache

This method contains some gotchas.  From its method name you would think that it would clear out the system cache, at least for the web page currently being viewed, but this is a bit of a misconception.

 

The documentation on the WatiN site indicates that this method is used to clear the browser cache and gives an example of clearing the cache and then going back to a page that requires a login.  Presumably you would have to log in again after the cache was cleared.  The documentation also indicates that this may be a problem because Internet Explorer tends to keep things in memory and will ignore this method.  It is suggested that the developer employ ie.ReOpen to force the browser to close and reopen, then navigate back to their desired web page to manually clear any cache at the browser level.

 

The gotcha is really with the system cache, however.  If the web page saves information to the cache maintained on the server and then reads the value back out later, neither ClearCache nor ReOpen, nor anything else that I can find, will clear these cache values before they are set to expire by IIS.

 

The following test demonstrates this behavior.  I modified the earlier created actions for the Default.aspx page to have the click event on the OK button to save information into cache and then the page load retrieves this information, if it exists and places it into the textbox for verification of the cache activity.

Example of Usage

 

The Default.aspx page used for our tests should now appear like this:

 

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WatiNTest._Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="OKButton" runat="server" Text="OK" />
        <asp:Button ID="CancelButton" runat="server" Text="Cancel" />
        <asp:TextBox ID="MessageTextBox" runat="server"></asp:TextBox>
        <br />
        <br />
        <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox></div>
    </form>
</body>
</html>

 

 

The Default.aspx.