plotly / dash-ag-grid

Dash AG Grid is a high-performance and highly customizable component that wraps AG Grid, designed for creating rich datagrids.
https://dash.plotly.com/dash-ag-grid
MIT License
177 stars 28 forks source link

test_cd001_cell_data_types_override is failing with timeout #317

Open gvwilson opened 4 months ago

gvwilson commented 4 months ago

pytest reports failure in

tests/test_cell_data_type_override.py:8 test_cd001_cell_data_types_override

message is

selenium.common.exceptions.TimeoutException: Message: text -> 17/01/2024 not found within 10s, found: 04/02/11720

at commit 7ecc77637c, using ChromeDriver 127.0.6533.72

BSd3v commented 1 month ago

@gvwilson,

Can you pull main and try again?

gvwilson commented 1 month ago

Sync'd with commit 1933810082

Actions:

$ uv venv                                        # I use uv for virtual environments these days
$ activate
$ uv pip install 'dash[dev,testing]'
$ npm i
$ npm run build
$ uv pip install -e .
$ pytest                                         # failed because of missing dependencies
$ uv pip install -e ".[dev, docs]"               # so do it right
$ pytest                                         # one test failed
$ pytest -k test_cd001_cell_data_types_override  # re-run the one failing test

Output:

============================= test session starts ==============================
platform darwin -- Python 3.11.9, pytest-8.0.2, pluggy-1.5.0 -- /Users/gvwilson/plotly/dash-ag-grid/.venv/bin/python3
cachedir: .pytest_cache
rootdir: /Users/gvwilson/plotly/dash-ag-grid
configfile: pytest.ini
testpaths: tests/
plugins: dash-2.18.1, flaky-3.8.1, anyio-4.6.0, rerunfailures-14.0, sugar-0.9.6, mock-3.14.0
collecting ... collected 58 items / 57 deselected / 1 selected

tests/test_cell_data_type_override.py::test_cd001_cell_data_types_override FAILED [100%]

=================================== FAILURES ===================================
_____________________ test_cd001_cell_data_types_override ______________________

self = <dash.testing.composite.DashComposite object at 0x11d898410>
method = <dash.testing.wait.text_to_equal object at 0x11bf9ce50>, timeout = None
msg = <bound method text_to_equal.message of <dash.testing.wait.text_to_equal object at 0x11bf9ce50>>

    def _wait_for(self, method, timeout, msg):
        """Abstract generic pattern for explicit WebDriverWait."""
        try:
            _wait = (
                self._wd_wait
                if timeout is None
                else WebDriverWait(self.driver, timeout)
            )
            logger.debug(
                "method, timeout, poll => %s %s %s",
                method,
                _wait._timeout,  # pylint: disable=protected-access
                _wait._poll,  # pylint: disable=protected-access
            )

>           return _wait.until(method)

.venv/lib/python3.11/site-packages/dash/testing/browser.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.support.wait.WebDriverWait (session="3b06311608ba8637a509ee4cfc35ae0a")>
method = <dash.testing.wait.text_to_equal object at 0x11bf9ce50>, message = ''

    def until(self, method, message=''):
        """Calls the method provided with the driver as an argument until the \
        return value does not evaluate to ``False``.

        :param method: callable(WebDriver)
        :param message: optional message for :exc:`TimeoutException`
        :returns: the result of the last call to `method`
        :raises: :exc:`selenium.common.exceptions.TimeoutException` if timeout occurs
        """
        screen = None
        stacktrace = None

        end_time = time.monotonic() + self._timeout
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            time.sleep(self._poll)
            if time.monotonic() > end_time:
                break
>       raise TimeoutException(message, screen, stacktrace)
E       selenium.common.exceptions.TimeoutException: Message:

.venv/lib/python3.11/site-packages/selenium/webdriver/support/wait.py:87: TimeoutException

The above exception was the direct cause of the following exception:

dash_duo = <dash.testing.composite.DashComposite object at 0x11d898410>

    def test_cd001_cell_data_types_override(dash_duo):
        app = Dash(__name__)

        rowData = [
            {"weight": 0.074657, "date": "01/01/2024"},
            {"weight": 0.06948567, "date": "02/01/2024"},
            {"weight": 0.02730574, "date": "03/01/2024"},
            {"weight": 0.0182345, "date": "04/01/2024"},
        ]

        columnDefs = [
            {"field": "weight", "cellDataType": "percentage"},
            {"field": "date", "cellDataType": "dateString"},
        ]

        # Only for second grid
        dataTypeDefinitions = {
            "percentage": {
                "baseDataType": "number",
                "extendsDataType": "number",
                "valueFormatter": {
                    "function": "params.value == null ? '' :  d3.format(',.1%')(params.value)"
                },
            },
            "dateString": {
                "baseDataType": 'dateString',
                "extendsDataType": 'dateString',
                "valueParser": {
                    "function": r"params.newValue != null && !!params.newValue.match(/\d{2}\/\d{2}\/\d{4}/) ? params.newValue : null"
                },
                "valueFormatter": {"function": "params.value == null ? '' : params.value"},
                "dataTypeMatcher": {"function": r"params != null && !!params.match(/\d{2}\/\d{2}\/\d{4}/)"},
                "dateParser": {"function": "dateParser(params)"},
                "dateFormatter": {"function": "dateFormatter(params)"},
            },
        }
        app.layout = html.Div(
            [
                dag.AgGrid(
                    id="grid-cell-data-types-override-full-JS",
                    columnDefs=columnDefs,
                    rowData=rowData,
                    defaultColDef={"filter": True, "editable": True},
                    dashGridOptions={"dataTypeDefinitions": {"function": "dataTypeDefinitions"}},
                ),
                dag.AgGrid(
                    id="grid-cell-data-types-override",
                    columnDefs=columnDefs,
                    rowData=rowData,
                    defaultColDef={"filter": True, "editable": True},
                    dashGridOptions={"dataTypeDefinitions": dataTypeDefinitions},
                ),
            ],
        )

        dash_duo.start_server(app)

        action = utils.ActionChains(dash_duo.driver)

        # same tests for both grids
        for id in ["grid-cell-data-types-override-full-JS", "grid-cell-data-types-override"]:
            grid = utils.Grid(dash_duo, id)

            # test overriden number cell data type
            action.double_click(grid.get_cell(0, 0)).perform()
            date_input_element = dash_duo.find_element(f'#{grid.id} .ag-number-field-input')
            date_input_element.send_keys("0.1" + Keys.ENTER)

            grid.wait_for_cell_text(0, 0, "10.0%")

            # test overriden dateString cell data type
            action.double_click(grid.get_cell(0, 1)).perform()
            date_input_element = dash_duo.find_element(f'#{grid.id} .ag-date-field-input')
            date_input_element.send_keys("01172024" + Keys.ENTER)

>           grid.wait_for_cell_text(0, 1, "17/01/2024")

tests/test_cell_data_type_override.py:82: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/utils.py:145: in wait_for_cell_text
    self.dash_duo.wait_for_text_to_equal(
.venv/lib/python3.11/site-packages/dash/testing/browser.py:359: in wait_for_text_to_equal
    return self._wait_for(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dash.testing.composite.DashComposite object at 0x11d898410>
method = <dash.testing.wait.text_to_equal object at 0x11bf9ce50>, timeout = None
msg = <bound method text_to_equal.message of <dash.testing.wait.text_to_equal object at 0x11bf9ce50>>

    def _wait_for(self, method, timeout, msg):
        """Abstract generic pattern for explicit WebDriverWait."""
        try:
            _wait = (
                self._wd_wait
                if timeout is None
                else WebDriverWait(self.driver, timeout)
            )
            logger.debug(
                "method, timeout, poll => %s %s %s",
                method,
                _wait._timeout,  # pylint: disable=protected-access
                _wait._poll,  # pylint: disable=protected-access
            )

            return _wait.until(method)
        except Exception as err:
            if callable(msg):
                message = msg(self.driver)
            else:
                message = msg
>           raise TimeoutException(message) from err
E           selenium.common.exceptions.TimeoutException: Message: text -> 17/01/2024 not found within 10s, found: 04/02/11720

.venv/lib/python3.11/site-packages/dash/testing/browser.py:286: TimeoutException
----------------------------- Captured stdout call -----------------------------
Dash is running on http://127.0.0.1:58050/

 * Serving Flask app 'tests.test_cell_data_type_override'
 * Debug mode: off
------------------------------ Captured log call -------------------------------
08:23:20 | INFO | dash.dash:2160 | Dash is running on http://127.0.0.1:58050/

08:23:20 | INFO | werkzeug:97 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:58050
08:23:20 | INFO | werkzeug:97 | Press CTRL+C to quit
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET / HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET / HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/deps/polyfill@7.v2_18_1m1728389663.12.1.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/deps/react@16.v2_18_1m1728389663.14.0.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/deps/prop-types@15.v2_18_1m1728389663.8.1.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/deps/react-dom@16.v2_18_1m1728389663.14.0.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash_ag_grid/dash_ag_grid.v31_3_0m1728389677.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash_mantine_components/dash_mantine_components.v0_12_1m1728389803.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /assets/dashAgGridFunctions.js?m=1728389590.3449574 HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /assets/dashAgGridComponentFunctions.js?m=1715094547.03432 HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_18_1m1728389662.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/dcc/dash_core_components.v2_14_2m1728389663.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/dcc/dash_core_components-shared.v2_14_2m1728389663.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/dash_table/bundle.v5_2_12m1728389662.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash/html/dash_html_components.v2_0_19m1728389663.min.js HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-layout HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-dependencies HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_favicon.ico?v=2.18.1 HTTP/1.1" 200 -
08:23:20 | INFO | werkzeug:97 | 127.0.0.1 - - [08/Oct/2024 08:23:20] "GET /_dash-component-suites/dash_ag_grid/async-community.js HTTP/1.1" 200 -
=============================== warnings summary ===============================
tests/test_cell_data_type_override.py: 101 warnings
  /Users/gvwilson/plotly/dash-ag-grid/.venv/lib/python3.11/site-packages/selenium/webdriver/remote/remote_connection.py:390: DeprecationWarning:

  HTTPResponse.getheader() is deprecated and will be removed in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).

tests/test_cell_data_type_override.py: 101 warnings
  /Users/gvwilson/plotly/dash-ag-grid/.venv/lib/python3.11/site-packages/selenium/webdriver/remote/remote_connection.py:391: DeprecationWarning:

  HTTPResponse.getheader() is deprecated and will be removed in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=============== 1 failed, 57 deselected, 202 warnings in 13.46s ================