-
-
Notifications
You must be signed in to change notification settings - Fork 143
Issue 485 - Slider className / external styling regression
#486
Changes from all commits
fba21be
99cf4ba
cba39b4
b7a21b5
0bd5a0b
f2e996a
4d2b99c
69a1ce8
694d140
1f0bf1a
4fd527e
d681399
a5372d4
e271919
70e1eb8
738527a
1e4e7e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| import io | ||
| import os | ||
| import sys | ||
| from multiprocessing import Lock | ||
| import time | ||
| import json | ||
|
|
||
|
|
@@ -215,6 +216,74 @@ def test_upload_gallery(self): | |
|
|
||
| self.snapshot('test_upload_gallery') | ||
|
|
||
| def test_loading_slider(self): | ||
| lock = Lock() | ||
| lock.acquire() | ||
|
|
||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div([ | ||
| html.Label(id='test-div', children=['Horizontal Slider']), | ||
| dcc.Slider( | ||
| id='horizontal-slider', | ||
| min=0, | ||
| max=9, | ||
| marks={i: 'Label {}'.format(i) if i == 1 else str(i) | ||
| for i in range(1, 6)}, | ||
| value=5, | ||
| ), | ||
| ]) | ||
|
|
||
| @app.callback( | ||
| Output('horizontal-slider', 'value'), | ||
| [Input('test-div', 'children')] | ||
| ) | ||
| def delayed_value(children): | ||
| lock.acquire() | ||
| lock.release() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nice @Marc-Andre-Rivet ! @plotly/dash whenever you are tempted to add a A lot of the time we can solve this just by waiting for some condition (an element with the right contents, for example). This one is a bit trickier, we were using a sleep in the server process (where callbacks run) to ensure something had time to be observed in the browser-control process, but this commit shows a fairly simple pattern to do this with a |
||
| return 5 | ||
|
|
||
| self.startServer(app) | ||
|
|
||
| self.wait_for_element_by_css_selector( | ||
| '#horizontal-slider[data-dash-is-loading="true"]' | ||
| ) | ||
| lock.release() | ||
|
|
||
| self.wait_for_element_by_css_selector( | ||
| '#horizontal-slider:not([data-dash-is-loading="true"])' | ||
| ) | ||
|
|
||
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_horizontal_slider(self): | ||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div([ | ||
| html.Label('Horizontal Slider'), | ||
| dcc.Slider( | ||
| id='horizontal-slider', | ||
| min=0, | ||
| max=9, | ||
| marks={i: 'Label {}'.format(i) if i == 1 else str(i) | ||
| for i in range(1, 6)}, | ||
| value=5, | ||
| ), | ||
| ]) | ||
| self.startServer(app) | ||
|
|
||
| self.wait_for_element_by_css_selector('#horizontal-slider') | ||
| self.snapshot('horizontal slider') | ||
|
|
||
| h_slider = self.driver.find_element_by_css_selector( | ||
| '#horizontal-slider div[role="slider"]' | ||
| ) | ||
| h_slider.click() | ||
|
|
||
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_vertical_slider(self): | ||
| app = dash.Dash(__name__) | ||
|
|
||
|
|
@@ -243,6 +312,112 @@ def test_vertical_slider(self): | |
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_loading_range_slider(self): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For both slider and range slider, make sure that the horizontal / vertical version displays correctly using the previously used styling, that the slider nubs can be clicked without error and that loading state is applied correctly to the DOM element |
||
| lock = Lock() | ||
| lock.acquire() | ||
|
|
||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div([ | ||
| html.Label(id='test-div', children=['Horizontal Range Slider']), | ||
| dcc.RangeSlider( | ||
| id='horizontal-range-slider', | ||
| min=0, | ||
| max=9, | ||
| marks={i: 'Label {}'.format(i) if i == 1 else str(i) | ||
| for i in range(1, 6)}, | ||
| value=[4, 6], | ||
| ), | ||
| ]) | ||
|
|
||
| @app.callback( | ||
| Output('horizontal-range-slider', 'value'), | ||
| [Input('test-div', 'children')] | ||
| ) | ||
| def delayed_value(children): | ||
| lock.acquire() | ||
| lock.release() | ||
| return [4, 6] | ||
|
|
||
| self.startServer(app) | ||
|
|
||
| self.wait_for_element_by_css_selector( | ||
| '#horizontal-range-slider[data-dash-is-loading="true"]' | ||
| ) | ||
| lock.release() | ||
|
|
||
| self.wait_for_element_by_css_selector( | ||
| '#horizontal-range-slider:not([data-dash-is-loading="true"])' | ||
| ) | ||
|
|
||
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_horizontal_range_slider(self): | ||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div([ | ||
| html.Label('Horizontal Range Slider'), | ||
| dcc.RangeSlider( | ||
| id='horizontal-range-slider', | ||
| min=0, | ||
| max=9, | ||
| marks={i: 'Label {}'.format(i) if i == 1 else str(i) | ||
| for i in range(1, 6)}, | ||
| value=[4, 6], | ||
| ), | ||
| ]) | ||
| self.startServer(app) | ||
|
|
||
| self.wait_for_element_by_css_selector('#horizontal-range-slider') | ||
| self.snapshot('horizontal range slider') | ||
|
|
||
| h_slider_1 = self.driver.find_element_by_css_selector( | ||
| '#horizontal-range-slider div.rc-slider-handle-1[role="slider"]' | ||
| ) | ||
| h_slider_1.click() | ||
|
|
||
| h_slider_2 = self.driver.find_element_by_css_selector( | ||
| '#horizontal-range-slider div.rc-slider-handle-2[role="slider"]' | ||
| ) | ||
| h_slider_2.click() | ||
|
|
||
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_vertical_range_slider(self): | ||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div([ | ||
| html.Label('Vertical Range Slider'), | ||
| dcc.RangeSlider( | ||
| id='vertical-range-slider', | ||
| min=0, | ||
| max=9, | ||
| marks={i: 'Label {}'.format(i) if i == 1 else str(i) | ||
| for i in range(1, 6)}, | ||
| value=[4, 6], | ||
| vertical=True, | ||
| ), | ||
| ], style={'height': '500px'}) | ||
| self.startServer(app) | ||
|
|
||
| self.wait_for_element_by_css_selector('#vertical-range-slider') | ||
| self.snapshot('vertical range slider') | ||
|
|
||
| v_slider_1 = self.driver.find_element_by_css_selector( | ||
| '#vertical-range-slider div.rc-slider-handle-1[role="slider"]' | ||
| ) | ||
| v_slider_1.click() | ||
|
|
||
| v_slider_2 = self.driver.find_element_by_css_selector( | ||
| '#vertical-range-slider div.rc-slider-handle-2[role="slider"]' | ||
| ) | ||
| v_slider_2.click() | ||
|
|
||
| for entry in self.get_log(): | ||
| raise Exception('browser error logged during test', entry) | ||
|
|
||
| def test_gallery(self): | ||
| app = dash.Dash(__name__) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apply class name to the wrapper. rc-slider applies very little styles to itself and relevant styles will be ok if applied to the parent (e.g. it doesn't explicitly set the color, font-size, etc.) unlike the dropdown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the other cases where we allow
className, we also allowstyle- do we want to do that here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. This is because the wrapper was added with Loading Components and the wrapped slider did not support the style property. I don't mind adding support for styling here -- but will need to handle the existing #481 style applied on the vertical slider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw, the rangeslider does not support
styleeither.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the main purpose of
classNameis styling, it seems appropriate to addstyle. But as that's a feature rather than a bugfix, feel free to make an issue and defer for later if you don't want to do it in this PR.