Skip to content

rename ctx.get_websocket to ctx.websocket

512e119
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
Open

[4.2] Persistent callbacks #3771

rename ctx.get_websocket to ctx.websocket
512e119
Select commit
Loading
Failed to load commit list.
GitHub Actions / Test Results Summary succeeded May 11, 2026 in 0s

1909 passed, 1 failed and 45 skipped

Tests failed

Report Passed Failed Skipped Time
test-results/background-test-results-py3.12/junit_async.xml 26✅ 74s
test-results/background-test-results-py3.12/junit_background.xml 36✅ 2⚪ 422s
test-results/background-test-results-py3.9/junit_async.xml 26✅ 75s
test-results/background-test-results-py3.9/junit_background.xml 36✅ 2⚪ 424s
test-results/dcc-test-results-py3.12-group1/junit_intg.xml 164✅ 1⚪ 563s
test-results/dcc-test-results-py3.12-group2/junit_intg.xml 135✅ 454s
test-results/dcc-test-results-py3.12-group3/junit_intg.xml 33✅ 103s
test-results/dcc-test-results-py3.8-group1/junit_intg.xml 164✅ 1⚪ 579s
test-results/dcc-test-results-py3.8-group2/junit_intg.xml 135✅ 431s
test-results/dcc-test-results-py3.8-group3/junit_intg.xml 33✅ 97s
test-results/html-test-results-py3.12/junit_html.xml 7✅ 10s
test-results/html-test-results-py3.8/junit_html.xml 7✅ 6s
test-results/table-server-results-group1/junit_table.xml 83✅ 1❌ 16⚪ 467s
test-results/table-server-results-group2/junit_table.xml 194✅ 3⚪ 490s
test-results/table-server-results-group3/junit_table.xml 154✅ 10⚪ 460s
test-results/test-main-results-py3.12-group1/junit_intg.xml 132✅ 2⚪ 295s
test-results/test-main-results-py3.12-group2/junit_intg.xml 110✅ 2⚪ 441s
test-results/test-main-results-py3.12-group3/junit_intg.xml 96✅ 1⚪ 243s
test-results/test-main-results-py3.8-group1/junit_intg.xml 132✅ 2⚪ 278s
test-results/test-main-results-py3.8-group2/junit_intg.xml 110✅ 2⚪ 412s
test-results/test-main-results-py3.8-group3/junit_intg.xml 96✅ 1⚪ 229s

✅ test-results/background-test-results-py3.12/junit_async.xml

26 tests were completed in 74s with 26 passed, 0 failed and 0 skipped.

✅ test-results/background-test-results-py3.12/junit_background.xml

38 tests were completed in 422s with 36 passed, 0 failed and 2 skipped.

✅ test-results/background-test-results-py3.9/junit_async.xml

26 tests were completed in 75s with 26 passed, 0 failed and 0 skipped.

✅ test-results/background-test-results-py3.9/junit_background.xml

38 tests were completed in 424s with 36 passed, 0 failed and 2 skipped.

✅ test-results/dcc-test-results-py3.12-group1/junit_intg.xml

165 tests were completed in 563s with 164 passed, 0 failed and 1 skipped.

✅ test-results/dcc-test-results-py3.12-group2/junit_intg.xml

135 tests were completed in 454s with 135 passed, 0 failed and 0 skipped.

✅ test-results/dcc-test-results-py3.12-group3/junit_intg.xml

33 tests were completed in 103s with 33 passed, 0 failed and 0 skipped.

✅ test-results/dcc-test-results-py3.8-group1/junit_intg.xml

165 tests were completed in 579s with 164 passed, 0 failed and 1 skipped.

✅ test-results/dcc-test-results-py3.8-group2/junit_intg.xml

135 tests were completed in 431s with 135 passed, 0 failed and 0 skipped.

✅ test-results/dcc-test-results-py3.8-group3/junit_intg.xml

33 tests were completed in 97s with 33 passed, 0 failed and 0 skipped.

✅ test-results/html-test-results-py3.12/junit_html.xml

7 tests were completed in 10s with 7 passed, 0 failed and 0 skipped.

✅ test-results/html-test-results-py3.8/junit_html.xml

7 tests were completed in 6s with 7 passed, 0 failed and 0 skipped.

❌ test-results/table-server-results-group1/junit_table.xml

100 tests were completed in 467s with 83 passed, 1 failed and 16 skipped.

Test suite Passed Failed Skipped Time
pytest 83✅ 1❌ 16⚪ 467s

❌ pytest

tests.selenium.test_basic_copy_paste
  ⚪ test_tbcp001_copy_paste_callback
  ⚪ test_tbcp002_sorted_copy_paste_callback
  ⚪ test_tbcp003_copy_multiple_rows[True]
  ⚪ test_tbcp003_copy_multiple_rows[False]
  ✅ test_tbcp004_copy_9_and_10
  ⚪ test_tbcp005_copy_multiple_rows_and_columns
  ⚪ test_tbcp006_copy_paste_between_tables
  ⚪ test_tbcp007_copy_paste_with_hidden_column
  ⚪ test_tbcp008_copy_paste_between_tables_with_hidden_columns
  ✅ test_tbcp009_copy_9_and_10_click
  ✅ test_tbcp010_copy_from_unselectable_cells_table
  ✅ test_tbcp011_copy_double_quotes
  ✅ test_tbcp011_copy_multiline
tests.selenium.test_basic_operations
  ✅ test_tbst001_get_cell[props0]
  ✅ test_tbst001_get_cell[props1]
  ✅ test_tbst002_select_all_text[props0]
  ✅ test_tbst002_select_all_text[props1]
  ✅ test_tbst003_edit_on_enter[props0]
  ✅ test_tbst003_edit_on_enter[props1]
  ✅ test_tbst004_edit_on_tab[props0]
  ✅ test_tbst004_edit_on_tab[props1]
  ✅ test_tbst005_edit_last_row_on_click_outside[props0]
  ✅ test_tbst005_edit_last_row_on_click_outside[props1]
  ✅ test_tbst006_focused_arrow_left
  ✅ test_tbst007_active_focused_arrow_right
  ✅ test_tbst008_active_focused_arrow_up
  ✅ test_tbst009_active_focused_arrow_down
  ✅ test_tbst010_active_with_dblclick[props0]
  ✅ test_tbst010_active_with_dblclick[props1]
  ✅ test_tbst011_delete_row[props0]
  ✅ test_tbst011_delete_row[props1]
  ✅ test_tbst012_delete_sorted_row[props0]
  ✅ test_tbst012_delete_sorted_row[props1]
  ✅ test_tbst013_select_row[props0]
  ✅ test_tbst013_select_row[props1]
  ✅ test_tbst013_select_row[props2]
  ✅ test_tbst014_selected_sorted_row[props0]
  ✅ test_tbst014_selected_sorted_row[props1]
  ✅ test_tbst014_selected_sorted_row[props2]
  ✅ test_tbst015_selected_row_respects_sort[props0]
  ✅ test_tbst015_selected_row_respects_sort[props1]
  ✅ test_tbst015_selected_row_respects_sort[props2]
  ✅ test_tbst016_delete_cell[props0]
  ✅ test_tbst016_delete_cell[props1]
  ⚪ test_tbst017_delete_cell_updates_while_selected[props0]
  ⚪ test_tbst017_delete_cell_updates_while_selected[props1]
  ✅ test_tbst018_delete_multiple_cells[props0]
  ✅ test_tbst018_delete_multiple_cells[props1]
  ⚪ test_tbst019_delete_multiple_cells_while_selected[props0]
  ⚪ test_tbst019_delete_multiple_cells_while_selected[props1]
  ✅ test_tbst020_sorted_table_delete_cell[props0]
  ✅ test_tbst020_sorted_table_delete_cell[props1]
  ⚪ test_tbst021_sorted_table_delete_cell_updates_while_selected[props0]
  ⚪ test_tbst021_sorted_table_delete_cell_updates_while_selected[props1]
  ✅ test_tbst022_sorted_table_delete_multiple_cells[props0]
  ✅ test_tbst022_sorted_table_delete_multiple_cells[props1]
  ⚪ test_tbst023_sorted_table_delete_multiple_cells_while_selected[props0]
  ⚪ test_tbst023_sorted_table_delete_multiple_cells_while_selected[props1]
  ✅ test_tbst024_row_selectable_filter_action
tests.selenium.test_column
  ✅ test_colm001_can_delete
  ✅ test_colm002_keep_hidden_on_delete
  ✅ test_colm003_can_clear
  ✅ test_colm004_can_hide
  ✅ test_colm005_dont_clear_hidden
  ✅ test_colm006_multi_select
  ✅ test_colm007_single_select
  ✅ test_colm008_top_row_by_subset
  ✅ test_colm009_newline_id
tests.selenium.test_derived_props
  ✅ test_tdrp001_select_rows
  ✅ test_tdrp002_select_cell
  ✅ test_tdrp003_select_cells
  ✅ test_tdrp004_navigate_selected_cells
  ❌ test_tdrp005_filtered_and_sorted_row_select
	test = <conftest.DataTableComposite object at 0x7f2f694c7980>
tests.selenium.test_dropdown
  ✅ test_drpd001_no_scroll
tests.selenium.test_edit
  ✅ test_edit001_can_delete_dropdown[props0]
  ✅ test_edit001_can_delete_dropdown[props1]
  ✅ test_edit002_can_delete_dropown_and_set[props0]
  ✅ test_edit002_can_delete_dropown_and_set[props1]
  ✅ test_edit003_can_edit_dropdown[props0]
  ✅ test_edit003_can_edit_dropdown[props1]
  ✅ test_edit004_edit_focused[props0]
  ✅ test_edit004_edit_focused[props1]
tests.selenium.test_editable
  ✅ test_tedi001_loading_on_data_change
  ✅ test_tedi002_ready_on_non_data_change
  ✅ test_tedi003_does_not_steal_focus
  ✅ test_tedi004_edit_on_non_blocking
  ✅ test_tedi005_prevent_copy_paste_on_blocking
  ✅ test_tedi006_allow_copy_paste_on_non_blocking
tests.selenium.test_empty
  ✅ test_empt001_clear_
tests.selenium.test_export
  ✅ test_tbex001_table_export_csv[csv-read_csv]
  ✅ test_tbex001_table_export_csv[xlsx-read_excel]
tests.selenium.test_filter
  ✅ test_filt001_basic[props0-expect0]
  ✅ test_filt001_basic[props1-expect1]
  ✅ test_filt001_basic[props2-expect2]
  ✅ test_filt002_sensitivity[sensitive-None0]
  ✅ test_filt002_sensitivity[sensitive-None1]
  ✅ test_filt002_sensitivity[sensitive-None2]
  ✅ test_filt002_sensitivity[insensitive-None]
  ✅ test_filt002_sensitivity[sensitive-insensitive]
  ✅ test_filt002_sensitivity[insensitive-sensitive]

✅ test-results/table-server-results-group2/junit_table.xml

197 tests were completed in 490s with 194 passed, 0 failed and 3 skipped.

✅ test-results/table-server-results-group3/junit_table.xml

164 tests were completed in 460s with 154 passed, 0 failed and 10 skipped.

✅ test-results/test-main-results-py3.12-group1/junit_intg.xml

134 tests were completed in 295s with 132 passed, 0 failed and 2 skipped.

✅ test-results/test-main-results-py3.12-group2/junit_intg.xml

112 tests were completed in 441s with 110 passed, 0 failed and 2 skipped.

✅ test-results/test-main-results-py3.12-group3/junit_intg.xml

97 tests were completed in 243s with 96 passed, 0 failed and 1 skipped.

✅ test-results/test-main-results-py3.8-group1/junit_intg.xml

134 tests were completed in 278s with 132 passed, 0 failed and 2 skipped.

✅ test-results/test-main-results-py3.8-group2/junit_intg.xml

112 tests were completed in 412s with 110 passed, 0 failed and 2 skipped.

✅ test-results/test-main-results-py3.8-group3/junit_intg.xml

97 tests were completed in 229s with 96 passed, 0 failed and 1 skipped.

Annotations

Check failure on line 0 in test-results/table-server-results-group1/junit_table.xml

See this annotation in the file changed.

@github-actions github-actions / Test Results Summary

pytest ► tests.selenium.test_derived_props ► test_tdrp005_filtered_and_sorted_row_select

Failed test found in:
  test-results/table-server-results-group1/junit_table.xml
Error:
  test = <conftest.DataTableComposite object at 0x7f2f694c7980>
Raw output
test = <conftest.DataTableComposite object at 0x7f2f694c7980>

    def test_tdrp005_filtered_and_sorted_row_select(test):
        test.start_server(get_app())
    
        target = test.table("table")
    
        target.row(0).select()
        target.row(1).select()
        target.row(2).select()
    
        time.sleep(1)
    
        assert test.find_element("#active_cell").get_attribute("innerHTML") in [
            "None",
            json.dumps([]),
        ]
        assert test.find_element("#start_cell").get_attribute("innerHTML") in [
            "None",
            json.dumps([]),
        ]
        assert test.find_element("#end_cell").get_attribute("innerHTML") in [
            "None",
            json.dumps([]),
        ]
        assert test.find_element("#selected_cells").get_attribute("innerHTML") in [
            "None",
            json.dumps([]),
        ]
        assert test.find_element("#selected_rows").get_attribute("innerHTML") == json.dumps(
            list(range(3))
        )
        assert test.find_element("#selected_row_ids").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3000, 3003)))
    
        assert test.find_element("#derived_viewport_selected_rows").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3)))
        assert test.find_element("#derived_viewport_selected_row_ids").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3000, 3003)))
        assert test.find_element("#derived_viewport_indices").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(10)))
        assert test.find_element("#derived_viewport_row_ids").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3000, 3010)))
    
        assert test.find_element("#derived_virtual_selected_rows").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3)))
        assert test.find_element("#derived_virtual_selected_row_ids").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3000, 3003)))
        assert test.find_element("#derived_virtual_indices").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(100)))
        assert test.find_element("#derived_virtual_row_ids").get_attribute(
            "innerHTML"
        ) == json.dumps(list(range(3000, 3100)))
    
        target.column(0).filter_value("is even")
    
>       assert test.find_element("#active_cell").get_attribute("innerHTML") in [
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            "None",
            json.dumps([]),
        ]

tests/selenium/test_derived_props.py:471: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/selenium/webdriver/remote/webelement.py:173: in get_attribute
    attribute_value = self.parent.execute_script(
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py:884: in execute_script
    return self.execute(command, {
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py:430: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f2f694c7da0>
response = {'status': 404, 'value': '{"value":{"error":"stale element reference","message":"stale element reference: stale elemen...\\n#15 0x55aa1334e5de \\u003Cunknown>\\n#16 0x7f694449caa4 \\u003Cunknown>\\n#17 0x7f6944529c6c \\u003Cunknown>\\n"}}'}

    def check_response(self, response: Dict[str, Any]) -> None:
        """
        Checks that a JSON response from the WebDriver does not have an error.
    
        :Args:
         - response - The JSON response from the WebDriver server as a dictionary
           object.
    
        :Raises: If the response contains an error message.
        """
        status = response.get('status', None)
        if not status or status == ErrorCode.SUCCESS:
            return
        value = None
        message = response.get("message", "")
        screen: str = response.get("screen", "")
        stacktrace = None
        if isinstance(status, int):
            value_json = response.get('value', None)
            if value_json and isinstance(value_json, str):
                import json
                try:
                    value = json.loads(value_json)
                    if len(value.keys()) == 1:
                        value = value['value']
                    status = value.get('error', None)
                    if not status:
                        status = value.get("status", ErrorCode.UNKNOWN_ERROR)
                        message = value.get("value") or value.get("message")
                        if not isinstance(message, str):
                            value = message
                            message = message.get('message')
                    else:
                        message = value.get('message', None)
                except ValueError:
                    pass
    
        exception_class: Type[WebDriverException]
        if status in ErrorCode.NO_SUCH_ELEMENT:
            exception_class = NoSuchElementException
        elif status in ErrorCode.NO_SUCH_FRAME:
            exception_class = NoSuchFrameException
        elif status in ErrorCode.NO_SUCH_SHADOW_ROOT:
            exception_class = NoSuchShadowRootException
        elif status in ErrorCode.NO_SUCH_WINDOW:
            exception_class = NoSuchWindowException
        elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
            exception_class = StaleElementReferenceException
        elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
            exception_class = ElementNotVisibleException
        elif status in ErrorCode.INVALID_ELEMENT_STATE:
            exception_class = InvalidElementStateException
        elif status in ErrorCode.INVALID_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
            exception_class = InvalidSelectorException
        elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
            exception_class = ElementNotSelectableException
        elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE:
            exception_class = ElementNotInteractableException
        elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
            exception_class = InvalidCookieDomainException
        elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
            exception_class = UnableToSetCookieException
        elif status in ErrorCode.TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.SCRIPT_TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.UNKNOWN_ERROR:
            exception_class = WebDriverException
        elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
            exception_class = UnexpectedAlertPresentException
        elif status in ErrorCode.NO_ALERT_OPEN:
            exception_class = NoAlertPresentException
        elif status in ErrorCode.IME_NOT_AVAILABLE:
            exception_class = ImeNotAvailableException
        elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
            exception_class = ImeActivationFailedException
        elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
            exception_class = MoveTargetOutOfBoundsException
        elif status in ErrorCode.JAVASCRIPT_ERROR:
            exception_class = JavascriptException
        elif status in ErrorCode.SESSION_NOT_CREATED:
            exception_class = SessionNotCreatedException
        elif status in ErrorCode.INVALID_ARGUMENT:
            exception_class = InvalidArgumentException
        elif status in ErrorCode.NO_SUCH_COOKIE:
            exception_class = NoSuchCookieException
        elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN:
            exception_class = ScreenshotException
        elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED:
            exception_class = ElementClickInterceptedException
        elif status in ErrorCode.INSECURE_CERTIFICATE:
            exception_class = InsecureCertificateException
        elif status in ErrorCode.INVALID_COORDINATES:
            exception_class = InvalidCoordinatesException
        elif status in ErrorCode.INVALID_SESSION_ID:
            exception_class = InvalidSessionIdException
        elif status in ErrorCode.UNKNOWN_METHOD:
            exception_class = UnknownMethodException
        else:
            exception_class = WebDriverException
        if not value:
            value = response['value']
        if isinstance(value, str):
            raise exception_class(value)
        if message == "" and 'message' in value:
            message = value['message']
    
        screen = None  # type: ignore[assignment]
        if 'screen' in value:
            screen = value['screen']
    
        stacktrace = None
        st_value = value.get('stackTrace') or value.get('stacktrace')
        if st_value:
            if isinstance(st_value, str):
                stacktrace = st_value.split('\n')
            else:
                stacktrace = []
                try:
                    for frame in st_value:
                        line = self._value_or_default(frame, 'lineNumber', '')
                        file = self._value_or_default(frame, 'fileName', '<anonymous>')
                        if line:
                            file = "%s:%s" % (file, line)
                        meth = self._value_or_default(frame, 'methodName', '<anonymous>')
                        if 'className' in frame:
                            meth = "%s.%s" % (frame['className'], meth)
                        msg = "    at %s (%s)"
                        msg = msg % (meth, file)
                        stacktrace.append(msg)
                except TypeError:
                    pass
        if exception_class == UnexpectedAlertPresentException:
            alert_text = None
            if 'data' in value:
                alert_text = value['data'].get('text')
            elif 'alert' in value:
                alert_text = value['alert'].get('text')
            raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
>       raise exception_class(message, screen, stacktrace)
E       selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found in the current frame
E         (Session info: chrome=147.0.7727.55)
E       Stacktrace:
E       #0 0x55aa1334fb6a <unknown>
E       #1 0x55aa12d51265 <unknown>
E       #2 0x55aa12d58111 <unknown>
E       #3 0x55aa12d5ac5b <unknown>
E       #4 0x55aa12deda99 <unknown>
E       #5 0x55aa12dec969 <unknown>
E       #6 0x55aa12d975cf <unknown>
E       #7 0x55aa12d98391 <unknown>
E       #8 0x55aa1331504b <unknown>
E       #9 0x55aa1331800d <unknown>
E       #10 0x55aa13301808 <unknown>
E       #11 0x55aa13318ba0 <unknown>
E       #12 0x55aa132e8280 <unknown>
E       #13 0x55aa1333cdb8 <unknown>
E       #14 0x55aa1333cf88 <unknown>
E       #15 0x55aa1334e5de <unknown>
E       #16 0x7f694449caa4 <unknown>
E       #17 0x7f6944529c6c <unknown>

/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/selenium/webdriver/remote/errorhandler.py:247: StaleElementReferenceException