Motivation
When diagnosing virtualized infinite-scroll membership issues (e.g. Grafana Flow 42 — under-collection, empty in-view pages, EOF stops), verbose logs tell you what the engine decided (0/N in view, dedupe skip, pagination returned false) but not what the table looked like at that moment.
It would help to visually inspect the table at key iterator checkpoints (before/after page advance, after commit of in-view rows, on stop).
Today debug only supports logLevel + slow delays (src/utils/debugUtils.ts). No visual artifacts.
Ideas (decide later)
A. Library-owned screenshots
Opt-in, e.g. debug: { screenshots: true | { on: ['pagination' | 'pageCommit' | 'stop'], path?, fullPage? } } for map / forEach / filter / findRows (and maybe findRow pagination).
Attach via Playwright test.info().attach when available, or write under a configurable directory.
B. Enrich the Playwright trace (prefer if “good enough”)
Traces already capture timeline + screenshots/DOM snapshots when tracing is enabled. Shortfall is semantics: library decisions don’t show up as labeled steps.
Possible enrichments without dumping PNGs ourselves:
- Wrap pagination / page-commit / stop in
test.step(...) (or tracing groups) with SmartTable labels: map page 12 — 0 new in-view; goNext
- Console messages already land in the trace — ensure critical decisions are one-liners that are easy to filter
- Optional: briefly highlight the scroll root / committed row locators before advance (visible in trace screenshots)
C. Hybrid
Trace steps always when debug.logLevel is on; screenshots only on stop / empty page / mismatch heuristics (cheaper).
Does a Playwright trace already provide this?
Partially yes. With trace: 'on' | 'retain-on-failure' (and screenshot/snapshot options), you get:
- Action timeline (clicks, evaluates, scrolls)
- Screenshots around actions
- DOM snapshots of mounted nodes
- Console + network
What it does not give you out of the box:
- SmartTable meaning: which logical page, which indices were committed vs skipped (overscan/dedupe/tracker), why
goNext returned false
- Correlation between a verbose log line and a specific frame (“this empty page”)
- Visibility into rows that were never mounted (virtualization) — neither screenshots nor DOM snapshots can show unmounted rows
- Guaranteed capture when users only run with
debug: { logLevel: 'verbose' } and tracing off
So: improve the trace first if we can make library steps obvious; add screenshots where trace steps aren’t enough or tracing isn’t on.
Shortfalls — screenshots
| Issue |
Why it matters for tables |
| Viewport-only |
Virtualized lists: most rows aren’t painted; a shot can’t prove “missing from catalog,” only “not in this viewport.” |
| Point-in-time vs read time |
Recycle races: pixel frame may not match the row identity toJSON just read (or skipped). |
| Cost |
Per-page shots on maxPages: 200 scrapes → slow tests + huge artifacts/CI storage. |
| No structure |
Without overlays (row index, committed set, scrollTop), a PNG is hard to interpret. |
| Scroll-root clipping |
Table body in a nested scroller may need locator.screenshot() on the scroll target, not page.screenshot(). |
| Headless differences |
Font/DPI/scrollbar chrome can mislead when comparing locally vs CI. |
Shortfalls — Playwright trace
| Issue |
Why it matters |
| Opt-in / often failure-only |
Repro loops with verbose debug usually don’t have a trace open. |
| Noise / size |
Long infinite-scroll maps generate enormous traces; hard to scrub to the bad page. |
| Unlabeled library logic |
Dedupe skip, ElementTracker “already seen,” visible-index filter, contentChanged timeout are not first-class steps today. |
| Still can’t see unmounted rows |
DOM snapshot = mounted virtual window only. |
| Evaluate-heavy strategies |
js-scroll / fingerprint reads show as opaque evaluates unless we name steps. |
| Viewer ≠ SmartTable UI |
No built-in “iterator page N” filmstrip unless we create steps/attachments. |
Suggested scope for a first cut
- Document how to use Playwright tracing effectively with SmartTable iterators (checklist).
- Add named steps (or equivalent) around pagination + page commit + stop when debug is enabled.
- Optional screenshot-on-empty-page / screenshot-on-stop only (not every page) as a footgun-resistant default.
- Explicitly not a visual-regression product (see ROADMAP) — debug aid only.
Related
Acceptance ideas
Motivation
When diagnosing virtualized infinite-scroll membership issues (e.g. Grafana Flow 42 — under-collection, empty in-view pages, EOF stops), verbose logs tell you what the engine decided (
0/N in view,dedupe skip,pagination returned false) but not what the table looked like at that moment.It would help to visually inspect the table at key iterator checkpoints (before/after page advance, after commit of in-view rows, on stop).
Today
debugonly supportslogLevel+slowdelays (src/utils/debugUtils.ts). No visual artifacts.Ideas (decide later)
A. Library-owned screenshots
Opt-in, e.g.
debug: { screenshots: true | { on: ['pagination' | 'pageCommit' | 'stop'], path?, fullPage? } }formap/forEach/filter/findRows(and maybefindRowpagination).Attach via Playwright
test.info().attachwhen available, or write under a configurable directory.B. Enrich the Playwright trace (prefer if “good enough”)
Traces already capture timeline + screenshots/DOM snapshots when tracing is enabled. Shortfall is semantics: library decisions don’t show up as labeled steps.
Possible enrichments without dumping PNGs ourselves:
test.step(...)(or tracing groups) with SmartTable labels:map page 12 — 0 new in-view; goNextC. Hybrid
Trace steps always when
debug.logLevelis on; screenshots only on stop / empty page / mismatch heuristics (cheaper).Does a Playwright trace already provide this?
Partially yes. With
trace: 'on' | 'retain-on-failure'(and screenshot/snapshot options), you get:What it does not give you out of the box:
goNextreturned falsedebug: { logLevel: 'verbose' }and tracing offSo: improve the trace first if we can make library steps obvious; add screenshots where trace steps aren’t enough or tracing isn’t on.
Shortfalls — screenshots
toJSONjust read (or skipped).maxPages: 200scrapes → slow tests + huge artifacts/CI storage.locator.screenshot()on the scroll target, notpage.screenshot().Shortfalls — Playwright trace
contentChangedtimeout are not first-class steps today.js-scroll/ fingerprint reads show as opaque evaluates unless we name steps.Suggested scope for a first cut
Related
Acceptance ideas