Now that we’ve got you started let’s dive a little deeper and see how to put Watin into action.

It’s all about the ids

Watin works by finding a control on your page, and then giving you access to it programmatically in your Watin unit test.

The easiest way is to let Watin get at your controls is to give each one a unique id.

For example, say we created a sample MVC.NET page that looked something like this:

For Watin to be able to access each of the controls on this page, we need to give them an id as follows:

    <input id="MyTextArea" type="text" value="A text area" /> <p/>
    <input id="MyButton" type="button" value="Push Me" /> <p/>
    <input id="MyCheckBox" type="checkbox" /> A checkbox <p/>
    <input id="MyRadioButton" type="radio" /> A radio button <p/>
    
    <table id="MyTable" >
     ...
    </table>

Then accessing them in a Watin simply becomes:

        [Test]
        public void HitSomeControls()
        {
            using (IE browser = new IE("http://localhost:4642/Home/WatinTestPage"))
            {
                // grab the controls
                TextField textField = browser.TextField("MyTextArea");
                Button button = browser.Button("MyButton");
                CheckBox checkBox = browser.CheckBox("MyCheckBox");
                RadioButton radioButton = browser.RadioButton("MyRadioButton");

                // make some assertions
                Assert.AreEqual("A text area", textField.Text);
                Assert.AreEqual("Push Me", button.Text);
                Assert.IsFalse(checkBox.Checked);
                Assert.IsFalse(radioButton.Checked);
            }
        }

Now tables are exactly the same. They just require a little more work.

        [Test]
        public void ParseTheTable()
        {
            using (IE browser = new IE("http://localhost:4642/Home/WatinTestPage"))
            {
                // get the first row of table data
                Table table = browser.Table("MyTable");
                TableRowCollection tableRows = table.TableRows;
                TableRow row = tableRows[1];
                ElementCollection rowData = row.Elements;

                string name = rowData[0].OuterText;
                string phoneNumber = rowData[1].OuterText;

                Assert.AreEqual("Paul", name);
                Assert.AreEqual("403 111 1111", phoneNumber);
            }
        }

* If you want the browser window to stay up after running the test remove the using statement (that will stop it from closing)

You could access any row or element of the table too. All you’d have to do is create an id for each row, and assign it a user id when you generate your table (probably in a foreach loop).

The Page abstraction

Now we could leave our tests as is, but chances are you are going to be writing a lot of them so anything we can do to make them more maintainable will help.

To keep all the unique id’s in one page, and make the tests a little more readable, I’ve found it handy to create a Page class for the MVC.NET view I am testing, and put all the Watin specific stuff in there.

For example, here’s a Page class for our Watin test page, along with the refactored unit tests.

using WatiN.Core;

namespace test
{
    public class WatinTestPage
    {
        private readonly IE browser;

        public WatinTestPage(IE browser)
        {
            this.browser = browser;
        }

        public string MyTextArea
        {
            get { return browser.TextField("MyTextArea").Text; }
        }

        public void SetMyTextArea(string myTextArea)
        {
            browser.TextField("MyTextArea").TypeText(myTextArea);
        }

        // same for other controls

        public ElementCollection GetTableRow(int row)
        {
            Table table = browser.Table("MyTable");
            TableRowCollection tableRows = table.TableRows;
            TableRow tableRow = tableRows[row];
            return tableRow.Elements;
        }

        public string TableName(int row)
        {
            ElementCollection rowData = GetTableRow(row);
            return rowData[0].OuterText;
        }

        public string TablePhoneNumber(int row)
        {
            ElementCollection rowData = GetTableRow(row);
            return rowData[1].OuterText;
        }
    }
}
using NUnit.Framework;
using test;
using WatiN.Core;

namespace tests
{
    [TestFixture]
    public class WatinTest
    {
        [Test]
        public void SetTextArea()
        {
            using (IE browser = new IE("http://localhost:4642/Home/WatinTestPage"))
            {
                WatinTestPage page = new WatinTestPage(browser);
                page.SetMyTextArea("I am changing you ...");
                Assert.AreEqual("I am changing you ...", page.MyTextArea);
            }
        }

        [Test]
        public void ParseTheTableNicely()
        {
            using (IE browser = new IE("http://localhost:4642/Home/WatinTestPage"))
            {
                WatinTestPage page = new WatinTestPage(browser);
                Assert.AreEqual("Paul", page.TableName(1));
                Assert.AreEqual("403 111 1111", page.TablePhoneNumber(1));
                Assert.AreEqual("Peter", page.TableName(2));
                Assert.AreEqual("403 222 2222", page.TablePhoneNumber(2));
            }
        }
}

See how much that cleans things up?

Next stop we’ll look at how to incorporate Watin tests into your MS-Build.

About these ads