diff --git a/tests/conftest.py b/tests/conftest.py index 2dedc570..3e513c7a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ import pytest from selenium.webdriver.chrome.options import Options as ChromeOptions +from selenium.webdriver.common.by import By def pytest_configure(config): @@ -216,14 +217,7 @@ def get_exception_message(self, e): :return: Error messaged extracted from an `WebDriverException`, raised when errors happen during tests using Selenium. """ - if self.selenium.name == 'phantomjs': - # PhantomJS driver for whatever reason encodes error message - # in JSON... - import json - - return json.loads(e.value.msg)["errorMessage"] - else: - return e.value.msg + return e.value.msg @pytest.fixture @@ -335,7 +329,7 @@ def get_container(self): :rtype: selenium.webdriver.remote.webelement.WebElement :return: DIV element containing graph drawing widget. """ - return self.selenium.find_element_by_id('graphContainer') + return self.selenium.find_element(By.ID, 'graphContainer') def get_container_size(self): """ @@ -398,8 +392,8 @@ def get(v, attr): ) color = color.lower() - edge = self.selenium.find_elements_by_css_selector( - 'path[stroke="{}"][d~="M"][d~="{}"][d~="{}"]'.format(color, h_right, v_center) + edge = self.selenium.find_elements( + By.CSS_SELECTOR, f'path[stroke="{color}"][d~="M"][d~="{h_right}"][d~="{v_center}"]' ) assert len(edge) <= 1 return edge[0] if len(edge) == 1 else None @@ -415,14 +409,14 @@ def get_label_element(self, cell): # vertices aren't child to cell drawing node in SVG of mxGraph, they # actually share a same parent node which contains both cell drawing # and text at a same level. - common = cell.find_element_by_xpath('../..') + common = cell.find_element(By.XPATH, '../..') if self.selenium.execute_script('return graphEditor.graph.isHtmlLabel()'): # If HTML labels are enabled, label is a bit more complicated... - g = common.find_element_by_css_selector('g[style]>g[transform]') - label = g.find_element_by_tag_name('div') - label = label.find_element_by_tag_name('div') + g = common.find_element(By.CSS_SELECTOR, 'g[style]>g[transform]') + label = g.find_element(By.TAG_NAME, 'div') + label = label.find_element(By.TAG_NAME, 'div') else: - label = common.find_element_by_css_selector('g>g>text') + label = common.find_element(By.CSS_SELECTOR, 'g>g>text') return label def get_edge_position(self, edge): @@ -511,8 +505,8 @@ def get_table_title(self, table): :rtype: str :return: Table title. """ - title = table.find_element_by_css_selector('table.table-cell-title') - return title.find_element_by_tag_name('tr').text + title = table.find_element(By.CSS_SELECTOR, 'table.table-cell-title') + return title.find_element(By.TAG_NAME, 'tr').text def get_table_contents(self, table): """ @@ -521,8 +515,8 @@ def get_table_contents(self, table): :rtype: str :return: Table contents. """ - contents = table.find_element_by_css_selector('table.table-cell-contents') - return [i.text for i in contents.find_elements_by_tag_name('td')] + contents = table.find_element(By.CSS_SELECTOR, 'table.table-cell-contents') + return [i.text for i in contents.find_elements(By.TAG_NAME, 'td')] def select_vertex(self, vertex): """ @@ -537,9 +531,10 @@ def select_vertex(self, vertex): # because of element mismatch. This is an attempt to click in the # bottom right part of vertex that *usually* doesn't seem to have # anything over it. - actions.move_to_element_with_offset( - vertex, int(vertex.get_attribute('width')) - 5, int(vertex.get_attribute('height')) - 5 - ) + x_offset = int(vertex.get_attribute('width')) // 2 + y_offset = int(vertex.get_attribute('height')) // 2 + assert (x_offset > 0) and (y_offset > 0) + actions.move_to_element_with_offset(vertex, x_offset, y_offset) actions.click() actions.perform() @@ -658,7 +653,7 @@ def get_vertices(self): "return graphEditor.graph.getStylesheet().getDefaultVertexStyle()[mxConstants.STYLE_FILLCOLOR]" # noqa ) color = color.lower() - vertices = self.selenium.find_elements_by_css_selector('g>g>rect[fill="{}"]'.format(color)) + vertices = self.selenium.find_elements(By.CSS_SELECTOR, f'g>g>rect[fill="{color}"]') return vertices def remove_cells(self, *cell_ids): @@ -733,7 +728,7 @@ def get_vertex(self): # tags); # * A tag with its label in SVG (which is a grandchild of two # consecutive tags) - rect = self.selenium.find_elements_by_css_selector('g>g>rect[fill="{}"]'.format(color)) + rect = self.selenium.find_elements(By.CSS_SELECTOR, f'g>g>rect[fill="{color}"]') assert len(rect) <= 1 return rect[0] if rect else None @@ -751,8 +746,8 @@ def __init__(self, selenium, host): ) def get_port(self): - port_elements = self.selenium.find_elements_by_css_selector( - f'g>g>ellipse[fill="{self.port_color}"]' + port_elements = self.selenium.find_elements( + By.CSS_SELECTOR, f'g>g>ellipse[fill="{self.port_color}"]' ) assert len(port_elements) <= 1 return port_elements[0] if port_elements else None @@ -780,7 +775,7 @@ def get_vertex(self): # tags); # * A tag with its label in SVG (which is a grandchild of two # consecutive tags) - rect = self.selenium.find_elements_by_css_selector('g>g>rect[fill="{}"]'.format(color)) + rect = self.selenium.find_elements(By.CSS_SELECTOR, f'g>g>rect[fill="{color}"]') assert len(rect) <= 1 return rect[0] if rect else None @@ -860,7 +855,7 @@ def __init__(self, selenium, host): def get_decorations(self): style = 'purple' selector = 'g>g>rect[fill="{}"]'.format(self.host.styles[style]['fill_color']) - decoration = self.selenium.find_elements_by_css_selector(selector) + decoration = self.selenium.find_elements(By.CSS_SELECTOR, selector) return decoration @@ -891,8 +886,8 @@ def __init__(self, selenium, host): ] def get_tables(self): - titles = self.selenium.find_elements_by_css_selector('div>table.table-cell-title') - return [web_el.find_element_by_xpath('../..') for web_el in titles] + titles = self.selenium.find_elements(By.CSS_SELECTOR, 'div>table.table-cell-title') + return [web_el.find_element(By.XPATH, '../..') for web_el in titles] class Graph1Table(BaseGraphCase): @@ -922,8 +917,8 @@ def __init__(self, selenium, host): ] def get_tables(self): - titles = self.selenium.find_elements_by_css_selector('div>table.table-cell-title') - return [web_el.find_element_by_xpath('../..') for web_el in titles] + titles = self.selenium.find_elements(By.CSS_SELECTOR, 'div>table.table-cell-title') + return [web_el.find_element(By.XPATH, '../..') for web_el in titles] def _wait_graph_page_ready(host, selenium): diff --git a/tests/test_js_graph.py b/tests/test_js_graph.py index 5c9ce48d..961da679 100644 --- a/tests/test_js_graph.py +++ b/tests/test_js_graph.py @@ -6,6 +6,7 @@ from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import WebDriverException from selenium.webdriver import ActionChains +from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import qmxgraph.constants @@ -152,15 +153,17 @@ def test_insert_edge_error_endpoint_not_found(graph_cases, selenium_extras) -> N with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.insertEdge", invalid_source_id, graph.get_id(vertex)) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - invalid_source_id + assert ( + f"Unable to find cell with id {invalid_source_id}" + in selenium_extras.get_exception_message(e) ) with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.insertEdge", graph.get_id(vertex), invalid_target_id) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - invalid_target_id + assert ( + f"Unable to find cell with id {invalid_target_id}" + in selenium_extras.get_exception_message(e) ) @@ -255,12 +258,12 @@ def test_group(graph_cases) -> None: group_fill = graph.host.styles['group']['fill_color'] group_selector = 'g>g>rect[fill="{}"]'.format(group_fill) - group = graph.selenium.find_elements_by_css_selector(group_selector) + group = graph.selenium.find_elements(By.CSS_SELECTOR, group_selector) assert len(group) == 1 # Ungroup selected vertices graph.selenium.execute_script("api.ungroup()") - group = graph.selenium.find_elements_by_css_selector(group_selector) + group = graph.selenium.find_elements(By.CSS_SELECTOR, group_selector) assert not group @@ -274,11 +277,11 @@ def test_toggle_outline(selenium, host, wait_graph_page_ready) -> None: # By default, outline starts hidden. Basically this means mxGraph's window # component used to shown outline doesn't exist yet. with pytest.raises(NoSuchElementException): - selenium.find_element_by_css_selector('div.mxWindow') + selenium.find_element(By.CSS_SELECTOR, 'div.mxWindow') # Once shown, outline is displayed in a mxGraph's window component selenium.execute_script("api.toggleOutline()") - outline = selenium.find_element_by_css_selector('div.mxWindow') + outline = selenium.find_element(By.CSS_SELECTOR, 'div.mxWindow') assert outline is not None # However once toggled back to hidden, it is not destroyed but simply @@ -300,9 +303,9 @@ def test_toggle_grid(selenium, host, grid, wait_graph_page_ready) -> None: if not grid: selenium.execute_script("api.toggleGrid()") - container = selenium.find_element_by_css_selector('div.graph') + container = selenium.find_element(By.CSS_SELECTOR, 'div.graph') assert container.get_attribute('id') == 'graphContainer' - assert container.get_attribute('class') == 'graph' if grid else 'graph hide-bg' + assert container.get_attribute('class') == ('graph' if grid else 'graph hide-bg') @pytest.mark.parametrize('snap', [True, False]) @@ -441,16 +444,12 @@ def test_set_visible_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.set_visible(cell_id, False) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) with pytest.raises(WebDriverException) as e: graph.is_visible(cell_id) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_get_geometry_plain(graph_cases) -> None: @@ -465,7 +464,7 @@ def test_get_geometry_plain(graph_cases) -> None: # Table geometry is dependent on how the contents are rendered. # Using `pytest.approx` to account for platform differences. obtained_table_geometry = graph.get_geometry(graph.get_tables()[0]) - assert pytest.approx(obtained_table_geometry, rel=0.1) == [20, 60, 108, 72] + assert pytest.approx(obtained_table_geometry, rel=0.1) == [20, 60, 100, 70] def test_get_geometry_error_not_found(graph_cases, selenium_extras) -> None: @@ -479,9 +478,7 @@ def test_get_geometry_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.get_geometry(cell_id) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_insert_table(graph_cases) -> None: @@ -575,7 +572,7 @@ def test_table_with_image(graph_cases) -> None: } graph.eval_js_function('api.updateTable', table_id, contents, '') - image_elements = graph.selenium.find_elements_by_css_selector('.table-cell-contents img') + image_elements = graph.selenium.find_elements(By.CSS_SELECTOR, '.table-cell-contents img') assert len(image_elements) == 1 image = image_elements[0] assert image.get_attribute('src').endswith('some-image-path') @@ -619,9 +616,7 @@ def test_update_table_error_not_found(graph_cases, selenium_extras) -> None: js.prepare_js_call('api.updateTable', table_id, contents, title) ) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - table_id - ) + assert f"Unable to find cell with id {table_id}" in selenium_extras.get_exception_message(e) def test_update_table_error_not_table(graph_cases, selenium_extras) -> None: @@ -640,7 +635,7 @@ def test_update_table_error_not_table(graph_cases, selenium_extras) -> None: js.prepare_js_call('api.updateTable', table_id, contents, title) ) - assert selenium_extras.get_exception_message(e) == "Cell is not a table" + assert "Cell is not a table" in selenium_extras.get_exception_message(e) def test_remove_cells(graph_cases) -> None: @@ -671,9 +666,7 @@ def test_remove_cells_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.eval_js_function('api.removeCells', [cell_id]) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_on_cells_removed(graph_cases) -> None: @@ -735,7 +728,7 @@ def test_custom_shapes(selenium, port, tmpdir, wait_graph_page_ready) -> None: ) def has_custom_shape(): - return bool(selenium.find_elements_by_css_selector('g>g>path[fill="#ffff00"]')) + return bool(selenium.find_elements(By.CSS_SELECTOR, 'g>g>path[fill="#ffff00"]')) with server.host(port=port.get(), styles=styles, stencils=stencils) as host: wait_graph_page_ready(host=host) @@ -819,9 +812,7 @@ def test_get_label_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.get_label(cell_id) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_has_cell(graph_cases) -> None: @@ -867,9 +858,7 @@ def test_get_cell_type_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.getCellType", cell_id) - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) @pytest.mark.parametrize( @@ -928,12 +917,13 @@ def test_insert_with_tags_error_value_not_string(graph_cases, cell_type, seleniu """ graph = graph_cases('empty') - tags = {'tagTest': 999} + tag_name = "tagTest" + tags = {tag_name: 999} with pytest.raises(WebDriverException) as e: insert_by_parametrized_type(graph, cell_type, tags=tags) - assert selenium_extras.get_exception_message(e) == "Tag '{}' is not a string".format("tagTest") + assert f"Tag '{tag_name}' is not a string" in selenium_extras.get_exception_message(e) @pytest.mark.parametrize( @@ -978,14 +968,16 @@ def test_set_get_tag_error_tag_not_found(graph_cases, cell_type, selenium_extras graph = graph_cases('empty') cell_id = insert_by_parametrized_type(graph, cell_type) - assert not graph.eval_js_function("api.hasTag", cell_id, "test") + tag_name = "test" + assert not graph.eval_js_function("api.hasTag", cell_id, tag_name) with pytest.raises(WebDriverException) as e: - graph.eval_js_function("api.getTag", cell_id, "test") + graph.eval_js_function("api.getTag", cell_id, tag_name) - assert selenium_extras.get_exception_message( - e - ) == "Tag '{}' not found in cell with id {}".format("test", cell_id) + assert ( + f"Tag '{tag_name}' not found in cell with id {cell_id}" + in selenium_extras.get_exception_message(e) + ) @pytest.mark.parametrize( @@ -1006,11 +998,12 @@ def test_set_get_tag_error_value_not_string(graph_cases, cell_type, selenium_ext graph = graph_cases('empty') cell_id = insert_by_parametrized_type(graph, cell_type) + tag_name = "test" with pytest.raises(WebDriverException) as e: - graph.eval_js_function("api.setTag", cell_id, "test", 999) + graph.eval_js_function("api.setTag", cell_id, tag_name, 999) - assert selenium_extras.get_exception_message(e) == "Tag '{}' is not a string".format("test") + assert f"Tag '{tag_name}' is not a string" in selenium_extras.get_exception_message(e) @pytest.mark.parametrize( @@ -1047,26 +1040,23 @@ def test_set_get_tag_error_cell_not_found(graph_cases, selenium_extras) -> None: cell_id = "999" + # Try to add tag to non exiting cell. with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.setTag", cell_id, "test", "foo") - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) + # Try to get tag from non exiting cell. with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.getTag", cell_id, "test") - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) + # Try to check if tag exist in non exiting cell. with pytest.raises(WebDriverException) as e: graph.eval_js_function("api.hasTag", cell_id, "test") - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_set_get_tag_without_initial_tag_support(graph_cases) -> None: @@ -1174,9 +1164,7 @@ def test_set_label_error_not_found(graph_cases, selenium_extras) -> None: with pytest.raises(WebDriverException) as e: graph.eval_js_function('api.setLabel', cell_id, 'foo') - assert selenium_extras.get_exception_message(e) == "Unable to find cell with id {}".format( - cell_id - ) + assert f"Unable to find cell with id {cell_id}" in selenium_extras.get_exception_message(e) def test_set_double_click_handler(graph_cases) -> None: @@ -1485,9 +1473,7 @@ def test_get_edge_terminals_error_edge_not_found(graph_cases, selenium_extras) - with pytest.raises(WebDriverException) as e: graph.eval_js_function('api.getEdgeTerminals', edge_id) - assert selenium_extras.get_exception_message(e) == "Unable to find edge with id {}".format( - edge_id - ) + assert f"Unable to find edge with id {edge_id}" in selenium_extras.get_exception_message(e) def test_get_edge_terminals_error_not_an_edge(graph_cases, selenium_extras) -> None: @@ -1501,8 +1487,9 @@ def test_get_edge_terminals_error_not_an_edge(graph_cases, selenium_extras) -> N with pytest.raises(WebDriverException) as e: graph.eval_js_function('api.getEdgeTerminals', graph.get_id(vertex)) - assert selenium_extras.get_exception_message(e) == "Cell with id {} is not an edge".format( - graph.get_id(vertex) + assert ( + f"Cell with id {graph.get_id(vertex)} is not an edge" + in selenium_extras.get_exception_message(e) ) @@ -1519,8 +1506,8 @@ def test_custom_font_family(graph_cases_factory, port) -> None: cases = graph_cases_factory(host) graph = cases("1v") - match = graph.selenium.find_elements_by_css_selector( - 'div[style*="font-family:"][style*="Helvetica"]' + match = graph.selenium.find_elements( + By.CSS_SELECTOR, 'div[style*="font-family:"][style*="Helvetica"]' ) assert len(match) == 1