d08323bb2ff524e4964a0922ecfb8336ab662007
braney
  Wed Sep 16 10:25:56 2026 -0700
docent: two tests for gaps a cart-visibility branch went past, refs #37892

The #37547 branch broke quickLift and nine scripts in tests/regress caught it
without help.  Two other things went past the whole suite, and these are the
tests for them.

heavysession is selftest on a cart with weight behind it.  selftest saves a
session and loads it back, which is the right shape, but the cart it round-trips
holds two rows.  Saving a cart is not a copy of it: outIfNotPresent() in
hg/hgSession/hgSession.c writes a trackDb default for every track that is
deliberately NOT in the cart, so the file says what is hidden as well as what is
shown, and a two-track cart barely reaches that code.  A save-and-reload path
that returned a 38-row clinical session as 34 rows left selftest green.

The weight comes from a Recommended Track Set, which is where a clinical user
starts: View/Clinical_SNVs_hg38, out of
DOCUMENT_ROOT/data/recTrackSets/recTrackSets.hg38.tab.  It draws 33 tracks and
the ruler, and the file the session: step writes out of that cart is 741
settings, 248 of them visibilities and 154 of those hide.  Both halves of the
trip assert the row set with exact: true, because rows: alone would pass on a
reload that lost four of them, and a count cannot say which row went missing.
It is a saved session on the server, so make preflight already checks it is
still there -- a deleted one answers 200 with a page that has no track image, on
which every noText: check passes.

firstrequest is about a bug that lags by exactly one request: the visibility
reaches the cart, the image drawn in reply does not carry the row, and the next
request draws it.  A script shaped track: -> go: -> expect: supplies that extra
request itself and passes on the broken build.  So this one asserts with no
go:, open: or convert: between the track: step and the check.

Which track it names is the other half, and it is not free choice.  A top-level
track passes on a build with the bug, because hgTracks adds every top-level
track as a lightweight stub so the track controls can list it -- microsat,
gtexGene and windowmaskerSdust all drew.  A default-visible child passes too,
because its container is in the list already: wgEncodeRegMarkH3k27ac drew while
its sibling wgEncodeRegMarkH3k4me1 did not, same superTrack and same request.
So the script names wgEncodeRegMarkH3k4me1, which is visibility hide under a
superTrack that is itself superTrack on hide, and the hideKids step before it is
what stops the other members coming back at their own trackDb visibility.

expected/firstrequest.derive is committed with it, and it is not decoration.
The test only means anything while the step under test is ONE round:

step 5 track {"wgEncodeRegMarkH3k4me1":"full"}
round 1 (2 vars): wgEncodeRegMarkH3k4me1=full wgEncodeReg=show

If Docent ever splits that the way it splits a container-plus-subtrack-hide, the
browser test would go on passing and stop being able to see the bug.  The
baseline says so out loud.

README.txt describes both, and adds hgCollection to "Still to write": no script
in either directory reaches that CGI, and hg/hgCollection/hgCollection.c carries
its own verbatim copy of isParentVisible() from hg/lib/trackHub.c.  Nine scripts
caught the trackHub.c copy on the branch; nothing caught this one.  Covering it
needs a collection: verb, since tracks go into a collection by dragging between
two jsTrees and drag: is the genomic drag-select on the track image.

Seventeen of seventeen pass in tests/, including the four xfails.

diff --git src/hg/utils/docent/tests/firstrequest.docent.yaml src/hg/utils/docent/tests/firstrequest.docent.yaml
new file mode 100644
index 00000000000..9e8a877c597
--- /dev/null
+++ src/hg/utils/docent/tests/firstrequest.docent.yaml
@@ -0,0 +1,52 @@
+# Turning a track on has to draw it in the SAME request that turned it on.
+#
+# The bug this exists for lags by exactly one request: the visibility reaches the cart,
+# the image drawn in reply to that request does not have the row, and the next request --
+# any next request -- draws it. So it is invisible to almost every script in this suite
+# and in regress/, because a script that navigates after a `track:` step supplies the
+# extra request itself and reads a correct image. Only an assertion made BEFORE any
+# `go:`, `open:` or `convert:` can see it.
+#
+# Two things have to be true of the track, or this passes on a build that has the bug:
+#
+#   * It must not be visible by default. A default-visible track is already in the list.
+#   * Its container must not be visible by default either. hgTracks adds every TOP-LEVEL
+#     track as a lightweight stub so the track controls can list it, so a top-level track
+#     is built whatever the cart says -- microsat, gtexGene and windowmaskerSdust all draw
+#     on a build with this bug.
+#
+# wgEncodeRegMarkH3k4me1 is both: `visibility hide`, and `superTrack wgEncodeReg hide`
+# under a superTrack that is itself `superTrack on hide`. Its sibling
+# wgEncodeRegMarkH3k27ac is `superTrack wgEncodeReg full` and draws on a broken build --
+# same superTrack, same request, opposite verdicts -- so it is the wrong track to name
+# here and the right one to name in a comment.
+#
+# The hideKids step is setup and is allowed its own requests. What is under test is the
+# ONE `track:` step after it, and nothing runs between that step and the assertion.
+target: genome-test
+db: hg38
+position: chr7:155799529-155812871
+reset: true
+fast: true
+steps:
+  - go: chr7:155799529-155812871
+  - hide: all
+
+  # Empty the superTrack first. `hide: all` is not enough: a superTrack does not pass its
+  # own visibility to its members, so turning it on later would bring every member up at
+  # its trackDb visibility and H3K27Ac would arrive alongside. hideKids writes an explicit
+  # hide for each member into the cart, which outlives the `wgEncodeReg=show` that the
+  # next step sends. See supertrack.docent.yaml for the same idiom.
+  - track: {wgEncodeReg: hideKids}
+  - expect: {rows: [ruler], exact: true, noText: "Too Long"}
+
+  # The gesture under test, in one request. Docent sends the containers above the track
+  # along with it, so this is `wgEncodeReg=show` plus `wgEncodeRegMarkH3k4me1=full`.
+  - track: {wgEncodeRegMarkH3k4me1: full}
+
+  # No navigation between the step above and this line, on purpose. `exact: true` also
+  # says the hides from the hideKids step survived the superTrack being shown again.
+  - expect:
+      rows: [ruler, wgEncodeRegMarkH3k4me1]
+      exact: true
+      noText: "Too Long"