@@ -188,6 +188,45 @@ test('Ledger bounds auto-fit zoom and keeps a dragged node under the pointer', a
188188 expect ( session . pageErrors ) . toEqual ( [ ] ) ;
189189} ) ;
190190
191+ test ( 'Classic keeps a dragged node under the pointer with reduced visual motion' , async ( { page } ) => {
192+ await page . emulateMedia ( { reducedMotion : 'reduce' } ) ;
193+ const session = await openDashboard ( page , { query : '?graph-engine=next' } ) ;
194+ await openGraphView ( page ) ;
195+ await page . waitForFunction ( ( ) => window . __fg && window . __fg . graphData ( ) . nodes . length > 0 ) ;
196+ await page . waitForFunction ( ( ) => window . __fg . graphData ( ) . nodes
197+ . every ( node => Number . isFinite ( node . x ) && Number . isFinite ( node . y ) ) ) ;
198+ await page . waitForTimeout ( 500 ) ;
199+
200+ const drag = await page . evaluate ( ( ) => {
201+ const graph = window . __fg ;
202+ const node = graph . graphData ( ) . nodes [ 0 ] ;
203+ const canvas = document . querySelector ( '#graph-net canvas' ) ;
204+ const box = canvas . getBoundingClientRect ( ) ;
205+ const point = graph . graph2ScreenCoords ( node . x , node . y ) ;
206+ return {
207+ before : { x : node . x , y : node . y } ,
208+ zoom : canvas . __zoom . k ,
209+ x : box . left + point . x ,
210+ y : box . top + point . y ,
211+ } ;
212+ } ) ;
213+
214+ await page . mouse . move ( drag . x , drag . y ) ;
215+ await page . mouse . down ( ) ;
216+ await page . mouse . move ( drag . x + 80 , drag . y + 40 , { steps : 8 } ) ;
217+ await page . mouse . up ( ) ;
218+ const after = await page . evaluate ( ( ) => {
219+ const node = window . __fg . graphData ( ) . nodes [ 0 ] ;
220+ return { x : node . x , y : node . y , fx : node . fx , fy : node . fy } ;
221+ } ) ;
222+
223+ expect ( after . x - drag . before . x ) . toBeCloseTo ( 80 / drag . zoom , 0 ) ;
224+ expect ( after . y - drag . before . y ) . toBeCloseTo ( 40 / drag . zoom , 0 ) ;
225+ expect ( after . fx ) . toBeCloseTo ( after . x , 8 ) ;
226+ expect ( after . fy ) . toBeCloseTo ( after . y , 8 ) ;
227+ expect ( session . pageErrors ) . toEqual ( [ ] ) ;
228+ } ) ;
229+
191230test ( 'a dashboard page that never opens the graph fetches neither graph script' , async ( { page } ) => {
192231 // The reason both scripts are lazy is not weight, it is CSP: force-graph applies inline
193232 // styles at runtime, so an eager <script> reported a violation on every page view — including
0 commit comments