def test_patches_hover_still_works_when_a_seleciton_is_preselcted(output_file_url, selenium): # This tests an edge case interaction when Patches (specifically) is used # with a tool that requires hit testing e.g. HitTool AND a selection is # pre-made on the data source driving it. plot = Plot( x_range=Range1d(0, 100), y_range=Range1d(0, 100), min_border=0 ) source = ColumnDataSource(dict( xs=[[0, 50, 50, 0], [50, 100, 100, 50]], ys=[[0, 0, 100, 100], [0, 0, 100, 100]], color=['pink', 'blue'] )) source.selected = { '0d': {'glyph': None, 'indices': []}, '1d': {'indices': [1]}, '2d': {} } plot.add_glyph(source, Patches(xs='xs', ys='ys', fill_color='color')) plot.add_tools(HoverTool()) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Hover plot and test no error canvas = selenium.find_element_by_tag_name('canvas') actions = ActionChains(selenium) actions.move_to_element_with_offset(canvas, 100, 100) actions.perform() # If this assertion fails then there were likely errors on hover assert has_no_console_errors(selenium)
def test_line_rendering_with_selected_points(output_file_url, selenium, screenshot): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 4), y_range=Range1d(-1, 1)) x = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4] y = [ 0., 0.84147098, 0.90929743, 0.14112001, -0.7568025, -0.95892427, -0.2794155, 0.6569866, 0.98935825 ] # sin(2*x) source = ColumnDataSource(data=dict(x=x, y=y)) plot.add_glyph(source, Circle(x='x', y='y')) plot.add_glyph(source, Line(x='x', y='y')) plot.add_tools(BoxSelectTool()) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Perform selection and take screenshot perform_box_selection(selenium, (0, 100), (400, 250)) screenshot.assert_is_valid()
def test_legend_powered_by_source(output_file_url, selenium, screenshot): plot = Plot(height=HEIGHT, width=WIDTH, x_range=Range1d(0, 4), y_range=Range1d(0, 4), toolbar_location=None) source = ColumnDataSource( dict( x=[1, 2, 3], y=[1, 2, 3], color=['red', 'green', 'blue'], label=['Color Red', 'Color Green', 'Color Blue'], )) circle = Circle(x='x', y='y', fill_color='color', size=20) circle_renderer = plot.add_glyph(source, circle) plot.add_layout( Legend(items=[ LegendItem(label=field('label'), renderers=[circle_renderer]) ])) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot assert screenshot.is_valid()
def test_color_bar_placement_and_render(output_file_url, selenium, screenshot): plot = Plot(height=HEIGHT, width=WIDTH, x_range=Range1d(0, 10), y_range=Range1d(0, 10), toolbar_location=None) bar_vertical_right_panel = create_vertical_color_bar_with_log_cmap() bar_vertical_right_panel.location = (0, 0) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.location = "top_right" bar_vertical_in_frame.title = "Dummy Title" bar_vertical_in_frame.title_standoff = 7 bar_horizontal_below_panel = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_below_panel.location = (0, 0) bar_horizontal_in_frame = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_in_frame.location = "bottom_left" bar_horizontal_in_frame.title = "Dummy Title" plot.add_layout(bar_vertical_right_panel, 'right') plot.add_layout(bar_vertical_in_frame) plot.add_layout(bar_horizontal_below_panel, 'below') plot.add_layout(bar_horizontal_in_frame) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot assert screenshot.is_valid()
def test_lasso_select(output_file_url, selenium): plot = generate_plot() #limit to one callback on click release plot.add_tools(LassoSelectTool(select_every_mousemove=False)) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Drag a lasso selection area around middle point canvas = selenium.find_element_by_tag_name('canvas') actions = ActionChains(selenium) actions.move_to_element_with_offset(canvas, PLOT_DIM * 0.25, PLOT_DIM * 0.25) actions.click_and_hold() actions.move_by_offset(0, PLOT_DIM * 0.5) actions.move_by_offset(PLOT_DIM * 0.5, 0) actions.move_by_offset(0, PLOT_DIM * -0.5) actions.release() actions.perform() # Get the alert from box select and assert that the middle item is selected alert = selenium.switch_to_alert() assert alert.text == 'middle'
def test_label(output_file_url, selenium, screenshot): # Have to specify x/y range as labels aren't included in the plot area solver plot = Plot(plot_height=HEIGHT, plot_width=WIDTH, x_range=Range1d(0, 10), y_range=Range1d(0, 10), toolbar_location=None) label1 = Label(x=1, y=6, x_offset=25, y_offset=25, text="Demo Label", text_font_size='38pt', text_color='red', text_alpha=0.9, text_baseline='bottom', text_align='left', background_fill_color='green', background_fill_alpha=0.2, angle=15, angle_units='deg', render_mode='canvas') label2 = Label(x=3, y=5.5, text="(I'm Canvas)", text_font_size='20pt', border_line_color='black', border_line_width=2, border_line_dash='8 4', render_mode='canvas') label3 = Label(x=1, y=2, x_offset=25, y_offset=25, text="Demo Label", text_font_size='38pt', text_color='red', text_alpha=0.9, text_baseline='bottom', text_align='left', background_fill_color='green', background_fill_alpha=0.2, angle=0.261, angle_units='rad', render_mode='css') label4 = Label(x=3, y=1.0, text="(I'm CSS)", text_font_size='20pt', border_line_color='black', border_line_width=2, border_line_dash='8 4', render_mode='css') label_above = Label( x=0, y=0, text="Label in above panel", x_units='screen', y_units='screen', text_font_size='38pt', text_color='firebrick', text_alpha=0.9, ) label_left = Label( x=0, y=0, text="Label in left panel", x_units='screen', y_units='screen', angle=90, angle_units='deg', text_font_size='18pt', text_color='firebrick', text_alpha=0.9, background_fill_color='aliceblue', text_baseline='top', ) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') plot.add_layout(label1) plot.add_layout(label2) plot.add_layout(label3) plot.add_layout(label4) plot.add_layout(label_above, 'above') plot.add_layout(label_left, 'left') # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot assert screenshot.is_valid()
def test_color_bar_placement_and_render(output_file_url, selenium, screenshot): plot = Plot(height=HEIGHT, width=WIDTH, x_range=Range1d(0,10), y_range=Range1d(0,10), toolbar_location=None) bar_vertical_right_panel = create_vertical_color_bar_with_log_cmap() bar_vertical_right_panel.location = (0, 0) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.location = "top_right" bar_vertical_in_frame.title = "Dummy Title" bar_vertical_in_frame.title_standoff = 7 bar_horizontal_below_panel = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_below_panel.location = (0, 0) bar_horizontal_in_frame = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_in_frame.location = "bottom_left" bar_horizontal_in_frame.title = "Dummy Title" plot.add_layout(bar_vertical_right_panel, 'right') plot.add_layout(bar_vertical_in_frame) plot.add_layout(bar_horizontal_below_panel, 'below') plot.add_layout(bar_horizontal_in_frame) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot screenshot.assert_is_valid()
def test_arrow(output_file_url, selenium, screenshot): # Have to specify x/y range as labels aren't included in the plot area solver plot = figure(height=HEIGHT, width=WIDTH, x_range=(0,10), y_range=(0,10), tools='', toolbar_location="above") arrow1 = Arrow(x_start=1, y_start=3, x_end=6, y_end=8, line_color='green', line_alpha=0.7, line_dash='8 4', line_width=5, end=OpenHead() ) arrow1.end.line_width=8 arrow2 = Arrow(x_start=2, y_start=2, x_end=7, y_end=7, start=NormalHead(), end=VeeHead() ) arrow2.start.fill_color = 'indigo' arrow2.end.fill_color = 'orange' arrow2.end.size = 50 plot.add_layout(arrow1) plot.add_layout(arrow2) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot assert screenshot.is_valid()
def test_label(output_file_url, selenium, screenshot): # Have to specify x/y range as labels aren't included in the plot area solver plot = Plot(plot_height=HEIGHT, plot_width=WIDTH, x_range=Range1d(0, 10), y_range=Range1d(0, 10), toolbar_location=None) label1 = Label(x=1, y=6, x_offset=25, y_offset=25, text="Demo Label", text_font_size='38pt', text_color='red', text_alpha=0.9, text_baseline='bottom', text_align='left', background_fill_color='green', background_fill_alpha=0.2, angle=15, angle_units='deg', render_mode='canvas') label2 = Label(x=3, y=5.5, text="(I'm Canvas)", text_font_size='20pt', border_line_color='black', border_line_width=2, border_line_dash='8 4', render_mode='canvas') label3 = Label(x=1, y=2, x_offset=25, y_offset=25, text="Demo Label", text_font_size='38pt', text_color='red', text_alpha=0.9, text_baseline='bottom', text_align='left', background_fill_color='green', background_fill_alpha=0.2, angle=0.261, angle_units='rad', render_mode='css') label4 = Label(x=3, y=1.0, text="(I'm CSS)", text_font_size='20pt', border_line_color='black', border_line_width=2, border_line_dash='8 4', render_mode='css') label_above = Label( x=0, y=0, text="Label in above panel", x_units='screen', y_units='screen', text_font_size='38pt', text_color='firebrick', text_alpha=0.9, ) label_left = Label( x=0, y=0, text="Label in left panel", x_units='screen', y_units='screen', angle=90, angle_units='deg', text_font_size='18pt', text_color='firebrick', text_alpha=0.9, background_fill_color='aliceblue', text_baseline='top', ) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') plot.add_layout(label1) plot.add_layout(label2) plot.add_layout(label3) plot.add_layout(label4) plot.add_layout(label_above, 'above') plot.add_layout(label_left, 'left') # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot screenshot.assert_is_valid()
def test_hover_changes_color(output_file_url, selenium, screenshot): # Make plot and add a taptool callback that generates an alert plot = figure(height=HEIGHT, width=WIDTH, tools='', toolbar_location="above") rect = plot.rect(x=[1, 2], y=[1, 1], width=1, height=1, fill_color='cyan', hover_fill_color='magenta', line_color=None, hover_line_color=None) plot.add_tools(HoverTool(tooltips=None, renderers=[rect])) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Hover over plot and take screenshot canvas = selenium.find_element_by_tag_name('canvas') hover_at_position(selenium, canvas, WIDTH * 0.33, HEIGHT * 0.5) assert screenshot.is_valid()
def test_y_range_does_not_pan_below_y_min(output_file_url, selenium): y_range_min = -1 plot = make_plot(yr=Range1d(0, 3, bounds=(y_range_min, None))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=50, pan_y=-150) new_range_start = float(selenium.execute_script("""alert(Bokeh.index['plot-id'].model.y_range.start)""")) selenium.switch_to_alert().dismiss() # This is not necessary but assists debugging assert round(new_range_start) == y_range_min
def test_x_range_does_not_pan_right_of_x_max(output_file_url, selenium): x_range_max = 4 plot = make_plot(xr=Range1d(0, 3, bounds=(None, x_range_max))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=-150, pan_y=0) new_range_end = float(selenium.execute_script("""alert(Bokeh.index['plot-id'].model.x_range.end)""")) selenium.switch_to_alert().dismiss() # This is not necessary but assists debugging assert round(new_range_end) == x_range_max
def test_reversed_x_range_does_not_pan_right_of_x_min(output_file_url, selenium): x_range_min = -1 plot = make_plot(xr=Range1d(3, 0, bounds=(x_range_min, None))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=-150, pan_y=0) new_range_start = float(selenium.execute_script("""alert(Bokeh.index['plot-id'].model.x_range.min)""")) selenium.switch_to_alert().dismiss() assert round(new_range_start) == x_range_min
def test_x_range_does_not_pan_left_of_x_min(output_file_url, selenium): x_range_min = -1 plot = make_pan_plot_with_callback(xr=Range1d(0, 3, bounds=(x_range_min, None))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=200, pan_y=0) new_range_start = float(selenium.execute_script("""alert(window.get_x_range_start())""")) selenium.switch_to_alert().dismiss() assert round(new_range_start) == x_range_min
def test_reversed_y_range_does_not_pan_below_y_max(output_file_url, selenium): y_range_max = 4 plot = make_pan_plot_with_callback(yr=Range1d(3, 0, bounds=(None, y_range_max))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=50, pan_y=-150) new_range_end = float(selenium.execute_script("""alert(window.get_y_range_start())""")) selenium.switch_to_alert().dismiss() assert round(new_range_end) == y_range_max
def test_y_range_does_not_pan_above_y_max(output_file_url, selenium): y_range_max = 4 plot = make_pan_plot_with_callback(yr=Range1d(0, 3, bounds=(None, y_range_max))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=50, pan_y=150) new_range_end = float(selenium.execute_script("""alert(window.get_y_range_end())""")) selenium.switch_to_alert().dismiss() # This is not necessary but assists debugging assert round(new_range_end) == y_range_max
def test_reversed_x_range_does_not_pan_left_of_x_max(output_file_url, selenium): x_range_max = 4 plot = make_pan_plot_with_callback(xr=Range1d(3, 0, bounds=(None, x_range_max))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=200, pan_y=0) new_range_end = float(selenium.execute_script("""alert(window.get_x_range_start())""")) selenium.switch_to_alert().dismiss() # This is not necessary but assists debugging assert round(new_range_end) == x_range_max
def test_selection_tool_make_selection(output_file_url, selenium): plot = make_plot() save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) perform_box_selection(selenium, (50, 200), (450, 400)) code = "return Bokeh.index['plot-id'].model.select_one('rect-glyph').data_source.selected['1d'].indices" selected = selenium.execute_script(code) assert selected == [0, 1]
def test_no_border_or_background_fill(output_file_url, selenium, screenshot): # Have body background-color that should appear through the no-fill plot template = Template(""" <!doctype html> <html lang="en"> <head> {{ bokeh_js }} {{ bokeh_css}} <style> body { background-color: lightblue; } </style> </head> <body> {{ plot_script }} {{ plot_div }} </body> </html> """) plot = Plot(plot_height=HEIGHT, plot_width=WIDTH, x_range=Range1d(0, 10), y_range=Range1d(0, 10), toolbar_location=None) # This is the no-fill that we're testing plot.background_fill_color = None plot.border_fill_color = None plot.add_glyph(Circle(x=3, y=3, size=50, fill_color='#ffffff')) plot.add_glyph(Circle(x=6, y=6, size=50, fill_color='#ffffff')) plot.add_layout( LinearAxis(major_label_text_color='#ffffff', major_label_text_font_size="30pt"), 'left') plot.add_layout( LinearAxis(major_label_text_color='#ffffff', major_label_text_font_size="30pt"), 'below') html = file_html(plot, INLINE, template=template) # filename has to match test function + '.html' light filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_no_border_or_background_fill.html") with io.open(filepath, "w", encoding="utf-8") as f: f.write(decode_utf8(html)) selenium.get(output_file_url) assert has_no_console_errors(selenium) assert screenshot.is_valid()
def test_selection_tool_selection_ending_outside_frame_makes_selection(output_file_url, selenium): plot = make_plot() save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # make selection ending outside of frame perform_box_selection(selenium, (50, 50), (1000, 1000)) code = "return Bokeh.index['plot-id'].model.select_one('rect-glyph').data_source.selected['1d'].indices" selected = selenium.execute_script(code) assert selected == [0,1,2]
def test_patches_hover_still_works_when_a_seleciton_is_preselcted( output_file_url, selenium): # This tests an edge case interaction when Patches (specifically) is used # with a tool that requires hit testing e.g. HitTool AND a selection is # pre-made on the data source driving it. plot = Plot(x_range=Range1d(0, 100), y_range=Range1d(0, 100), min_border=0) source = ColumnDataSource( dict(xs=[[0, 50, 50, 0], [50, 100, 100, 50]], ys=[[0, 0, 100, 100], [0, 0, 100, 100]], color=['pink', 'blue'])) source.selected = { '0d': { 'glyph': None, 'indices': [] }, '1d': { 'indices': [1] }, '2d': { 'indices': {} }, } plot.add_glyph(source, Patches(xs='xs', ys='ys', fill_color='color')) plot.add_tools(HoverTool()) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Hover plot and test no error canvas = selenium.find_element_by_tag_name('canvas') actions = ActionChains(selenium) actions.move_to_element_with_offset(canvas, 100, 100) actions.perform() # If this assertion fails then there were likely errors on hover assert has_no_console_errors(selenium)
def test_no_border_or_background_fill(output_file_url, selenium, screenshot): # Have body background-color that should appear through the no-fill plot template = Template(""" <!doctype html> <html lang="en"> <head> {{ bokeh_js }} {{ bokeh_css}} <style> body { background-color: lightblue; } </style> </head> <body> {{ plot_script }} {{ plot_div }} </body> </html> """) plot = Plot(plot_height=HEIGHT, plot_width=WIDTH, x_range=Range1d(0, 10), y_range=Range1d(0, 10), toolbar_location=None) # This is the no-fill that we're testing plot.background_fill_color = None plot.border_fill_color = None plot.add_glyph(Circle(x=3, y=3, size=50, fill_color='#ffffff')) plot.add_glyph(Circle(x=6, y=6, size=50, fill_color='#ffffff')) plot.add_layout(LinearAxis(major_label_text_color='#ffffff', major_label_text_font_size="30pt"), 'left') plot.add_layout(LinearAxis(major_label_text_color='#ffffff', major_label_text_font_size="30pt"), 'below') html = file_html(plot, INLINE, template=template) # filename has to match test function + '.html' light filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_no_border_or_background_fill.html") with io.open(filepath, "w", encoding="utf-8") as f: f.write(decode_utf8(html)) selenium.get(output_file_url) assert has_no_console_errors(selenium) screenshot.assert_is_valid()
def test_selection_tool_selection_ending_outside_frame_stops_selection( output_file_url, selenium): plot = make_plot() save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # make selection ending outside of frame perform_box_selection(selenium, (50, 50), (1000, 1000)) code = "return Bokeh.index['plot-id'].model.select_one('rect-glyph').data_source.selected['1d'].indices" selected = selenium.execute_script(code) assert selected == []
def test_band(output_file_url, selenium, screenshot): x_range = Range1d(0, 10) y_range = Range1d(0, 10) # Have to specify x/y range as labels aren't included in the plot area solver plot = Plot(plot_height=HEIGHT, plot_width=WIDTH, x_range=x_range, y_range=y_range, toolbar_location=None) source = ColumnDataSource(data=dict( x1=[1, 3, 5, 7, 9], lower1=[1, 2, 1, 2, 1], upper1=[2, 3, 2, 3, 2], x2=[200, 250, 350, 450, 550], lower2=[400, 300, 400, 300, 400], upper2=[500, 400, 500, 400, 500], )) band1 = Band(base='x1', lower='lower1', upper='upper1', line_width=3, line_color='red', line_dash='dashed', source=source) band2 = Band(base='x2', lower='lower2', upper='upper2', base_units='screen', lower_units='screen', upper_units='screen', dimension='width', line_width=3, fill_color='blue', line_color='green', source=source) plot.add_layout(band1) plot.add_layout(band2) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot screenshot.assert_is_valid()
def test_wheel_zoom_is_deselected_by_default(output_file_url, selenium): # Make plot and add a taptool callback that generates an alert plot = make_plot() # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Tap the plot and test for alert scroll_button = get_non_stale_scroll_button(selenium) scroll_classes = scroll_button.get_attribute('class') assert 'active' not in scroll_classes
def test_visible_property_hides_things_correctly(output_file_url, selenium, screenshot): plot = figure(toolbar_location=None) l1 = plot.line([1, 2, 3], [1, 2, 3]) l2 = plot.line([1, 2, 3], [2, 4, 6]) plot.xaxis.visible = False plot.ygrid.visible = False l1.visible = False # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) assert screenshot.is_valid()
def test_visible_property_hides_things_correctly(output_file_url, selenium, screenshot): plot = figure() l1 = plot.line([1, 2, 3], [1, 2, 3]) l2 = plot.line([1, 2, 3], [2, 4, 6]) plot.xaxis.visible = False plot.ygrid.visible = False l1.visible = False # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) assert screenshot.is_valid()
def test_reversed_y_range_does_not_pan_above_y_min(output_file_url, selenium): y_range_min = -1 plot = make_plot(yr=Range1d(3, 0, bounds=(y_range_min, None))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=50, pan_y=150) new_range_start = float( selenium.execute_script( """alert(Bokeh.index['plot-id'].model.y_range.min)""")) selenium.switch_to_alert().dismiss() assert round(new_range_start) == y_range_min
def test_y_range_does_not_pan_below_y_min(output_file_url, selenium): y_range_min = -1 plot = make_plot(yr=Range1d(0, 3, bounds=(y_range_min, None))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=50, pan_y=-150) new_range_start = float( selenium.execute_script( """alert(Bokeh.index['plot-id'].model.y_range.start)""")) selenium.switch_to_alert().dismiss( ) # This is not necessary but assists debugging assert round(new_range_start) == y_range_min
def test_range_with_callback_triggers_alert(output_file_url, selenium): # Simple test to ensure range callbacks are working # Rest of tests in this file depend on range callback. plot = make_pan_plot_with_callback() initial_start = plot.x_range.start save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=100, pan_y=100) new_range_start = float(selenium.execute_script("""alert(window.get_x_range_start())""")) selenium.switch_to_alert().dismiss() assert new_range_start < initial_start
def test_x_range_does_not_pan_right_of_x_max(output_file_url, selenium): x_range_max = 4 plot = make_plot(xr=Range1d(0, 3, bounds=(None, x_range_max))) save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Pan plot and test for new range value pan_plot(selenium, pan_x=-150, pan_y=0) new_range_end = float( selenium.execute_script( """alert(Bokeh.index['plot-id'].model.x_range.end)""")) selenium.switch_to_alert().dismiss( ) # This is not necessary but assists debugging assert round(new_range_end) == x_range_max
def test_scale_width_chart_starts_at_correct_size(output_file_url, selenium): hist = Histogram(df['mpg'], title="MPG Distribution", sizing_mode='scale_width') save(hist) selenium.set_window_size(width=1000, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) # Canvas width should be just under 1000 * 0.9 # (default file_html has a body width of 90%) assert canvas.size['width'] > 850 assert canvas.size['width'] < 900
def test_scale_width_plot_starts_at_correct_size(output_file_url, selenium): plot = make_sizing_mode_plot(600, 600, sizing_mode='scale_width') save(plot) selenium.set_window_size(width=1000, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) # Canvas width should be just under 1000 * 0.9 # (default file_html has a body width of 90%) assert canvas.size['width'] > 850 assert canvas.size['width'] < 900
def test_responsive_chart_starts_at_correct_size(output_file_url, selenium): hist = Histogram(df['mpg'], title="MPG Distribution", responsive=True) save(hist) selenium.set_window_size(width=1000, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) # Canvas width should be just under 1000 * 0.9 # (default file_html has a body width of 90%) assert canvas.size['width'] > 850 assert canvas.size['width'] < 900
def test_scale_width_maintains_a_minimum_height(output_file_url, selenium): # The aspect ratio is landscape but should not allow a height less than 100 plot = make_sizing_mode_plot(1200, 600, sizing_mode='scale_width') save(plot) # Open the browser with the plot and resize the window small selenium.set_window_size(width=100, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) # Plot should have been shrunk somewhat assert canvas.size['height'] < 600 assert canvas.size['height'] >= 100
def test_box_select(output_file_url, selenium): PLOT_DIM = 600 source = ColumnDataSource( dict( x=[1, 2, 3], y=[3, 2, 3], name=['top_left', 'middle', 'top_right'], )) # Make plot and add a taptool callback that generates an alert plot = figure(tools='box_select', height=PLOT_DIM, width=PLOT_DIM, x_range=[1, 3], y_range=[1, 3]) plot.circle(x='x', y='y', radius=0.2, source=source) source.callback = CustomJS(code=""" var indices = cb_obj.get('selected')['1d'].indices, data = cb_obj.get('data'), selected_names = ''; Bokeh.$.each(indices, function(i, index) { selected_names += data['name'][index]; }); alert(selected_names); """) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Drag a box zoom around middle point canvas = selenium.find_element_by_tag_name('canvas') actions = ActionChains(selenium) actions.move_to_element_with_offset(canvas, PLOT_DIM * 0.25, PLOT_DIM * 0.25) actions.click_and_hold() actions.move_by_offset(PLOT_DIM * 0.5, PLOT_DIM * 0.5) actions.release() actions.perform() # Get the alert from box select and assert that the middle item is selected alert = selenium.switch_to_alert() assert alert.text == 'middle'
def test_selection_tool_multiselection_with_shift(output_file_url, selenium): plot = make_plot() # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # make first selection perform_box_selection(selenium, (50, 200), (250, 400)) # make second, multi-selection with shift perform_box_selection(selenium, (475, 200), (275, 400), hold_shift=True) code = "return Bokeh.index['plot-id'].model.select_one('rect-glyph').data_source.selected['1d'].indices" selected = selenium.execute_script(code) assert selected == [0, 2]
def test_scale_width_resizes_plot_while_maintaining_aspect_ratio( output_file_url, selenium): # We want the aspect ratio of the initial plot to be maintained, but we # can't measure it perfectly so we test against bounds. aspect_ratio = 2 plot_height = 400 plot_width = 400 * aspect_ratio lower_bound = aspect_ratio * 0.95 upper_bound = aspect_ratio * 1.05 # In this test we tell selenium what to set the browser window to be # initially and then finally so we can test that the canvas has # scaled down by approximately the correct amount. initial_window_width = 1200 final_window_width = 600 # Make the plot with autoresize plot = make_sizing_mode_plot(plot_width, plot_height, sizing_mode='scale_width') save(plot) # Open the browser with the plot and resize the window to get an initial measure selenium.set_window_size(width=initial_window_width, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) initial_height = canvas.size['height'] initial_width = canvas.size['width'] initial_aspect_ratio = initial_width / initial_height assert initial_aspect_ratio > lower_bound assert initial_aspect_ratio < upper_bound # Now resize to a smaller window size and check again selenium.set_window_size(width=final_window_width, height=600) selenium.set_window_size(width=final_window_width, height=599) # See note (1) below wait_for_canvas_resize(canvas, selenium) final_height = canvas.size['height'] final_width = canvas.size['width'] final_aspect_ratio = final_width / final_height assert final_aspect_ratio > lower_bound assert final_aspect_ratio < upper_bound
def test_tap_with_callback_triggers_alert(output_file_url, selenium): # Make plot and add a taptool callback that generates an alert plot = make_plot('tap') tap = plot.select(dict(type=TapTool))[0] tap.callback = CustomJS(code='alert("tapped")') # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Tap the plot and test for alert canvas = selenium.find_element_by_tag_name('canvas') click_glyph_at_position(selenium, canvas, 250, 400) alert = selenium.switch_to_alert() assert alert.text == 'tapped'
def test_reset_triggers_range_callback(output_file_url, selenium): # Make plot and add a range callback that generates an alert plot = make_plot('reset') range1d = plot.select(dict(type=Range1d))[0] range1d.callback = CustomJS(code='alert("plot reset")') # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Tap the plot and test for alert reset_button = selenium.find_element_by_class_name('bk-tool-icon-reset') click_element_at_position(selenium, reset_button, 10, 10) alert = selenium.switch_to_alert() assert alert.text == 'plot reset'
def test_data_table_preselection_python(output_file_url, selenium, screenshot): data = dict(x = list(range(10))) selected = { '0d': {'glyph': None, 'indices': []}, '1d': {'indices': [1, 2]}, '2d': {'indices': {}}} source = ColumnDataSource(data=data, selected=selected) columns = [TableColumn(field="x", title="X")] data_table = DataTable(source=source, columns=columns) # Save the table and start the test save(data_table) selenium.get(output_file_url) assert has_no_console_errors(selenium) screenshot.assert_is_valid()
def test_color_bar_with_scale_alpha(output_file_url, selenium, screenshot): plot = Plot(height=HEIGHT, width=WIDTH, x_range=Range1d(0,10), y_range=Range1d(0,10), outline_line_alpha=0.0, toolbar_location=None) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.scale_alpha = 0.5 plot.add_layout(bar_vertical_in_frame) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot screenshot.assert_is_valid()
def test_reset_triggers_factorrange_callback(output_file_url, selenium): x_range = FactorRange(factors=["a", "b", "c"]) x_range.callback = CustomJS(code='alert("plot reset")') y_range = Range1d() # Make plot and add a range callback that generates an alert plot = make_plot(x_range, y_range, tools='reset') # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Tap the plot and test for alert reset_button = selenium.find_element_by_class_name('bk-tool-icon-reset') click_element_at_position(selenium, reset_button, 10, 10) alert = selenium.switch_to_alert() assert alert.text == 'plot reset'
def test_rect_rendering_with_log_axis(output_file_url, selenium, screenshot): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0,30), y_range=Range1d(1,100), y_axis_type="log") x = [10, 20] y = [10, 20] source = ColumnDataSource(data=dict(x=[(x[0]+x[1])/2], y=[(y[0]+y[1])/2], width=[x[1]-x[0]], height=[y[1]-y[0]])) plot.add_glyph(source, Rect(x='x', y='y', width='width', height='height')) plot.add_layout(LogAxis(), "left") # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) screenshot.assert_is_valid()
def test_scale_width_resizes_plot_while_maintaining_aspect_ratio(output_file_url, selenium): # We want the aspect ratio of the initial plot to be maintained, but we # can't measure it perfectly so we test against bounds. aspect_ratio = 2 plot_height = 400 plot_width = 400 * aspect_ratio lower_bound = aspect_ratio * 0.95 upper_bound = aspect_ratio * 1.05 # In this test we tell selenium what to set the browser window to be # initially and then finally so we can test that the canvas has # scaled down by approximately the correct amount. initial_window_width = 1200 final_window_width = 600 # Make the plot with autoresize plot = make_sizing_mode_plot(plot_width, plot_height, sizing_mode='scale_width') save(plot) # Open the browser with the plot and resize the window to get an initial measure selenium.set_window_size(width=initial_window_width, height=600) selenium.get(output_file_url) assert has_no_console_errors(selenium) canvas = selenium.find_element_by_tag_name('canvas') wait_for_canvas_resize(canvas, selenium) initial_height = canvas.size['height'] initial_width = canvas.size['width'] initial_aspect_ratio = initial_width / initial_height assert initial_aspect_ratio > lower_bound assert initial_aspect_ratio < upper_bound # Now resize to a smaller window size and check again selenium.set_window_size(width=final_window_width, height=600) selenium.set_window_size(width=final_window_width, height=599) # See note (1) below wait_for_canvas_resize(canvas, selenium) final_height = canvas.size['height'] final_width = canvas.size['width'] final_aspect_ratio = final_width / final_height assert final_aspect_ratio > lower_bound assert final_aspect_ratio < upper_bound
def _assert_autorange_prevents_panning_but_can_zoom(output_file_url, selenium): selenium.get(output_file_url) assert has_no_console_errors(selenium) # Zoom into plot so we can pan around a little zoom_plot(selenium) # Now the plot is zoomed in, try a little to the right pan_plot(selenium, pan_x=-50, pan_y=0) x_range_start = float(selenium.execute_script("""alert(window.get_x_range_start())""")) selenium.switch_to_alert().dismiss() assert x_range_start > 0.5 # Now try panning far to left to check bounds pan_plot(selenium, pan_x=200, pan_y=0) x_range_start = float(selenium.execute_script("""alert(window.get_x_range_start())""")) selenium.switch_to_alert().dismiss() assert x_range_start > 0.4 assert x_range_start < 0.5