From 0bbfcf99581d2e42f7c6bdc7e19879616df76e4d Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 12 Feb 2024 21:41:38 +0100 Subject: [PATCH 1/9] Remove version pin for Selenium --- requirements.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.in b/requirements.in index a67d51e..4ade41d 100644 --- a/requirements.in +++ b/requirements.in @@ -4,6 +4,5 @@ lxml metsrw pexpect requests -selenium<4 +selenium tenacity -urllib3<2 From 17bf7a04f2f41bf5a93dfda6c998153c52afa7e5 Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 12 Feb 2024 21:41:55 +0100 Subject: [PATCH 2/9] Upgrade Python dependencies --- requirements-dev.txt | 55 +++++++++++++++++++++++++++++++++++++++++--- requirements.txt | 41 +++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 993ea6f..429c780 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,6 +6,11 @@ # amclient==1.3.0 # via -r requirements.txt +attrs==23.2.0 + # via + # -r requirements.txt + # outcome + # trio behave==1.2.6 # via -r requirements.txt build==1.0.3 @@ -16,6 +21,7 @@ certifi==2024.2.2 # via # -r requirements.txt # requests + # selenium chardet==5.2.0 # via tox charset-normalizer==3.3.2 @@ -28,14 +34,24 @@ colorama==0.4.6 # via tox distlib==0.3.8 # via virtualenv +exceptiongroup==1.2.0 + # via + # -r requirements.txt + # trio + # trio-websocket filelock==3.13.1 # via # tox # virtualenv +h11==0.14.0 + # via + # -r requirements.txt + # wsproto idna==3.6 # via # -r requirements.txt # requests + # trio importlib-metadata==7.0.1 # via build lxml==5.1.0 @@ -44,6 +60,10 @@ lxml==5.1.0 # metsrw metsrw==0.5.1 # via -r requirements.txt +outcome==1.3.0.post0 + # via + # -r requirements.txt + # trio packaging==23.2 # via # build @@ -76,17 +96,29 @@ pyproject-api==1.6.1 # via tox pyproject-hooks==1.0.0 # via build +pysocks==1.7.1 + # via + # -r requirements.txt + # urllib3 requests==2.31.0 # via # -r requirements.txt # amclient -selenium==3.141.0 +selenium==4.17.2 # via -r requirements.txt six==1.16.0 # via # -r requirements.txt # behave # parse-type +sniffio==1.3.0 + # via + # -r requirements.txt + # trio +sortedcontainers==2.4.0 + # via + # -r requirements.txt + # trio tenacity==8.2.3 # via -r requirements.txt tomli==2.0.1 @@ -98,7 +130,20 @@ tomli==2.0.1 # tox tox==4.12.1 # via -r requirements-dev.in -urllib3==1.26.18 +trio==0.24.0 + # via + # -r requirements.txt + # selenium + # trio-websocket +trio-websocket==0.11.1 + # via + # -r requirements.txt + # selenium +typing-extensions==4.9.0 + # via + # -r requirements.txt + # selenium +urllib3[socks]==2.2.0 # via # -r requirements.txt # amclient @@ -108,11 +153,15 @@ virtualenv==20.25.0 # via tox wheel==0.42.0 # via pip-tools +wsproto==1.2.0 + # via + # -r requirements.txt + # trio-websocket zipp==3.17.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: pip==24.0 # via pip-tools -setuptools==69.0.3 +setuptools==69.1.0 # via pip-tools diff --git a/requirements.txt b/requirements.txt index ed11f7d..f137e86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,20 +6,36 @@ # amclient==1.3.0 # via -r requirements.in +attrs==23.2.0 + # via + # outcome + # trio behave==1.2.6 # via -r requirements.in certifi==2024.2.2 - # via requests + # via + # requests + # selenium charset-normalizer==3.3.2 # via requests +exceptiongroup==1.2.0 + # via + # trio + # trio-websocket +h11==0.14.0 + # via wsproto idna==3.6 - # via requests + # via + # requests + # trio lxml==5.1.0 # via # -r requirements.in # metsrw metsrw==0.5.1 # via -r requirements.in +outcome==1.3.0.post0 + # via trio parse==1.20.1 # via # behave @@ -30,21 +46,36 @@ pexpect==4.9.0 # via -r requirements.in ptyprocess==0.7.0 # via pexpect +pysocks==1.7.1 + # via urllib3 requests==2.31.0 # via # -r requirements.in # amclient -selenium==3.141.0 +selenium==4.17.2 # via -r requirements.in six==1.16.0 # via # behave # parse-type +sniffio==1.3.0 + # via trio +sortedcontainers==2.4.0 + # via trio tenacity==8.2.3 # via -r requirements.in -urllib3==1.26.18 +trio==0.24.0 + # via + # selenium + # trio-websocket +trio-websocket==0.11.1 + # via selenium +typing-extensions==4.9.0 + # via selenium +urllib3[socks]==2.2.0 # via - # -r requirements.in # amclient # requests # selenium +wsproto==1.2.0 + # via trio-websocket From 5a36c8c1e8b875adfa00bc7f8ff41d56ddd224e8 Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 12 Feb 2024 21:42:30 +0100 Subject: [PATCH 3/9] Update driver initializations --- amuser/selenium_ability.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/amuser/selenium_ability.py b/amuser/selenium_ability.py index 9f678fa..13c2f4a 100644 --- a/amuser/selenium_ability.py +++ b/amuser/selenium_ability.py @@ -8,7 +8,6 @@ from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait @@ -40,23 +39,14 @@ def get_driver(self): if self.driver_name == "Chrome": options = webdriver.ChromeOptions() if headless: - options.add_argument("headless") - driver = webdriver.Chrome(chrome_options=options) + options.add_argument("--headless=new") + driver = webdriver.Chrome(options=options) driver.set_window_size(1700, 900) elif self.driver_name == "Firefox": - fp = webdriver.FirefoxProfile() - fp.set_preference("dom.max_chrome_script_run_time", 0) - fp.set_preference("dom.max_script_run_time", 0) options = webdriver.FirefoxOptions() if headless: options.add_argument("-headless") - capabilities = DesiredCapabilities.FIREFOX.copy() - capabilities["moz:webdriverClick"] = False - driver = webdriver.Firefox( - firefox_profile=fp, - firefox_options=options, - desired_capabilities=capabilities, - ) + driver = webdriver.Firefox(options=options) else: driver = getattr(webdriver, self.driver_name)() driver.set_script_timeout(self.apathetic_wait) From 8e3be38680e43cf3eec420436e701b6f9557c1bb Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 12 Feb 2024 22:43:52 +0100 Subject: [PATCH 4/9] Update find_element_by_id calls --- amuser/am_browser_ability.py | 46 ++++++++++--------- amuser/am_browser_auth_ability.py | 8 ++-- amuser/am_browser_file_explorer_ability.py | 4 +- amuser/am_browser_ingest_ability.py | 6 +-- ...m_browser_preservation_planning_ability.py | 25 +++++----- amuser/am_browser_ss_ability.py | 21 +++++---- amuser/am_browser_transfer_ability.py | 2 +- amuser/am_browser_transfer_ingest_ability.py | 3 +- features/steps/utils.py | 5 +- 9 files changed, 64 insertions(+), 56 deletions(-) diff --git a/amuser/am_browser_ability.py b/amuser/am_browser_ability.py index 0a0c0b0..35e0a3e 100644 --- a/amuser/am_browser_ability.py +++ b/amuser/am_browser_ability.py @@ -47,8 +47,8 @@ class ArchivematicaBrowserAbility( def ss_api_key(self): if not self._ss_api_key: self.driver.get(self.get_ss_login_url()) - self.driver.find_element_by_id("id_username").send_keys(self.ss_username) - self.driver.find_element_by_id("id_password").send_keys(self.ss_password) + self.driver.find_element(By.ID, "id_username").send_keys(self.ss_username) + self.driver.find_element(By.ID, "id_password").send_keys(self.ss_password) self.driver.find_element_by_css_selector( c.varvn("SELECTOR_SS_LOGIN_BUTTON", self.vn) ).click() @@ -95,9 +95,11 @@ def wait_for_aip_in_archival_storage(self, aip_uuid): Select( self.driver.find_element_by_css_selector('select[title="query type"]') ).select_by_visible_text("Phrase") - self.driver.find_element_by_id("search_submit").click() + self.driver.find_element(By.ID, "search_submit").click() self.wait_for_presence("#archival-storage-entries_info") - summary_el = self.driver.find_element_by_id("archival-storage-entries_info") + summary_el = self.driver.find_element( + By.ID, "archival-storage-entries_info" + ) if summary_el.text.strip() == "Showing 0 to 0 of 0 entries": attempts += 1 if attempts > max_attempts: @@ -118,13 +120,13 @@ def request_aip_delete(self, aip_uuid): self.wait_for_presence(delete_tab_selector, timeout=self.apathetic_wait) while True: try: - self.driver.find_element_by_id("id_delete-uuid").click() + self.driver.find_element(By.ID, "id_delete-uuid").click() break except (ElementNotVisibleException, ElementNotInteractableException): self.driver.find_element_by_css_selector(delete_tab_selector).click() time.sleep(self.optimistic_wait) - self.driver.find_element_by_id("id_delete-uuid").send_keys(aip_uuid) - self.driver.find_element_by_id("id_delete-reason").send_keys("Cuz wanna") + self.driver.find_element(By.ID, "id_delete-uuid").send_keys(aip_uuid) + self.driver.find_element(By.ID, "id_delete-reason").send_keys("Cuz wanna") self.driver.find_element_by_css_selector( 'button[name="submit-delete-form"]' ).click() @@ -218,9 +220,9 @@ def wait_for_dip_in_transfer_backlog(self, dip_uuid): Select( self.driver.find_element_by_css_selector('select[title="query type"]') ).select_by_visible_text("Phrase") - self.driver.find_element_by_id("search_submit").click() + self.driver.find_element(By.ID, "search_submit").click() self.wait_for_presence("#backlog-entries_info") - summary_el = self.driver.find_element_by_id("backlog-entries_info") + summary_el = self.driver.find_element(By.ID, "backlog-entries_info") if summary_el.text.strip() == "Showing 0 to 0 of 0 entries": seconds += 1 if seconds > max_seconds: @@ -269,7 +271,7 @@ def configure_handle(self, **kwargs): self.navigate(self.get_handle_config_url()) for key, val in kwargs.items(): dom_id = "id_" + key - input_el = self.driver.find_element_by_id(dom_id) + input_el = self.driver.find_element(By.ID, dom_id) if input_el.tag_name == "select": Select(input_el).select_by_visible_text(val) elif input_el.get_attribute("type") == "checkbox": @@ -342,7 +344,7 @@ def get_processing_config_decision_options(self, **kwargs): else: if not decision_id.startswith("id_"): decision_id = "id_" + decision_id - decision_el = self.driver.find_element_by_id(decision_id) + decision_el = self.driver.find_element(By.ID, decision_id) options = [] if decision_el.tag_name == "select": for option_el in decision_el.find_elements_by_tag_name("option"): @@ -389,7 +391,7 @@ def set_processing_config_decision(self, **kwargs): else: if not decision_id.startswith("id_"): decision_id = "id_" + decision_id - decision_el = self.driver.find_element_by_id(decision_id) + decision_el = self.driver.find_element(By.ID, decision_id) if decision_el.tag_name == "select": decision_select = Select(decision_el) if choice_value_attr is not None: @@ -520,7 +522,7 @@ def setup_new_install(self): ss_api_key = self.ss_api_key self.create_first_user() self.wait_for_presence("#id_storage_service_apikey", 100) - self.driver.find_element_by_id("id_storage_service_apikey").send_keys( + self.driver.find_element(By.ID, "id_storage_service_apikey").send_keys( ss_api_key ) self.driver.find_element_by_css_selector( @@ -531,16 +533,18 @@ def create_first_user(self): """Create a test user via the /installer/welcome/ page interface.""" self.driver.get(self.get_installer_welcome_url()) self.wait_for_presence("#id_org_name") - self.driver.find_element_by_id("id_org_name").send_keys(c.DEFAULT_AM_USERNAME) - self.driver.find_element_by_id("id_org_identifier").send_keys( + self.driver.find_element(By.ID, "id_org_name").send_keys(c.DEFAULT_AM_USERNAME) + self.driver.find_element(By.ID, "id_org_identifier").send_keys( + c.DEFAULT_AM_USERNAME + ) + self.driver.find_element(By.ID, "id_username").send_keys(c.DEFAULT_AM_USERNAME) + self.driver.find_element(By.ID, "id_first_name").send_keys( c.DEFAULT_AM_USERNAME ) - self.driver.find_element_by_id("id_username").send_keys(c.DEFAULT_AM_USERNAME) - self.driver.find_element_by_id("id_first_name").send_keys(c.DEFAULT_AM_USERNAME) - self.driver.find_element_by_id("id_last_name").send_keys(c.DEFAULT_AM_USERNAME) - self.driver.find_element_by_id("id_email").send_keys("test@gmail.com") - self.driver.find_element_by_id("id_password1").send_keys(c.DEFAULT_AM_PASSWORD) - self.driver.find_element_by_id("id_password2").send_keys(c.DEFAULT_AM_PASSWORD) + self.driver.find_element(By.ID, "id_last_name").send_keys(c.DEFAULT_AM_USERNAME) + self.driver.find_element(By.ID, "id_email").send_keys("test@gmail.com") + self.driver.find_element(By.ID, "id_password1").send_keys(c.DEFAULT_AM_PASSWORD) + self.driver.find_element(By.ID, "id_password2").send_keys(c.DEFAULT_AM_PASSWORD) self.driver.find_element_by_tag_name("button").click() continue_button_selector = "input[value=Continue]" self.wait_for_presence(continue_button_selector, 100) diff --git a/amuser/am_browser_auth_ability.py b/amuser/am_browser_auth_ability.py index 51a8a67..3638d9f 100644 --- a/amuser/am_browser_auth_ability.py +++ b/amuser/am_browser_auth_ability.py @@ -29,9 +29,9 @@ def login(self): WebDriverWait(self.driver, self.pessimistic_wait).until(element_present) except TimeoutException: logger.warning("Timed out when waiting for login page to load") - username_elem = self.driver.find_element_by_id(username_input_id) + username_elem = self.driver.find_element(By.ID, username_input_id) username_elem.send_keys(self.am_username) - password_elem = self.driver.find_element_by_id(password_input_id) + password_elem = self.driver.find_element(By.ID, password_input_id) password_elem.send_keys(self.am_password) submit_button_elem = self.driver.find_element_by_tag_name("button") submit_button_elem.click() @@ -46,9 +46,9 @@ def login_ss(self): WebDriverWait(self.driver, self.pessimistic_wait).until(element_present) except TimeoutException: logger.warning("Timed out when waiting for SS login page to load") - username_elem = self.driver.find_element_by_id(username_input_id) + username_elem = self.driver.find_element(By.ID, username_input_id) username_elem.send_keys(self.ss_username) - password_elem = self.driver.find_element_by_id(password_input_id) + password_elem = self.driver.find_element(By.ID, password_input_id) password_elem.send_keys(self.ss_password) submit_button_elem = self.driver.find_element_by_css_selector( "input[type=submit]" diff --git a/amuser/am_browser_file_explorer_ability.py b/amuser/am_browser_file_explorer_ability.py index d889b8e..76711c3 100644 --- a/amuser/am_browser_file_explorer_ability.py +++ b/amuser/am_browser_file_explorer_ability.py @@ -115,7 +115,7 @@ def click_add_folder(self, folder_id): """ block = WebDriverWait(self.driver, 10) block.until(EC.presence_of_element_located((By.ID, folder_id))) - folder_elem = self.driver.find_element_by_id(folder_id) + folder_elem = self.driver.find_element(By.ID, folder_id) hover = ActionChains(self.driver).move_to_element(folder_elem) hover.perform() time.sleep(self.micro_wait) # seems to be necessary (! jQuery animations?) @@ -200,7 +200,7 @@ def click_folder_old_browser(self, folder_id, is_file=False): """ block = WebDriverWait(self.driver, 10) block.until(EC.presence_of_element_located((By.ID, folder_id))) - folder_elem = self.driver.find_element_by_id(folder_id) + folder_elem = self.driver.find_element(By.ID, folder_id) hover = ActionChains(self.driver).move_to_element(folder_elem) hover.perform() time.sleep(self.micro_wait) # seems to be necessary (! jQuery animations?) diff --git a/amuser/am_browser_ingest_ability.py b/amuser/am_browser_ingest_ability.py index adb9fa4..6970bdf 100644 --- a/amuser/am_browser_ingest_ability.py +++ b/amuser/am_browser_ingest_ability.py @@ -178,12 +178,12 @@ def _navigate_to_aip_directory_and_click(self, path): def add_dummy_metadata(self, sip_uuid): self.navigate(self.get_ingest_url()) - self.driver.find_element_by_id( - f"sip-row-{sip_uuid}" + self.driver.find_element( + By.ID, f"sip-row-{sip_uuid}" ).find_element_by_css_selector("a.btn_show_metadata").click() self.navigate(self.get_metadata_add_url(sip_uuid)) for attr in self.metadata_attrs: - self.driver.find_element_by_id(f"id_{attr}").send_keys(self.dummy_val) + self.driver.find_element(By.ID, f"id_{attr}").send_keys(self.dummy_val) try: self.driver.find_element_by_css_selector("input[value=Create]").click() except NoSuchElementException: diff --git a/amuser/am_browser_preservation_planning_ability.py b/amuser/am_browser_preservation_planning_ability.py index 9d96966..bbfa32c 100644 --- a/amuser/am_browser_preservation_planning_ability.py +++ b/amuser/am_browser_preservation_planning_ability.py @@ -2,6 +2,7 @@ import logging from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from . import selenium_ability @@ -43,7 +44,7 @@ def wait_for_rule_edit_interface(self): self.wait_for_presence("input[type=submit]") def set_fpr_command(self, command_name): - command_select_el = self.driver.find_element_by_id("id_f-command") + command_select_el = self.driver.find_element(By.ID, "id_f-command") command_select_el.click() Select(command_select_el).select_by_visible_text(command_name) @@ -74,7 +75,7 @@ def navigate_to_first_policy_check_validation_command(self): """ policy_command_url = None policy_command_descriptions = [] - commands_table_el = self.driver.find_element_by_id("DataTables_Table_0") + commands_table_el = self.driver.find_element(By.ID, "DataTables_Table_0") for row_el in commands_table_el.find_elements_by_tag_name("tr"): try: anchor_el = row_el.find_element_by_tag_name("a") @@ -149,19 +150,19 @@ def save_policy_check_command(self, policy_command, description): description, ) self.navigate(self.get_create_command_url()) - for option in self.driver.find_element_by_id( - "id_tool" + for option in self.driver.find_element( + By.ID, "id_tool" ).find_elements_by_tag_name("option"): if "MediaConch" in option.text: option.click() break - self.driver.find_element_by_id("id_description").send_keys(description) + self.driver.find_element(By.ID, "id_description").send_keys(description) js_script = 'document.getElementById("id_command").value =' " `{}`;".format( policy_command ) self.driver.execute_script(js_script) - self.driver.find_element_by_id("id_script_type").send_keys("Python") - self.driver.find_element_by_id("id_command_usage").send_keys("Validation") + self.driver.find_element(By.ID, "id_script_type").send_keys("Python") + self.driver.find_element(By.ID, "id_command_usage").send_keys("Validation") self.driver.find_element_by_css_selector("input[type=submit]").click() logger.info("Created the FPR policy check command") @@ -184,13 +185,13 @@ def ensure_fpr_rule(self, purpose, format_, command_description): return logger.info("Creating the needed FPR rule.") self.navigate(self.get_create_rule_url()) - Select(self.driver.find_element_by_id("id_f-purpose")).select_by_visible_text( + Select(self.driver.find_element(By.ID, "id_f-purpose")).select_by_visible_text( purpose ) - Select(self.driver.find_element_by_id("id_f-format")).select_by_visible_text( + Select(self.driver.find_element(By.ID, "id_f-format")).select_by_visible_text( format_ ) - Select(self.driver.find_element_by_id("id_f-command")).select_by_visible_text( + Select(self.driver.find_element(By.ID, "id_f-command")).select_by_visible_text( command_description ) self.driver.find_element_by_css_selector("input[type=submit]").click() @@ -202,7 +203,7 @@ def fpr_rule_already_exists(self, purpose, format_, command_description): """ self.navigate(self.get_rules_url()) self.search_for_fpr_rule(purpose, format_, command_description) - info_el = self.driver.find_element_by_id("DataTables_Table_0_info") + info_el = self.driver.find_element(By.ID, "DataTables_Table_0_info") if info_el.text.strip().startswith("Showing 0 to 0 of 0 entries"): return False return True @@ -221,7 +222,7 @@ def ensure_fpr_rule_enabled(self, purpose, format_, command_description): self.navigate(self.get_rules_url()) self.search_for_fpr_rule(purpose, format_, command_description) self.wait_for_presence("#DataTables_Table_0_info") - info_el = self.driver.find_element_by_id("DataTables_Table_0_info") + info_el = self.driver.find_element(By.ID, "DataTables_Table_0_info") if info_el.text.strip().startswith("Showing 0 to 0 of 0 entries"): return disabled_rules = [ diff --git a/amuser/am_browser_ss_ability.py b/amuser/am_browser_ss_ability.py index bc35d73..265915d 100644 --- a/amuser/am_browser_ss_ability.py +++ b/amuser/am_browser_ss_ability.py @@ -4,6 +4,7 @@ import time from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from . import base @@ -31,8 +32,8 @@ def approve_aip_delete_request(self, aip_uuid): SS GUI. """ self.navigate(self.get_ss_package_delete_request_url()) - self.driver.find_element_by_id( - "DataTables_Table_0_filter" + self.driver.find_element( + By.ID, "DataTables_Table_0_filter" ).find_element_by_tag_name("input").send_keys(aip_uuid) matching_rows = [] for row_el in self.driver.find_elements_by_css_selector( @@ -125,7 +126,7 @@ def create_ss_space(self, attributes): form_el = self.driver.find_element_by_css_selector( 'form[action="/spaces/create/"]' ) - protocol_el = self.driver.find_element_by_id("protocol_form") + protocol_el = self.driver.find_element(By.ID, "protocol_form") for parent in (form_el, protocol_el): for p_el in parent.find_elements_by_tag_name("p"): for el in p_el.find_elements_by_css_selector("*"): @@ -134,7 +135,7 @@ def create_ss_space(self, attributes): for key, val in attributes.items(): if key.lower() == label_text: input_id = el.get_attribute("for") - input_el = self.driver.find_element_by_id(input_id) + input_el = self.driver.find_element(By.ID, input_id) if input_el.tag_name == "select": Select(input_el).select_by_visible_text(val) else: @@ -164,7 +165,7 @@ def create_ss_location(self, space_uuid, attributes): for key, val in attributes.items(): if key.lower() == label_text: input_id = el.get_attribute("for") - input_el = self.driver.find_element_by_id(input_id) + input_el = self.driver.find_element(By.ID, input_id) if input_el.tag_name == "select": Select(input_el).select_by_visible_text(val) else: @@ -175,7 +176,7 @@ def create_ss_location(self, space_uuid, attributes): # be changed for setups with multiple pipelines. if label_text == "pipeline": input_id = el.get_attribute("for") - select_el = self.driver.find_element_by_id(input_id) + select_el = self.driver.find_element(By.ID, input_id) select = Select(select_el) select.select_by_index(0) self.driver.find_element_by_css_selector("input[type=submit]").click() @@ -329,7 +330,7 @@ def import_gpg_key(self, key_path): """ self.navigate(self.get_import_gpg_key_url()) with open(key_path) as filei: - self.driver.find_element_by_id("id_ascii_armor").send_keys(filei.read()) + self.driver.find_element(By.ID, "id_ascii_armor").send_keys(filei.read()) self.driver.find_element_by_css_selector("input[type=submit]").click() self.wait_for_presence("div.alert", 20) return self.driver.find_element_by_css_selector("div.alert").text.strip() @@ -427,8 +428,8 @@ def create_new_gpg_key(self): self.navigate(self.get_create_gpg_key_url()) new_key_name = f"GPGKey {utils.unixtimestamp()}" new_key_email = "{}@example.com".format(new_key_name.lower().replace(" ", "")) - self.driver.find_element_by_id("id_name_real").send_keys(new_key_name) - self.driver.find_element_by_id("id_name_email").send_keys(new_key_email) + self.driver.find_element(By.ID, "id_name_real").send_keys(new_key_name) + self.driver.find_element(By.ID, "id_name_email").send_keys(new_key_email) self.driver.find_element_by_css_selector("input[type=submit]").click() self.wait_for_presence("div.alert-success", self.nihilistic_wait) alert_text = self.driver.find_element_by_css_selector("div.alert-success").text @@ -441,7 +442,7 @@ def change_encrypted_space_key(self, space_uuid, new_key_repr=None): any other key. """ self.navigate(self.get_space_edit_url(space_uuid)) - select = Select(self.driver.find_element_by_id("id_protocol-key")) + select = Select(self.driver.find_element(By.ID, "id_protocol-key")) if new_key_repr: select.select_by_visible_text(new_key_repr) else: diff --git a/amuser/am_browser_transfer_ability.py b/amuser/am_browser_transfer_ability.py index 8f348dc..4f00208 100644 --- a/amuser/am_browser_transfer_ability.py +++ b/amuser/am_browser_transfer_ability.py @@ -209,7 +209,7 @@ def navigate_to_transfer_tab(self): def enter_transfer_name(self, transfer_name): """Enter a transfer name into the text input.""" - # transfer_name_elem = self.driver.find_element_by_id('transfer-name') + # transfer_name_elem = self.driver.find_element(By.ID, 'transfer-name') transfer_name_elem = self.driver.find_element_by_css_selector( c.SELECTOR_INPUT_TRANSFER_NAME ) diff --git a/amuser/am_browser_transfer_ingest_ability.py b/amuser/am_browser_transfer_ingest_ability.py index 6925bf8..32b6445 100644 --- a/amuser/am_browser_transfer_ingest_ability.py +++ b/amuser/am_browser_transfer_ingest_ability.py @@ -4,6 +4,7 @@ import time from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from . import am_browser_file_explorer_ability as file_explorer_abl @@ -208,7 +209,7 @@ def get_transfer_micro_service_group_elem(self, group_name, transfer_uuid): transfer_dom_id = f"sip-row-{transfer_uuid}" for elem in self.driver.find_elements_by_css_selector("div.sip"): try: - elem.find_element_by_id(transfer_dom_id) + elem.find_element(By.ID, transfer_dom_id) transfer_div_elem = elem except NoSuchElementException: pass diff --git a/features/steps/utils.py b/features/steps/utils.py index 0917d53..ec27d75 100644 --- a/features/steps/utils.py +++ b/features/steps/utils.py @@ -15,6 +15,7 @@ from environment import AM_API_CONFIG_KEY from environment import SS_API_CONFIG_KEY from lxml import etree +from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select logger = logging.getLogger("amauat.steps.utils") @@ -1204,9 +1205,9 @@ def find_aip_by_transfer_metadata( browser.driver.find_elements_by_css_selector('select[title="query type"]')[-1] ).select_by_visible_text("Phrase") # Submit search and wait for expected result - browser.driver.find_element_by_id("search_submit").click() + browser.driver.find_element(By.ID, "search_submit").click() browser.wait_for_presence("#archival-storage-entries tbody tr") - summary_el = browser.driver.find_element_by_id("archival-storage-entries_info") + summary_el = browser.driver.find_element(By.ID, "archival-storage-entries_info") summary_text = summary_el.text.strip() result = summary_text == expected_summary_message # This assertion allows tenacity to retry the call on error From f074e4b8c3e442538e35fabf6b93b1c41d3f0333 Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 12 Feb 2024 22:51:03 +0100 Subject: [PATCH 5/9] Update find_element_by_css_selector calls --- amuser/am_browser_ability.py | 74 ++++++++++--------- amuser/am_browser_auth_ability.py | 4 +- amuser/am_browser_file_explorer_ability.py | 26 +++---- amuser/am_browser_ingest_ability.py | 16 ++-- amuser/am_browser_jobs_tasks_ability.py | 33 +++++---- ...m_browser_preservation_planning_ability.py | 18 ++--- amuser/am_browser_ss_ability.py | 68 +++++++++-------- amuser/am_browser_transfer_ability.py | 39 +++++----- amuser/am_browser_transfer_ingest_ability.py | 14 ++-- features/steps/utils.py | 10 +-- 10 files changed, 155 insertions(+), 147 deletions(-) diff --git a/amuser/am_browser_ability.py b/amuser/am_browser_ability.py index 35e0a3e..97b0eea 100644 --- a/amuser/am_browser_ability.py +++ b/amuser/am_browser_ability.py @@ -49,8 +49,8 @@ def ss_api_key(self): self.driver.get(self.get_ss_login_url()) self.driver.find_element(By.ID, "id_username").send_keys(self.ss_username) self.driver.find_element(By.ID, "id_password").send_keys(self.ss_password) - self.driver.find_element_by_css_selector( - c.varvn("SELECTOR_SS_LOGIN_BUTTON", self.vn) + self.driver.find_element( + By.CSS_SELECTOR, c.varvn("SELECTOR_SS_LOGIN_BUTTON", self.vn) ).click() self.driver.get(self.get_default_ss_user_edit_url()) block = WebDriverWait(self.driver, 20) @@ -60,8 +60,8 @@ def ss_api_key(self): def get_displayed_tabs(self): ret = [] - for li_el in self.driver.find_element_by_css_selector( - "ul.navbar-nav" + for li_el in self.driver.find_element( + By.CSS_SELECTOR, "ul.navbar-nav" ).find_elements_by_tag_name("li"): ret.append(li_el.text.strip().split("\n")[0]) return list(filter(None, ret)) @@ -69,10 +69,10 @@ def get_displayed_tabs(self): def assert_sip_arrange_pane_not_displayed(self): for selector in ("form#search_form", "div#originals", "div#arrange"): try: - self.driver.find_element_by_css_selector(selector) + self.driver.find_element(By.CSS_SELECTOR, selector) except NoSuchElementException as exc: assert f"Unable to locate element: {selector}" in str(exc) - assert self.driver.find_element_by_css_selector("div#sip-container") + assert self.driver.find_element(By.CSS_SELECTOR, "div#sip-container") # ========================================================================== # Archival Storage Tab @@ -86,14 +86,14 @@ def wait_for_aip_in_archival_storage(self, aip_uuid): attempts = 0 while True: self.navigate(self.get_archival_storage_url(), reload=True) - self.driver.find_element_by_css_selector( - 'input[title="search query"]' + self.driver.find_element( + By.CSS_SELECTOR, 'input[title="search query"]' ).send_keys(aip_uuid) Select( - self.driver.find_element_by_css_selector('select[title="field name"]') + self.driver.find_element(By.CSS_SELECTOR, 'select[title="field name"]') ).select_by_visible_text("AIP UUID") Select( - self.driver.find_element_by_css_selector('select[title="query type"]') + self.driver.find_element(By.CSS_SELECTOR, 'select[title="query type"]') ).select_by_visible_text("Phrase") self.driver.find_element(By.ID, "search_submit").click() self.wait_for_presence("#archival-storage-entries_info") @@ -123,15 +123,15 @@ def request_aip_delete(self, aip_uuid): self.driver.find_element(By.ID, "id_delete-uuid").click() break except (ElementNotVisibleException, ElementNotInteractableException): - self.driver.find_element_by_css_selector(delete_tab_selector).click() + self.driver.find_element(By.CSS_SELECTOR, delete_tab_selector).click() time.sleep(self.optimistic_wait) self.driver.find_element(By.ID, "id_delete-uuid").send_keys(aip_uuid) self.driver.find_element(By.ID, "id_delete-reason").send_keys("Cuz wanna") - self.driver.find_element_by_css_selector( - 'button[name="submit-delete-form"]' + self.driver.find_element( + By.CSS_SELECTOR, 'button[name="submit-delete-form"]' ).click() - alert_text = self.driver.find_element_by_css_selector( - "div.alert-info" + alert_text = self.driver.find_element( + By.CSS_SELECTOR, "div.alert-info" ).text.strip() assert alert_text == "Delete request created successfully." @@ -184,19 +184,19 @@ def initiate_reingest(self, aip_uuid, reingest_type="metadata-only"): " {}".format(reingest_type, aip_uuid) ) while True: - type_input_el = self.driver.find_element_by_css_selector(type_selector) + type_input_el = self.driver.find_element(By.CSS_SELECTOR, type_selector) if type_input_el.is_displayed(): break else: - self.driver.find_element_by_css_selector(reingest_tab_selector).click() + self.driver.find_element(By.CSS_SELECTOR, reingest_tab_selector).click() time.sleep(self.optimistic_wait) - self.driver.find_element_by_css_selector(type_selector).click() - self.driver.find_element_by_css_selector( - "button[name=submit-reingest-form]" + self.driver.find_element(By.CSS_SELECTOR, type_selector).click() + self.driver.find_element( + By.CSS_SELECTOR, "button[name=submit-reingest-form]" ).click() self.wait_for_visibility("div.alert-success") - alert_text = self.driver.find_element_by_css_selector( - "div.alert-success" + alert_text = self.driver.find_element( + By.CSS_SELECTOR, "div.alert-success" ).text.strip() assert alert_text.startswith(f"Package {aip_uuid} sent to pipeline") assert alert_text.endswith("for re-ingest") @@ -211,14 +211,14 @@ def wait_for_dip_in_transfer_backlog(self, dip_uuid): seconds = 0 while True: self.navigate(self.get_transfer_backlog_url(), reload=True) - self.driver.find_element_by_css_selector( - 'input[title="search query"]' + self.driver.find_element( + By.CSS_SELECTOR, 'input[title="search query"]' ).send_keys(dip_uuid) Select( - self.driver.find_element_by_css_selector('select[title="field name"]') + self.driver.find_element(By.CSS_SELECTOR, 'select[title="field name"]') ).select_by_visible_text("Transfer UUID") Select( - self.driver.find_element_by_css_selector('select[title="query type"]') + self.driver.find_element(By.CSS_SELECTOR, 'select[title="query type"]') ).select_by_visible_text("Phrase") self.driver.find_element(By.ID, "search_submit").click() self.wait_for_presence("#backlog-entries_info") @@ -254,10 +254,10 @@ def upload_policy(self, policy_path): self.driver.execute_script( "document.getElementById('file').style.display='block'" ) - self.driver.find_element_by_css_selector("input[name=file]").send_keys( + self.driver.find_element(By.CSS_SELECTOR, "input[name=file]").send_keys( policy_path ) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() def navigate_to_policies(self): self.navigate(self.get_policies_url()) @@ -283,18 +283,20 @@ def configure_handle(self, **kwargs): else: input_el.clear() input_el.send_keys(val) - submit_button = self.driver.find_element_by_css_selector("input[type=submit]") + submit_button = self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]") submit_button.click() self.wait_for_visibility("div.alert-info") assert ( - self.driver.find_element_by_css_selector(".alert-info").text.strip() + self.driver.find_element(By.CSS_SELECTOR, ".alert-info").text.strip() == "Saved." ), "Unable to confirm saving of Handle configuration" def get_es_indexing_config_text(self): self.navigate(self.get_admin_general_url()) try: - el = self.driver.find_element_by_css_selector("p.es-indexing-configuration") + el = self.driver.find_element( + By.CSS_SELECTOR, "p.es-indexing-configuration" + ) except NoSuchElementException: return None else: @@ -316,7 +318,7 @@ def save_default_processing_config(self): ) if self.driver.current_url != edit_default_processing_config_url: self.navigate(edit_default_processing_config_url) - self.driver.find_element_by_css_selector("input[value=Save]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[value=Save]").click() def get_processing_config_decision_options(self, **kwargs): """Return the options available for a given processing config decision @@ -525,8 +527,8 @@ def setup_new_install(self): self.driver.find_element(By.ID, "id_storage_service_apikey").send_keys( ss_api_key ) - self.driver.find_element_by_css_selector( - c.varvn("SELECTOR_DFLT_SS_REG", self.vn) + self.driver.find_element( + By.CSS_SELECTOR, c.varvn("SELECTOR_DFLT_SS_REG", self.vn) ).click() def create_first_user(self): @@ -548,8 +550,8 @@ def create_first_user(self): self.driver.find_element_by_tag_name("button").click() continue_button_selector = "input[value=Continue]" self.wait_for_presence(continue_button_selector, 100) - continue_button_el = self.driver.find_element_by_css_selector( - continue_button_selector + continue_button_el = self.driver.find_element( + By.CSS_SELECTOR, continue_button_selector ) continue_button_el.click() diff --git a/amuser/am_browser_auth_ability.py b/amuser/am_browser_auth_ability.py index 3638d9f..0ac7b1c 100644 --- a/amuser/am_browser_auth_ability.py +++ b/amuser/am_browser_auth_ability.py @@ -50,7 +50,7 @@ def login_ss(self): username_elem.send_keys(self.ss_username) password_elem = self.driver.find_element(By.ID, password_input_id) password_elem.send_keys(self.ss_password) - submit_button_elem = self.driver.find_element_by_css_selector( - "input[type=submit]" + submit_button_elem = self.driver.find_element( + By.CSS_SELECTOR, "input[type=submit]" ) submit_button_elem.click() diff --git a/amuser/am_browser_file_explorer_ability.py b/amuser/am_browser_file_explorer_ability.py index 76711c3..7ed5171 100644 --- a/amuser/am_browser_file_explorer_ability.py +++ b/amuser/am_browser_file_explorer_ability.py @@ -31,11 +31,11 @@ def add_transfer_directory(self, path): link. """ # Click the "Browse" button, if necessary. - if not self.driver.find_element_by_css_selector( - c.SELECTOR_DIV_TRANSFER_SOURCE_BROWSE + if not self.driver.find_element( + By.CSS_SELECTOR, c.SELECTOR_DIV_TRANSFER_SOURCE_BROWSE ).is_displayed(): - browse_button_elem = self.driver.find_element_by_css_selector( - c.SELECTOR_BUTTON_BROWSE_TRANSFER_SOURCES + browse_button_elem = self.driver.find_element( + By.CSS_SELECTOR, c.SELECTOR_BUTTON_BROWSE_TRANSFER_SOURCES ) browse_button_elem.click() # Wait for the File Explorer modal dialog to open. @@ -119,8 +119,8 @@ def click_add_folder(self, folder_id): hover = ActionChains(self.driver).move_to_element(folder_elem) hover.perform() time.sleep(self.micro_wait) # seems to be necessary (! jQuery animations?) - span_elem = self.driver.find_element_by_css_selector( - f"div#{folder_id} span.{c.CLASS_ADD_TRANSFER_FOLDER}" + span_elem = self.driver.find_element( + By.CSS_SELECTOR, f"div#{folder_id} span.{c.CLASS_ADD_TRANSFER_FOLDER}" ) hover = ActionChains(self.driver).move_to_element(span_elem) hover.perform() @@ -145,16 +145,16 @@ def click_folder_label(self, folder_el, offset=0): if counter > 10: return folder_el.click() - if not self.driver.find_element_by_css_selector( - c.SELECTOR_BUTTON_ADD_DIR_TO_TRANSFER + if not self.driver.find_element( + By.CSS_SELECTOR, c.SELECTOR_BUTTON_ADD_DIR_TO_TRANSFER ).is_enabled(): logger.info("The Add button has not become clickable.") raise WebDriverException("ADD is not clickable") logger.info("The Add button has become clickable.") except WebDriverException: counter += 1 - container_el = self.driver.find_element_by_css_selector( - ".transfer-tree-container" + container_el = self.driver.find_element( + By.CSS_SELECTOR, ".transfer-tree-container" ) self.driver.execute_script( f"arguments[0].scrollTop = {offset}", container_el @@ -183,8 +183,8 @@ def click_folder(self, folder_label_xpath, is_file=False, offset=0): # TODO: when clicking a file in the new interface (if ever this is # required), we may need different behaviour. except WebDriverException: - container_el = self.driver.find_element_by_css_selector( - ".transfer-tree-container" + container_el = self.driver.find_element( + By.CSS_SELECTOR, ".transfer-tree-container" ) self.driver.execute_script( f"arguments[0].scrollTop = {offset}", container_el @@ -209,7 +209,7 @@ def click_folder_old_browser(self, folder_id, is_file=False): class_ = "backbone-file-explorer-directory_entry_name" folder_id = folder_id.replace(".", r"\.") selector = f"div#{folder_id} span.{class_}" - span_elem = self.driver.find_element_by_css_selector(selector) + span_elem = self.driver.find_element(By.CSS_SELECTOR, selector) hover = ActionChains(self.driver).move_to_element(span_elem) hover.perform() span_elem.click() diff --git a/amuser/am_browser_ingest_ability.py b/amuser/am_browser_ingest_ability.py index 6970bdf..36c98b4 100644 --- a/amuser/am_browser_ingest_ability.py +++ b/amuser/am_browser_ingest_ability.py @@ -178,18 +178,18 @@ def _navigate_to_aip_directory_and_click(self, path): def add_dummy_metadata(self, sip_uuid): self.navigate(self.get_ingest_url()) - self.driver.find_element( - By.ID, f"sip-row-{sip_uuid}" - ).find_element_by_css_selector("a.btn_show_metadata").click() + self.driver.find_element(By.ID, f"sip-row-{sip_uuid}").find_element( + By.CSS_SELECTOR, "a.btn_show_metadata" + ).click() self.navigate(self.get_metadata_add_url(sip_uuid)) for attr in self.metadata_attrs: self.driver.find_element(By.ID, f"id_{attr}").send_keys(self.dummy_val) try: - self.driver.find_element_by_css_selector("input[value=Create]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[value=Create]").click() except NoSuchElementException: # Should be a "Create" button but sometimes during development the # metadata already exists so it is a "Save" button. - self.driver.find_element_by_css_selector("input[value=Save]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[value=Save]").click() def parse_normalization_report(self, sip_uuid): """Wait for the "Approve normalization" job to appear and then open the @@ -211,11 +211,11 @@ def parse_normalization_report(self, sip_uuid): self.login() self.driver.get(nrmlztn_rprt_url) self.wait_for_presence("table") - table_el = self.driver.find_element_by_css_selector("table") + table_el = self.driver.find_element(By.CSS_SELECTOR, "table") keys = [ td_el.text.strip().lower().replace(" ", "_") - for td_el in table_el.find_element_by_css_selector( - "thead tr" + for td_el in table_el.find_element( + By.CSS_SELECTOR, "thead tr" ).find_elements_by_css_selector("th") ] for tr_el in table_el.find_elements_by_css_selector("tbody tr"): diff --git a/amuser/am_browser_jobs_tasks_ability.py b/amuser/am_browser_jobs_tasks_ability.py index c9de0ef..29a5ea5 100644 --- a/amuser/am_browser_jobs_tasks_ability.py +++ b/amuser/am_browser_jobs_tasks_ability.py @@ -4,6 +4,7 @@ import time from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By from . import constants as c from . import selenium_ability @@ -33,8 +34,8 @@ def get_job_output(self, ms_name, transfer_uuid): "div.job-detail-microservice span" ): if span_elem.text.strip() == ms_name: - return job_elem.find_element_by_css_selector( - "div.job-detail-currentstep span" + return job_elem.find_element( + By.CSS_SELECTOR, "div.job-detail-currentstep span" ).text.strip() return None @@ -56,7 +57,7 @@ def expose_job(self, ms_name, transfer_uuid, unit_type="transfer"): self.wait_for_transfer_micro_service_group(group_name, transfer_uuid) is_visible = ( self.get_transfer_micro_service_group_elem(group_name, transfer_uuid) - .find_element_by_css_selector("div.microservice-group + div") + .find_element(By.CSS_SELECTOR, "div.microservice-group + div") .is_displayed() ) if not is_visible: @@ -125,22 +126,22 @@ def _parse_tasks_table_am_gte_1_7(self, tasks_url, table_dict): for task_art_elem in self.driver.find_elements_by_css_selector("article.task"): row_dict = {} try: - row_dict["stdout"] = task_art_elem.find_element_by_css_selector( - ".panel-info pre" + row_dict["stdout"] = task_art_elem.find_element( + By.CSS_SELECTOR, ".panel-info pre" ).text.strip() except NoSuchElementException: row_dict["stdout"] = "" try: - row_dict["stderr"] = task_art_elem.find_element_by_css_selector( - ".panel-danger pre" + row_dict["stderr"] = task_art_elem.find_element( + By.CSS_SELECTOR, ".panel-danger pre" ).text.strip() except NoSuchElementException: row_dict["stderr"] = "" - row_dict["command"] = task_art_elem.find_element_by_css_selector( - "h3.panel-title.panel-title-simple" + row_dict["command"] = task_art_elem.find_element( + By.CSS_SELECTOR, "h3.panel-title.panel-title-simple" ).text.strip() - arguments = task_art_elem.find_element_by_css_selector( - "div.panel-primary div.shell-output pre" + arguments = task_art_elem.find_element( + By.CSS_SELECTOR, "div.panel-primary div.shell-output pre" ).text.strip() row_dict["arguments"] = utils.parse_task_arguments_to_list(arguments) for dl_el in task_art_elem.find_elements_by_css_selector("div.row dl"): @@ -151,7 +152,7 @@ def _parse_tasks_table_am_gte_1_7(self, tasks_url, table_dict): val = el.text.strip() row_dict[attr] = val row_dict["task_uuid"] = ( - task_art_elem.find_element_by_css_selector("div.task-heading h4") + task_art_elem.find_element(By.CSS_SELECTOR, "div.task-heading h4") .text.strip() .split()[1] ) @@ -187,8 +188,8 @@ def get_job_uuid( "div.job-detail-microservice span" ): if utils.squash(span_elem.text) == utils.squash(ms_name): - job_output = job_elem.find_element_by_css_selector( - "div.job-detail-currentstep span" + job_output = job_elem.find_element( + By.CSS_SELECTOR, "div.job-detail-currentstep span" ).text.strip() if job_output in job_outputs: return (span_elem.get_attribute("title").strip(), job_output) @@ -262,12 +263,12 @@ def get_tasks_row_type(row_elem): if row_elem.get_attribute("class").strip(): return "header" try: - row_elem.find_element_by_css_selector("td.stdout") + row_elem.find_element(By.CSS_SELECTOR, "td.stdout") return "stdout" except NoSuchElementException: pass try: - row_elem.find_element_by_css_selector("td.stderror") + row_elem.find_element(By.CSS_SELECTOR, "td.stderror") return "stderr" except NoSuchElementException: pass diff --git a/amuser/am_browser_preservation_planning_ability.py b/amuser/am_browser_preservation_planning_ability.py index bbfa32c..215cf32 100644 --- a/amuser/am_browser_preservation_planning_ability.py +++ b/amuser/am_browser_preservation_planning_ability.py @@ -26,8 +26,8 @@ def navigate_to_normalization_rules(self): self.navigate(self.get_normalization_rules_url()) def search_rules(self, search_term): - search_input_el = self.driver.find_element_by_css_selector( - "#DataTables_Table_0_filter input" + search_input_el = self.driver.find_element( + By.CSS_SELECTOR, "#DataTables_Table_0_filter input" ) search_input_el.send_keys(search_term) @@ -49,8 +49,8 @@ def set_fpr_command(self, command_name): Select(command_select_el).select_by_visible_text(command_name) def save_fpr_command(self): - command_select_el = self.driver.find_element_by_css_selector( - "input[type=submit]" + command_select_el = self.driver.find_element( + By.CSS_SELECTOR, "input[type=submit]" ) command_select_el.click() self.wait_for_presence("#DataTables_Table_0") @@ -163,7 +163,7 @@ def save_policy_check_command(self, policy_command, description): self.driver.execute_script(js_script) self.driver.find_element(By.ID, "id_script_type").send_keys("Python") self.driver.find_element(By.ID, "id_command_usage").send_keys("Validation") - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() logger.info("Created the FPR policy check command") def ensure_fpr_rule(self, purpose, format_, command_description): @@ -194,7 +194,7 @@ def ensure_fpr_rule(self, purpose, format_, command_description): Select(self.driver.find_element(By.ID, "id_f-command")).select_by_visible_text( command_description ) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() logger.info("Created the needed FPR rule.") def fpr_rule_already_exists(self, purpose, format_, command_description): @@ -230,7 +230,7 @@ def ensure_fpr_rule_enabled(self, purpose, format_, command_description): for row in self.driver.find_elements_by_css_selector( "#DataTables_Table_0 tbody tr" ) - if row.find_element_by_css_selector("td:nth-child(5)").text == "No" + if row.find_element(By.CSS_SELECTOR, "td:nth-child(5)").text == "No" ] if not disabled_rules: logger.info( @@ -247,8 +247,8 @@ def ensure_fpr_rule_enabled(self, purpose, format_, command_description): ) ) rule = disabled_rules[0] - rule.find_element_by_css_selector("td:nth-child(6) a:nth-child(3)").click() - self.driver.find_element_by_css_selector("input[value=Enable]").click() + rule.find_element(By.CSS_SELECTOR, "td:nth-child(6) a:nth-child(3)").click() + self.driver.find_element(By.CSS_SELECTOR, "input[value=Enable]").click() @staticmethod def get_policy_command_description(policy_file): diff --git a/amuser/am_browser_ss_ability.py b/amuser/am_browser_ss_ability.py index 265915d..7a2006a 100644 --- a/amuser/am_browser_ss_ability.py +++ b/amuser/am_browser_ss_ability.py @@ -47,9 +47,9 @@ def approve_aip_delete_request(self, aip_uuid): " {}".format(len(matching_rows), aip_uuid) ) matching_rows[0].find_element_by_tag_name("textarea").send_keys("Cuz wanna") - matching_rows[0].find_element_by_css_selector('input[name="approve"]').click() - assert self.driver.find_element_by_css_selector( - "div.alert-success" + matching_rows[0].find_element(By.CSS_SELECTOR, 'input[name="approve"]').click() + assert self.driver.find_element( + By.CSS_SELECTOR, "div.alert-success" ).text.strip() == ("Request approved: Package deleted successfully.") def search_for_aip_in_storage_service(self, aip_uuid): @@ -60,7 +60,9 @@ def search_for_aip_in_storage_service(self, aip_uuid): attempts = 0 self.navigate(self.get_packages_url()) self.wait_for_presence('#DataTables_Table_0_filter input[type="text"]') - self.driver.find_element_by_css_selector("input[type=text]").send_keys(aip_uuid) + self.driver.find_element(By.CSS_SELECTOR, "input[type=text]").send_keys( + aip_uuid + ) while True: # DataTables_Table_0 row_els = self.driver.find_elements_by_css_selector( @@ -123,8 +125,8 @@ def create_ss_space(self, attributes): # Visiting this URL creates a default GPG key when there is none self.navigate(self.get_gpg_keys_url()) self.navigate(self.get_spaces_create_url()) - form_el = self.driver.find_element_by_css_selector( - 'form[action="/spaces/create/"]' + form_el = self.driver.find_element( + By.CSS_SELECTOR, 'form[action="/spaces/create/"]' ) protocol_el = self.driver.find_element(By.ID, "protocol_form") for parent in (form_el, protocol_el): @@ -140,10 +142,10 @@ def create_ss_space(self, attributes): Select(input_el).select_by_visible_text(val) else: input_el.send_keys(val) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() self.wait_for_presence("div.alert-success", self.nihilistic_wait) assert ( - self.driver.find_element_by_css_selector("div.alert-success").text.strip() + self.driver.find_element(By.CSS_SELECTOR, "div.alert-success").text.strip() == "Space saved." ) header = self.driver.find_element_by_tag_name("h1").text.strip() @@ -155,8 +157,8 @@ def create_ss_location(self, space_uuid, attributes): attributes ``attributes``. """ self.navigate(self.get_locations_create_url(space_uuid)) - form_el = self.driver.find_element_by_css_selector( - f'form[action="/spaces/{space_uuid}/location_create/"]' + form_el = self.driver.find_element( + By.CSS_SELECTOR, f'form[action="/spaces/{space_uuid}/location_create/"]' ) for p_el in form_el.find_elements_by_tag_name("p"): for el in p_el.find_elements_by_css_selector("*"): @@ -179,7 +181,7 @@ def create_ss_location(self, space_uuid, attributes): select_el = self.driver.find_element(By.ID, input_id) select = Select(select_el) select.select_by_index(0) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() header = self.driver.find_element_by_tag_name("h1").text.strip() location_uuid = header.split()[0].replace('"', "").replace(":", "") return location_uuid @@ -203,7 +205,7 @@ def get_existing_spaces(self): space_uuid = space_uuid[:-1] space_uuid = space_uuid.split("/")[-1] space = {"uuid": space_uuid} - space_div_el = self.driver.find_element_by_css_selector("div.space dl") + space_div_el = self.driver.find_element(By.CSS_SELECTOR, "div.space dl") last_key = None for el in space_div_el.find_elements_by_css_selector("dt, dd"): text = el.text.strip() @@ -228,7 +230,7 @@ def get_existing_locations(self, space_uuid): for loc_uuid, loc_url in location_urls.items(): self.navigate(loc_url) location = {"uuid": loc_uuid} - loc_div_el = self.driver.find_element_by_css_selector("div.location dl") + loc_div_el = self.driver.find_element(By.CSS_SELECTOR, "div.location dl") last_key = None for el in loc_div_el.find_elements_by_css_selector("dt, dd"): text = el.text.strip() @@ -269,7 +271,7 @@ def add_replicator_to_default_aip_stor_loc(self, replicator_location_uuid): standard Archivematica Directory" is THE default AIP Storage location. """ self.navigate(self.get_locations_url()) - search_el = self.driver.find_element_by_css_selector("input[type=text]") + search_el = self.driver.find_element(By.CSS_SELECTOR, "input[type=text]") search_el.send_keys("Store AIP in standard Archivematica Directory") row_els = self.driver.find_elements_by_css_selector( "#DataTables_Table_0 > tbody > tr" @@ -304,8 +306,8 @@ def add_replicator_to_default_aip_stor_loc(self, replicator_location_uuid): ) edit_a_el.click() self.wait_for_presence("select#id_replicators") - replicators_select_el = self.driver.find_element_by_css_selector( - "select#id_replicators" + replicators_select_el = self.driver.find_element( + By.CSS_SELECTOR, "select#id_replicators" ) replicators_select = Select(replicators_select_el) found_replicator = False @@ -320,7 +322,7 @@ def add_replicator_to_default_aip_stor_loc(self, replicator_location_uuid): " for the default AIP Storage" " location".format(replicator_location_uuid) ) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() def import_gpg_key(self, key_path): """Navigate to the GPG key import page and attempt to import the GPG @@ -331,9 +333,9 @@ def import_gpg_key(self, key_path): self.navigate(self.get_import_gpg_key_url()) with open(key_path) as filei: self.driver.find_element(By.ID, "id_ascii_armor").send_keys(filei.read()) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() self.wait_for_presence("div.alert", 20) - return self.driver.find_element_by_css_selector("div.alert").text.strip() + return self.driver.find_element(By.CSS_SELECTOR, "div.alert").text.strip() def get_gpg_key_search_matches(self, search_string): """Navigate to the GPG keys page and return the fingerprints of all @@ -341,7 +343,7 @@ def get_gpg_key_search_matches(self, search_string): """ fingerprints = [] self.navigate(self.get_gpg_keys_url()) - self.driver.find_element_by_css_selector("input[type=text]").send_keys( + self.driver.find_element(By.CSS_SELECTOR, "input[type=text]").send_keys( search_string ) for row_el in self.driver.find_elements_by_css_selector( @@ -362,7 +364,9 @@ def delete_gpg_key(self, key_name): string. """ self.navigate(self.get_gpg_keys_url()) - self.driver.find_element_by_css_selector("input[type=text]").send_keys(key_name) + self.driver.find_element(By.CSS_SELECTOR, "input[type=text]").send_keys( + key_name + ) matches = self.driver.find_elements_by_css_selector( "table#DataTables_Table_0 tbody tr" ) @@ -379,12 +383,12 @@ def delete_gpg_key(self, key_name): else: matches[0].find_element_by_xpath('td[3]/a[text() = "Delete"]').click() try: - self.driver.find_element_by_css_selector("input[value=Delete]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[value=Delete]").click() try: return ( True, - self.driver.find_element_by_css_selector( - "div.alert-success" + self.driver.find_element( + By.CSS_SELECTOR, "div.alert-success" ).text.strip(), ) except NoSuchElementException: @@ -392,14 +396,14 @@ def delete_gpg_key(self, key_name): except NoSuchElementException: return ( False, - self.driver.find_element_by_css_selector( - "div.alert-error" + self.driver.find_element( + By.CSS_SELECTOR, "div.alert-error" ).text.strip(), ) def disable_default_transfer_backlog(self): self.navigate(self.get_locations_url()) - search_el = self.driver.find_element_by_css_selector("input[type=text]") + search_el = self.driver.find_element(By.CSS_SELECTOR, "input[type=text]") search_el.send_keys("Default transfer backlog") row_els = self.driver.find_elements_by_css_selector( "#DataTables_Table_0 > tbody > tr" @@ -430,9 +434,9 @@ def create_new_gpg_key(self): new_key_email = "{}@example.com".format(new_key_name.lower().replace(" ", "")) self.driver.find_element(By.ID, "id_name_real").send_keys(new_key_name) self.driver.find_element(By.ID, "id_name_email").send_keys(new_key_email) - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() self.wait_for_presence("div.alert-success", self.nihilistic_wait) - alert_text = self.driver.find_element_by_css_selector("div.alert-success").text + alert_text = self.driver.find_element(By.CSS_SELECTOR, "div.alert-success").text new_key_fingerprint = alert_text.split()[2] return new_key_name, new_key_email, new_key_fingerprint @@ -451,10 +455,10 @@ def change_encrypted_space_key(self, space_uuid, new_key_repr=None): if option.text != currently_selected: select.select_by_visible_text(option.text) break - self.driver.find_element_by_css_selector("input[type=submit]").click() + self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() # Nihilistic wait is the only value working on Docker at present... and # may still need to be longer. Wait needed to accumulate GPG entropy. self.wait_for_presence("div.alert-success", self.nihilistic_wait) - assert self.driver.find_element_by_css_selector( - "div.alert-success" + assert self.driver.find_element( + By.CSS_SELECTOR, "div.alert-success" ).text.strip() == ("Space saved.") diff --git a/amuser/am_browser_transfer_ability.py b/amuser/am_browser_transfer_ability.py index 4f00208..5f05eb4 100644 --- a/amuser/am_browser_transfer_ability.py +++ b/amuser/am_browser_transfer_ability.py @@ -5,6 +5,7 @@ from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import StaleElementReferenceException +from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from . import constants as c @@ -92,7 +93,9 @@ def remove_top_transfer(self, top_transfer_elem): """Remove the topmost transfer: click on its "Remove" button and click "Confirm". """ - remove_elem = top_transfer_elem.find_element_by_css_selector("a.btn_remove_sip") + remove_elem = top_transfer_elem.find_element( + By.CSS_SELECTOR, "a.btn_remove_sip" + ) if remove_elem: remove_elem.click() dialog_selector = "div.ui-dialog" @@ -140,11 +143,11 @@ def wait_for_transfer_to_appear(self, transfer_name, name_is_prefix=False): for transfer_div_elem in self.driver.find_elements_by_css_selector( c.SELECTOR_TRANSFER_DIV ): - transfer_name_div_elem = transfer_div_elem.find_element_by_css_selector( - transfer_name_div_selector + transfer_name_div_elem = transfer_div_elem.find_element( + By.CSS_SELECTOR, transfer_name_div_selector ) - transfer_uuid_div_elem = transfer_div_elem.find_element_by_css_selector( - transfer_uuid_div_selector + transfer_uuid_div_elem = transfer_div_elem.find_element( + By.CSS_SELECTOR, transfer_uuid_div_selector ) # Identify the transfer by its name. The complication here is that # AM detects a narrow browser window and hides the UUID in the @@ -191,8 +194,8 @@ def wait_for_transfer_to_appear(self, transfer_name, name_is_prefix=False): return transfer_uuid, correct_transfer_div_elem, transfer_name def click_start_transfer_button(self): - start_transfer_button_elem = self.driver.find_element_by_css_selector( - c.SELECTOR_BUTTON_START_TRANSFER + start_transfer_button_elem = self.driver.find_element( + By.CSS_SELECTOR, c.SELECTOR_BUTTON_START_TRANSFER ) start_transfer_button_elem.click() @@ -210,29 +213,29 @@ def navigate_to_transfer_tab(self): def enter_transfer_name(self, transfer_name): """Enter a transfer name into the text input.""" # transfer_name_elem = self.driver.find_element(By.ID, 'transfer-name') - transfer_name_elem = self.driver.find_element_by_css_selector( - c.SELECTOR_INPUT_TRANSFER_NAME + transfer_name_elem = self.driver.find_element( + By.CSS_SELECTOR, c.SELECTOR_INPUT_TRANSFER_NAME ) transfer_name_elem.send_keys(transfer_name) def set_transfer_type(self, transfer_type): """Select transfer type ``transfer_type`` in the