From fba21be3ef901cf6e9cc7d367fb8b15b46595fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 11 Mar 2019 11:30:17 -0400 Subject: [PATCH 01/12] Apply class to slider wrapper --- src/components/Slider.react.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index 9d415f355..f7183c475 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -18,7 +18,14 @@ export default class Slider extends Component { } render() { - const {id, setProps, updatemode, loading_state} = this.props; + const { + className, + id, + loading_state, + setProps, + updatemode, + vertical + } = this.props; const {value} = this.state; return (
{ @@ -44,7 +53,7 @@ export default class Slider extends Component { } }} value={value} - {...omit(['setProps', 'updatemode', 'value'], this.props)} + {...omit(['className', 'setProps', 'updatemode', 'value'], this.props)} />
); From cba39b404e78c18cf4bee35f761973a0c172d83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 11 Mar 2019 11:33:31 -0400 Subject: [PATCH 02/12] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76cc6214c..f14b5776f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] ### Fixed - Fix Vertical Slider regression [#479](https://github.com/plotly/dash/issues/479) +- Fix Slider regression [#485](https://github.com/plotly/dash/issues/485) ## [0.44.0] - 2019-03-04 ### Added From b7a21b52a8d5d2acdeb6db9babe097bbfe0d67ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 11 Mar 2019 11:45:45 -0400 Subject: [PATCH 03/12] fix lint --- src/components/Slider.react.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index f7183c475..552a0b696 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -24,7 +24,7 @@ export default class Slider extends Component { loading_state, setProps, updatemode, - vertical + vertical, } = this.props; const {value} = this.state; return ( @@ -53,7 +53,10 @@ export default class Slider extends Component { } }} value={value} - {...omit(['className', 'setProps', 'updatemode', 'value'], this.props)} + {...omit( + ['className', 'setProps', 'updatemode', 'value'], + this.props + )} /> ); From f2e996a60ffa9103c825abf7ba85711e26e84824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 10:45:04 -0400 Subject: [PATCH 04/12] - range slider loading state - additional visual tests for range slider --- src/components/RangeSlider.react.js | 50 +++++++++------ test/test_integration.py | 94 +++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 17 deletions(-) diff --git a/src/components/RangeSlider.react.js b/src/components/RangeSlider.react.js index c0ee802f3..56cb52b63 100644 --- a/src/components/RangeSlider.react.js +++ b/src/components/RangeSlider.react.js @@ -18,31 +18,47 @@ export default class RangeSlider extends Component { } render() { - const {setProps, updatemode, loading_state} = this.props; + const { + className, + id, + loading_state, + setProps, + updatemode, + vertical + } = this.props; const {value} = this.state; return ( - { - this.setState({value}); - if (updatemode === 'drag') { - if (setProps) { - setProps({value}); + className={className} + style={vertical ? {height: '100%'} : {}} + > + { + this.setState({value}); + if (updatemode === 'drag') { + if (setProps) { + setProps({value}); + } } - } - }} - onAfterChange={value => { - if (updatemode === 'mouseup') { - if (setProps) { - setProps({value}); + }} + onAfterChange={value => { + if (updatemode === 'mouseup') { + if (setProps) { + setProps({value}); + } } + }} + value={value} + {...omit( + ['className', 'value', 'setProps', 'updatemode'], + this.props) } - }} - value={value} - {...omit(['value', 'setProps', 'updatemode'], this.props)} - /> + /> + ); } } diff --git a/test/test_integration.py b/test/test_integration.py index facfedbd4..ab0b1a89f 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -217,6 +217,34 @@ def test_upload_gallery(self): self.snapshot('test_upload_gallery') + 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, + vertical=True, + ), + ]) + 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__) @@ -245,6 +273,72 @@ def test_vertical_slider(self): 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], + vertical=True, + ), + ]) + 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=5, + 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__) From 4d2b99ce24e462ab6eb4243ab8fd993b0ff7484b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 10:45:35 -0400 Subject: [PATCH 05/12] lint --- src/components/RangeSlider.react.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/RangeSlider.react.js b/src/components/RangeSlider.react.js index 56cb52b63..3a3f0b4d5 100644 --- a/src/components/RangeSlider.react.js +++ b/src/components/RangeSlider.react.js @@ -24,7 +24,7 @@ export default class RangeSlider extends Component { loading_state, setProps, updatemode, - vertical + vertical, } = this.props; const {value} = this.state; return ( @@ -55,8 +55,8 @@ export default class RangeSlider extends Component { value={value} {...omit( ['className', 'value', 'setProps', 'updatemode'], - this.props) - } + this.props + )} /> ); From 69a1ce86de60c963683a81d92b77a9dc95099c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 10:56:44 -0400 Subject: [PATCH 06/12] fix test --- test/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_integration.py b/test/test_integration.py index ab0b1a89f..f3f64f24e 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -317,7 +317,7 @@ def test_vertical_range_slider(self): max=9, marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, - value=5, + value=[4, 6], vertical=True, ), ], style={'height': '500px'}) From 694d14072e7e3b24f04d6c92fde3f6abbe08f3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 11:09:19 -0400 Subject: [PATCH 07/12] loading slider test --- test/test_integration.py | 79 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/test/test_integration.py b/test/test_integration.py index f3f64f24e..49b1eb76a 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -217,6 +217,45 @@ def test_upload_gallery(self): self.snapshot('test_upload_gallery') + def test_loading_slider(self): + app = dash.Dash(__name__) + + app.layout = html.Div([ + html.Label(id='test-div', '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, + vertical=True, + ), + ]) + + @app.callback( + Output('horizontal-slider', 'value'), + [Input('test-div', 'children')] + ) + def delayed_value(children): + time.sleep(5) + return 5 + + self.startServer(app) + + slider = self.driver.find_element_by_css_selector( + '#horizontal-slider[data-dash-is-loading="true"]' + ) + + time.sleep(5) + + slider = self.driver.find_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__) @@ -273,6 +312,46 @@ 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): + app = dash.Dash(__name__) + + app.layout = html.Div([ + html.Label(id='test-div', '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], + vertical=True, + ), + ]) + + @app.callback( + Output('horizontal-range-slider', 'value'), + [Input('test-div', 'children')] + ) + def delayed_value(children): + time.sleep(5) + return [4, 6] + + self.startServer(app) + + slider = self.driver.find_element_by_css_selector( + '#horizontal-range-slider[data-dash-is-loading="true"]' + ) + + time.sleep(5) + + slider = self.driver.find_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__) From 1f0bf1a492adf3621eb971481332c9da75a0d1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 11:15:03 -0400 Subject: [PATCH 08/12] fix dash code for tests --- test/test_integration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index 49b1eb76a..d77e65aec 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -221,7 +221,7 @@ def test_loading_slider(self): app = dash.Dash(__name__) app.layout = html.Div([ - html.Label(id='test-div', 'Horizontal Slider'), + html.Label(id='test-div', children=['Horizontal Slider']), dcc.Slider( id='horizontal-slider', min=0, @@ -316,7 +316,7 @@ def test_loading_range_slider(self): app = dash.Dash(__name__) app.layout = html.Div([ - html.Label(id='test-div', 'Horizontal Range Slider'), + html.Label(id='test-div', children=['Horizontal Range Slider']), dcc.RangeSlider( id='horizontal-range-slider', min=0, From 4fd527ebb35c5ab0eaa1b98a3b03dfef111f84d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 11:28:19 -0400 Subject: [PATCH 09/12] verticals --- test/test_integration.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index d77e65aec..a856d04c8 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -229,7 +229,6 @@ def test_loading_slider(self): marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, value=5, - vertical=True, ), ]) @@ -268,7 +267,6 @@ def test_horizontal_slider(self): marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, value=5, - vertical=True, ), ]) self.startServer(app) @@ -324,7 +322,6 @@ def test_loading_range_slider(self): marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, value=[4, 6], - vertical=True, ), ]) @@ -364,7 +361,6 @@ def test_horizontal_range_slider(self): marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, value=[4, 6], - vertical=True, ), ]) self.startServer(app) From d6813995448f0793ff1c2cd78fd464a03a690fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 13:21:38 -0400 Subject: [PATCH 10/12] wait instead of find --- test/test_integration.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index a856d04c8..6e0ef7d94 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -242,13 +242,11 @@ def delayed_value(children): self.startServer(app) - slider = self.driver.find_element_by_css_selector( + self.wait_for_element_by_css_selector( '#horizontal-slider[data-dash-is-loading="true"]' ) - time.sleep(5) - - slider = self.driver.find_element_by_css_selector( + self.wait_for_element_by_css_selector( '#horizontal-slider:not([data-dash-is-loading="true"])' ) @@ -335,13 +333,11 @@ def delayed_value(children): self.startServer(app) - slider = self.driver.find_element_by_css_selector( + self.wait_for_element_by_css_selector( '#horizontal-range-slider[data-dash-is-loading="true"]' ) - time.sleep(5) - - slider = self.driver.find_element_by_css_selector( + self.wait_for_element_by_css_selector( '#horizontal-range-slider:not([data-dash-is-loading="true"])' ) From a5372d4723302280710e39d2aaa494c835ca614d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 13:32:28 -0400 Subject: [PATCH 11/12] lint --- test/test_integration.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_integration.py b/test/test_integration.py index 6e0ef7d94..9cef42550 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -344,7 +344,6 @@ def delayed_value(children): for entry in self.get_log(): raise Exception('browser error logged during test', entry) - def test_horizontal_range_slider(self): app = dash.Dash(__name__) From 738527a28dac6959037628b0b9be31ef536e4c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Mon, 18 Mar 2019 15:20:42 -0400 Subject: [PATCH 12/12] use lock instead of time sleep --- test/test_integration.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index 9cef42550..9b5cf4fbb 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -5,6 +5,7 @@ import io import os import sys +from multiprocessing import Lock import time import json @@ -218,6 +219,9 @@ 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([ @@ -237,7 +241,8 @@ def test_loading_slider(self): [Input('test-div', 'children')] ) def delayed_value(children): - time.sleep(5) + lock.acquire() + lock.release() return 5 self.startServer(app) @@ -245,6 +250,7 @@ def delayed_value(children): 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"])' @@ -309,6 +315,9 @@ def test_vertical_slider(self): raise Exception('browser error logged during test', entry) def test_loading_range_slider(self): + lock = Lock() + lock.acquire() + app = dash.Dash(__name__) app.layout = html.Div([ @@ -328,7 +337,8 @@ def test_loading_range_slider(self): [Input('test-div', 'children')] ) def delayed_value(children): - time.sleep(5) + lock.acquire() + lock.release() return [4, 6] self.startServer(app) @@ -336,6 +346,7 @@ def delayed_value(children): 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"])'