1import os
2from pathlib import Path
3
4from django.test.html import Element, parse_html
5
6from crispy_forms.utils import render_crispy_form
7
8TEST_DIR = os.path.dirname(os.path.abspath(__file__))
9
10
11def contains_partial(haystack, needle, ignore_needle_children=False):
12    """Search for a html element with at least the corresponding elements
13    (other elements may be present in the matched element from the haystack)
14    """
15    if not isinstance(haystack, Element):
16        haystack = parse_html(haystack)
17    if not isinstance(needle, Element):
18        needle = parse_html(needle)
19
20    if len(needle.children) > 0 and not ignore_needle_children:
21        raise NotImplementedError("contains_partial does not check needle's children:%s" % str(needle.children))
22
23    if needle.name == haystack.name and set(needle.attributes).issubset(haystack.attributes):
24        return True
25    return any(
26        contains_partial(child, needle, ignore_needle_children=ignore_needle_children)
27        for child in haystack.children
28        if isinstance(child, Element)
29    )
30
31
32def parse_expected(expected_file):
33    test_file = Path(TEST_DIR) / "results" / expected_file
34    with test_file.open() as f:
35        return parse_html(f.read())
36
37
38def parse_form(form):
39    html = render_crispy_form(form)
40    return parse_html(html)
41