def test_mouse_hover(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # hover over second element items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class')
def test_arrow_cannot_escape_menu(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow down moves to second item enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow down again has no effect enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow up moves to first item enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow up again has no effect enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_server_on_change_round_trip(self, bokeh_server_page): page = bokeh_server_page(modify_doc) el = page.driver.find_element_by_class_name('foo') enter_text_in_element(page.driver, el, "val1" + Keys.TAB) page.click_custom_action() results = page.results assert results['data']['val'] == ["", "val1"]
def test_server_on_change_no_round_trip_without_enter_or_click(self, bokeh_server_page): page = bokeh_server_page(modify_doc) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "pre", enter=False) # not change event if enter is not pressed page.click_custom_action() results = page.results assert results['data']['val'] == ["a", "b"]
def test_server_on_change_round_trip( self, bokeh_server_page: BokehServerPage) -> None: num_input = NumericInput(low=-1, high=100, value=4) modify_doc, plot = mk_modify_doc(num_input) page = bokeh_server_page(modify_doc) el = find_element_for(page.driver, num_input, "input") enter_text_in_element(page.driver, el, "2") page.eval_custom_action() results = page.results assert results['data']['val'] == [4, 42] # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "34", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [42, 34] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "56", click=2, enter=False) page.click_canvas_at_position(plot, 10, 10) page.eval_custom_action() results = page.results assert results['data']['val'] == [34, 56]
def test_server_on_change_round_trip_partial_entry( self, bokeh_server_page) -> None: page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "100", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "100001"] enter_text_in_element(page.driver, el, "123", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["100001", "12344556"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "319", click=2, enter=False) page.click_canvas_at_position(10, 10) page.click_custom_action() results = page.results assert results['data']['val'] == ["12344556", "3194567289"]
def test_server_on_change_round_trip_menu_entry(self, bokeh_server_page) -> None: page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) enter_text_in_element(page.driver, el, Keys.DOWN, click=0) page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"] enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) items[1].click() page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"]
def test_js_on_change_executes(self, single_plot_page) -> None: source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) num_input = NumericInput(css_classes=['foo']) num_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(num_input, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "10") results = page.results assert results['value'] == 10 # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "20", click=2) results = page.results assert results['value'] == 20 # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "30", click=2, enter=False) page.click_canvas_at_position(10, 10) results = page.results assert results['value'] == 30 assert page.has_no_console_errors()
def test_js_on_change_executes(self, single_plot_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) text_input = TextInput(css_classes=['foo']) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(text_input, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "val1") results = page.results assert results['value'] == 'val1' # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) results = page.results assert results['value'] == 'val2' # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) results = page.results assert results['value'] == 'val3' assert page.has_no_console_errors()
def test_server_on_change_round_trip_menu_entry( self, bokeh_server_page: BokehServerPage) -> None: input_box = AutocompleteInput() modify_doc, _ = mk_modify_doc(input_box) page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = find_element_for(page.driver, input_box, "input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) enter_text_in_element(page.driver, el, Keys.DOWN, click=0) page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"] enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = find_element_for(page.driver, input_box, ".bk-menu") items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) items[1].click() page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"]
def test_server_on_change_round_trip_partial_entry( self, bokeh_server_page: BokehServerPage) -> None: input_box = AutocompleteInput() modify_doc, plot = mk_modify_doc(input_box) page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = find_element_for(page.driver, input_box, "input") enter_text_in_element(page.driver, el, "100", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "100001"] enter_text_in_element(page.driver, el, "123", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["100001", "12344556"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "319", click=2, enter=False) page.click_canvas_at_position(plot, 10, 10) page.eval_custom_action() results = page.results assert results['data']['val'] == ["12344556", "3194567289"]
def test_server_on_change_round_trip( self, bokeh_server_page: BokehServerPage) -> None: text_input = PasswordInput() modify_doc, plot = mk_modify_doc(text_input) page = bokeh_server_page(modify_doc) el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "val1") page.eval_custom_action() results = page.results assert results['data']['val'] == ["", "val1"] # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["val1", "val2"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(plot, 10, 10) page.eval_custom_action() results = page.results assert results['data']['val'] == ["val2", "val3"]
def test_js_on_change_executes(self, single_plot_page: SinglePlotPage) -> None: source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(height=400, width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) text_input = PasswordInput() text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(text_input, plot)) el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "val1") results = page.results assert results['value'] == 'val1' # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) results = page.results assert results['value'] == 'val2' # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(plot, 10, 10) results = page.results assert results['value'] == 'val3' assert page.has_no_console_errors()
def test_single_row_copy_with_zero(self, bokeh_model_page) -> None: data = {'x': [1,2,3,4], 'y': [0,0,0,0], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) row = get_table_row(page.driver, 2) row.click() enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) enter_text_in_element(page.driver, input_el, "") sleep(0.5) results = page.results assert results['value'] == '1\t2\t0\tbar' assert page.has_no_console_errors()
def test_multi_row_copy(self, bokeh_model_page) -> None: data = {'x': [1,2,3,4], 'y': [0,1,2,3], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) row = get_table_row(page.driver, 1) row.click() row = get_table_row(page.driver, 3) shift_click(page.driver, row) enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) enter_text_in_element(page.driver, input_el, "") results = page.results # XXX (bev) these should be newlines with a TextAreaInput but TextAreaInput # is not working in tests for some reason presently assert results['value'] == '0\t1\t0\tfoo 1\t2\t1\tbar 2\t3\t2\tbaz' assert page.has_no_console_errors()
def test_mouse_hover(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", ], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") # hover over second element items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute("class") assert "bk-active" in items[1].get_attribute("class")
def test_callback_property_executes(self, single_plot_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) text_input = TextInput(css_classes=['foo']) text_input.callback = CustomJS(code=RECORD("value", "cb_obj.value")) page = single_plot_page(column(text_input, plot)) el = page.driver.find_element_by_class_name('foo') enter_text_in_element(page.driver, el, "val1") results = page.results assert results['value'] == 'val1' # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) results = page.results assert results['value'] == 'val2' # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) results = page.results assert results['value'] == 'val3' assert page.has_no_console_errors()
def test_server_on_change_round_trip(self, bokeh_server_page) -> None: page = bokeh_server_page(modify_doc) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "2") page.click_custom_action() results = page.results assert results['data']['val'] == [4, 42] # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "34", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == [42, 34] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, 56, click=2, enter=False) page.click_canvas_at_position(10, 10) page.click_custom_action() results = page.results assert results['data']['val'] == [34, 56]
def test_server_on_change_round_trip(self, bokeh_server_page): page = bokeh_server_page(modify_doc) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "val1") page.click_custom_action() results = page.results assert results['data']['val'] == ["", "val1"] # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["val1", "val2"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) page.click_custom_action() results = page.results assert results['data']['val'] == ["val2", "val3"]
def test_server_on_change_round_trip_partial_entry(self, bokeh_server_page): page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "100", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "100001"] enter_text_in_element(page.driver, el, "123", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["100001", "12344556"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "319", click=2, enter=False) page.click_canvas_at_position(10, 10) page.click_custom_action() results = page.results assert results['data']['val'] == ["12344556", "3194567289"]
def test_server_on_change_round_trip(self, bokeh_server_page): page = bokeh_server_page(modify_doc) el = page.driver.find_element_by_class_name('foo') enter_text_in_element(page.driver, el, "val1") page.click_custom_action() results = page.results assert results['data']['val'] == ["", "val1"] # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["val1", "val2"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) page.click_custom_action() results = page.results assert results['data']['val'] == ["val2", "val3"]
def test_server_no_restriction(self, bokeh_server_page) -> None: """Test effect of 'restrict=False' without explicit callback.""" text_input = AutocompleteInput( css_classes=["foo"], completions=["aAaBbb", "aAaBbB"], restrict=False, fuzzy_comparison=False, ) def add_autocomplete(doc): # note: for some reason, bokeh_server_page requires a 'canvas' in the document plot = Plot() doc.add_root(column(text_input, plot)) page = bokeh_server_page(add_autocomplete) el = page.driver.find_element_by_css_selector(".foo input") text = "not in completions" enter_text_in_element(page.driver, el, text, click=1, enter=True) assert text_input.value == text assert page.has_no_console_errors()
def test_server_restriction_to_list(self, bokeh_server_page) -> None: """Test that input entered manually doesn't end up in the value.""" text_input = AutocompleteInput( css_classes=["foo"], completions=["aAaBbb"], restrict=True, fuzzy_comparison=False, ) def add_autocomplete(doc): # note: for some reason, bokeh_server_page requires a 'canvas' in the document plot = Plot() doc.add_root(column(text_input, plot)) page = bokeh_server_page(add_autocomplete) el = page.driver.find_element_by_css_selector(".foo input") text = "not in completions" enter_text_in_element(page.driver, el, text, click=1, enter=True) assert text_input.value == "" assert page.has_no_console_errors()
def test_min_characters(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB", ], min_characters=1, fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "1", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "100001" assert items[1].text == "12344556" assert items[2].text == "12344557" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") assert "bk-active" not in items[2].get_attribute("class")
def test_low_high(self, single_plot_page: SinglePlotPage) -> None: source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(height=400, width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) num_input = NumericInput(value=4, low=-1, high=10) num_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(num_input, plot)) el = find_element_for(page.driver, num_input, "input") assert el.get_attribute('value') == "4" enter_text_in_element(page.driver, el, "30", click=2) assert el.get_attribute('value') == "10" enter_text_in_element(page.driver, el, "-10", click=2) assert el.get_attribute('value') == "-1"
def test_spinner_smallest_step(self, bokeh_model_page) -> None: spinner = Spinner(value=0, low=0, high=1, step=1e-16, css_classes=["foo"]) spinner.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(spinner) input_el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, input_el, "0.43654644333534") results = page.results assert results['value'] == 0.43654644333534 enter_text_in_element(page.driver, input_el, "1e-16", click=2) results = page.results assert results['value'] == 1e-16 assert page.has_no_console_errors()
def test_displays_menu(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", ], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "100", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 1 assert items[0].text == "100001" assert "bk-active" in items[0].get_attribute("class") el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute("class") assert "bk-active" in items[1].get_attribute("class") assert page.has_no_console_errors()
def test_case_insensitivity(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], case_sensitive=False, completions=["100001", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB"], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 4 assert items[0].text == "aaaaaa" assert items[1].text == "aaabbb" assert items[2].text == "AAAaAA" assert items[3].text == "AAABbB" assert "bk-active" in items[0].get_attribute("class") el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" not in items[0].get_attribute("class") assert "bk-active" in items[1].get_attribute("class") assert page.has_no_console_errors()
def test_case_insensitivity(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput( title="title", case_sensitive=False, completions=["100001", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB"]) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 4 assert items[0].text == "aaaaaa" assert items[1].text == "aaabbb" assert items[2].text == "AAAaAA" assert items[3].text == "AAABbB" assert "bk-active" in items[0].get_attribute('class') el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_case_sensitivity(self, bokeh_model_page) -> None: # case_sensitive=True by default text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=["100001", "aAaaaa", "aAaBbb", "AAAaAA", "aAaBbB"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "aAaaaa" assert items[1].text == "aAaBbb" assert items[2].text == "aAaBbB" assert "bk-active" in items[0].get_attribute('class') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aAaBbb" assert items[1].text == "aAaBbB" assert "bk-active" in items[0].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aAaBbb" assert items[1].text == "aAaBbB" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_displays_menu(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput(title="title", completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374" ]) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "100", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 1 assert items[0].text == "100001" assert "bk-active" in items[0].get_attribute('class') el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_displays_menu(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "100", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 1 assert items[0].text == "100001" assert "bk-active" in items[0].get_attribute('class') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_server_on_change_round_trip_menu_entry(self, bokeh_server_page): page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) enter_text_in_element(page.driver, el, Keys.DOWN, click=0) page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"] enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) items[1].click() page.click_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"]
def test_server_on_change_round_trip(self, bokeh_server_page) -> None: page = bokeh_server_page(modify_doc) input_el = page.driver.find_element_by_css_selector('.foo input') # same value enter_text_in_element(page.driver, input_el, "4", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == ["a", "b"] # new valid value enter_text_in_element(page.driver, input_el, "5", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == [4, 5] # new overflow value enter_text_in_element(page.driver, input_el, "11", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == [5, 10] # new underflow value enter_text_in_element(page.driver, input_el, "-2", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == [10, -1] # new decimal value input_el.clear( ) #negative previous values needs a triple click to be selected enter_text_in_element(page.driver, input_el, "5.1") page.click_custom_action() results = page.results assert results['data']['val'] == [None, 5.1] # new decimal value test rounding enter_text_in_element(page.driver, input_el, "5.19", click=2) page.click_custom_action() results = page.results assert results['data']['val'] == [5.1, 5.19] assert input_el.get_attribute('value') == '5.2'
def test_spinner_spinning_events(self, bokeh_model_page) -> None: spinner = Spinner(value=0, low=0, high=1, step=0.01, css_classes=["foo"]) spinner.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(spinner) input_el = page.driver.find_element_by_css_selector('.foo input') btn_up_el = page.driver.find_element_by_css_selector( '.foo .bk-spin-btn-up') btn_down_el = page.driver.find_element_by_css_selector( '.foo .bk-spin-btn-down') enter_text_in_element(page.driver, input_el, "0.5") results = page.results assert results['value'] == 0.5 #click btn up actions = ActionChains(page.driver) actions.click(on_element=btn_up_el) actions.perform() results = page.results assert results['value'] == 0.51 #dbl click btn down actions = ActionChains(page.driver) actions.double_click(on_element=btn_down_el) actions.perform() results = page.results assert results['value'] == 0.49 #arrow up actions = ActionChains(page.driver) actions.click(on_element=input_el) actions.send_keys(Keys.ARROW_UP) actions.perform() results = page.results assert results['value'] == 0.50 #arrow down actions = ActionChains(page.driver) actions.click(on_element=input_el) actions.key_down(Keys.ARROW_DOWN) actions.perform() results = page.results assert results['value'] == 0.49 #page up actions = ActionChains(page.driver) actions.click(on_element=input_el) actions.key_down(Keys.PAGE_UP) actions.perform() results = page.results assert results['value'] == 0.59 #page down actions = ActionChains(page.driver) actions.click(on_element=input_el) actions.key_down(Keys.PAGE_DOWN) actions.perform() results = page.results assert results['value'] == 0.49 assert page.has_no_console_errors()
def test_server_on_change_round_trip(self, bokeh_server_page: BokehServerPage) -> None: spinner = Spinner(low=-1, high=10, step=0.1, value=4, format="0[.]0") page = bokeh_server_page(mk_modify_doc(spinner)) input_el = find_element_for(page.driver, spinner, "input") # same value enter_text_in_element(page.driver, input_el, "4", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["a", "b"] # new valid value enter_text_in_element(page.driver, input_el, "5", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [4, 5] # new overflow value enter_text_in_element(page.driver, input_el, "11", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [5, 10] # new underflow value enter_text_in_element(page.driver, input_el, "-2", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [10, -1] # new decimal value input_el.clear() #negative previous values needs a triple click to be selected enter_text_in_element(page.driver, input_el, "5.1") page.eval_custom_action() results = page.results assert results['data']['val'] == [None, 5.1] # new decimal value test rounding enter_text_in_element(page.driver, input_el, "5.19", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [5.1, 5.19] assert input_el.get_attribute('value') == '5.2'
def test_arrow_cannot_escape_menu(self, bokeh_model_page) -> None: text_input = AutocompleteInput(title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374" ]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow down moves to second item enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow down again has no effect enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow up moves to first item enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow up again has no effect enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') assert page.has_no_console_errors()