Creating Selenium Tests for Multiple Browsers

This website is no longer actively supported

Written by John DeVightJohn DeVight on 20 Jun 2011 14:24

Download Sample Project

Overview

The project that I am on requires that the web application is compatible on both Internet Explorer 7 and Firefox 3.6. I wanted to make sure that the Selenium tests that I write would be executed on both browsers. During the setup of the unit test class, an instance of DefaultSelenium is created and the type of browser is passed into the constructor. All the unit tests in the unit test class are tested with the browser specified during the setup of the test class. The solution I came up with was to create a unit test class with the unit tests but without the unit test setup. I then created derived classes, one for setting up the unit test class for Firefox and one for setting up the unit test class for Internet Explorer. I declared the derived classes inside the base class containing the unit tests. When I run the NUnit GUI, I see the following:

nunit-gui.png

To demonstrate creating a Selenium unit test, I decided to write a simple test that goes to http://www.aspnetwiki.com and does a search for selenium. When the test results are displayed, the Testing ASP.NET Applications with Selenium is selected. The test then verifies that the correct article is displayed.

Creating the Selenium Unit Test Class

I created a class library project in Visual Studio and include the appropriate references as described half way down the Testing ASP.NET Applications with Selenium article under the Creating a Test Project for the Selenium User Interface Test heading. I then renamed the Class1.cs file to AspNewWIkiTests.cs. I changed the class to be declared as:

public abstract class AspNetWikiTests : SeleniumBase

Note: I'll talk about the SeleniumBase class later in this article

In it, I declared 2 classes, Firefox and IExplorer. Each class has a method defined called SetupTest with the Setup attribute to create an instance of DefaultSelenium for the appropriate browser. The AspNetWikiTests class contains the TeardownTest method to stop Selenium and the SearchForSeleniumArticle unit test method.

Here is the code:

namespace SeleniumUnitTests
{
    public abstract class AspNetWikiTests : SeleniumBase
    {
        [TestFixture]
        public class Firefox : AspNetWikiTests
        {
            [SetUp]
            public void SetupTest()
            {
                selenium = new DefaultSelenium("localhost", 
                    4444, "*firefox", "http://www.aspnetwiki.com/");
                selenium.Start();
                verificationErrors = new StringBuilder();
            }
        }

        [TestFixture]
        public class IExplorer : AspNetWikiTests
        {
            [SetUp]
            public void SetupTest()
            {
                HttpCommandProcessor proc = new HttpCommandProcessor("localhost", 
                    4444, "*iexplore", "http://www.aspnetwiki.com/");
                selenium = new DefaultSelenium(proc);
                selenium.Start();
                verificationErrors = new StringBuilder();
                selenium.UseXpathLibrary("javascript-xpath");
            }
        }

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

        [Test]
        public void SearchForSeleniumArticle()
        {
            selenium.Open("/");
            selenium.Type("search-top-box-input", "Selenium");
            selenium.Click("search");
            Assert.IsTrue(this.WaitForXpathCount(
                "//a[@href='http://www.aspnetwiki.com/testing-asp-net-applications-with-selenium']"));
            selenium.Click("link=Testing ASP.NET Applications with Selenium");
            selenium.WaitForPageToLoad("30000");
            Assert.AreEqual("Testing ASP.NET Applications with Selenium", 
                selenium.GetText("//div[@id='page-title']").Trim());
        }
    }
}

SeleniumBase Class

I created the SeleniumBase class to provide methods to make it easier for testing with Selenium. In the SearchForSeleniumArticle method, I call the WairForXpathCount method. This method evaluates an xpath ( selenium.GetXpathCount ) every second ( Thread.Sleep(1000) ) until the appropriate number of occurrences of the xpath are returned or until the timeout seconds are reached.

Here is the code:

namespace SeleniumUnitTests
{
    public abstract class SeleniumBase
    {
        protected ISelenium selenium;
        protected StringBuilder verificationErrors;

        /// <summary>
        /// Wait until the xpath count equals the count passed in or the timeout is reached.
        /// </summary>
        /// <param name="xpath">xpath to evaluate.</param>
        /// <param name="timeout">number of seconds to wait.</param>
        /// <param name="count">number of occurances to find.</param>
        /// <returns>true if the number of xpath occurances is equal to the count passed in.</returns>
        protected bool WaitForXpathCount(string xpath, int timout = 60, int count = 1)
        {
            bool found = false;

            for (int second = 0; ; second++)
            {
                if (second >= timout)
                {
                    break;
                }

                try
                {
                    if (count == selenium.GetXpathCount(xpath))
                    {
                        found = true;
                        break;
                    }
                }
                catch (Exception)
                {
                }
                Thread.Sleep(1000);
            }
            return found;
        }
    }
}

References

Discussion Closed

Add a New Comment

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License