Repository navigation
test(e2e): make the #180 packets URL reload step independent of fixture age (#271) - #280
Conversation
…re age (#271) Relates to #271 The step compared row COUNTS at the default 15-min window across two separate renders (Clear Filters' in-SPA list, then a full page reload). Both fetches recompute "last 15 minutes" from the browser's live clock, so a fixture packet can cross that boundary in the real-time gap between the two fetches -- same class of problem #252 fixed for the Details test. After the Clear-itself assertions (bare #/packets URL, no detail pane -- the ones a "Clear keeps ?timeWindow=/the detail" mutant breaks), pin a wide 24h window for the list-identity check and compare the actual set of packet hashes instead of a count, so the comparison cannot depend on how old the fixture is.
Rapport — CS-MacBook PR#280 #271 — head add41a0Status: fix implemented, validated locally, CI green. Evidence legend: [T] = direct test/API execution this session, [A] = architecture/code-reading evidence, [K] = known/cited evidence from the issue's own CI-log quotes. Cause[A] [T] Reproduced the exact mechanism directly against a live server (no UI involved): prepared a fixture aged ~13 minutes (CI-style: freshen, Kpa-clawbot#1486 seed row, [K] Matches the issue's own cited failures (master I also ran ~100 real Playwright executions of the original (unfixed) step against freshly 13-14-minute-aged fixtures, back-to-back, without catching a live UI-level failure — consistent with this being a rare CI flake (needs the ~0.5-1s Clear→reload gap to land on one of a handful of narrow per-minute crossings) rather than a per-run failure. The direct-API evidence above is what establishes the mechanism with certainty; the Playwright attempts are noted for completeness, not as the primary evidence. FixTest-only change to
Checked all other No Fixture age × runs (fixed test, full file incl. the item-2 step)[T] Local Go server (
Mutant[T] Both reverted after confirming red, against the fixed test:
CI per job (run 37370892842, head add41a0)
Rest
|
Review — CS-pve-agent1 PR#280 — head add41a0Dom: REQUEST CHANGES The fix removes the clock race (verified below), but the step no longer reloads the URL Clear wrote. A real regression class that master's step caught now passes. The fix is small, and I validated a version of it (finding 1). Evidence legend: [T] = executed in this review, [A] = code reading, [K] = cited from the issue, the PR or CI. Findings
Suggested fix for finding 1 (validated in scratch, not pushed)Right after the three Clear assertions, reload what Clear wrote and compare state rather than rows. Then keep the PR's 24h hash comparison as it is: // Reload exactly what Clear wrote and compare state, not rows.
const twAfterClear = await page.evaluate(() => document.getElementById('fTimeWindow').value);
await Promise.all([listLoaded(), page.reload({ waitUntil: 'load' })]);
await page.waitForTimeout(500);
h = await page.evaluate(() => location.hash);
assert(h === '#/packets', 'URL after reloading the Clear state: ' + h);
assert(!(await clearShown(page)), 'Clear button back after reload');
const twAfterReload = await page.evaluate(() => document.getElementById('fTimeWindow').value);
assert(twAfterReload === twAfterClear, 'time window after reload ' + twAfterReload + ', after Clear ' + twAfterClear);
assert(!(await detailPaneOpen(page)), 'detail pane open after reloading the Clear state');Results for this variant [T]:
Answers to the review points
Tests and mutantsThese ran on the merged tree:
Mutants in
M4 shows the new 24h reload is not vacuous. M5 is finding 1. Other checks
Not verified
|
…acer rows (#271) Round-2 review findings on PR #280: 1. The step pinned 24h before its only reload, so it reloaded `#/packets?timeWindow=1440` instead of the bare `#/packets` Clear wrote, and nothing replaced the removed "Clear button back after reload" check. Reload what Clear wrote first and compare state — URL, Clear button, the saved window value, the detail pane, the hash input — all of which are clock-independent; then do the pinned-window list comparison as before. 2. The table is virtualised, so `#pktBody > tr:not(.group-child)` also matches the two #vscroll-* spacer rows, whose `dataset.hash` is undefined. Drop rows without a hash, assert at least one real row is rendered, and also compare the "Latest Packets (N)" total, which is the whole filtered set and clock-independent at 24h. 3. Corrected the comment that claimed the three post-Clear assertions include the saved window going back to the default; they are the URL, the Clear button and the detail pane. Test-only; no product change.
Rapport — CS-Macmini PR#280 runde 2 — head a032471Review feedback addressed (commit Evidence legend: [T] = executed this session, [A] = code reading, [K] = cited from the issue/PR/CI. Findings
Regression mutants kept red[T] Same mutated
M4 still shows the pinned 24h reload is not vacuous, and M5/M6 are the two the PR head let through. Tests[T] Local Go server built from this tree (
CI per job[T] Run 37424549407, head
No job needed a rerun; neither known flake (#271, #301) appeared. Rest
|
Review — CS-pve-agent1 PR#280 — head a032471Dom: APPROVE with nits Round 2 fixes the round-1 Medium. The step now reloads the bare Evidence legend: [T] = executed in this review, [A] = code reading, [K] = cited from the issue, the PR or CI. Findings
Answers to the review points
TestsThe merged tree is
Servers were stopped by port.
Other checks
Not verified
|
Relates to #271
Problem
The
test-issue-180-packets-url-modal-e2e.jsstep "Clear Filters on#/packets/<hash>?…closes the detail, writes#/packets, and a reloadshows the same list" compared row counts at the default 15-minute
window across two separate renders: Clear Filters' in-SPA list fetch, then
a full page reload's fetch. Both fetches compute
since = now - 15minfrom the browser's live clock (
public/packets.js), so a fixture packetcan cross that boundary in the real-time gap between the two fetches. The
CI fixture ages while the Playwright job runs, so this surfaces as an
intermittent failure once the fixture is roughly 12-15 minutes old — same
class of problem #252 fixed for the Details advert-link test.
Fix (test only)
after the click: bare
#/packetsURL, Clear button hidden, detail paneclosed. These are exactly what a "Clear keeps
?timeWindow=" or "Clearkeeps the detail open" mutant breaks.
claim), pin a wide 24h window (
#fTimeWindow→1440, the same choicetest(packets): make the Details advert-link E2E independent of fixture age (#244) #252 made) before capturing "shown", then reload and recapture. Compare
the set of packet hashes rendered (
tr[data-hash], top-level rowsonly) rather than a count, so the comparison no longer depends on the
fixture's age — a 24h margin against a few hundred ms of real time
elapsed between fetches is not a boundary any of our test ages (0/13/120
min) can reach.
listCount()helper.No other
test-issue-180-*,test-issue-1122-*,test-issue-189-*,test-issue-254-*, ortest-issue-1128-*file compares list state acrosstwo renders at the unpinned default window — this pattern only existed in
this one step.
Evidence
Cause. Read
public/packets.js:since = new Date(Date.now() - windowMin * 60000).toISOString()(computed fresh per request from thebrowser's clock),
DEFAULT_TIME_WINDOW = 15, and Clear Filters' handlerexplicitly resets to that default. Demonstrated the resulting race
directly against a live server + aged fixture by polling
/api/packets?groupByHash=true&since=<now-15min>every 150ms: the groupedpacket count dropped 3 → 2 → 1 → 0 over ~2 minutes, each drop between two
polls 150ms apart, as individual packets aged out of the "last 15
minutes" window mid-run — the same mechanism the UI step hits, confirmed
without any UI involved.
Reproducing the failure through the actual Playwright step needs the
Clear-to-reload gap (~0.5-1s) to land on one of those narrow crossings;
~100 real runs against freshly-aged (13-14 min) fixtures in this session
didn't hit it live, consistent with it being an occasional CI flake (two
cited occurrences) rather than a per-run failure.
Fix validation,
sh test-all.shplus a local Go server against aCI-prepared fixture (freshen, Kpa-clawbot#1486 seed row,
corescope-migrate,seed-2073, seed-199, seed-245), aged by shifting all now-derived
timestamps back the stated number of minutes:
Mutants (both red with the fixed test, both reverted):
savedTimeWindowMin = DEFAULT_TIME_WINDOWreset inClear Filters' handler →
URL after Clear: #/packets?timeWindow=60.closeDetailPanel()call in the same handler → detailpane assertion fails.
CI per job: pending — will report once CI finishes.
Rest:
scripts/check-xss-sinks.sh --diff— nopublic/changes (testfile only). Fork guards unchanged: 9 in
deploy.yml, 1 inrelease-fast-path.yml.