示例#1
0
        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);
        }
示例#2
0
        /// <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));
        }
示例#3
0
        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));
        }
示例#4
0
        /// <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");
        }