Repository navigation
Conversation
State-kind scenario (zoom before a gated first read): guards the contract that a gesture made before the accessor's first read is reflected in that read. It passes both pre- and post-#412 -- ipyleaflet pushes its synced traits to Python unconditionally, so the pre-#412 lazy attach's seed self-healed -- and would catch a frontend that ever gates its state sync on a Python-side listener. Event-kind characterization (clicked): documents the intentional lazy attach -- a map click made before the first read is missed, and clicks after it are captured.
There was a problem hiding this comment.
🟡 Changes recommended
The test can pass before the first read completes and accept coordinates from the pre-read click, so it may miss an eager-listener regression without a distinct no-event value to wait for.
1 open issue
What changed in this PR
Adds browser coverage for accessor behavior when the first read is delayed, complementing #412’s unit tests for attach timing.
Changes:
- Adds a state-accessor contract test verifying that a zoom gesture is reflected in the first read.
- Adds an event-accessor characterization test for lazy click-listener attachment.
- Introduces a fixture with button-gated reads and a raw zoom-trait synchronization sentinel.
| File | Description |
|---|---|
| tests/playwright/ipyleaflet_eager_attach/test_ipyleaflet_eager_attach.py | Adds browser tests for state and event behavior before the first accessor read. |
| tests/playwright/ipyleaflet_eager_attach/app.py | Provides gated accessor reads and a zoom synchronization output. |
Review effort: Balanced
An empty string couldn't distinguish 'server processed the read and there was no event' from 'server hasn't re-rendered yet', so the test could proceed to the second map click before the lazy listener attached (and, if event accessors ever become eager, accept stale coordinates). Waiting for the distinct None marker fixes both.
… test/eager-accessor-regression
cpsievert
marked this pull request as ready for review
November 4, 2026 18:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #412.
Summary
Browser-level tests for accessor attach timing, following up #412:
test_state_accessor_captures_gesture_before_first_read— a zoom-in gesture before a button-gated first read of ipyleafletzoom(); the read reflects the gesture. This is a scenario-contract guard, not a feat: state-kind accessors attach eagerly at render by default #412-specific regression test: it passes both pre- and post-feat: state-kind accessors attach eagerly at render by default #412 (verified by flippingAccessorSpec.eager's default back toFalse), because ipyleaflet pushes synced traits unconditionally and the lazy attach's seed self-heals. What it guards is the user-visible contract against any future frontend that gates state sync on a listener existing. Attach timing itself is covered by feat: state-kind accessors attach eagerly at render by default #412's unit tests.test_event_accessor_misses_click_before_first_read— characterization of intentional behavior:kind="event"clicked()still attaches lazily, so a pre-read map click is missed while post-read clicks are captured. Acts as a tripwire if the event default ever changes.The app fixture gates all accessor reads behind
@reactive.eventbuttons and exposes a raw-trait sentinel output so tests wait for browser→server sync deterministically.A survey of every state-kind accessor in the package (ipyleaflet, jscatter, altair, bokeh, quak, mosaic, perspective, itables, ipydatagrid, embedding_atlas, pythreejs, k3d, ipyaladin, lonboard, matplotlib) found all are trait/signal-backed with self-healing seeds; the only browser-listener-gated mechanisms are the plotly bridge (event-kind only) and the reactable bridge (state-kind, but re-seeds on bind). So no current state accessor can discriminate pre/post-#412 in a browser test — a truly discriminating test would need a listener-gated state frontend that doesn't exist in the package yet.
Verification
ipyleaflet_accessors,ipyleaflet_marker_click,jscatter_accessors,accessor_helper.make checkclean (the onetest_geolibrefailure is pre-existing on this base and already fixed on main by feat(geolibre): use geolibre's async command methods when available #360).