code: def test_xpan_ranges_update(
      self, single_plot_page: SinglePlotPage
  ) -> None:
      source = ColumnDataSource(dict(x=[1, 2], y=[1, 1]))
      plot = Plot(
          height=400,
          width=400,
          x_range=Range1d(0, 1),
          y_range=Range1d(0, 1),
          min_border=0,
      )
      plot.add_glyph(source, Rect(x="x", y="y", width=0.9, height=0.9))
      plot.add_tools(WheelPanTool(dimension="width"))
      code = (
          RECORD("event_name", "cb_obj.event_name", final=False)
          + RECORD("x0", "cb_obj.x0", final=False)
          + RECORD("x1", "cb_obj.x1", final=False)
          + RECORD("y0", "cb_obj.y0", final=False)
          + RECORD("y1", "cb_obj.y1")
      )
      plot.js_on_event(RangesUpdate, CustomJS(code=code))
      plot.tags.append(CustomJS(name="custom-action", code=""))
      plot.toolbar_sticky = False
  
      page = single_plot_page(plot)
  
      [button] = page.get_toolbar_buttons(plot)
      button.click()
      page.driver.execute_script(SCROLL(-200))
      page.eval_custom_action()
      results = page.results
      assert results["event_name"] == "rangesupdate"
      assert results["x0"] < 0
      assert results["x1"] < 1
      assert results["y0"] == 0
      assert results["y1"] == 1
  
      assert page.has_no_console_errors()
  
file_path: bokeh/tests/integration/tools/test_wheel_pan_tool.py
imports: from __future__ import annotations
  import pytest
  from bokeh.events import RangesUpdate
  from bokeh.models import ColumnDataSource, CustomJS, Plot, Range1d, Rect, WheelPanTool
  from tests.support.plugins.project import SinglePlotPage
  from tests.support.util.selenium import RECORD, SCROLL
label_desc: Use image node_id 7 for calling the Test_WheelPanTool obj's underlying member method code with example usage: obj.test_xpan_ranges_update(single_plot_page) without return types