@@ -168,6 +168,41 @@ def test_worker_settings_relayout_and_reheat_move_nodes() -> None:
168168 assert report ["reheated_streams" ] is True
169169
170170
171+ def test_worker_settling_resistance_keeps_high_end_distinct () -> None :
172+ script = """
173+ const nodes = [
174+ { id: 'a', community_id: 'c' },
175+ { id: 'b', community_id: 'c' },
176+ { id: 'c', community_id: 'c' },
177+ ];
178+ send({ type: 'prepare', payload: { nodes, links: [{ source: 'a', target: 'b' }] } });
179+ const waitForLayouts = (count, callback) => {
180+ const tick = () => {
181+ if (all('layout').length >= count) return callback();
182+ setTimeout(tick, 10);
183+ };
184+ tick();
185+ };
186+ waitForLayouts(1, () => {
187+ const samples = {};
188+ const next = (resistance, callback) => {
189+ const before = all('layout').length;
190+ send({ type: 'settings', settings: { damping: resistance }, relayout: true, fit: false });
191+ // settings emits the reseeded preview immediately; wait for the first relaxed layout.
192+ waitForLayouts(before + 2, () => {
193+ samples[resistance] = latest('layout').positions;
194+ callback();
195+ });
196+ };
197+ next(13, () => next(14, () => next(15, () => console.log(JSON.stringify({ samples })))));
198+ });
199+ """
200+ report = _run_worker (script )
201+ samples = report ["samples" ]
202+ assert samples ["13" ] != samples ["14" ]
203+ assert samples ["14" ] != samples ["15" ]
204+
205+
171206def test_renderer_is_webgl2_only_without_live_simulation_or_canvas_fallback () -> None :
172207 renderer = RENDERER .read_text (encoding = "utf-8" )
173208 assert "getContext('webgl2'" in renderer
0 commit comments