diff --git a/OpenOversight/tests/conftest.py b/OpenOversight/tests/conftest.py index c494b1edc..4c51a8cd1 100644 --- a/OpenOversight/tests/conftest.py +++ b/OpenOversight/tests/conftest.py @@ -16,6 +16,8 @@ from flask import current_app from PIL import Image as Pimage from selenium import webdriver +from selenium.webdriver.firefox.options import Options +from selenium.webdriver.firefox.service import Service from sqlalchemy.orm import scoped_session, sessionmaker from xvfbwrapper import Xvfb @@ -906,7 +908,11 @@ def browser(app, server_port): # start headless webdriver visual_display = Xvfb() visual_display.start() - driver = webdriver.Firefox(service_log_path="/tmp/geckodriver.log") + options = Options() + options.add_argument("--headless") + driver = webdriver.Firefox( + options=options, service=Service(log_path="/tmp/geckodriver.log") + ) # wait for browser to start up sleep(3) yield driver diff --git a/OpenOversight/tests/test_functional.py b/OpenOversight/tests/test_functional.py index 77c61d40f..e7098b40b 100644 --- a/OpenOversight/tests/test_functional.py +++ b/OpenOversight/tests/test_functional.py @@ -21,7 +21,7 @@ @contextmanager def wait_for_page_load(browser, timeout=10): - old_page = browser.find_element_by_tag_name(FILE_TYPE_HTML) + old_page = browser.find_element(By.TAG_NAME, FILE_TYPE_HTML) yield WebDriverWait(browser, timeout).until(expected_conditions.staleness_of(old_page)) @@ -29,14 +29,14 @@ def wait_for_page_load(browser, timeout=10): def login_admin(browser, server_port): browser.get(f"http://localhost:{server_port}/auth/login") with wait_for_page_load(browser): - elem = browser.find_element_by_id("email") + elem = browser.find_element(By.ID, "email") elem.clear() elem.send_keys(ADMIN_USER_EMAIL) - elem = browser.find_element_by_id("password") + elem = browser.find_element(By.ID, "password") elem.clear() elem.send_keys("testtest") with wait_for_page_load(browser): - browser.find_element_by_id("submit").click() + browser.find_element(By.ID, "submit").click() wait_for_element(browser, By.TAG_NAME, "body") @@ -91,7 +91,7 @@ def test_user_can_load_homepage_and_get_to_form(mockdata, browser, server_port): scroll_to_element(browser, element) element.click() - page_text = browser.find_element_by_tag_name("body").text + page_text = browser.find_element(By.TAG_NAME, "body").text assert "Find an Officer" in page_text @@ -103,10 +103,10 @@ def test_user_can_get_to_complaint(browser, server_port): ) wait_for_element(browser, By.TAG_NAME, "h1") - # Complainant arrives at page with the badge number, name, and link + # Complaint arrives at page with the badge number, name, and link # to complaint form - title_text = browser.find_element_by_tag_name("h1").text + title_text = browser.find_element(By.TAG_NAME, "h1").text assert "File a Complaint" in title_text @@ -118,7 +118,7 @@ def test_officer_browse_pagination(mockdata, browser, server_port): f"http://localhost:{server_port}/departments/{AC_DEPT}?page=1&gender=Not+Sure" ) wait_for_element(browser, By.TAG_NAME, "body") - page_text = browser.find_element_by_tag_name("body").text + page_text = browser.find_element(By.TAG_NAME, "body").text expected = f"Showing 1-{current_app.config[KEY_OFFICERS_PER_PAGE]} of {total}" assert expected in page_text @@ -135,7 +135,7 @@ def test_officer_browse_pagination(mockdata, browser, server_port): f"http://localhost:{server_port}/departments/{AC_DEPT}?page={last_page_index}&gender=Not+Sure" ) wait_for_element(browser, By.TAG_NAME, "body") - page_text = browser.find_element_by_tag_name("body").text + page_text = browser.find_element(By.TAG_NAME, "body").text start_of_page = ( current_app.config[KEY_OFFICERS_PER_PAGE] * (total // current_app.config[KEY_OFFICERS_PER_PAGE]) @@ -162,8 +162,8 @@ def test_find_officer_can_see_uii_question_for_depts_with_uiis( Department.unique_internal_identifier_label.is_not(None) ).first() - dept_selector = Select(browser.find_element_by_id("dept")) - uii_element = browser.find_element_by_id("uii-question") + dept_selector = Select(browser.find_element(By.ID, "dept")) + uii_element = browser.find_element(By.ID, "uii-question") dept_selector.select_by_value(str(dept_with_uii.id)) assert uii_element.is_displayed() @@ -179,11 +179,11 @@ def test_find_officer_cannot_see_uii_question_for_depts_without_uiis( unique_internal_identifier_label=None ).first() - dept_selector = browser.find_element_by_id("dept") + dept_selector = browser.find_element(By.ID, "dept") scroll_to_element(browser, dept_selector) Select(dept_selector).select_by_value(str(dept_without_uii.id)) - uii_element = browser.find_element("id", "uii-question") + uii_element = browser.find_element(By.ID, "uii-question") assert not uii_element.is_displayed() @@ -198,7 +198,7 @@ def test_incident_detail_display_read_more_button_for_descriptions_over_cutoff( ).one_or_none() incident_id = str(incident_long_description.id) - result = browser.find_element_by_id("description-overflow-row_" + incident_id) + result = browser.find_element(By.ID, "description-overflow-row_" + incident_id) scroll_to_element(browser, result) assert result.is_displayed() @@ -216,7 +216,7 @@ def test_incident_detail_truncate_description_for_descriptions_over_cutoff( # Check that the text is truncated and contains more than just the ellipsis truncated_text = browser.find_element( - "id", "incident-description_" + incident_id + By.ID, "incident-description_" + incident_id ).text assert "…" in truncated_text # Include buffer for jinja rendered spaces @@ -230,7 +230,7 @@ def test_incident_detail_do_not_display_read_more_button_for_descriptions_under_ browser.get(f"http://localhost:{server_port}/officers/1") # Select incident for officer that has description under cutoff chars - result = browser.find_element_by_id("description-overflow-row_1") + result = browser.find_element(By.ID, "description-overflow-row_1") scroll_to_element(browser, result) assert not result.is_displayed() @@ -245,12 +245,12 @@ def test_click_to_read_more_displays_full_description(mockdata, browser, server_ original_description = incident_long_description.description.strip() incident_id = str(incident_long_description.id) - button = browser.find_element_by_id("description-overflow-button_" + incident_id) + button = browser.find_element(By.ID, "description-overflow-button_" + incident_id) scroll_to_element(browser, button) button.click() - description_text = browser.find_element_by_id( - "incident-description_" + incident_id + description_text = browser.find_element( + By.ID, "incident-description_" + incident_id ).text.strip() assert len(description_text) == len(original_description) assert description_text == original_description @@ -265,11 +265,11 @@ def test_click_to_read_more_hides_the_read_more_button(mockdata, browser, server ).one_or_none() incident_id = str(incident_long_description.id) - button = browser.find_element_by_id("description-overflow-button_" + incident_id) + button = browser.find_element(By.ID, "description-overflow-button_" + incident_id) scroll_to_element(browser, button) button.click() - buttonRow = browser.find_element_by_id("description-overflow-row_" + incident_id) + buttonRow = browser.find_element(By.ID, "description-overflow-row_" + incident_id) assert not buttonRow.is_displayed() @@ -286,13 +286,13 @@ def test_officer_form_has_units_alpha_sorted(browser, server_port, session): # Check for the Unit sort on the 'add officer' form browser.get(f"http://localhost:{server_port}/officers/new") - unit_select = Select(browser.find_element_by_id("unit")) + unit_select = Select(browser.find_element(By.ID, "unit")) select_units_sorted = [x.text for x in unit_select.options] assert db_units_sorted == select_units_sorted # Check for the Unit sort on the 'add assignment' form browser.get(f"http://localhost:{server_port}/officers/1") - unit_select = Select(browser.find_element_by_id("unit")) + unit_select = Select(browser.find_element(By.ID, "unit")) select_units_sorted = [x.text for x in unit_select.options] assert db_units_sorted == select_units_sorted @@ -312,13 +312,13 @@ def test_edit_officer_form_coerces_none_race_or_gender_to_not_sure( browser.get(f"http://localhost:{server_port}/officers/1/edit") wait_for_element(browser, By.ID, "gender") - select = Select(browser.find_element_by_id("gender")) + select = Select(browser.find_element(By.ID, "gender")) selected_option = select.first_selected_option selected_text = selected_option.text assert selected_text == "Not Sure" wait_for_element(browser, By.ID, "race") - select = Select(browser.find_element_by_id("race")) + select = Select(browser.find_element(By.ID, "race")) selected_option = select.first_selected_option selected_text = selected_option.text assert selected_text == "Not Sure" @@ -344,7 +344,7 @@ def test_image_classification_and_tagging(browser, server_port): browser.get(f"http://localhost:{server_port}/officers/new") wait_for_page_load(browser) - dept_select = Select(browser.find_element("id", "department")) + dept_select = Select(browser.find_element(By.ID, "department")) dept_select.select_by_visible_text("Auburn Police Department") dept_id = dept_select.first_selected_option.get_attribute("value") @@ -364,7 +364,7 @@ def test_image_classification_and_tagging(browser, server_port): browser.get(f"http://localhost:{server_port}/submit") wait_for_page_load(browser) - select = browser.find_element("id", "department") + select = browser.find_element(By.ID, "department") scroll_to_element(browser, select) Select(select).select_by_value(dept_id) submit_image_to_dropzone(browser, img_path) diff --git a/dev-requirements.txt b/dev-requirements.txt index 88a72f6cb..01306a5d3 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -8,7 +8,7 @@ pytest==7.4.0 pytest-cov==4.1.0 pytest-pep8==1.0.6 pytest-xdist==3.3.1 -selenium==3.14.0 # Updating this breaks the build for python 3.9 +selenium==4.26.0 sphinx==7.0.1 sphinx-autobuild==2021.3.14 xvfbwrapper==0.2.9 diff --git a/dockerfiles/web/Dockerfile-test b/dockerfiles/web/Dockerfile-test index c5db22405..b5214d7af 100644 --- a/dockerfiles/web/Dockerfile-test +++ b/dockerfiles/web/Dockerfile-test @@ -14,8 +14,8 @@ RUN apt-get update && apt-get install -y xvfb firefox-esr libpq-dev python3-dev apt-get install -y libsqlite3-0 && apt-get clean # install geckodriver -ENV GECKODRIVER_VERSION="v0.26.0" -ENV GECKODRIVER_SHA=d59ca434d8e41ec1e30dd7707b0c95171dd6d16056fb6db9c978449ad8b93cc0 +ENV GECKODRIVER_VERSION="v0.35.0" +ENV GECKODRIVER_SHA=ac26e9ba8f3b8ce0fbf7339b9c9020192f6dcfcbf04a2bcd2af80dfe6bb24260 ENV GECKODRIVER_BASE_URL="https://github.com/mozilla/geckodriver/releases/download" RUN curl ${CURL_FLAGS} \ ${GECKODRIVER_BASE_URL}/${GECKODRIVER_VERSION}/geckodriver-${GECKODRIVER_VERSION}-linux64.tar.gz diff --git a/requirements.txt b/requirements.txt index 0d16256e7..b6ca34aae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -56,13 +56,12 @@ recommonmark==0.7.1 requests~=2.31.0 rich~=13.4.2 s3transfer~=0.6.1 -selenium~=4.10.0 six~=1.16.0 sphinx==7.1.2 SQLAlchemy==1.4.52 tornado~=6.4 trio==0.22.1 -urllib3~=1.26.16 # This version is required for other packages to run +urllib3==1.26.20 us==3.1.1 visitor~=0.1.3 webencodings~=0.5.1