code: def test_ranges_update_event_trigger_on_pan(
      self, bokeh_server_page: BokehServerPage
  ) -> None:
      events = []
  
      x_range = Range1d(0, 4)
      y_range = Range1d(0, 4)
      p = figure(
          height=400, width=400, x_range=x_range, y_range=y_range
      )
      p.line([1, 2, 3], [1, 2, 3])
  
      def modify_doc(doc: Document):
          p.on_event(
              RangesUpdate,
              lambda evt: events.append(
                  ("RangesUpdate", evt.x0, evt.x1, evt.y0, evt.y1)
              ),
          )
          doc.add_root(p)
  
      page = bokeh_server_page(modify_doc)
  
      # This can only be called once - calling it multiple times appears to have no effect
      page.drag_canvas_at_position(p, 100, 100, 200, 200)
  
      # Wait for drag to happen
      time.sleep(0.2)
      assert events[0][0] == "RangesUpdate"
      assert events[0][1] < -2.3
      assert events[0][2] < 1.7
      assert events[0][3] > 2.1
      assert events[0][4] > 6.1
  
imports: from __future__ import annotations
  import pytest
  import time
  from dataclasses import dataclass
  from typing import Any
  from bokeh.core.property.singletons import Undefined
  from bokeh.document import Document
  from bokeh.events import LODEnd, LODStart, RangesUpdate
  from bokeh.layouts import column
  from bokeh.models import Button, Plot, Range1d
  from bokeh.plotting import figure
  from bokeh.plotting.glyph_api import GlyphAPI
  from tests.support.plugins.project import BokehServerPage
  from tests.support.util.selenium import find_element_for
label_desc: Use image node_id 3 for calling the Test_Plot obj's underlying member method code with example usage: obj.test_ranges_update_event_trigger_on_pan(bokeh_server_page) without return types