private static void AssertMismatch(HtmlCompareResult result, string expected = null, string actual = null, HtmlCompareMismatchReason reason = HtmlCompareMismatchReason.Default) { Assert.False(result.Matches, "Expected a mismatch, but was a match."); var expectedResult = HtmlCompareResult.Mismatch(expected, actual, reason); Assert.Equal(expectedResult, result); }
/// <summary> /// Checks if the provided HTML string matches an expected HTML string. /// </summary> /// <param name="expected">A string represeting the expected HTML that the <paramref name="html"/> should be compared against.</param> /// <param name="html">A string representing the HTML that should be checked.</param> /// <returns><c>True</c> if the selected element matched the expected html; otherwise <c>false</c>.</returns> public HtmlCompareResult Equals(string expected, string html) { if (string.IsNullOrWhiteSpace(expected)) { return(string.IsNullOrWhiteSpace(html) ? HtmlCompareResult.Match : HtmlCompareResult.Mismatch(expected, html)); } if (string.IsNullOrWhiteSpace(html)) { return(HtmlCompareResult.Mismatch(expected, html)); } var expectedNodeTree = CreateNodeTree(ParseHtml(expected, _options.TreatHtmlAsFragment)); var candidateNodeTree = CreateNodeTree(ParseHtml(html, _options.TreatHtmlAsFragment)); return(NodeTreesAreEqual(expectedNodeTree, candidateNodeTree) ? HtmlCompareResult.Match : HtmlCompareResult.Mismatch(expected, html)); }
private HtmlCompareResult MatchesElement(string expected, NodeTree expectedNodeTree, IElement element) { if (_options.ElementComparisonMode == ElementComparisonMode.Element) { var expectedElement = expectedNodeTree.First(); if (NodesAreEqual(expectedElement, element)) { return(HtmlCompareResult.Match); } return(HtmlCompareResult.Mismatch(expected, HtmlMarkupFormatter.Instance.OpenTag(element, true))); } var includeRoot = _options.ElementComparisonMode == ElementComparisonMode.OuterHtml; var elementNodeTree = CreateNodeTree(element, includeRoot); if (NodeTreesAreEqual(expectedNodeTree, elementNodeTree)) { return(HtmlCompareResult.Match); } return(HtmlCompareResult.Mismatch(expected, includeRoot ? element.OuterHtml : element.InnerHtml)); }
/// <summary> /// Checks if element in the provided HTML string matches an expected HTML string. /// </summary> /// <param name="expected">A string represeting the expected HTML that the <paramref name="html"/> should be compared against.</param> /// <param name="html">A string representing the HTML that contains the element that should be checked.</param> /// <param name="selector">The CSS selector that should be used to find a matching element.</param> /// <returns><c>True</c> if the selected element matched the expected html; otherwise <c>false</c>.</returns> public HtmlCompareResult Equals(string expected, string html, string selector) { if (selector == null) { throw new ArgumentNullException(nameof(selector)); } if (string.IsNullOrWhiteSpace(selector)) { throw new ArgumentException("Selector cannot be empty.", nameof(selector)); } var expectedRoot = ParseHtml(expected, true); if (_options.ElementComparisonMode != ElementComparisonMode.InnerHtml && expectedRoot.ChildElementCount > 1) { throw new ArgumentException($"The expected html cannot contain multiple child nodes when the ElementComparisonMode option is set to '{_options.ElementComparisonMode}'.", nameof(expected)); } if (_options.ElementComparisonMode == ElementComparisonMode.Element && expectedRoot.FirstChild.HasChildNodes) { throw new ArgumentException("The expected html cannot contain child nodes when the ElementComparisonMode option is set to Element.", nameof(expected)); } var expectedNodeTree = CreateNodeTree(expectedRoot); var candidateRoot = ParseHtml(html, _options.TreatHtmlAsFragment); // Default selection mode will only need the first element if (_options.ElementSelectionMode == ElementSelectionMode.First) { var element = candidateRoot.QuerySelector(selector); if (element is null) { return(HtmlCompareResult.ElementNotFound); } return(MatchesElement(expected, expectedNodeTree, element)); } // All other selection modes needs all elements var elements = candidateRoot.QuerySelectorAll(selector); if (elements.Length == 0) { return(HtmlCompareResult.ElementNotFound); } if (_options.ElementSelectionMode == ElementSelectionMode.Single) { if (elements.Length > 1) { return(HtmlCompareResult.Mismatch(reason: HtmlCompareMismatchReason.MultipleElementsFound)); } return(MatchesElement(expected, expectedNodeTree, elements[0])); } var results = elements.Select(el => MatchesElement(expected, expectedNodeTree, el)); if (_options.ElementSelectionMode == ElementSelectionMode.All) { return(results.FirstOrDefault(r => !r.Matches) ?? HtmlCompareResult.Match); } if (_options.ElementSelectionMode == ElementSelectionMode.Any) { return(results.FirstOrDefault(r => r.Matches) ?? results.First()); } throw new InvalidOperationException("Unknown element selection mode encountered"); }