Skip to content
roryprimrose edited this page Oct 19, 2013 · 11 revisions

Abstract Uri values

Testing a web application should mean that you will have many tests that refer to the same Uri. Pushing these locations into a static class is helpful because it is DRY (good for refactoring) and also keeps the test methods clean.

internal static class Products
{
    public static Uri Index
    {
        get
        {
            return new Uri(Config.WebApplicationUri, "/products");
        }
    }

    public static Uri Edit
    {
        get
        {
            return new Uri(Config.WebApplicationUri, "/products/edit/");
        }
    }

    public static Uri EditForId(int id)
    {
        return new Uri(Edit, id.ToString());
    }
}

[TestMethod]
public void ProductUrisTest()
{
    using (var browser = new Browser())
    {
        var product = ProductFactory.Build().Save();

        var indexPage = browser.GoTo(Products.Index);

        var page = browser.GoTo<ProductEditPage>(Products.EditForId(product.Id));
    }
}

Test non-200 OK outcomes

Navigation methods have overloads that support an expected status code outcome.

[TestMethod]
public void BrowserCorrectlyValidatesNon200StatusCodeResponseTest()
{
    using (var browser = new Browser())
    {
        browser.GoTo(Home.Failure, HttpStatusCode.InternalServerError);
    }
}

NOTE: Link clicks, button clicks and form submissions all expect 200 outcomes

Navigate to dynamic Uri using page model

Using the page model for navigation by default will take the Uri of IPage.TargetLocation as the location to request. This doesn't work well when you have a dynamic Uri that is determined by the calling code rather than the definition of the page model. The way to handle this is to use the navigation overload that specifies the Uri to request.

[TestMethod]
public void EditProductDisplaysProductDetailsTest()
{
    using (var browser = new Browser())
    {
        var product = ProductFactory.Build().Save();

        // Page model will validate ultimate location based on the page
        var page = browser.GoTo<ProductEditPage>(Products.EditForId(product.Id));

        page.Name.Value.Should().Be(product.Name);
    }
}

Handle redirection to page model

Using the page model for navigation by default will take the Uri of IPage.TargetLocation as the location to request. The result of the navigation will be the page model specified. You can use navigation overloads to test redirections if IPage.TargetLocation is not the original Uri to request in order to land on the expected target page.

[TestMethod]
public void EditProductRedirectsToSignInForUnauthenticatedRequestTest()
{
    using (var browser = new Browser())
    {
        // Page model will validate ultimate location based on the page
        browser.GoTo<SignInPage>(Products.EditForId(123));
    }
}

Multiple location validation with page model

The page model only supports a TargetLocation by default. ASP.Net MVC for example allows for multiple Uri's to map to a single logical resource. The page location supports validation of multiple routes by allowing for a set of regular expressions to validate against.

public class HomeIndexPage : HtmlPage
{
    /// <inheritdoc />
    public override IEnumerable<Regex> LocationExpressions
    {
        get
        {
            var withControllerAction = new Uri(Config.BaseWebAddress, "/home/index");

            // Validate against the address with the controller and action specified (plus optional trailing /)
            yield return new Regex(Regex.Escape(withControllerAction.ToString()) + "(/)?", RegexOptions.IgnoreCase);

            // Validate against the root URL (plus optional trailing /)
            yield return new Regex(Regex.Escape(Config.BaseWebAddress.ToString()) + "(/)?", RegexOptions.IgnoreCase);
        }
    }

    /// <inheritdoc />
    public override Uri TargetLocation
    {
        get
        {
            return Home.Index;
        }
    }
}

[TestMethod]
public void PageCanValidateAgainstMultipleLocationsTest()
{
    using (var browser = new Browser())
    {
        browser.GoTo<HomeIndexPage>(new Uri(Config.BaseWebAddress, "home/index/"));
        browser.GoTo<HomeIndexPage>(new Uri(Config.BaseWebAddress, "home/index"));
        browser.GoTo<HomeIndexPage>(new Uri(Config.BaseWebAddress, "/"));
        browser.GoTo<HomeIndexPage>();
    }
}

Clone this wiki locally