CI add visual regression tests - #672
Conversation
c0ddc08 to
8e84075
Compare
Renders the six dataview classes through quickshow and plot_panels -- for alpha-bearing data, NaNs in the data, and NaNs in the alpha map -- plus non-flatmap views through save_3d_views. Each render is checked against a stored reference, and the two renderers against each other. Four criteria per check, because they are complementary: the mean misses a few pixels moving a long way, the gross fraction misses a broad low-amplitude shift, and SSIM misses a channel permutation. The renderers do not share a pixel grid, so webgl is mapped onto quickflat's frame by a fixed affine first (fit_cross_renderer_affine.py re-derives it), and curvature is un-thresholded on both sides -- which halves the cross-renderer floor at the cost of not covering the default curvature path. Vertex2D is xfailed strictly: its webgl flatmap fails to link its shader (gallantlabgh-714), so it cannot be tested through that path. The test dependency group pins playwright and matplotlib, which between them fix every renderer the references depend on.
Twenty-eight lossless WebP (method=6, quality=100, exact=True) across alpha_dataviews, nan_dataviews, nan_alpha_dataviews and nonflat_views, kept separate from the code that reads them since no diff will explain them. Stored as git LFS pointers from the outset, so the image data never enters this repository's history. Rendered by chromium 151.0.7922.34 and matplotlib 3.10.9, pinned in the test dependency group. Regenerate with REGENERATE_REFERENCE_IMAGES=1 and review the result: regenerating is how a real regression gets silently blessed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A shader that over-allocates vertex attributes compiles but fails to *link*, and the viewer draws a blank canvas without any error (causes e.g. gallantlabgh-714). Three defences. filter_webgl_failures() scans browser output for unambiguous signatures. An event pump is what makes those messages arrive at all: Playwright's sync API dispatches only while something calls into it, and the worker parked in _shutdown_event.wait() for the whole session, so save_3d_views' check was dead code reading a list that stayed empty until teardown. _assert_not_blank inspects the pixels, for a driver that reports nothing at all. save_3d_views now raises RuntimeError naming the view and file, where a broken Vertex2D previously surfaced as "zero-size array to reduction operation minimum" from plot_panels' border trim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude finished @mvdoc's task in 3m 11s —— View job Review of "CI add visual regression tests"Todo list:
This is a very well-engineered PR — the calibration work behind the tolerances ( 1. Stale doc comment: pw_thread = handle._pw_thread # `handle` is a `WebApp`Per 2. Typo: 3. 4. Minor style: Things that look solid:
No blocking issues found; the three code notes above (1-3) are polish, not correctness bugs. |
- `handle` is the JSMixer, not the WebApp; `handle.server` is the WebApp. - "interactivemode" -> "interactive mode". - Two blank lines before the new test in test_export.py, per PEP8. - Note that browser_errors is cumulative: with a shared handle, one transient failure fails every later test in the class too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8e84075 to
dcd4c24
Compare
|
I pushed new commits that address problem 1, 2, and 4. I think it's not worth fixing problem 3, but I added a note for it. |
Rendering changes in Pycortex are currently only caught by eye. This PR automatically compares renders from both renderers (quickflat and webgl) against stored reference images, so a change in output fails a test instead of needing to be spotted in a screenshot. It also checks for consistency between the two renderers.
Tests
Four groups of reference images, covering the six public dataview classes through both renderers. (webgl references for
Vertex2Dare not included because it's broken onmain, per gh-714.)alpha_dataviews/Volume/Vertexas a no-alpha baseline,Volume2Dvia the 2D alpha colormapRdBu_r_alpha, the RGB classes via thealpha=keyword. All composite the curvature underlay.nan_dataviews/Vertex2Dxfailed) with NaNs over roughly half the primary data channel. Both renderers should draw those elements fully transparent, falling through to curvature, rather than mapping NaN through the colormap.nan_alpha_dataviews/VolumeRGB/VertexRGBwith the NaNs in the alpha map instead. A separate path: alpha is not colour-mapped but used directly as a blend weight, so the NaN reaches the compositing arithmetic.nonflat_views/VolumeandVertexon the inflated and fiducial surfaces. webgl only —quickshowrenders flatmaps and nothing else — so these get the reference check and no cross-renderer leg.The images are tracked with git LFS and should be regenerated whenever a rendering change is blessed.
The within-renderer checks run at tighter tolerances than the cross-renderer checks, since the two renderers differ by a fixed affine transform. (
fit_cross_renderer_affine.pyre-derives the ideal transform.)WebGL errors now fail loudly. Previously, WebGL console messages were not being caught properly due to buffering. This PR correctly propagates console error into pycortex. (This change would have caught gh-714.)
A blank render now fails loudly.
save_3d_viewsalso now raises on a blank view, naming the view and the file.What it catches
Three real bugs:
nanmeandefault. The mean difference (0.21 against a limit of 2.0) and the fraction of pixels moving more than 16 (0.68% against 2%) both pass. Only the gross-difference fraction and SSIM catch it — which is why there are four criteria and not one.main: the canvas comes back blank, nothing raises, and the png is still written.Notes for reviewers
tmp_path. There is no side-by-side composite; the two files are easier to flip between than one wide image.git lfs pullif the reference images arrive as 130-byte text stubs. The tests skip rather than fail on that, and on the images being absent.xfail(strict=True). When the fix (Vertex2D objects do not render in webviewer #714) merges they turn XPASS.matplotlibandplaywrightare now pinned in dev environments for consistency with the reference images.install_from_wheel.ymldeliberately does not, since wheels exclude them.cortex/tests/reference_images/README.mdcovers regeneration and provenance.