/
Art86
/
DefectDojo-DevSecOps
Обзор
Документация
Войти
/
Art86
/
DefectDojo-DevSecOps
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
tests/finding_test.py
844 строки
41 KB
valentijnscholten
Add CVSS4 support (#12751)
16 июл 2025, 00:26
16 июл 2025, 00:26
cd5cd03
Код
Авторство
О чём код?
import logging import os import sys import time import unittest from pathlib import Path from base_test_class import BaseTestCase, on_exception_html_source_logger, set_suite_settings from product_test import ProductTest, WaitForPageLoad from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions from selenium.webdriver.support.ui import Select, WebDriverWait from user_test import UserTest logger = logging.getLogger(__name__) dir_path = Path(os.path.realpath(__file__)).parent class FindingTest(BaseTestCase): def test_list_findings_all(self): return self.test_list_findings("finding") def test_list_findings_closed(self): return self.test_list_findings("finding/closed") def test_list_findings_accepted(self): return self.test_list_findings("finding/accepted") def test_list_findings_open(self): return self.test_list_findings("finding/open") def test_list_findings(self, suffix): # bulk edit dropdown menu driver = self.driver driver.get(self.base_url + suffix) driver.find_element(By.ID, "select_all").click() driver.find_element(By.ID, "dropdownMenu2").click() bulk_edit_menu = driver.find_element(By.ID, "bulk_edit_menu") self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_active").is_enabled(), False) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_verified").is_enabled(), False) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_false_p").is_enabled(), False) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_out_of_scope").is_enabled(), False) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_is_mitigated").is_enabled(), False) driver.find_element(By.ID, "id_bulk_status").click() bulk_edit_menu = driver.find_element(By.ID, "bulk_edit_menu") self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_active").is_enabled(), True) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_verified").is_enabled(), True) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_false_p").is_enabled(), True) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_out_of_scope").is_enabled(), True) self.assertEqual(bulk_edit_menu.find_element(By.ID, "id_bulk_is_mitigated").is_enabled(), True) def test_quick_report(self): # bulk edit dropdown menu driver = self.driver driver.get(self.base_url + "finding") driver.find_element(By.ID, "downloadMenu").click() driver.find_element(By.ID, "report").click() self.assertIn("<title>Finding Report</title>", driver.page_source) def check_file(self, file_name): file_found = False for _ in range(1, 30): time.sleep(1) if Path(file_name).is_file(): file_found = True break self.assertTrue(file_found, f"Cannot find {file_name}") Path(file_name).unlink() def test_csv_export(self): driver = self.driver driver.get(self.base_url + "finding") driver.find_element(By.ID, "downloadMenu").click() driver.find_element(By.ID, "csv_export").click() time.sleep(5) self.check_file(f"{self.export_path}/findings.csv") def test_excel_export(self): driver = self.driver driver.get(self.base_url + "finding") driver.find_element(By.ID, "downloadMenu").click() driver.find_element(By.ID, "excel_export").click() time.sleep(5) self.check_file(f"{self.export_path}/findings.xlsx") @on_exception_html_source_logger def test_edit_finding(self): # The Name of the Finding created by test_add_product_finding => 'App Vulnerable to XSS' # Test To Add Finding To product # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Edit Finding` driver.find_element(By.LINK_TEXT, "Edit Finding").click() # finding Severity Select(driver.find_element(By.ID, "id_severity")).select_by_visible_text("Critical") # finding Vulnerability Ids driver.find_element(By.ID, "id_vulnerability_ids").send_keys("\nREF-3\nREF-4\n") # "Click" the Done button to Edit the finding driver.find_element(By.XPATH, "//input[@name='_Finished']").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding saved successfully")) self.assertTrue(self.is_text_present_on_page(text="REF-1")) self.assertTrue(self.is_text_present_on_page(text="REF-2")) self.assertTrue(self.is_text_present_on_page(text="REF-3")) self.assertTrue(self.is_text_present_on_page(text="REF-4")) self.assertTrue(self.is_text_present_on_page(text="Additional Vulnerability Ids")) def _edit_finding_cvss_and_assert( self, cvssv3_value=None, cvssv3_score=None, cvssv4_value=None, cvssv4_score=None, expected_cvssv3_value=None, expected_cvssv3_score=None, expected_cvssv4_value=None, expected_cvssv4_score=None, expect_success=True, # noqa: FBT002 success_message="Finding saved successfully", error_message=None, ): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Edit Finding` driver.find_element(By.LINK_TEXT, "Edit Finding").click() driver.find_element(By.ID, "id_cvssv3").clear() driver.find_element(By.ID, "id_cvssv3_score").clear() driver.find_element(By.ID, "id_cvssv4").clear() driver.find_element(By.ID, "id_cvssv4_score").clear() if cvssv3_value: # Set cvssv3 value and score driver.find_element(By.ID, "id_cvssv3").send_keys(cvssv3_value) if cvssv3_score: driver.find_element(By.ID, "id_cvssv3_score").send_keys(str(cvssv3_score)) if cvssv4_value: # Set cvssv3 value and score driver.find_element(By.ID, "id_cvssv4").send_keys(cvssv4_value) if cvssv4_score: driver.find_element(By.ID, "id_cvssv4_score").send_keys(str(cvssv4_score)) # Submit the form driver.find_element(By.XPATH, "//input[@name='_Finished']").click() if expect_success: self.assertTrue(self.is_success_message_present(text=success_message)) # Go into edit mode again to check stored values driver.find_element(By.ID, "dropdownMenu1").click() driver.find_element(By.LINK_TEXT, "Edit Finding").click() else: self.assertTrue(self.is_error_message_present(text=error_message)) if expected_cvssv3_value: self.assertEqual(expected_cvssv3_value, driver.find_element(By.ID, "id_cvssv3").get_attribute("value")) if expected_cvssv3_score: self.assertEqual(str(expected_cvssv3_score), driver.find_element(By.ID, "id_cvssv3_score").get_attribute("value")) if expected_cvssv4_value: self.assertEqual(expected_cvssv4_value, driver.find_element(By.ID, "id_cvssv4").get_attribute("value")) if expected_cvssv4_score: self.assertEqual(str(expected_cvssv4_score), driver.find_element(By.ID, "id_cvssv4_score").get_attribute("value")) @on_exception_html_source_logger def test_edit_finding_cvssv3_valid_vector(self): self._edit_finding_cvss_and_assert( cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", cvssv3_score="1", expected_cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", expected_cvssv3_score="8.8", expect_success=True, ) @on_exception_html_source_logger def test_edit_finding_cvssv3_valid_vector_no_score(self): self._edit_finding_cvss_and_assert( cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", cvssv3_score=None, expected_cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", expected_cvssv3_score="8.8", expect_success=True, ) @on_exception_html_source_logger def test_edit_finding_cvssv3_valid_vector_no_prefix(self): self._edit_finding_cvss_and_assert( cvssv3_value="AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", cvssv3_score="2", expected_cvssv3_value="AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", expected_cvssv3_score="2", expect_success=False, error_message="No valid CVSS3 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv3_valid_vector_with_trailing_slash(self): self._edit_finding_cvss_and_assert( cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/", cvssv3_score="3", expected_cvssv3_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/", expected_cvssv3_score="3", expect_success=False, error_message="No valid CVSS3 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv3_with_v2_vector_invalid_due_to_prefix(self): self._edit_finding_cvss_and_assert( cvssv3_value="CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", cvssv3_score="4", expected_cvssv3_value="CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", expected_cvssv3_score="4", expect_success=False, error_message="No valid CVSS3 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv3_with_v2_vector(self): self._edit_finding_cvss_and_assert( cvssv3_value="AV:N/AC:L/Au:N/C:P/I:P/A:P", cvssv3_score="4", expected_cvssv3_value="AV:N/AC:L/Au:N/C:P/I:P/A:P", expected_cvssv3_score="4", expect_success=False, error_message="Unsupported CVSS2 version detected.", ) @on_exception_html_source_logger def test_edit_finding_cvssv3_with_v4_vector(self): self._edit_finding_cvss_and_assert( cvssv3_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", cvssv3_score="5", expected_cvssv3_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", expected_cvssv3_score="5", expect_success=False, error_message="CVSS4 vector cannot be stored in the cvssv3 field. Use the cvssv4 field.", ) @on_exception_html_source_logger def test_edit_finding_cvssv3_with_rubbish(self): self._edit_finding_cvss_and_assert( cvssv3_value="happy little vector", cvssv3_score="5", expected_cvssv3_value="happy little vector", expected_cvssv3_score="5", expect_success=False, error_message="No valid CVSS3 vectors found by cvss.parse_cvss_from_text()", ) """"CVSS4 Test""" @on_exception_html_source_logger def test_edit_finding_cvssv4_valid_vector(self): self._edit_finding_cvss_and_assert( cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", cvssv4_score="1", expected_cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", expected_cvssv4_score="7.3", expect_success=True, ) @on_exception_html_source_logger def test_edit_finding_cvssv4_valid_vector_no_score(self): self._edit_finding_cvss_and_assert( cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", cvssv4_score=None, expected_cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", expected_cvssv4_score="7.3", expect_success=True, ) @on_exception_html_source_logger def test_edit_finding_cvssv4_valid_vector_no_prefix(self): self._edit_finding_cvss_and_assert( cvssv4_value="AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", cvssv4_score="2", expected_cvssv4_value="AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N", expected_cvssv4_score="2", expect_success=False, error_message="No valid CVSS4 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv4_valid_vector_with_trailing_slash(self): self._edit_finding_cvss_and_assert( cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/", cvssv4_score="3", expected_cvssv4_value="CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/", expected_cvssv4_score="3", expect_success=False, error_message="No valid CVSS4 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv4_with_v2_vector_invalid_due_to_prefix(self): self._edit_finding_cvss_and_assert( cvssv4_value="CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", cvssv4_score="4", expected_cvssv4_value="CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", expected_cvssv4_score="4", expect_success=False, error_message="No valid CVSS4 vectors found by cvss.parse_cvss_from_text()", ) @on_exception_html_source_logger def test_edit_finding_cvssv4_with_v2_vector(self): self._edit_finding_cvss_and_assert( cvssv4_value="AV:N/AC:L/Au:N/C:P/I:P/A:P", cvssv4_score="4", expected_cvssv4_value="AV:N/AC:L/Au:N/C:P/I:P/A:P", expected_cvssv4_score="4", expect_success=False, error_message="Unsupported CVSS2 version detected.", ) @on_exception_html_source_logger def test_edit_finding_cvssv4_with_v3_vector(self): self._edit_finding_cvss_and_assert( cvssv4_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", cvssv4_score="5", expected_cvssv4_value="CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", expected_cvssv4_score="5", expect_success=False, error_message="CVSS3 vector cannot be stored in the cvssv4 field. Use the cvssv3 field.", ) @on_exception_html_source_logger def test_edit_finding_cvssv4_with_rubbish(self): self._edit_finding_cvss_and_assert( cvssv4_value="happy little vector", cvssv4_score="5", expected_cvssv4_value="happy little vector", expected_cvssv4_score="5", expect_success=False, error_message="No valid CVSS4 vectors found by cvss.parse_cvss_from_text()", ) def test_add_image(self): # The Name of the Finding created by test_add_product_finding => 'App Vulnerable to XSS' # Test To Add Finding To product # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Edit Finding` driver.find_element(By.LINK_TEXT, "Manage Files").click() # select first file input field: form-0-image # Set full image path for image file 'strange.png image_path = dir_path / "finding_image.png" driver.find_element(By.ID, "id_form-0-file").send_keys(str(image_path)) driver.find_element(By.ID, "id_form-0-title").send_keys("Image Title") # Save uploaded image with WaitForPageLoad(driver, timeout=50): driver.find_element(By.CSS_SELECTOR, "button.btn.btn-success").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Files updated successfully.")) @on_exception_html_source_logger def test_add_note_to_finding(self): # The Name of the Finding created by test_add_product_finding => 'App Vulnerable to XSS' # Test To Add Finding To product # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Notes are on the view_test page driver.find_element(By.ID, "id_entry").clear() driver.find_element(By.ID, "id_entry").send_keys("This is a sample note for all to see.") # "Click" the submit button to complete the transaction driver.find_element(By.XPATH, "//input[@value='Add Note']").click() # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Note saved.")) def test_mark_finding_for_review(self): # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Request Peer Reveiw` driver.find_element(By.LINK_TEXT, "Request Peer Review").click() # select Reviewer # Let's make the first user in the list a reviewer # set select element style from 'none' to 'inline' try: WebDriverWait(driver, 5).until(expected_conditions.presence_of_element_located((By.ID, "id_reviewers"))) except TimeoutException: self.fail("Timed out waiting for reviewer dropdown to initialize ") driver.execute_script("document.getElementsByName('reviewers')[0].style.display = 'inline'") # select the first option tag element = driver.find_element(By.XPATH, "//select[@name='reviewers']") reviewer_option = element.find_elements(By.TAG_NAME, "option")[0] Select(element).select_by_value(reviewer_option.get_attribute("value")) # Add Review notes driver.find_element(By.ID, "id_entry").clear() driver.find_element(By.ID, "id_entry").send_keys("This is to be reviewed critically. Make sure it is well handled.") # Click 'Mark for review' driver.find_element(By.NAME, "submit").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding marked for review and reviewers notified.")) @on_exception_html_source_logger def test_clear_review_from_finding(self): # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on `Clear Review` link text driver.find_element(By.LINK_TEXT, "Clear Review").click() # Mark Active and Verified checkboxes driver.find_element(By.ID, "id_active").click() driver.find_element(By.ID, "id_verified").click() # Add Review notes driver.find_element(By.ID, "id_entry").clear() driver.find_element(By.ID, "id_entry").send_keys("This has been reviewed and confirmed. A fix needed here.") # Click 'Clear reveiw' button driver.find_element(By.NAME, "submit").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding review has been updated successfully.")) def test_delete_image(self): # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Edit Finding` driver.find_element(By.LINK_TEXT, "Manage Files").click() # mark delete checkbox for first file input field: form-0-DELETE driver.find_element(By.ID, "id_form-0-DELETE").click() # Save selection(s) for image deletion driver.find_element(By.CSS_SELECTOR, "button.btn.btn-success").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Files updated successfully.")) def test_close_finding(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint pre_status = driver.find_element(By.XPATH, '//*[@id="vuln_endpoints"]/tbody/tr/td[3]').text # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Close Finding` driver.find_element(By.LINK_TEXT, "Close Finding").click() # fill notes stating why finding should be closed driver.find_element(By.ID, "id_entry").send_keys("All issues in this Finding have been resolved successfully") # click 'close Finding' submission button driver.find_element(By.CSS_SELECTOR, "input.btn.btn-primary").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding closed.")) # Check to see if the endpoint was mitigated # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint # This will throw exception if the test fails due to invalid xpath post_status = driver.find_element(By.XPATH, '//*[@id="remd_endpoints"]/tbody/tr/td[3]').text # Assert ot the query to dtermine status of failure self.assertNotEqual(pre_status, post_status) def test_open_finding(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint pre_status = driver.find_element(By.XPATH, '//*[@id="remd_endpoints"]/tbody/tr/td[3]').text # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Open Finding` driver.find_element(By.LINK_TEXT, "Open Finding").click() # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding Reopened.")) # Check to see if the endpoint was set to active again # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint # This will throw exception if the test fails due to invalid xpath post_status = driver.find_element(By.XPATH, '//*[@id="vuln_endpoints"]/tbody/tr/td[3]').text # Assert ot the query to dtermine status of failure self.assertNotEqual(pre_status, post_status) @on_exception_html_source_logger def test_simple_accept_finding(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Close Finding` driver.find_element(By.LINK_TEXT, "Accept Risk").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding risk accepted.")) # Check to see if the endpoint was mitigated # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint # This will throw exception if the test fails due to invalid xpath # TODO: risk acceptance doesn't mitigate endpoints currently # post_status = driver.find_element(By.XPATH, '//*[@id="remd_endpoints"]/tbody/tr/td[3]').text # self.assertNotEqual(pre_status, post_status) def test_unaccept_finding(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Close Finding` driver.find_element(By.LINK_TEXT, "Unaccept Risk").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding risk unaccepted.")) # Check to see if the endpoint was mitigated # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Get the status of the current endpoint # This will throw exception if the test fails due to invalid xpath # TODO: risk acceptance doesn't mitigate endpoints currently # post_status = driver.find_element(By.XPATH, '//*[@id="remd_endpoints"]/tbody/tr/td[3]').text # self.assertNotEqual(pre_status, post_status) def test_make_finding_a_template(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Make Finding a Template` driver.find_element(By.LINK_TEXT, "Make Finding a Template").click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding template added successfully. You may edit it here.")) def test_apply_template_to_a_finding(self): driver = self.driver # Navigate to All Finding page logger.info("\nListing findings \n") self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() self.assertNoConsoleErrors() # Click on `Apply Template to Finding` driver.find_element(By.LINK_TEXT, "Apply Template to Finding").click() self.assertNoConsoleErrors() # click on the template of 'App Vulnerable to XSS' logger.info("\nClicking on the template \n") driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() self.assertNoConsoleErrors() # Click on 'Replace all' button logger.info("\nClicking on replace all \n") driver.find_element(By.XPATH, "//button[@data-option='Replace']").click() self.assertNoConsoleErrors() # Click the 'finished' button to submit driver.find_element(By.NAME, "_Finished").click() self.assertNoConsoleErrors() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_text_present_on_page(text="App Vulnerable to XSS")) @on_exception_html_source_logger def test_create_finding_from_template(self): driver = self.driver # Navigate to All Finding page # goto engagemnent list (and wait for javascript to load) self.goto_all_engagements_overview(driver) # Select a previously created engagement title driver.find_element(By.PARTIAL_LINK_TEXT, "Ad Hoc Engagement").click() driver.find_element(By.PARTIAL_LINK_TEXT, "Pen Test").click() # Click on the 'dropdownMenu1 button' # logger.info("\nClicking on dropdown menu \n") driver.find_element(By.ID, "dropdownMenu_test_add").click() self.assertNoConsoleErrors() # Click on `Apply Template to Finding` driver.find_element(By.LINK_TEXT, "Finding From Template").click() self.assertNoConsoleErrors() # click on the template of 'App Vulnerable to XSS' logger.info("\nClicking on the template \n") driver.find_element(By.LINK_TEXT, "Use This Template").click() self.assertNoConsoleErrors() driver.find_element(By.ID, "id_title").clear() driver.find_element(By.ID, "id_title").send_keys("App Vulnerable to XSS from Template") self.assertNoConsoleErrors() # Click the 'finished' button to submit driver.find_element(By.ID, "id_finished").click() self.assertNoConsoleErrors() # Query the site to determine if the finding has been added # Assert to the query to determine status of failure self.assertTrue(self.is_success_message_present(text="Finding from template added successfully.")) self.assertTrue(self.is_text_present_on_page(text="App Vulnerable to XSS From Template")) @on_exception_html_source_logger def test_create_finding_with_unqiue_characters(self): driver = self.driver # Navigate to All Finding page # goto engagemnent list (and wait for javascript to load) self.goto_all_engagements_overview(driver) # Select a previously created engagement title driver.find_element(By.PARTIAL_LINK_TEXT, "Ad Hoc Engagement").click() driver.find_element(By.PARTIAL_LINK_TEXT, "Pen Test").click() # Click on the 'dropdownMenu1 button' # logger.info("\nClicking on dropdown menu \n") driver.find_element(By.ID, "dropdownMenu_test_add").click() self.assertNoConsoleErrors() # Click on `Apply Template to Finding` driver.find_element(By.LINK_TEXT, "Finding From Template").click() self.assertNoConsoleErrors() # click on the template of 'App Vulnerable to XSS' logger.info("\nClicking on the template \n") driver.find_element(By.LINK_TEXT, "Use This Template").click() self.assertNoConsoleErrors() driver.find_element(By.ID, "id_title").clear() # Backslash causes error driver.find_element(By.ID, "id_title").send_keys("App Vulnerable to XSS from \\Template") self.assertNoConsoleErrors() # Click the 'finished' button to submit driver.find_element(By.ID, "id_finished").click() self.assertNoConsoleErrors() # Query the site to determine if the finding has been added # Assert to the query to determine status of failure self.assertTrue(self.is_success_message_present(text="Finding from template added successfully.")) self.assertTrue(self.is_text_present_on_page(text="App Vulnerable to XSS From \\Template")) # Navigate back to the finding list driver.find_element(By.LINK_TEXT, "Findings").click() self.assertNoConsoleErrors() driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS from \\Template").click() self.assertNoConsoleErrors() # Assert that the finding is present self.assertTrue(self.is_text_present_on_page(text="App Vulnerable to XSS from \\Template")) @on_exception_html_source_logger def test_delete_finding_template(self): driver = self.driver # Navigate to All Finding page driver.get(self.base_url + "template") # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on `Delete Template` button driver.find_element(By.XPATH, "//button[text()='Delete Template']").click() # Click 'Yes' on Alert popup driver.switch_to.alert.accept() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="Finding Template deleted successfully.")) def test_import_scan_result(self): driver = self.driver # Navigate to All Finding page self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'Finding' dropdown menubar driver.find_element(By.PARTIAL_LINK_TEXT, "Findings").click() # Click on `Import Scan Results` link text driver.find_element(By.LINK_TEXT, "Import Scan Results").click() # Select `ZAP Scan` as Scan Type Select(driver.find_element(By.ID, "id_scan_type")).select_by_visible_text("ZAP Scan") # Select `Default` as the Environment Select(driver.find_element(By.ID, "id_environment")).select_by_visible_text("Development") # upload scan file file_path = dir_path / "zap_sample.xml" driver.find_element(By.NAME, "file").send_keys(str(file_path)) # Click Submit button with WaitForPageLoad(driver, timeout=50): driver.find_elements(By.CSS_SELECTOR, "button.btn.btn-primary")[1].click() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure self.assertTrue(self.is_success_message_present(text="ZAP Scan processed a total of 4 findings")) @on_exception_html_source_logger def test_delete_finding(self): # The Name of the Finding created by test_add_product_finding => 'App Vulnerable to XSS' # Test To Add Finding To product # login to site, password set to fetch from environ driver = self.driver # Navigate to All Finding page # driver.get(self.base_url + "finding") self.goto_all_findings_list(driver) # Select and click on the particular finding to edit driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click() # Click on the 'dropdownMenu1 button' driver.find_element(By.ID, "dropdownMenu1").click() # Click on `Delete Finding` driver.find_element(By.LINK_TEXT, "Delete Finding").click() # Click 'Yes' on Alert popup driver.switch_to.alert.accept() # Query the site to determine if the finding has been added # Assert ot the query to dtermine status of failure # self.assertTrue(self.is_success_message_present(text='Finding deleted successfully')) # there's no alert when deleting this way self.assertTrue(self.is_text_present_on_page(text="Finding deleted successfully")) # check that user was redirect back to url where it came from based on return_url def test_list_components(self): driver = self.driver self.goto_component_overview(driver) self.assertTrue(self.is_element_by_css_selector_present("table")) def add_finding_tests_to_suite(suite, *, jira=False, github=False, block_execution=False): suite.addTest(BaseTestCase("test_login")) set_suite_settings(suite, jira=jira, github=github, block_execution=block_execution) # Add each test the the suite to be run # success and failure is output by the test suite.addTest(BaseTestCase("delete_finding_template_if_exists")) suite.addTest(ProductTest("test_create_product")) suite.addTest(ProductTest("test_add_product_finding")) suite.addTest(UserTest("test_create_user_with_writer_global_role")) suite.addTest(FindingTest("test_list_findings_all")) suite.addTest(FindingTest("test_list_findings_open")) suite.addTest(FindingTest("test_quick_report")) suite.addTest(FindingTest("test_csv_export")) suite.addTest(FindingTest("test_excel_export")) suite.addTest(FindingTest("test_list_components")) suite.addTest(FindingTest("test_edit_finding")) suite.addTest(FindingTest("test_edit_finding_cvssv3_valid_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv3_valid_vector_no_score")) suite.addTest(FindingTest("test_edit_finding_cvssv3_valid_vector_no_prefix")) suite.addTest(FindingTest("test_edit_finding_cvssv3_valid_vector_with_trailing_slash")) suite.addTest(FindingTest("test_edit_finding_cvssv3_with_v2_vector_invalid_due_to_prefix")) suite.addTest(FindingTest("test_edit_finding_cvssv3_with_v2_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv3_with_v4_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv3_with_rubbish")) suite.addTest(FindingTest("test_edit_finding_cvssv4_valid_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv4_valid_vector_no_score")) suite.addTest(FindingTest("test_edit_finding_cvssv4_valid_vector_no_prefix")) suite.addTest(FindingTest("test_edit_finding_cvssv4_valid_vector_with_trailing_slash")) suite.addTest(FindingTest("test_edit_finding_cvssv4_with_v2_vector_invalid_due_to_prefix")) suite.addTest(FindingTest("test_edit_finding_cvssv4_with_v2_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv4_with_v3_vector")) suite.addTest(FindingTest("test_edit_finding_cvssv4_with_rubbish")) suite.addTest(FindingTest("test_add_note_to_finding")) suite.addTest(FindingTest("test_add_image")) suite.addTest(FindingTest("test_delete_image")) suite.addTest(FindingTest("test_mark_finding_for_review")) suite.addTest(FindingTest("test_clear_review_from_finding")) suite.addTest(FindingTest("test_close_finding")) suite.addTest(FindingTest("test_list_findings_closed")) suite.addTest(FindingTest("test_open_finding")) suite.addTest(ProductTest("test_enable_simple_risk_acceptance")) suite.addTest(FindingTest("test_simple_accept_finding")) suite.addTest(FindingTest("test_list_findings_accepted")) suite.addTest(FindingTest("test_list_findings_all")) suite.addTest(FindingTest("test_unaccept_finding")) suite.addTest(FindingTest("test_make_finding_a_template")) suite.addTest(FindingTest("test_apply_template_to_a_finding")) suite.addTest(FindingTest("test_create_finding_from_template")) suite.addTest(FindingTest("test_import_scan_result")) suite.addTest(FindingTest("test_delete_finding")) suite.addTest(FindingTest("test_delete_finding_template")) suite.addTest(ProductTest("test_delete_product")) suite.addTest(UserTest("test_user_with_writer_role_delete")) return suite def suite(): suite = unittest.TestSuite() add_finding_tests_to_suite(suite, jira=False, github=False, block_execution=False) add_finding_tests_to_suite(suite, jira=True, github=True, block_execution=True) return suite if __name__ == "__main__": runner = unittest.TextTestRunner(descriptions=True, failfast=True, verbosity=2) ret = not runner.run(suite()).wasSuccessful() BaseTestCase.tearDownDriver() sys.exit(ret)