|
| 1 | +import pytest |
| 2 | +from dash import Dash, Input, Output, dcc, html |
| 3 | +from humanfriendly import parse_size |
| 4 | + |
| 5 | +test_cases = [ |
| 6 | + {"step": 2, "min": 0, "max": 10, "value": 6}, |
| 7 | + {"step": 3, "min": 0, "max": 100, "value": 33}, |
| 8 | + {"step": 0.05, "min": 0, "max": 1, "value": 0.5}, |
| 9 | + {"step": 1_000_000, "min": 1e9, "max": 1e10, "value": 1e10}, |
| 10 | +] |
| 11 | + |
| 12 | + |
| 13 | +def slider_value_divisible_by_step(slider_args, slider_value) -> bool: |
| 14 | + if type(slider_value) is str: |
| 15 | + slider_value = float(slider_value.split()[-1]) |
| 16 | + |
| 17 | + if slider_value == slider_args["min"] or slider_value == slider_args["max"]: |
| 18 | + return True |
| 19 | + |
| 20 | + step = slider_args["step"] |
| 21 | + remainder = slider_value % step |
| 22 | + |
| 23 | + # For float equality, we check if the remainder is close to 0 or close to step |
| 24 | + return remainder < 1e-10 or abs(remainder - step) < 1e-10 |
| 25 | + |
| 26 | + |
| 27 | +@pytest.mark.parametrize("test_case", test_cases) |
| 28 | +def test_slst001_step_params(dash_dcc, test_case): |
| 29 | + |
| 30 | + app = Dash(__name__) |
| 31 | + app.layout = html.Div( |
| 32 | + [ |
| 33 | + dcc.Slider(id="slider", **test_case), |
| 34 | + html.Div(id="out"), |
| 35 | + ] |
| 36 | + ) |
| 37 | + |
| 38 | + @app.callback(Output("out", "children"), [Input("slider", "value")]) |
| 39 | + def update_output(value): |
| 40 | + return f"{value}" |
| 41 | + |
| 42 | + dash_dcc.start_server(app) |
| 43 | + dash_dcc.driver.set_window_size(800, 600) |
| 44 | + |
| 45 | + slider = dash_dcc.find_element("#slider") |
| 46 | + marks = dash_dcc.find_elements(".dash-slider-mark") |
| 47 | + |
| 48 | + # Expect to find some amount of marks in between the first and last mark |
| 49 | + assert len(marks) > 2 |
| 50 | + |
| 51 | + # Every mark must be divisible by the given `step`. |
| 52 | + for mark in marks: |
| 53 | + value = parse_size(mark.text) |
| 54 | + assert slider_value_divisible_by_step(test_case, value) |
| 55 | + |
| 56 | + # Perform multiple clicks along the slider track. After every click, the |
| 57 | + # resulting slider value must be divisible by the step |
| 58 | + i = 0 |
| 59 | + while i < 1: |
| 60 | + dash_dcc.click_at_coord_fractions(slider, i, 0.25) |
| 61 | + value = dash_dcc.find_element("#out").text |
| 62 | + assert slider_value_divisible_by_step(test_case, value) |
| 63 | + i += 0.05 |
| 64 | + |
| 65 | + assert dash_dcc.get_logs() == [] |
0 commit comments