Exemple #1
0
def check_input_group_button_callbacks(runner):
    runner.find_element("#input-group-button").click()
    wait.until(
        lambda: runner.find_element("#input-group-button-input").get_attribute(
            "value") != "",
        timeout=4,
    )
Exemple #2
0
def test_dltx001_download_text(dash_dcc):
    text = "Hello, world!"
    filename = "hello.txt"
    # Create app.
    app = dash.Dash(__name__, prevent_initial_callbacks=True)
    app.layout = html.Div(
        [html.Button("Click", id="btn"),
         dcc.Download(id="download")])

    @app.callback(Output("download", "data"), Input("btn", "n_clicks"))
    def download(_):
        return dcc.send_string(text, filename)

    dash_dcc.start_server(app)

    # Check that there is nothing before clicking
    fp = os.path.join(dash_dcc.download_path, filename)
    assert not os.path.isfile(fp)

    dash_dcc.find_element("#btn").click()

    # Check that a file has been download, and that it's content matches the original text.
    until(lambda: os.path.exists(fp), 10)
    with open(fp, "r") as f:
        content = f.read()
    assert content == text
Exemple #3
0
    def start(self, app, **kwargs):
        """Start the app server in threading flavor."""
        app.server.add_url_rule(self.stop_route, self.stop_route,
                                self._stop_server)

        def _handle_error():
            self._stop_server()

        app.server.errorhandler(500)(_handle_error)

        def run():
            app.scripts.config.serve_locally = True
            app.css.config.serve_locally = True
            if "port" not in kwargs:
                kwargs["port"] = self.port
            else:
                self.port = kwargs["port"]
            app.run_server(threaded=True, **kwargs)

        self.thread = threading.Thread(target=run)
        self.thread.daemon = True
        try:
            self.thread.start()
        except RuntimeError:  # multiple call on same thread
            logger.exception("threaded server failed to start")
            self.started = False

        self.started = self.thread.is_alive()

        # wait until server is able to answer http request
        wait.until(lambda: self.accessible(self.url), timeout=1)
Exemple #4
0
    def check_chapter(chapter):
        dash_duo.wait_for_element(
            '#{}-graph:not(.dash-graph--pending)'.format(chapter))

        for key in dash_duo.redux_state_paths:
            assert dash_duo.find_elements(
                "#{}".format(key)), "each element should exist in the dom"

        value = (chapters[chapter][0]["{}-controls".format(chapter)].value
                 if chapter == "chapter3" else
                 chapters[chapter]["{}-controls".format(chapter)].value)

        # check the actual values
        dash_duo.wait_for_text_to_equal("#{}-label".format(chapter), value)

        wait.until(
            lambda: (dash_duo.driver.execute_script(
                "return document."
                'querySelector("#{}-graph:not(.dash-graph--pending) .js-plotly-plot").'
                .format(chapter) + "layout.title.text") == value),
            TIMEOUT,
        )

        rqs = dash_duo.redux_state_rqs
        assert rqs, "request queue is not empty"
        assert all((rq["status"] == 200 and not rq["rejected"] for rq in rqs))
Exemple #5
0
def test_head001_renames_only_row(test, row):
    test.start_server(get_app())

    target = test.table("table")

    title = [
        target.column("rows").get_text(0),
        target.column("rows").get_text(1),
        target.column("rows").get_text(2),
    ]

    target.column("rows").edit(row)

    alert = test.driver.switch_to.alert
    alert.send_keys("modified")
    alert.accept()

    for i in range(3):
        wait.until(
            lambda: target.column("rows").get_text(i) == "modified"
            if row == i
            else title[i],
            3,
        )

    assert test.get_log_errors() == []
Exemple #6
0
    def percy_snapshot(self, name="", wait_for_callbacks=False, convert_canvases=False):
        """percy_snapshot - visual test api shortcut to `percy_runner.snapshot`.
        It also combines the snapshot `name` with the Python version.
        """
        snapshot_name = "{} - py{}.{}".format(
            name, sys.version_info.major, sys.version_info.minor
        )
        logger.info("taking snapshot name => %s", snapshot_name)
        try:
            if wait_for_callbacks:
                # the extra one second sleep adds safe margin in the context
                # of wait_for_callbacks
                time.sleep(1)
                until(self._wait_for_callbacks, timeout=40, poll=0.3)
        except TestingTimeoutError:
            # API will log the error but this TimeoutError should not block
            # the test execution to continue and it will still do a snapshot
            # as diff reference for the build run.
            logger.error(
                "wait_for_callbacks failed => status of invalid rqs %s",
                self.redux_state_rqs,
            )

        if convert_canvases:
            self.driver.execute_script(
                """
                const stash = window._canvasStash = [];
                Array.from(document.querySelectorAll('canvas')).forEach(c => {
                    const i = document.createElement('img');
                    i.src = c.toDataURL();
                    i.width = c.width;
                    i.height = c.height;
                    i.setAttribute('style', c.getAttribute('style'));
                    i.className = c.className;
                    i.setAttribute('data-canvasnum', stash.length);
                    stash.push(c);
                    c.parentElement.insertBefore(i, c);
                    c.parentElement.removeChild(c);
                });
            """
            )

            self.percy_runner.snapshot(name=snapshot_name)

            self.driver.execute_script(
                """
                const stash = window._canvasStash;
                Array.from(
                    document.querySelectorAll('img[data-canvasnum]')
                ).forEach(i => {
                    const c = stash[+i.getAttribute('data-canvasnum')];
                    i.parentElement.insertBefore(c, i);
                    i.parentElement.removeChild(i);
                });
                delete window._canvasStash;
            """
            )

        else:
            self.percy_runner.snapshot(name=snapshot_name)
def check_spinner_callbacks(runner):
    runner.find_element("#loading-button").click()
    wait.until(
        lambda: runner.find_element("#loading-output").text ==
        "Output loaded 1 times",
        timeout=4,
    )
Exemple #8
0
def test_snap001_index_page_links(dash_doc, index_pages):
    dash_doc.wait_for_element(".toc .toc--chapter-content")
    dash_doc.percy_snapshot("index - 1")
    bad_links = []
    timeout_pages = []

    good_links = ['/', '/search']

    for resource in index_pages:
        if resource.startswith('/'):
            hook_id = "wait-for-page-{}".format(resource)
            res = resource.lstrip("/")
            try:
                dash_doc.driver.get("{}/{}".format(
                    dash_doc.server_url.rstrip("/"), res))
                dash_doc.wait_for_element_by_id(hook_id)

                if res in ['basic-callbacks', 'datatable/callbacks']:
                    # these two pages have an intermittent problem with their
                    # resource queues not clearing properly. While we sort this out,
                    # just wait a reasonably long time on these pages.
                    sleep(3)
                else:
                    # everything else we can just wait for all callbacks to finish
                    sleep(1)
                    until(dash_doc._wait_for_callbacks, timeout=40, poll=0.3)

                # hide non-repeatable elements before the snapshot
                selectors_to_hide = ",".join([
                    "#my-dashbio-molecule2d", "#molecule2d-selectedatomids",
                    "#molecule2d-modeldata", ".forna-container",
                    "#first_output_3", "#second_output_3", "#third_output_3"
                ])
                dash_doc.driver.execute_script(
                    "document.querySelectorAll('" + selectors_to_hide +
                    "').forEach(el=>el.style.visibility = 'hidden');")
                dash_doc.percy_snapshot(res, wait_for_callbacks=False)
            except Exception as e:
                timeout_pages.append('{} --- on page {}'.format(
                    str(e), resource))

            linked_paths = dash_doc.driver.execute_script(
                'return Array.from(document.querySelectorAll(\'a[href^="/"]\'))'
                '.map(a=>a.attributes.href.value)')
            for link in linked_paths:
                if (link.rstrip('/') not in URL_TO_CONTENT_MAP
                        and link not in good_links and '.mp4' not in link
                    ):  # we link to a video on the devtools page
                    msg = '{} --- on page {}'.format(link, resource)
                    logger.info(msg)
                    bad_links.append(msg)

            try:
                dash_doc.driver.execute_script("window.history.go(-1)")
            except Exception as e:
                raise Exception([
                    Exception(['Error going back while on page ', resource]), e
                ])

    assert (bad_links + timeout_pages) == []
Exemple #9
0
def test_cbsc016_extra_components_callback(dash_duo):
    lock = Lock()

    app = Dash(__name__)
    app._extra_components.append(dcc.Store(id="extra-store", data=123))

    app.layout = html.Div([
        dcc.Input(id="input", value="initial value"),
        html.Div(html.Div([1.5, None, "string",
                           html.Div(id="output-1")])),
    ])
    store_data = Value("i", 0)

    @app.callback(
        Output("output-1", "children"),
        [Input("input", "value"),
         Input("extra-store", "data")],
    )
    def update_output(value, data):
        with lock:
            store_data.value = data
            return value

    dash_duo.start_server(app)

    assert dash_duo.find_element("#output-1").text == "initial value"

    input_ = dash_duo.find_element("#input")
    dash_duo.clear_input(input_)
    input_.send_keys("A")

    wait.until(lambda: dash_duo.find_element("#output-1").text == "A", 2)

    assert store_data.value == 123
    assert dash_duo.get_logs() == []
Exemple #10
0
    def check_chapter(chapter):
        dash_duo.wait_for_element("#{}-graph:not(.dash-graph--pending)".format(chapter))

        for key in dash_duo.redux_state_paths["strs"]:
            assert dash_duo.find_elements(
                "#{}".format(key)
            ), "each element should exist in the dom"

        value = (
            chapters[chapter][0]["{}-controls".format(chapter)].value
            if chapter == "chapter3"
            else chapters[chapter]["{}-controls".format(chapter)].value
        )

        # check the actual values
        dash_duo.wait_for_text_to_equal("#{}-label".format(chapter), value)

        wait.until(
            lambda: (
                dash_duo.driver.execute_script(
                    'return document.querySelector("'
                    + "#{}-graph:not(.dash-graph--pending) .js-plotly-plot".format(
                        chapter
                    )
                    + '").layout.title.text'
                )
                == value
            ),
            TIMEOUT,
        )

        assert dash_duo.redux_state_rqs == [], "pendingCallbacks is empty"
Exemple #11
0
    def percy_snapshot(self, name="", wait_for_callbacks=False):
        """percy_snapshot - visual test api shortcut to `percy_runner.snapshot`.
        It also combines the snapshot `name` with the python version.
        """
        snapshot_name = "{} - py{}.{}".format(name, sys.version_info.major,
                                              sys.version_info.minor)
        logger.info("taking snapshot name => %s", snapshot_name)
        try:
            if wait_for_callbacks:
                # the extra one second sleep adds safe margin in the context
                # of wait_for_callbacks
                time.sleep(1)
                until(self._wait_for_callbacks, timeout=40, poll=0.3)
        except TestingTimeoutError:
            # API will log the error but this TimeoutError should not block
            # the test execution to continue and it will still do a snapshot
            # as diff reference for the build run.
            logger.error(
                "wait_for_callbacks failed => status of invalid rqs %s",
                list(_ for _ in self.redux_state_rqs
                     if not _.get("responseTime")),
            )
            logger.debug("full content of the rqs => %s", self.redux_state_rqs)

        self.percy_runner.snapshot(name=snapshot_name)
Exemple #12
0
def check_nav_callbacks(runner):
    runner.find_element("#button-link").click()
    wait.until(
        lambda: runner.find_element("#button-clicks").text ==
        "Button clicked 1 times",
        timeout=4,
    )
def _click_radio(runner, radio_id, option):
    label_id = f"_dbcprivate_radioitems_{radio_id}_input_{option}"
    wait.until(
        lambda: len(runner.find_elements(f"#{label_id}")) != 0,
        timeout=8,
    )
    runner.driver.find_element_by_id(label_id).click()
def check_button_callbacks(runner):
    runner.find_element("#example-button").click()
    wait.until(
        lambda: runner.find_element("#example-output").text ==
        "Clicked 1 times.",
        timeout=4,
    )
Exemple #15
0
def test_dlfi001_download_file(dash_dcc):
    filename = "chuck.jpg"
    asset_folder = os.path.join(os.path.dirname(__file__), "download-assets")
    # Create app.
    app = Dash(__name__, prevent_initial_callbacks=True)
    app.layout = html.Div(
        [html.Button("Click", id="btn"),
         dcc.Download(id="download")])

    @app.callback(Output("download", "data"), Input("btn", "n_clicks"))
    def download(_):
        return dcc.send_file(os.path.join(asset_folder, filename))

    dash_dcc.start_server(app)

    # Check that there is nothing before clicking
    fp = os.path.join(dash_dcc.download_path, filename)
    assert not os.path.isfile(fp)

    dash_dcc.find_element("#btn").click()

    # Check that a file has been download, and that it's content matches the original.
    until(lambda: os.path.exists(fp), 10)
    with open(fp, "rb") as f:
        content = f.read()
    with open(os.path.join(asset_folder, filename), "rb") as f:
        original = f.read()
    assert content == original

    assert dash_dcc.get_logs() == []
def check_list_group_callbacks(runner):
    runner.find_element("#button-item").click()
    wait.until(
        lambda: runner.find_element("#counter").text ==
        "Button clicked 1 times",
        timeout=4,
    )
Exemple #17
0
def test_head002_preserves_hidden_columns_on_rename(test):
    test.start_server(get_app(dict(merge_duplicate_headers=True)))

    target = test.table("table")

    wait.until(lambda: target.column(6).get().get_attribute("colspan") == "4", 3)
    assert target.column(6).get_text() == ""

    target.column(8).hide(2)
    target.column(6).hide(2)
    target.column(1).hide(2)

    target.column(5).edit()

    alert = test.driver.switch_to.alert
    alert.send_keys("Chill")
    alert.accept()

    target.toggle_columns().open()
    for el in target.toggle_columns().get_hidden():
        el.click()

    target.toggle_columns().close()

    wait.until(lambda: target.column(6).get().get_attribute("colspan") == "4", 3)

    assert target.column(6).get_text() == "Chill"
    assert test.get_log_errors() == []
Exemple #18
0
def check_tabs_active_tab_callbacks(runner):
    # Get julia to wait until it's loaded
    wait.until(lambda: len(runner.find_elements(".card")) > 0, timeout=4)

    # Default view on landing
    wait.until(
        lambda: runner.find_element("div.card-body > p.card-text").text ==
        "This is tab 1!",
        timeout=4,
    )
    wait.until(
        lambda: runner.find_element("div.card-body > button.btn-success").text
        == "Click here",
        timeout=4,
    )

    # Activate the second tab
    runner.find_elements("a.nav-link")[1].click()

    wait.until(
        lambda: runner.find_element("div.card-body > p.card-text").text ==
        "This is tab 2!",
        timeout=4,
    )
    wait.until(
        lambda: runner.find_element("div.card-body > button.btn-danger").text
        == "Don't click here",
        timeout=4,
    )
def test_dbpo003_popover_legacy(dash_duo):
    app = Dash(external_stylesheets=[themes.BOOTSTRAP])

    app.layout = html.Div(
        [
            html.Div("No Target Here", id="not-a-target"),
            html.Hr(),
            Popover(
                [PopoverHeader("Test Header"),
                 PopoverBody("Test content")],
                id="popover",
                target="popover-target",
                trigger="legacy",
            ),
            html.Div("Target", id="popover-target"),
        ],
        className="container p-5 w-50",
    )

    dash_duo.start_server(app)

    dash_duo.wait_for_element_by_id("popover-target").click()
    dash_duo.wait_for_text_to_equal(".popover-body", "Test content", timeout=4)

    # Try clicking on the popover - shouldn't dismiss
    dash_duo.wait_for_element_by_id("popover").click()
    dash_duo.wait_for_text_to_equal(".popover-body", "Test content", timeout=4)

    # Try clicking outside the popover - should dismiss
    dash_duo.wait_for_element_by_id("not-a-target").click()
    wait.until(
        lambda: len(dash_duo.find_elements("#popover")) == 0,
        timeout=4,
    )
Exemple #20
0
def test_scrol001_fixed_alignment(test, fixed_rows, fixed_columns, ops):
    props = {**base_props, **fixed_rows, **fixed_columns, **ops}

    app = dash.Dash(__name__)
    app.layout = DataTable(**props)

    test.start_server(app)

    target = test.table("table")
    assert target.is_ready()

    fixed_width = test.driver.execute_script(
        "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;"
    )

    assert -get_margin(test) == pytest.approx(fixed_width, abs=1)

    scroll_by(test, 200)

    wait.until(
        lambda: -get_margin(test) == pytest.approx(fixed_width + 200, abs=1),
        3)

    scroll_by(test, -200)

    wait.until(lambda: -get_margin(test) == pytest.approx(fixed_width, abs=1),
               3)
    assert test.get_log_errors() == []
def check_popover_callbacks(runner):
    assert len(runner.find_elements("#popover")) == 0
    runner.find_element("#toggle").click()
    wait.until(
        lambda: len(runner.find_elements("#popover")) > 0,
        timeout=4,
    )
Exemple #22
0
def test_cdpr002_updatemodes(dash_dcc):
    app = dash.Dash(__name__)

    app.layout = html.Div([
        dcc.DatePickerRange(
            id="date-picker-range",
            start_date_id="startDate",
            end_date_id="endDate",
            start_date_placeholder_text="Select a start date!",
            end_date_placeholder_text="Select an end date!",
            updatemode="bothdates",
        ),
        html.Div(id="date-picker-range-output"),
    ])

    @app.callback(
        Output("date-picker-range-output", "children"),
        [
            Input("date-picker-range", "start_date"),
            Input("date-picker-range", "end_date"),
        ],
    )
    def update_output(start_date, end_date):
        return "{} - {}".format(start_date, end_date)

    dash_dcc.start_server(app=app)

    start_date = dash_dcc.find_element("#startDate")
    start_date.click()

    end_date = dash_dcc.find_element("#endDate")
    end_date.click()

    assert (
        dash_dcc.find_element(
            "#date-picker-range-output").text == "None - None"
    ), "the output should not update when both clicked but no selection happen"

    start_date.click()

    dash_dcc.find_elements(dash_dcc.date_picker_day_locator)[4].click()
    assert (dash_dcc.find_element(
        "#date-picker-range-output").text == "None - None"
            ), "the output should not update when only one is selected"

    eday = dash_dcc.find_elements(dash_dcc.date_picker_day_locator)[-4]
    wait.until(lambda: eday.is_displayed() and eday.is_enabled(), timeout=2)
    eday.click()

    date_tokens = set(start_date.get_attribute("value").split("/"))
    date_tokens.update(end_date.get_attribute("value").split("/"))

    assert (set(
        itertools.chain(*[
            _.split("-") for _ in dash_dcc.find_element(
                "#date-picker-range-output").text.split(" - ")
        ])) == date_tokens), "date should match the callback output"
Exemple #23
0
def test_grbs002_wrapped_graph_has_no_infinite_loop(dash_dcc, is_eager):

    df = pd.DataFrame(np.random.randn(50, 50))
    figure = {
        "data": [
            {"x": df.columns, "y": df.index, "z": df.values, "type": "heatmap"}
        ],
        "layout": {"xaxis": {"scaleanchor": "y"}},
    }

    app = dash.Dash(__name__, eager_loading=is_eager)
    app.layout = html.Div(
        style={
            "backgroundColor": "red",
            "height": "100vmin",
            "width": "100vmin",
            "overflow": "hidden",
            "position": "relative",
        },
        children=[
            dcc.Loading(
                children=[
                    dcc.Graph(
                        id="graph",
                        figure=figure,
                        style={
                            "position": "absolute",
                            "top": 0,
                            "left": 0,
                            "backgroundColor": "blue",
                            "width": "100%",
                            "height": "100%",
                            "overflow": "hidden",
                        },
                    )
                ]
            )
        ],
    )
    call_count = Value("i", 0)

    @app.callback(Output("graph", "figure"), [Input("graph", "relayoutData")])
    def selected_df_figure(selection):
        call_count.value += 1
        figure["data"][0]["x"] = df.columns
        figure["data"][0]["y"] = df.index
        figure["data"][0]["z"] = df.values
        return figure

    dash_dcc.start_server(app)

    wait.until(lambda: dash_dcc.driver.title == "Dash", timeout=2)
    sleep(1)
    # TODO: not sure 2 calls actually makes sense here, shouldn't it be 1?
    # but that's what we had as of the 608 fix, PR 621, so let's lock that
    # in for now.
    assert call_count.value == 2
Exemple #24
0
def test_inin003_aborted_callback(dash_duo):
    """Raising PreventUpdate OR returning no_update prevents update and
    triggering dependencies."""

    initial_input = "initial input"
    initial_output = "initial output"

    app = Dash(__name__)
    app.layout = html.Div(
        [
            dcc.Input(id="input", value=initial_input),
            html.Div(initial_output, id="output1"),
            html.Div(initial_output, id="output2"),
        ]
    )

    callback1_count = Value("i", 0)
    callback2_count = Value("i", 0)

    @app.callback(Output("output1", "children"), [Input("input", "value")])
    def callback1(value):
        callback1_count.value += 1
        if callback1_count.value > 2:
            return no_update
        raise PreventUpdate("testing callback does not update")
        return value

    @app.callback(
        Output("output2", "children"), [Input("output1", "children")]
    )
    def callback2(value):
        callback2_count.value += 1
        return value

    dash_duo.start_server(app)

    input_ = dash_duo.find_element("#input")
    input_.send_keys("xyz")
    dash_duo.wait_for_text_to_equal("#input", "initial inputxyz")

    until(
        lambda: callback1_count.value == 4,
        timeout=3,
        msg="callback1 runs 4x (initial page load and 3x through send_keys)",
    )

    assert (
        callback2_count.value == 0
    ), "callback2 is never triggered, even on initial load"

    # double check that output1 and output2 children were not updated
    assert dash_duo.find_element("#output1").text == initial_output
    assert dash_duo.find_element("#output2").text == initial_output

    assert not dash_duo.get_logs()

    dash_duo.percy_snapshot(name="aborted")
Exemple #25
0
def test_scrol001_fixed_alignment(test, fixed_rows, fixed_columns, ops):
    base_props = dict(
        id="table",
        columns=[{
            "name": i,
            "id": i
        } for i in df.columns],
        row_selectable="single",
        row_deletable=True,
        data=df.to_dict("records"),
        fixed_rows={
            "headers": True,
            "data": 1
        },
        style_cell=dict(width=150),
        style_table=dict(width=500),
    )

    props = {**base_props, **fixed_rows, **fixed_columns, **ops}

    app = dash.Dash(__name__)
    app.layout = DataTable(**props)

    test.start_server(app)

    target = test.table("table")
    assert target.is_ready()

    fixed_width = test.driver.execute_script(
        "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;"
    )
    margin_left = test.driver.execute_script(
        "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);"
    )

    assert -margin_left == fixed_width

    test.driver.execute_script(
        "document.querySelector('#table .row-1').scrollBy(200, 0);")

    wait.until(
        lambda: -test.driver.execute_script(
            "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);"
        ) == fixed_width + 200,
        3,
    )

    test.driver.execute_script(
        "document.querySelector('#table .row-1').scrollBy(-200, 0);")

    wait.until(
        lambda: -test.driver.execute_script(
            "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);"
        ) == fixed_width,
        3,
    )
Exemple #26
0
 def wait_for_no_elements(self, selector, timeout=None):
     """Explicit wait until an element is NOT found. timeout defaults to
     the fixture's `wait_timeout`."""
     until(
         # if we use get_elements it waits a long time to see if they appear
         # so this one calls out directly to execute_script
         lambda: self.driver.execute_script(
             f"return document.querySelectorAll('{selector}').length") == 0,
         timeout or self._wait_timeout,
     )
def check_dropdown_callbacks(runner):
    runner.find_element(".btn").click()

    runner.find_element("#dropdown-button").click()

    wait.until(
        lambda: runner.find_element("#item-clicks").text ==
        "Button clicked 1 times.",
        timeout=4,
    )
Exemple #28
0
 def percy_snapshot(self, name="", wait_for_callbacks=False):
     """percy_snapshot - visual test api shortcut to `percy_runner.snapshot`.
     It also combines the snapshot `name` with the python version.
     """
     snapshot_name = "{} - py{}.{}".format(name, sys.version_info.major,
                                           sys.version_info.minor)
     logger.info("taking snapshot name => %s", snapshot_name)
     if wait_for_callbacks:
         until(self._wait_for_callbacks, timeout=10)
     self.percy_runner.snapshot(name=snapshot_name)
Exemple #29
0
def check_toast_auto_callbacks(runner):
    wait.until(
        lambda: len(runner.find_elements("#auto-toast")) == 0,
        timeout=5,
    )

    runner.find_element("#auto-toast-toggle").click()
    wait.until(
        lambda: len(runner.find_elements("#auto-toast")) > 0,
        timeout=4,
    )
Exemple #30
0
def check_tabs_card_callbacks(runner):
    tab_links = runner.find_elements("#card-tabs > div.nav-item > a.nav-link")
    wait.until(lambda: tab_links[1].text == "Tab 2", timeout=4)

    tab_links[1].click()

    wait.until(
        lambda: runner.find_element("#card-content").text ==
        "This is tab tab-2",
        timeout=4,
    )