Skip to content

Commit a225922

Browse files
committed
add chained loading states test and format
1 parent 32939ef commit a225922

File tree

1 file changed

+113
-12
lines changed

1 file changed

+113
-12
lines changed

tests/integration/renderer/test_loading_states.py

Lines changed: 113 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ def test_rdls001_multi_loading_components(dash_duo):
1515
app.layout = html.Div(
1616
children=[
1717
html.H3("Edit text input to see loading state"),
18-
dcc.Input(id="input-3", value='Input triggers the loading states'),
19-
dcc.Loading(className="loading-1", children=[
20-
html.Div(id="loading-output-1")
21-
], type="default"),
18+
dcc.Input(id="input-3", value="Input triggers the loading states"),
19+
dcc.Loading(
20+
className="loading-1",
21+
children=[html.Div(id="loading-output-1")],
22+
type="default",
23+
),
2224
html.Div(
2325
[
2426
dcc.Loading(
@@ -28,9 +30,9 @@ def test_rdls001_multi_loading_components(dash_duo):
2830
),
2931
dcc.Loading(
3032
className="loading-3",
31-
children=dcc.Graph(id='graph'),
33+
children=dcc.Graph(id="graph"),
3234
type="cube",
33-
)
35+
),
3436
]
3537
),
3638
],
@@ -42,18 +44,19 @@ def test_rdls001_multi_loading_components(dash_duo):
4244
Output("loading-output-1", "children"),
4345
Output("loading-output-2", "children"),
4446
],
45-
[Input("input-3", "value")])
47+
[Input("input-3", "value")],
48+
)
4649
def input_triggers_nested(value):
4750
with lock:
4851
return dict(data=[dict(y=[1, 4, 2, 3])]), value, value
4952

5053
def wait_for_all_spinners():
51-
dash_duo.find_element('.loading-1 .dash-spinner.dash-default-spinner')
52-
dash_duo.find_element('.loading-2 .dash-spinner.dash-sk-circle')
53-
dash_duo.find_element('.loading-3 .dash-spinner.dash-cube-container')
54+
dash_duo.find_element(".loading-1 .dash-spinner.dash-default-spinner")
55+
dash_duo.find_element(".loading-2 .dash-spinner.dash-sk-circle")
56+
dash_duo.find_element(".loading-3 .dash-spinner.dash-cube-container")
5457

5558
def wait_for_no_spinners():
56-
dash_duo.wait_for_no_elements('.dash-spinner')
59+
dash_duo.wait_for_no_elements(".dash-spinner")
5760

5861
with lock:
5962
dash_duo.start_server(app)
@@ -62,7 +65,105 @@ def wait_for_no_spinners():
6265
wait_for_no_spinners()
6366

6467
with lock:
65-
dash_duo.find_element('#input-3').send_keys('X')
68+
dash_duo.find_element("#input-3").send_keys("X")
6669
wait_for_all_spinners()
6770

6871
wait_for_no_spinners()
72+
73+
74+
def test_rdls002_chained_loading_states(dash_duo):
75+
lock1, lock2, lock34 = Lock(), Lock(), Lock()
76+
app = dash.Dash(__name__)
77+
78+
def loading_wrapped_div(_id, color):
79+
return html.Div(
80+
dcc.Loading(
81+
html.Div(
82+
id=_id,
83+
style={"width": 200, "height": 200, "backgroundColor": color},
84+
),
85+
className=_id,
86+
),
87+
style={"display": "inline-block"},
88+
)
89+
90+
app.layout = html.Div(
91+
[
92+
html.Button(id="button", children="Start", n_clicks=0),
93+
loading_wrapped_div("output-1", "hotpink"),
94+
loading_wrapped_div("output-2", "rebeccapurple"),
95+
loading_wrapped_div("output-3", "green"),
96+
loading_wrapped_div("output-4", "#FF851B"),
97+
]
98+
)
99+
100+
@app.callback(Output("output-1", "children"), [Input("button", "n_clicks")])
101+
def update_output_1(n_clicks):
102+
with lock1:
103+
return "Output 1: {}".format(n_clicks)
104+
105+
@app.callback(Output("output-2", "children"), [Input("output-1", "children")])
106+
def update_output_2(children):
107+
with lock2:
108+
return "Output 2: {}".format(children)
109+
110+
@app.callback(
111+
[Output("output-3", "children"), Output("output-4", "children")],
112+
[Input("output-2", "children")],
113+
)
114+
def update_output_34(children):
115+
with lock34:
116+
return "Output 3: {}".format(children), "Output 4: {}".format(children)
117+
118+
dash_duo.start_server(app)
119+
120+
def find_spinners(*nums):
121+
if not nums:
122+
dash_duo.wait_for_no_elements(".dash-spinner")
123+
return
124+
125+
for n in nums:
126+
dash_duo.find_element(".output-{} .dash-spinner".format(n))
127+
128+
assert len(dash_duo.find_elements(".dash-spinner")) == len(nums)
129+
130+
def find_text(spec):
131+
templates = [
132+
"Output 1: {}",
133+
"Output 2: Output 1: {}",
134+
"Output 3: Output 2: Output 1: {}",
135+
"Output 4: Output 2: Output 1: {}",
136+
]
137+
for n, v in spec.items():
138+
dash_duo.wait_for_text_to_equal(
139+
"#output-{}".format(n), templates[n - 1].format(v)
140+
)
141+
142+
find_text({1: 0, 2: 0, 3: 0, 4: 0})
143+
find_spinners()
144+
145+
btn = dash_duo.find_element("#button")
146+
# Can't use lock context managers here, because we want to acquire the
147+
# second lock before releasing the first
148+
lock1.acquire()
149+
btn.click()
150+
151+
find_spinners(1)
152+
find_text({2: 0, 3: 0, 4: 0})
153+
154+
lock2.acquire()
155+
lock1.release()
156+
157+
find_spinners(2)
158+
find_text({1: 1, 3: 0, 4: 0})
159+
160+
lock34.acquire()
161+
lock2.release()
162+
163+
find_spinners(3, 4)
164+
find_text({1: 1, 2: 1})
165+
166+
lock34.release()
167+
168+
find_spinners()
169+
find_text({1: 1, 2: 1, 3: 1, 4: 1})

0 commit comments

Comments
 (0)