File size: 5,158 Bytes
7b284c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""`hidden` has to mean hidden.

Eight elements carried the `hidden` attribute and rendered anyway, because the
UA sheet's `[hidden] { display: none }` loses to ANY author `display:` on the
element — it is an author-vs-UA contest, not a specificity one, so a plain
`.run-meta { display: flex }` cancels it.

What that looked like: an empty bordered box, 888x30 with one pixel of border
and nothing in it, sitting under "How to read this" on every library painted
from a conversation (renderRunMeta re-hides the box when the payload has no
`settings_used`, which an agent-painted run never does). A reviewing scientist
photographed it. Measured on a fresh load the same fault was also rendering a
92px CRISPR base-editor row, a 136px primer organism block, two clone panes, a
stray filter-clear glyph, and the entire 946x401 primer results card.

This test re-derives the list from the markup rather than hard-coding it, so
the next class that acquires a `display:` fails here instead of in a
screenshot.
"""
import re

_HTML = "dee/static/index.html"
_SHEETS = ("dee/static/app.css", "dee/static/catalog.css")

_EXEMPT = {
    # Deliberate, and says so in a comment: the scrim keeps its box while it
    # fades out, so `.sidebar-scrim[hidden] { display: block }` is the point.
    "sidebar-scrim":
        "keeps its box during the fade-out transition, on purpose",
    # These get a display ONLY from `body[data-ui="bench"][data-bench="open"]
    # .bench-strip`, and app.js clears their `hidden` in the same block that
    # sets data-bench. The state and the attribute never co-occur, and a bare
    # `.bench-strip[hidden]` guard is (0,2,0) — it would lose to that (0,3,1)
    # selector anyway, so adding one would look like protection and be none.
    "bench-strip":
        "display comes only from a body[data-bench=open] rule; JS clears "
        "hidden in the same block",
    "bench-canvashead":
        "same as .bench-strip",
}


def _read(path):
    with open(path, encoding="utf-8") as fh:
        return fh.read()


def _classes_rendered_with_hidden(html):
    """Every class that appears on an element written with a bare `hidden`."""
    out = set()
    for m in re.finditer(r"<\w+([^>]*)>", html):
        attrs = m.group(1)
        if not re.search(r"(^|\s)hidden(\s|=|/|$)", attrs):
            continue
        cm = re.search(r'class="([^"]*)"', attrs)
        if cm:
            out.update(cm.group(1).split())
    return out


def _strip_comments(css):
    return re.sub(r"/\*.*?\*/", " ", css, flags=re.S)


def _classes_given_a_display(css):
    """Classes that are the SUBJECT of a rule declaring `display:`.

    Subject means the last compound selector — `.brand-mark svg` styles the
    svg, not `.brand-mark`, so it cannot cancel `hidden` on `.brand-mark`.
    Selectors already qualified with `[hidden]` are the fix, not the fault.
    """
    css = _strip_comments(css)
    out = {}
    for rule in re.finditer(r"([^{}]+)\{([^{}]*)\}", css):
        selector, body = rule.group(1), rule.group(2)
        decl = re.search(r"(?:^|[;{\s])display\s*:\s*([a-z-]+)", body)
        if not decl:
            continue
        # `display: none` cannot cancel `hidden` — it agrees with it.
        if decl.group(1) == "none":
            continue
        for part in selector.split(","):
            part = part.strip()
            if not part or part.startswith("@"):
                continue
            subject = re.split(r"[\s>+~]+", part)[-1]
            if "[hidden]" in subject:
                continue
            for cls in re.findall(r"\.([A-Za-z0-9_-]+)", subject):
                out.setdefault(cls, part)
    return out


def _guarded(css):
    return set(re.findall(r"\.([A-Za-z0-9_-]+)\[hidden\]", _strip_comments(css)))


def test_no_class_silently_cancels_the_hidden_attribute():
    html = _read(_HTML)
    displays, guards = {}, set()
    for sheet in _SHEETS:
        css = _read(sheet)
        displays.update(_classes_given_a_display(css))
        guards |= _guarded(css)

    unguarded = sorted(
        cls for cls in _classes_rendered_with_hidden(html)
        if cls in displays and cls not in guards and cls not in _EXEMPT
    )
    assert not unguarded, (
        "these classes are written with `hidden` in index.html but a stylesheet "
        "gives them a display:, which beats the UA [hidden] rule, so they render "
        "anyway — add `.<class>[hidden] { display: none; }`: "
        + ", ".join(f"{c} (from `{displays[c]}`)" for c in unguarded)
    )


def test_the_run_meta_box_is_the_one_from_the_review():
    """Named explicitly: this is the empty bordered box in the screenshots, and
    it appears twice (#runMeta on Directed Evolution, #primerRunMeta on Primer
    Analysis) because both use the .run-meta class."""
    css = _read("dee/static/app.css")
    assert re.search(r"\.run-meta\[hidden\][^{]*\{[^}]*display\s*:\s*none", _strip_comments(css)), (
        ".run-meta[hidden] must resolve to display:none; without it the box "
        "renders empty on any library painted from a conversation."
    )
    html = _read(_HTML)
    assert html.count('class="run-meta"') >= 2