code: def test_server_source_callback_triggered_after_edit(
      self, bokeh_server_page: BokehServerPage
  ) -> None:
      data = {"x": [1, 2, 5, 6], "y": [60, 50, 20, 10]}
      source = ColumnDataSource(data)
  
      table = DataTable(
          columns=[
              TableColumn(field="x", title="x", sortable=True),
              TableColumn(
                  field="y",
                  title="y",
                  sortable=True,
                  editor=NumberEditor(),
              ),
          ],
          source=source,
          editable=True,
      )
  
      result = []
  
      def modify_doc(doc):
          plot = Plot(
              height=400,
              width=400,
              x_range=Range1d(0, 1),
              y_range=Range1d(0, 1),
              min_border=0,
          )
  
          def cb(attr, old, new):
              result.append("CALLED")
  
          source.on_change("data", cb)
          doc.add_root(column(plot, table))
  
      page = bokeh_server_page(modify_doc)
  
      assert result == []
  
      cell = get_table_cell(page.driver, table, 3, 2)
      assert cell.text == "20"
      enter_text_in_cell(page.driver, table, 3, 2, "100")
  
      assert result == ["CALLED"]
  
      assert page.has_no_console_errors()
  
imports: from __future__ import annotations
  import pytest
  from bokeh.layouts import column
  from bokeh.models import Button, ColumnDataSource, CustomJS, DataTable, NumberEditor, Plot, Range1d, Rect, TableColumn, TapTool
  from tests.support.plugins.project import BokehServerPage, SinglePlotPage
  from tests.support.util.selenium import RECORD, alt_click, enter_text_in_cell, find_element_for, get_table_cell, get_table_column_cells, get_table_row, get_table_selected_rows, shift_click, sort_table_column
label_desc: Use image node_id 12 for calling the Test_DataTableSource obj's underlying member method code with example usage: obj.test_server_source_callback_triggered_after_edit(bokeh_server_page) without return types