diff --git a/tests/render_cases_navigation.py b/tests/render_cases_navigation.py index ce320a387..68ce7d6c8 100644 --- a/tests/render_cases_navigation.py +++ b/tests/render_cases_navigation.py @@ -107,17 +107,28 @@ # placed from and where the option's own room starts: a joined cell wears the hairline # below it as its own border, so measured from the border box, the last cell of every # group would sit one pixel apart from the rest while the page shows them level. +# +# The gutter the chip stands in comes back with it, because where the chip belongs is a +# relation to the two boxes either side of it rather than a number. The status rule is the +# option's own `::before` and the prose opens at the column the option pads to, so +# `afterStatus` and `opens` are read where the theme spends them. Written as the number +# they came to, the reading would have to be re-pinned every time either neighbour moved, +# and a re-pinned number proves only that somebody ran the test. INSIDE_ITS_OPTION = """el => { const chip = el.getBoundingClientRect(); const opt = el.parentElement.getBoundingClientRect(); const s = getComputedStyle(el.parentElement); + const status = getComputedStyle(el.parentElement, '::before'); const top = opt.y + parseFloat(s.borderTopWidth); const left = opt.x + parseFloat(s.borderLeftWidth); const bottom = opt.bottom - parseFloat(s.borderBottomWidth); const above = parseFloat(s.paddingTop), below = parseFloat(s.paddingBottom); const words = top + above + (bottom - top - above - below) / 2; - return {x: chip.x - left, y: chip.y - top, past: chip.bottom - bottom, - level: (chip.y + chip.height / 2) - words}; + return {x: chip.x - left, ends: chip.right - left, + y: chip.y - top, past: chip.bottom - bottom, + level: (chip.y + chip.height / 2) - words, + afterStatus: parseFloat(status.left) + parseFloat(status.width), + opens: parseFloat(s.paddingInlineStart)}; }""" diff --git a/tests/test_render_navigation.py b/tests/test_render_navigation.py index e5c60a479..a20d3ff51 100644 --- a/tests/test_render_navigation.py +++ b/tests/test_render_navigation.py @@ -113,8 +113,15 @@ def test_a_questions_digits_are_drawn_whole(browser, serve): row. Pinned as one 8px it was level with a 15px row, and the day the row went to the page's own 17px it was two pixels too high with the gate still green — because what the gate read was the number the theme stated, and the claim beside it, that a row's - digit is level with its words, was checked by nothing.""" + digit is level with its words, was checked by nothing. + + How far in it stands is the whole group's, and it is asked as the relation it is: the + gutter reads status rule, digit, then prose, so the digit is measured against those two + neighbours and against the other form's seat. Pinned as the number the gutter came to, + the reading broke the day a status rule took the head of the column and the digit moved + along behind it — a move the page wanted, reported as a failure of the digit.""" page, errors = open_page(browser, serve(ADDRESS_PAGE)) + seats = {} for options, sitting in [ (["c-heater", "c-cable", "c-hand"], "in the corner"), (["r-now", "r-later"], "centred"), @@ -125,11 +132,20 @@ def test_a_questions_digits_are_drawn_whole(browser, serve): expect(chip).to_be_visible() cut = chip.evaluate(CLIPPED_BY) assert cut is None, f"{id_}'s digit is cut: {cut}" + # Never on the hairline the outer corner would have shared with the cells + # around it, and never in either neighbour's room: the option's gutter opens + # with the status rule, and its words open at the column the option pads to. + # `test_the_pointer_does_not_take_a_cells_status_with_it` asks that order of + # one recommended cell of the card form, with the pointer moved off it before + # the reading; the row form is asked here and nowhere else. sits = chip.evaluate(INSIDE_ITS_OPTION) - # The status/address/prose order has its own focused geometry test. Here the - # address only has to stay wholly inside its option and off the option's - # words; pinning its old 6px inset made this test reject that new gutter. - assert sits["x"] > 0, f"{id_}'s digit sits on its option's outer edge" + assert sits["afterStatus"] < sits["x"] < sits["ends"] < sits["opens"], ( + f"{id_}'s digit runs {sits['x']}…{sits['ends']} in a gutter whose status " + f"rule ends at {sits['afterStatus']} and whose words open at " + f"{sits['opens']}, so the gutter is holding one of the three in another's " + "room" + ) + seats.setdefault(round(sits["x"], 1), []).append(id_) if sitting == "in the corner": assert round(sits["y"]) == 8, ( f"{id_}'s digit sits {sits['y']} down from its option's top, not in " @@ -147,6 +163,9 @@ def test_a_questions_digits_are_drawn_whole(browser, serve): # only right for as long as the column the theme reserves is. on = chip.evaluate(OVER_WORDS, id_) assert on is None, f"{id_}'s digit is drawn over the words “{on}”" + # One column, in both forms: a card's cell and a row's are the two shapes whose room + # differed, and a seat each would read as a straight rail down neither. + assert len(seats) == 1, f"the digits stand at more than one column: {seats}" assert errors == [] page.close()