c4bcca06ef1a06c434c9136a79459f1512cd0606
braney
  Tue Sep 8 07:41:02 2026 -0700
docent: expect: can assert the color a track's row was drawn in, and a test for #36212

A bug about color leaves the page identical -- same rows, same height, same item
names, same tooltips -- so every check expect: had was blind to it. `color:` reads
the pixels instead: it names the color a row is mostly drawn in (`is:`), or one it
must not be (`not:`), with `part: label` for the center label rather than the
items, `at:`/`frac:`/`x:` for one item rather than the whole row, and a list form
so one step can state a whole color matrix and a failure name every row that came
out wrong.

hgTracks draws the whole view into one png and shows each row as a CSS-offset
slice of it, so a row's pixels are that slice drawn into a canvas at its offset.
The clipping box is the img's own div.sliceDiv, not the table cell: the center
label and the data are two slices inside one td_data_<key>, and measuring the cell
runs the canvas past the end of this row and into the next track's, which reads
that track's color as part of this one. The side labels are a separate png and are
never included, since "what color is this row" must not be answered by the label
text. White is background; everything else counts, black included, because a track
with no color of its own draws black items. is:/not: take r,g,b or #rrggbb and no
CSS color names, because trackDb's `color 0,255,0` is not CSS green.

tests/colorchecks covers all of it and tests/colorchecks.xfail aims all six forms
wrong in one step, so the failure has to name all six.

tests/regress/rm36212.xfail is the bug it was written for: a stanza that sets both
`itemRgb on` and `color` draws its items in the color setting instead of in the
file's own RGB column, because bedItemRgb() (hg/cgilib/bedCart.c) tests for the
presence of `color` before it tests for an explicit `itemRgb on`, so the explicit
setting is never reached. It is an xfail because the bug is live on the RR, on beta
and on genome-test.

It is also the first script in that directory that has been watched both to fail on
a build with the bug and to pass on a build with the fix -- the three-line reorder
built into parked #36212 and the same script pointed at that port. The fixture is
~/public_html/docentFixtures/itemRgbHub/, four tracks over four copies of one bed9
file whose items all carry a pure blue itemRgb column.

refs #36212, refs #37892

diff --git src/hg/utils/docent/tests/regress/README.txt src/hg/utils/docent/tests/regress/README.txt
index ef9b0f72abf..a052c576f21 100644
--- src/hg/utils/docent/tests/regress/README.txt
+++ src/hg/utils/docent/tests/regress/README.txt
@@ -1,36 +1,55 @@
 Docent regression tests
 -----------------------
 
 One script per fixed bug, named for its ticket. Run by hand:
 
     make test               # every *.docent.yaml here
     make test T=rm36382     # just one
 
 The candidate list this directory is being built from, with the recipe and assertion
 worked out for each ticket, is at
 
     /hive/groups/browser/redmineNotes/37892/claude/2026-09-04_1100_regression_candidates.md
 
 What these are, and what they are not
 -------------------------------------
 
 Each script asserts the behavior the ticket says is correct, on genome-test. None of them
 was run against a build that still had the bug, so none has been seen to fail for the
 reason it exists. That is a deliberate choice about cost, and it puts the whole weight on
 how tight the assertion is:
 
   * name the error string the ticket quoted in `noText:`, not a generic "Error"
   * prefer `rows: [...] exact: true` and `noRows:` over a bare `rows:`
   * a test that only checks a row is PRESENT usually passes on the buggy build too,
     because the bug was an extra row, a wrong label, or a bad tooltip
 
 Two things will rot these tests
 -------------------------------
 
 Most recipes start from the saved session named in the ticket, because that is the
 cheapest way to reach the exact state. A session that is deleted does not fail loudly:
 hgTracks serves a page saying it could not find it, and every `noText:` check on that
 page passes. So a session-based test also asserts something that is only true when the
 session really loaded.
 
 Six recipes need a test hub on a colleague's public_html. Same problem, same remedy.
+
+Fixtures we own live in ~/public_html/docentFixtures/, and `make preflight` checks that
+every hub a script here names still answers. Copy a reporter's hub in there rather than
+loading theirs, so nothing outside this repository can change what a test measures.
+
+rm36212 is the one to read before writing another
+--------------------------------------------------
+
+It is the only script here that has been watched to fail on a build with the bug AND to
+pass on a build with the fix, which is the evidence every other script in this directory
+would like to have and does not. The recipe: build the fix into a ticket sandbox, point a
+copy of the script at that port with `target: http://127.0.0.1:PORT/cgi-bin`, and record
+in the comment which checks flipped. It costs one build and it settles what a tight
+assertion can only argue.
+
+It is also the first script to assert a COLOR, using `expect: {color: ...}`, because it
+is the first bug here that leaves the page identical -- same rows, same height, same item
+names, same tooltips. When rows:, height:, text: and has: are all blind to a bug, the
+pixels are what is left. See tests/colorchecks.docent.yaml for the check itself.