Last active
December 20, 2015 18:59
-
-
Save gabrieljoelc/6180319 to your computer and use it in GitHub Desktop.
Custom `Microsoft.VisualStudio.TestTools.WebTesting.ExtractionRule` that groups all of the form field `Microsoft.VisualStudio.TestTools.WebTesting.HtmlTag`s for ASP.NET MVC-style view model array form field names.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Microsoft.VisualStudio.TestTools.WebTesting; | |
namespace GabesWebTesting.Extraction | |
{ | |
public class ExtractArrayFields : ExtractionRule | |
{ | |
public const string ArrayRootElementPlaceholderName = "root"; | |
public bool Required { get; set; } | |
public string FullyQualifiedNameAttributeValueUpToArrayName { get; set; } | |
public override void Extract(object sender, ExtractionEventArgs e) | |
{ | |
if (!e.Response.IsHtml) | |
{ | |
e.Success = !Required; | |
return; | |
} | |
var tagsForArrayIndexes = GetHtmlTagsFromArrayFields(e.Response, FullyQualifiedNameAttributeValueUpToArrayName); | |
if (tagsForArrayIndexes.Any()) | |
{ | |
e.Success = true; | |
e.WebTest.Context[ContextParameterName] = tagsForArrayIndexes; | |
} | |
else | |
{ | |
e.Success = !Required; | |
e.Message = string.Format("No array tags for array {0}.", FullyQualifiedNameAttributeValueUpToArrayName); | |
} | |
} | |
internal static IEnumerable<IDictionary<string, HtmlTag>> GetHtmlTagsFromArrayFields(WebTestResponse response, string fullyQualifiedNameAttributeValueUpToArrayName) | |
{ | |
if (!response.IsHtml) | |
{ | |
return Enumerable.Empty<IDictionary<string, HtmlTag>>(); | |
} | |
var startsWith = fullyQualifiedNameAttributeValueUpToArrayName + "["; | |
var tagsForArrayIndexes = new List<IDictionary<string, HtmlTag>>(); | |
foreach (var tag in response.HtmlDocument.HtmlTags) | |
{ | |
var name = tag.GetNameAttributeValue(); | |
var doesStartWith = name.StartsWith(startsWith); | |
if (!doesStartWith) | |
{ | |
continue; | |
} | |
var indexAndSuffix = name.Substring(startsWith.Length, name.Length - startsWith.Length); | |
if (string.IsNullOrWhiteSpace(indexAndSuffix)) | |
{ | |
continue; | |
} | |
var indexStr = string.Concat(indexAndSuffix.TakeWhile(c => !c.Equals(']'))); | |
int index; | |
if (!int.TryParse(indexStr, out index) || index < 0) | |
{ | |
continue; | |
} | |
var suffix = indexAndSuffix.Substring((indexStr + "]").Length, | |
indexAndSuffix.Length - (indexStr + "]").Length).Trim('.'); | |
var arrayElemName = !string.IsNullOrWhiteSpace(suffix) ? suffix : ArrayRootElementPlaceholderName; | |
if (tagsForArrayIndexes.Count == 0 || index >= tagsForArrayIndexes.Count) | |
{ | |
tagsForArrayIndexes.Add(new Dictionary<string, HtmlTag> { { arrayElemName, tag } }); | |
} | |
else if (tagsForArrayIndexes[index].ContainsKey(arrayElemName) | |
|| tagsForArrayIndexes[index].ContainsKey(string.Format("{0}.{1}", tag.Name, arrayElemName)) | |
|| tagsForArrayIndexes[index].ContainsKey(string.Format("input[type={0}].{1}", tag.GetAttributeValueAsString("type"), arrayElemName))) | |
{ | |
if (tag.Name.Equals("input") && tag.Attributes.Any(a => a.Name.Equals("type"))) | |
{ | |
tagsForArrayIndexes[index].Add( | |
string.Format("input[type={0}].{1}", tag.GetAttributeValueAsString("type"), arrayElemName), | |
tag); | |
} | |
else | |
{ | |
tagsForArrayIndexes[index].Add( | |
string.Format("{0}.{1}", tag.Name, arrayElemName), | |
tag); | |
} | |
} | |
else | |
{ | |
tagsForArrayIndexes[index].Add(arrayElemName, tag); | |
} | |
} | |
return tagsForArrayIndexes; | |
} | |
} | |
public static class HtmlTagExtensions | |
{ | |
/// <summary> | |
/// Gets the value for name attribute of the specified <see cref="HtmlTag"/>. | |
/// </summary> | |
/// <param name="htmlTag"></param> | |
/// <returns>Defaults to empty <see cref="String"/>.</returns> | |
public static string GetNameAttributeValue(this HtmlTag htmlTag) | |
{ | |
if (htmlTag == null) | |
{ | |
return string.Empty; | |
} | |
return htmlTag.GetAttributeValueAsString("name") ?? string.Empty; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment