plotly / plotly/dash

dash_duo does not work with All-in-One components

Open
#1,933 17 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3 size: 3
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

dash                      2.1.0
dash-bootstrap-components 1.0.3
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0
pytest                    7.0.1

Describe the bug

It seems that dash testing utils don't work property with All-in-One components. For instance, given the following test scenario:

import uuid
from typing import Optional

import dash
from dash import MATCH, Input, Output, callback, html


class SomeButton(html.Button):
    class ids:
        button = lambda aio_id: {"component": "SomeButton", "aio_id": aio_id}

    def __init__(self, aio_id: Optional[str] = None):
        if aio_id is None:
            aio_id = str(uuid.uuid4())

        super().__init__(
            "Loading...",
            id=self.ids.button(aio_id),
            disabled=True,
        )

    @callback(
        Input(ids.button(MATCH), "children"),
        output=dict(
            label=Output(ids.button(MATCH), "children"),
            disabled=Output(ids.button(MATCH), "disabled"),
        ),
    )
    def update_button(_):
        return dict(label="Loaded", disabled=False)


def test_some_button_first_time(dash_duo: dash.testing.composite.DashComposite):
    app = dash.Dash("foo123")
    app.layout = html.Div(SomeButton(), id="wrapper")

    dash_duo.start_server(app)
    dash_duo.wait_for_contains_text("#wrapper", "Loaded")


def test_some_button_second_time(dash_duo: dash.testing.composite.DashComposite):
    app = dash.Dash("bar123")
    app.layout = html.Div(SomeButton(), id="wrapper")

    dash_duo.start_server(app)
    dash_duo.wait_for_contains_text("#wrapper", "Loaded")

The first run test_some_button_first_time is perfectly fine. But test_some_button_second_time results with selenium.common.exceptions.TimeoutException: Message: text -> Loaded not found inside element within 10s error.
I ran it with --pause option and in the DevTools I noticed that for the second test the update callback _dash-update-component is not being triggered (see the attached screenshots).

Moreover, if I run test_some_button_second_time separately or if I comment out the first test everything is fine.
For some reason callbacks are fired only for the first test.

Expected behavior

It seems that dash_duo does not work with @callback for all-in-one components.

Screenshots

CleanShot 2022-02-17 at 17 25 05

CleanShot 2022-02-17 at 17 26 26

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the two test functions shown, using dash_duo and SomeButton, and compare the first and second runs in the browser. Trace the dash.testing composite behavior around @callback and the _dash-update-component request. Done means both tests pass together and the second test triggers its update callback without requiring isolation.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
frontend, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.