When a user creates a new casefile in our system. Its created as a custom content-type that inherits from SharePoint’s document set. My load tests need at least the following information in order to continue working with that casefile:

  1. The title of the document set.
  2. SharePoint’s ID of the content-type.
  3. SharePoint’s ID of the list item.
  4. SharePoint’s ID of the list where its created in.

The POST to a MVC controller is the starting point for our system to create the casefile. The only way to find out what the values are is by following a URL contained within the HTTP 200 response (looks like this)

<script type="text/javascript">window.parent.location.href="https://...../DocSetHome.aspx?......";</script>

By doing a GET request to that URL, we get a HTTP 302 response, Visual Studio automatically follows the redirect and the final HTTP 200 response’s URI contains all the dynamic values as querystring parameters:
https://……/docsethomepage.aspx?ID=…&FolderCTID=…&List=…&RootFolder=…&RecSrc=…

Visual Studio doesn’t have an out-of-the-box plugin that can extract the values of those querystring parameters. So I created my own:

using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.Globalization;
using System.ComponentModel;
using System.Web;
using System.Collections.Specialized;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;

namespace LoadTestPlugins
{
    [DisplayNameAttribute("Extract querystring parameter")]
    [DescriptionAttribute("Extracts the value of a querystring parameter from the URI of a response")]
    public class ExtractQuerystringParameter : ExtractionRule
    {
        //Which field to parse and store in the context
        [Description("Name of the querystring parameter to extract"),
        DisplayName("Field name")]
        public string FieldName {get; set;}


        public override void Extract(object sender, ExtractionEventArgs e)
        {
            if (e.Response.ResponseUri != null)
            {
                NameValueCollection NVC = HttpUtility.ParseQueryString(e.Response.ResponseUri.Query);
                string value = NVC[this.FieldName];
                if(!string.IsNullOrEmpty(value))
                {
                    //The last part of the RootFolder or RecSrc contains the name of the 
                    //documentset. It needs to be Url encoded as it might contain spaces  
                    if (   this.FieldName.ToLower().Equals("RootFolder".ToLower())
                        || this.FieldName.ToLower().Equals("RecSrc".ToLower()))
                    {
                       value = Uri.EscapeUriString(value.Split('/').Last());
                    }
                    e.WebTest.Context.Add(this.ContextParameterName, value);
                    e.Success = true;
                    return;
                }
                else
                {
                    e.Success = false;
                    e.Message = string.Format(CultureInfo.CurrentCulture
                        , "Querystring Parameter Not Found: {0}"
                        , this.FieldName);
                }
            }
        }
    }
}