diff --git a/classes/repositories/kit_service_management_repository.py b/classes/repositories/kit_service_management_repository.py index 3ad5ab18..78b863ca 100644 --- a/classes/repositories/kit_service_management_repository.py +++ b/classes/repositories/kit_service_management_repository.py @@ -1,8 +1,10 @@ import logging -from typing import Optional +from typing import Optional, Any from utils.oracle.oracle import OracleDB from classes.kits.kit_service_management_record import KitServiceManagementRecord from classes.entities.kit_service_management_entity import KitServiceManagementEntity +import numpy as np +from decimal import Decimal class KitServiceManagementRepository: @@ -284,6 +286,22 @@ def update_kit_service_management_entity( if entity.put_attempts is not None: params["put_attempts"] = entity.put_attempts + params = {k: _sanitize_param(v) for k, v in params.items()} self.oracle_db.update_or_insert_data_to_table(sql_query, params) except Exception as ex: raise RuntimeError(f"Error updating KIT_QUEUE record: {ex}") + + +def _sanitize_param(val: Any) -> Any: + """ + Sanitizes a parameter value for database operations. + Args: + val: The parameter value to sanitize. + Returns: + The sanitized parameter value. + """ + if isinstance(val, np.generic): + return val.item() + if isinstance(val, Decimal): + return float(val) + return val diff --git a/docs/InvestigationDatasetBuilderApplication.md b/docs/InvestigationDatasetBuilderApplication.md index 417567e5..08c55fb8 100644 --- a/docs/InvestigationDatasetBuilderApplication.md +++ b/docs/InvestigationDatasetBuilderApplication.md @@ -329,7 +329,7 @@ Examples include `"yes_no"` and `"therapeutic_diagnostic"`, which are handled as 1. Choose a unique string for `"type"` (e.g., `"yes_no"`, `"therapeutic_diagnostic"`). 2. In your JSON field definition, set `"type"` to this string. -3. Ensure your `render_field` function in `investigation_dataset_ui.py` has a case for your custom type, rendering the appropriate widget (usually a dropdown/selectbox). +3. Ensure your `render_field` function in `investigation_dataset_ui.py` has a case for your custom type, rendering the appropriate widget (dropdown, radio, etc.). - For `"yes_no"`, the UI will show a dropdown with "yes" and "no". - For `"therapeutic_diagnostic"`, the UI will show a dropdown with "therapeutic" and "diagnostic". 4. You can add more custom types by extending the `render_field` function with new cases in the `match-case` or `if` dispatch. diff --git a/investigation_dataset_ui.py b/investigation_dataset_ui.py index 52712a17..fda2ecb7 100644 --- a/investigation_dataset_ui.py +++ b/investigation_dataset_ui.py @@ -546,7 +546,23 @@ def show_section_with_imports(section_name: str) -> None: ) else: import_block = "" - st.code(f"{import_block}{section_name} = {pretty_dict(result)}", language="python") + # Map section to correct fill method + fill_methods = { + "general_information": "fill_out_general_information", + "drug_information": "fill_out_drug_information", + "endoscopy_information": "fill_endoscopy_information", + "completion_information": "fill_out_completion_information", + "failure_information": "fill_out_failure_information", + "radiology_information": "fill_out_radiology_information", + "suspected_findings": "fill_out_suspected_findings", + } + method = fill_methods.get(section_name, f"fill_{section_name}") + st.code( + f"InvestigationDatasetCompletion(page).{method}({pretty_dict(result)})", + language="python", + ) + if import_block: + st.code(import_block, language="python") def show_drug_group_section_with_imports(section_name: str) -> None: @@ -569,6 +585,8 @@ def show_drug_group_section_with_imports(section_name: str) -> None: all_fields.extend(group["fields"]) _render_drug_group(section_name, group, result) + # No special merging; each section is handled independently + enums = get_enums_used(all_fields) if enums: import_block = ( @@ -576,7 +594,19 @@ def show_drug_group_section_with_imports(section_name: str) -> None: ) else: import_block = "" - st.code(f"{import_block}{section_name} = {pretty_dict(result)}", language="python") + # Map section to correct fill method + fill_methods = { + "drug_information": "fill_out_drug_information", + "contrast_tagging_and_drug": "fill_out_contrast_tagging_and_drug_information", + "tagging_agent_given_drug_information": "fill_out_tagging_agent_given_drug_information", + } + method = fill_methods.get(section_name, f"fill_{section_name}") + st.code( + f"InvestigationDatasetCompletion(page).{method}({pretty_dict(result)})", + language="python", + ) + if import_block: + st.code(import_block, language="python") def _render_single_entry_fields(fields: list, result: dict) -> None: @@ -638,6 +668,51 @@ def _render_drug_entry(fields: list, index: int, result: dict) -> None: result[dose_field["key"]] = ddose +def _polyp_output_block( + pi: int, info_dict: dict, intervention: object, hist_dict: dict +) -> str: + """ + Generate the code block for a polyp's information, intervention(s), and histology. + Args: + pi (int): The polyp index (1-based). + info_dict (dict): The polyp information dictionary. + intervention (object): The polyp intervention(s), can be dict or list of dicts. + hist_dict (dict): The polyp histology dictionary. + Returns: + str: The generated code block. + """ + code_lines = [] + code_lines.append( + f"InvestigationDatasetCompletion(page).fill_polyp_x_information({pretty_dict(info_dict)}, {pi})" + ) + # Intervention + if isinstance(intervention, list): + if len(intervention) > 1: + code_lines.append( + f"InvestigationDatasetCompletion(page).fill_polyp_x_multiple_interventions({pretty_list(intervention)}, {pi})" + ) + elif len(intervention) == 1 and isinstance(intervention[0], dict): + code_lines.append( + f"InvestigationDatasetCompletion(page).fill_polyp_x_intervention({pretty_dict(intervention[0])}, {pi})" + ) + else: + code_lines.append(f"# No intervention for polyp {pi}") + elif isinstance(intervention, dict): + code_lines.append( + f"InvestigationDatasetCompletion(page).fill_polyp_x_intervention({pretty_dict(intervention)}, {pi})" + ) + else: + code_lines.append(f"# No intervention for polyp {pi}") + # Histology + if not hist_dict: + code_lines.append(f"# No histology for polyp {pi}") + else: + code_lines.append( + f"InvestigationDatasetCompletion(page).fill_polyp_x_histology({pretty_dict(hist_dict)}, {pi})" + ) + return "\n".join(code_lines) + + def show_polyp_information_and_intervention_and_histology() -> None: """ Show the Polyp Information, Intervention & Histology section, allowing multiple polyps and interventions. @@ -652,39 +727,39 @@ def show_polyp_information_and_intervention_and_histology() -> None: # Collect all fields for import analysis all_fields = polyp_info_fields + polyp_intervention_fields + polyp_histology_fields enums = get_enums_used(all_fields) - if enums: - import_block = ( - enum_import_string + new_indented_line_string.join(sorted(enums)) + "\n)\n" - ) - else: - import_block = "" + import_block = ( + enum_import_string + new_indented_line_string.join(sorted(enums)) + "\n)\n" + if enums + else "" + ) num_polyps = st.number_input( "Number of polyps", min_value=0, max_value=20, value=1, step=1 ) - polyp_information = [] - polyp_intervention = [] - polyp_histology = [] + polyp_info_dicts = {} + polyp_histology_dicts = {} + polyp_interventions_dicts = {} for pi in range(1, num_polyps + 1): st.markdown(f"### Polyp {pi}") - polyp_information.append(_render_polyp_info(polyp_info_fields, pi)) - polyp_intervention.append(_render_interventions(polyp_intervention_fields, pi)) - polyp_histology.append(_render_histology(polyp_histology_fields, pi)) + polyp_info_dicts[pi] = _render_polyp_info(polyp_info_fields, pi) + interventions = _render_interventions(polyp_intervention_fields, pi) + polyp_interventions_dicts[pi] = ( + interventions[0] + if isinstance(interventions, list) and len(interventions) == 1 + else interventions + ) + polyp_histology_dicts[pi] = _render_histology(polyp_histology_fields, pi) st.markdown("#### Output") - st.code( - f"{import_block}polyp_information = {pretty_list(polyp_information)}", - language="python", - ) - st.code( - f"polyp_intervention = {pretty_list(polyp_intervention)}", - language="python", - ) - st.code( - f"polyp_histology = {pretty_list(polyp_histology)}", - language="python", - ) + for pi in range(1, num_polyps + 1): + info_dict = polyp_info_dicts[pi] + hist_dict = polyp_histology_dicts[pi] + intervention = polyp_interventions_dicts[pi] + code_block = _polyp_output_block(pi, info_dict, intervention, hist_dict) + st.code(code_block, language="python") + if import_block: + st.code(import_block, language="python") def _render_polyp_info(fields: list, pi: int) -> dict: @@ -718,7 +793,7 @@ def _render_interventions(fields: list, pi: int) -> list: f"Add interventions for polyp {pi}?", key=f"add_interventions_{pi}" ) if not add_interventions: - return interventions + return [] num_int = st.number_input( f"Number of interventions for polyp {pi}", min_value=0, @@ -735,6 +810,8 @@ def _render_interventions(fields: list, pi: int) -> list: if val is not None: int_dict[field["key"]] = val interventions.append(int_dict) + if len(interventions) == 1: + return interventions[0] return interventions @@ -799,7 +876,7 @@ def _render_histology(fields: list, pi: int) -> dict: "endoscopy_information": show_section_with_imports, "completion_information": show_section_with_imports, "failure_information": show_section_with_imports, - "polyp_information_and_intervention_and_histology": lambda _: show_polyp_information_and_intervention_and_histology(), # If you want imports here, update similarly + "polyp_information_and_intervention_and_histology": lambda _: show_polyp_information_and_intervention_and_histology(), "contrast_tagging_and_drug": show_drug_group_section_with_imports, "tagging_agent_given_drug_information": show_drug_group_section_with_imports, "radiology_information": show_section_with_imports, diff --git a/pages/contacts_list/maintain_contacts_page.py b/pages/contacts_list/maintain_contacts_page.py index f2346d94..b668b406 100644 --- a/pages/contacts_list/maintain_contacts_page.py +++ b/pages/contacts_list/maintain_contacts_page.py @@ -65,3 +65,14 @@ def click_person_link_from_forename(self, forename: str) -> None: forename (str): The forename of the subject """ self.click(self.page.get_by_role("link", name=forename).last) + + def select_person_by_id(self, person_id: int) -> None: + """ + Selects a person by their unique person ID by clicking the corresponding link. + Requires a search to have been conducted and returned at least one result. + Args: + person_id (int): The unique ID of the person to select + """ + href_selector = f"a[href*='{person_id}']" + person_link = self.page.locator(href_selector).first + self.click(person_link) diff --git a/pages/datasets/investigation_dataset_page.py b/pages/datasets/investigation_dataset_page.py index 9ba4ab08..82078482 100644 --- a/pages/datasets/investigation_dataset_page.py +++ b/pages/datasets/investigation_dataset_page.py @@ -96,6 +96,7 @@ def __init__(self, page: Page): self.diagnostic_test_result = self.page.locator( "#datasetContent > div:nth-child(1) > div:nth-child(7) > span.userInput" ) + self.show_details_links = self.page.locator('a:has-text("Show details")') # Repeat strings: self.bowel_preparation_administered_string = "Bowel Preparation Administered" @@ -361,10 +362,13 @@ def select_diagnostic_procedure_type(self) -> None: def click_show_completion_proof_information(self) -> None: """ - This method is designed to click on the show completion proof information link. - It clicks on the show completion proof information link. + Clicks on the show completion proof information link if it contains the text "show" (case-insensitive). """ - self.click(self.show_completion_proof_information_details) + if ( + "show" + in self.show_completion_proof_information_details.inner_text().lower() + ): + self.click(self.show_completion_proof_information_details) def click_show_failure_information(self) -> None: """ @@ -415,6 +419,17 @@ def click_save_dataset_button(self) -> None: It clicks on the save dataset button. """ self.safe_accept_dialog(self.save_dataset_button) + self.page.wait_for_timeout(3000) # 3 second timeout to allow page to update + + def click_save_dataset_button_assert_dialog(self, expected_text: str) -> None: + """ + Clicks on the save dataset button and performs an assertion of the resulting dialog text. + Once done it dismisses the dialog. + Args: + expected_text (str): The expected text in the resultant dialog + """ + self.assert_dialog_text(expected_text) + self.click(self.save_dataset_button) def expect_text_to_be_visible(self, text: str) -> None: """ @@ -1193,6 +1208,24 @@ def assert_test_result(self, expected_text: str) -> None: actual_text.lower() == expected_text.lower() ), f"Expected '{expected_text}', but found '{actual_text}'" + def open_all_details_tabs(self) -> None: + """ + Clicks all visible "Show details" links on the page to open all details tabs. + """ + count = self.show_details_links.count() + for i in range(count): + link = self.show_details_links.nth(i) + if link.is_visible(): + self.click(link) + + def open_all_minimized_sections(self) -> None: + """ + Opens all the minimized sections in the investigation dataset form. + """ + self.open_all_details_tabs() + # Then do it again to get the internal sections + self.open_all_details_tabs() + def normalize_label(text: str) -> str: """ diff --git a/pages/screening_subject_search/contact_with_patient_page.py b/pages/screening_subject_search/contact_with_patient_page.py index 8487928c..00f5954c 100644 --- a/pages/screening_subject_search/contact_with_patient_page.py +++ b/pages/screening_subject_search/contact_with_patient_page.py @@ -2,6 +2,7 @@ from pages.base_page import BasePage from utils.calendar_picker import CalendarPicker from datetime import datetime +from typing import List class ContactWithPatientPage(BasePage): @@ -149,6 +150,21 @@ def record_contact(self, outcome: str, patient_contacted: str = "Yes") -> None: self.select_outcome_dropdown_option(outcome) self.click_save_button() + def outcome_dropdown_contains_options(self, options: List[str]) -> None: + """ + Asserts that all provided options are present in the Outcome of Diagnostic Test dropdown. + + Args: + options (List[str]): List of option strings to check. + """ + dropdown_options = [ + opt.inner_text() for opt in self.outcome_dropdown.locator("option").all() + ] + for item in options: + assert ( + item in dropdown_options + ), f"Dropdown is missing expected option: '{item}'" + def verify_contact_with_patient_page_is_displayed(self) -> None: """Verify that the 'Contact With Patient' page is displayed.""" expect(self.bowel_cancer_screening_ntsh_page_title).to_have_text( diff --git a/pages/screening_subject_search/diagnostic_test_outcome_page.py b/pages/screening_subject_search/diagnostic_test_outcome_page.py index c29a02b1..90ab9715 100644 --- a/pages/screening_subject_search/diagnostic_test_outcome_page.py +++ b/pages/screening_subject_search/diagnostic_test_outcome_page.py @@ -84,6 +84,24 @@ def test_outcome_dropdown_contains_options(self, options: List[str]) -> None: item in dropdown_options ), f"Dropdown is missing expected option: '{item}'" + def reason_for_onward_referral_dropdown_contains_options( + self, options: List[str] + ) -> None: + """ + Asserts that all provided options are present in the Outcome of Diagnostic Test dropdown. + + Args: + options (List[str]): List of option strings to check. + """ + dropdown_options = [ + opt.inner_text() + for opt in self.reason_for_onward_referral_dropdown.locator("option").all() + ] + for item in options: + assert ( + item in dropdown_options + ), f"Dropdown is missing expected option: '{item}'" + def verify_reason_for_symptomatic_referral(self, symptomatic_reason: str) -> None: """ Verify reason for symptomatic referral is visible. diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_10.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_10.py index d4ca6bf4..ccecbece 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_10.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_10.py @@ -15,9 +15,6 @@ from utils.oracle.oracle import OracleDB from utils.investigation_dataset import InvestigationDatasetCompletion from utils.datasets.investigation_datasets import ( - get_default_general_information, - get_default_drug_information, - get_default_endoscopy_information, get_normal_smokescreen_information, ) from utils.sspi_change_steps import SSPIChangeSteps @@ -57,6 +54,14 @@ from pages.datasets.investigation_dataset_page import ( InvestigationDatasetsPage, FailureReasonsOptions, + BowelPreparationQualityOptions, + ComfortOptions, + EndoscopyLocationOptions, + InsufflationOptions, + OutcomeAtTimeOfProcedureOptions, + DrugTypeOptions, + YesNoOptions, + LateOutcomeOptions, ) from pages.screening_subject_search.reopen_fobt_screening_episode_page import ( ReopenFOBTScreeningEpisodePage, @@ -197,12 +202,18 @@ def test_scenario_10(page: Page) -> None: # And there is a "A183" letter batch for my subject with the exact title "Practitioner Clinic 1st Appointment" # When I process the open "A183 - Practitioner Clinic 1st Appointment" letter batch for my subject - # Then my subject has been updated as follows: batch_processing( page, "A183", "Practitioner Clinic 1st Appointment", - "A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Specialist Screening Practitioner" @@ -274,7 +285,6 @@ def test_scenario_10(page: Page) -> None: page, "A183", "GP Result (Abnormal)", - "A99 - Suitable for Endoscopic Test", ) # Then my subject has been updated as follows: @@ -350,31 +360,66 @@ def test_scenario_10(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = get_default_drug_information() + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = get_default_general_information() - endoscopy_information = get_default_endoscopy_information() - endoscopy_information["procedure type"] = "diagnostic" + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": 1, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = { - "failure reasons": FailureReasonsOptions.PAIN, - } + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} + ) # And I mark the Investigation Dataset as completed - # When I press the save Investigation Dataset button - # And I press OK on my confirmation prompt - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - ) + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then my subject has been updated as follows: subject_assertion( @@ -482,9 +527,17 @@ def test_scenario_10(page: Page) -> None: page, "A318", "Result Letters - No Post-investigation Appointment", - "A380 - Failed Diagnostic Test - Refer Another", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A380 Failed Diagnostic Test - Refer Another"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I select the advance episode option for "Record Contact with Patient" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_record_contact_with_patient_button() @@ -540,9 +593,15 @@ def test_scenario_10(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I apply the "Normal_Smokescreen" Investigation Dataset Scenario - # And I mark the Investigation Dataset as completed - # When I press the save Investigation Dataset button ( general_information, drug_information, @@ -550,19 +609,32 @@ def test_scenario_10(page: Page) -> None: failure_information, completion_information, ) = get_normal_smokescreen_information() - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, + InvestigationDatasetCompletion(page).fill_out_drug_information(drug_information) + InvestigationDatasetCompletion(page).fill_out_general_information( + general_information + ) + InvestigationDatasetCompletion(page).fill_endoscopy_information( + endoscopy_information + ) + InvestigationDatasetCompletion(page).fill_out_failure_information( + failure_information ) + InvestigationDatasetCompletion(page).fill_out_completion_information( + completion_information + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "Normal (No Abnormalities Found)" - InvestigationDatasetsPage(page).expect_text_to_be_visible( + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog( "Normal (No Abnormalities Found)" ) + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() + # Then my subject has been updated as follows: subject_assertion( nhs_no, @@ -631,7 +703,14 @@ def test_scenario_10(page: Page) -> None: page, "A410", "Post-Investigation Appointment Invitation Letter", - "A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -670,7 +749,6 @@ def test_scenario_10(page: Page) -> None: page, "A430", "Result Letters Following Post-investigation Appointment", - "S61 - Normal (No Abnormalities Found) ", ) # Then my subject has been updated as follows: @@ -785,7 +863,6 @@ def test_scenario_10(page: Page) -> None: page, "A430", "Result Letters Following Post-investigation Appointment", - "S61 - Normal (No Abnormalities Found) ", ) # Then my subject has been updated as follows: diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_11.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_11.py index eb33740e..6d479a4b 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_11.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_11.py @@ -207,12 +207,18 @@ def test_scenario_11(page: Page) -> None: # And there is a "A183" letter batch for my subject with the exact title "Practitioner Clinic 1st Appointment" # When I process the open "A183 - Practitioner Clinic 1st Appointment" letter batch for my subject - # Then my subject has been updated as follows: batch_processing( page=page, batch_type="A183", batch_description="Practitioner Clinic 1st Appointment", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -342,6 +348,15 @@ def test_scenario_11(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { "Person has current role": "Accredited Screening Colonoscopist", @@ -358,49 +373,54 @@ def test_scenario_11(page: Page) -> None: ) # And I set the following fields and values within the "Investigation Dataset" section of the investigation dataset: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "site": 1, + "practitioner": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) # When I add the following "bowel preparation administered" drugs and doses within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + ) # And I set the following fields and values within the "Endoscopy Information" section of the investigation dataset: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "detection assistant used": YesNoOptions.YES, - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "detection assistant used": YesNoOptions.YES, + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) # When I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 4 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 5 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 6 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.RECTUM, "classification": PolypClassificationOptions.IP, @@ -410,6 +430,37 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 1, + ) + + # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + }, + 1, + ) + + # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( + { + "date of receipt": datetime.today(), + "date of reporting": datetime.today(), + "pathology provider": 1, + "pathologist": 1, + "polyp type": PolypTypeOptions.SERRATED_LESION, + "serrated lesion sub type": SerratedLesionSubTypeOptions.HYPERPLASTIC_POLYP, + "polyp excision complete": PolypExcisionCompleteOptions.R1, + "polyp size": "5", + }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.CAECUM, "classification": PolypClassificationOptions.LST_NG, @@ -419,6 +470,23 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 2, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 2", + }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.DESCENDING_COLON, "classification": PolypClassificationOptions.IP, @@ -428,6 +496,23 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 3, + ) + + # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.COLD_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 3", + }, + 3, + ) + + # And I add new polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ASCENDING_COLON, "classification": PolypClassificationOptions.ISP, @@ -437,6 +522,23 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 4, + ) + + # And I add intervention 1 for polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.ESD, + "device": PolypInterventionDeviceOptions.ENDOSCOPIC_KNIFE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 4", + }, + 4, + ) + + # And I add new polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.RECTUM, "classification": PolypClassificationOptions.ISP, @@ -446,6 +548,23 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 5, + ) + + # And I add intervention 1 for polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 5", + }, + 5, + ) + + # And I add new polyp 6 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.SIGMOID_COLON, "classification": PolypClassificationOptions.IS, @@ -455,99 +574,30 @@ def test_scenario_11(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, - ] + 6, + ) - # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 4 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 5 with the following fields and values within the Investigation Dataset for this subject: # And I add intervention 1 for polyp 6 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 2", - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.COLD_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 3", - } - ], - [ - { - "modality": PolypInterventionModalityOptions.ESD, - "device": PolypInterventionDeviceOptions.ENDOSCOPIC_KNIFE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 4", - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 5", - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 6", - } - ], - ] - - # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( { - "date of receipt": datetime.today(), - "date of reporting": datetime.today(), - "pathology provider": 1, - "pathologist": 1, - "polyp type": PolypTypeOptions.SERRATED_LESION, - "serrated lesion sub type": SerratedLesionSubTypeOptions.HYPERPLASTIC_POLYP, - "polyp excision complete": PolypExcisionCompleteOptions.R1, - "polyp size": "5", - } - ] - - # And I mark the Investigation Dataset as complete - # And I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 6", + }, + 6, ) + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "Abnormal" - InvestigationDatasetsPage(page).expect_text_to_be_visible("Abnormal") + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("Abnormal") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 5 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "5") @@ -613,9 +663,19 @@ def test_scenario_11(page: Page) -> None: page, "A410", "Post-Investigation Appointment Invitation Letter", - "A415 - Post-investigation Appointment Invitation Letter Printed", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I view the event history for the subject's latest episode SubjectScreeningSummaryPage(page).expand_episodes_list() SubjectScreeningSummaryPage(page).click_first_fobt_episode_link() @@ -646,9 +706,19 @@ def test_scenario_11(page: Page) -> None: page, "A417", "Post-Investigation Appointment Cancelled (Screening Centre)", - "A422 - Post-investigation Appointment Cancellation Letter Printed", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A422 Post-investigation Appointment Cancellation Letter Printed" + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I advance the subject's episode for "Post-investigation Appointment Required" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage( @@ -689,7 +759,14 @@ def test_scenario_11(page: Page) -> None: page=page, batch_type="A410", batch_description="Post-Investigation Appointment Invitation Letter", - latest_event_status="A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -794,6 +871,7 @@ def test_scenario_11(page: Page) -> None: "A430", "Result Letters Following Post-investigation Appointment", ) + # Then my subject has been updated as follows: criteria = { "which diagnostic test": "Latest not-void test in latest episode", diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_12.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_12.py index 7346f1f0..b40bf404 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_12.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_12.py @@ -4,6 +4,7 @@ from playwright.sync_api import Page from classes.subject.subject import Subject from classes.user.user import User +from classes.repositories.person_repository import PersonRepository from utils.calendar_picker import CalendarPicker from utils.user_tools import UserTools from utils.subject_assertion import subject_assertion @@ -231,7 +232,14 @@ def test_scenario_12(page: Page) -> None: page, "A183", "Practitioner Clinic 1st Appointment", - "A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -341,50 +349,82 @@ def test_scenario_12(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() - # And I set the following fields and values within the "Investigation Dataset" section of the investigation dataset: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": 1, - "aspirant endoscopist": None, + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + + # And there is a clinician who meets the following criteria: + user = User.from_user_role_type(user_role) + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "User's SC", + "Resect & Discard accreditation status": "None", } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=user, subject=None + ) + df = OracleDB().execute_query(query) + person_name = ( + f"{df["person_family_name"].iloc[0]} {df["person_given_name"].iloc[0]}" + ) + + # And I set the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) # When I add the following "bowel preparation administered" drugs and doses within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following fields and values within the "Endoscopy Information" section of the investigation dataset: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.FAIR, - "comfort during examination": ComfortOptions.MODERATE_DISCOMFORT, - "comfort during recovery": ComfortOptions.MINIMAL_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.FAIR, + "comfort during examination": ComfortOptions.MODERATE_DISCOMFORT, + "comfort during recovery": ComfortOptions.MINIMAL_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.PAIN} - - # And I mark the Investigation Dataset as complete - # And I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} ) + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # And my subject has been updated as follows: subject_assertion(nhs_no, {"latest episode accumulated result": "No result"}) @@ -450,7 +490,14 @@ def test_scenario_12(page: Page) -> None: page, "A410", "Post-Investigation Appointment Invitation Letter", - "A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -492,9 +539,17 @@ def test_scenario_12(page: Page) -> None: page, "A353", "GP Letter Indicating Referral to Symptomatic", - "A372 - Refer Symptomatic, GP Letter Printed", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A372 Refer Symptomatic, GP Letter Printed"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I view the advance episode options SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() @@ -552,8 +607,7 @@ def test_scenario_12(page: Page) -> None: page, "A358", "Return FOBT Letter after Referral to Symptomatic", - "P202 - Waiting Completion of Outstanding Events", - True, + run_timed_events=True, ) # Then my subject has been updated as follows: @@ -987,7 +1041,12 @@ def test_scenario_12(page: Page) -> None: page=page, batch_type="A319", batch_description="Result Letters - Refer another test after symptomatic referral", - latest_event_status="A395 - Refer Another Diagnostic Test", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A395 Refer Another Diagnostic Test"}, ) LogoutPage(page).log_out() diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_13.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_13.py index 761eaf0c..1944e203 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_13.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_13.py @@ -212,7 +212,14 @@ def test_scenario_13(page: Page) -> None: page, "A183", "Practitioner Clinic 1st Appointment", - "A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -348,6 +355,14 @@ def test_scenario_13(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { @@ -365,43 +380,54 @@ def test_scenario_13(page: Page) -> None: ) # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.ADHESION} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.ADHESION} + ) # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ANASTOMOSIS, "classification": PolypClassificationOptions.IP, @@ -409,59 +435,22 @@ def test_scenario_13(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, - { - "location": EndoscopyLocationOptions.CAECUM, - "classification": PolypClassificationOptions.LST_NG, - "estimate of whole polyp size": "5", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, - "classification": PolypClassificationOptions.LST_NG, - "estimate of whole polyp size": "21", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - ] + 1, + ) # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - "polyp appears fully resected endoscopically": YesNoOptions.YES, - } - ], - ] + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + }, + 1, + ) # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 3 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -474,6 +463,35 @@ def test_scenario_13(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "5", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -486,26 +504,52 @@ def test_scenario_13(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "21", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 3, + ) + + # And I update histology details for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "pathology lost": YesNoOptions.YES, "reason pathology lost": ReasonPathologyLostOptions.LOST_IN_TRANSIT, }, - ] - - # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, + 3, ) + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" - InvestigationDatasetsPage(page).expect_text_to_be_visible("LNPCP") + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 13 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "13") diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_14.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_14.py index 629e0e85..defa12ce 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_14.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_14.py @@ -277,7 +277,14 @@ def test_scenario_14(page: Page) -> None: page=page, batch_description="Practitioner Clinic 1st Appointment", batch_type="A183", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -385,6 +392,14 @@ def test_scenario_14(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { @@ -406,44 +421,55 @@ def test_scenario_14(page: Page) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following endoscopy fields and values within the Investigation Dataset for this subject: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.ADHESION} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.ADHESION} + ) - # And I add new polyp 1-5 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.CAECUM, "classification": PolypClassificationOptions.LST_NG, @@ -451,95 +477,23 @@ def test_scenario_14(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, - { - "location": EndoscopyLocationOptions.ASCENDING_COLON, - "classification": PolypClassificationOptions.IIA, - "estimate of whole polyp size": "8", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, - "classification": PolypClassificationOptions.IIB, - "estimate of whole polyp size": "9", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.TRANSVERSE_COLON, - "classification": PolypClassificationOptions.IIC, - "estimate of whole polyp size": "7", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.SPLENIC_FLEXURE, - "classification": PolypClassificationOptions.LST_G, - "estimate of whole polyp size": "8", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - ] + 1, + ) # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 4 with the following fields and values within the Investigation Dataset for this subject: - # And I add intervention 1 for polyp 5 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.ESD, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - ] + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 1, + ) # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 3 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 4 with the following fields and values within the Investigation Dataset for this subject: - # And I update histology details for polyp 5 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -552,6 +506,35 @@ def test_scenario_14(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NO_DYSPLASIA, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.ASCENDING_COLON, + "classification": PolypClassificationOptions.IIA, + "estimate of whole polyp size": "8", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + }, + 2, + ) + + # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -564,7 +547,59 @@ def test_scenario_14(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, - {}, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.IIB, + "estimate of whole polyp size": "9", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.ESD, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 3, + ) + + # And I add new polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.TRANSVERSE_COLON, + "classification": PolypClassificationOptions.IIC, + "estimate of whole polyp size": "7", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 4, + ) + + # And I add intervention 1 for polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + }, + 4, + ) + + # And I update histology details for polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -576,6 +611,35 @@ def test_scenario_14(page: Page) -> None: "polyp size": "8", "polyp carcinoma": YesNoUncertainOptions.NO, }, + 4, + ) + + # And I add new polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.SPLENIC_FLEXURE, + "classification": PolypClassificationOptions.LST_G, + "estimate of whole polyp size": "8", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 5, + ) + + # And I add intervention 1 for polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 5, + ) + + # And I update histology details for polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -588,22 +652,20 @@ def test_scenario_14(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.LOW_GRADE_DYSPLASIA, "polyp carcinoma": YesNoUncertainOptions.NO, }, - ] + 5, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, + # Then the Investigation Dataset result message, which I will cancel, is "High-risk findings" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog( + "High-risk findings" ) - # Then the Investigation Dataset result message, which I will cancel, is "High-risk findings" - InvestigationDatasetsPage(page).expect_text_to_be_visible("High-risk findings") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 9 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "9") diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_15.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_15.py index 12a5a1ed..1d0763f9 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_15.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_15.py @@ -228,7 +228,14 @@ def test_scenario_15(page: Page) -> None: page, "A183", "Practitioner Clinic 1st Appointment", - "A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -384,6 +391,14 @@ def test_scenario_15(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role_type=user_role) criteria = { @@ -401,41 +416,54 @@ def test_scenario_15(page: Page) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "site": 1, + "practitioner": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) - # And I add new polyps 1-5 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.SIGMOID_COLON, "classification": PolypClassificationOptions.IS, @@ -443,87 +471,23 @@ def test_scenario_15(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 1, + ) + + # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( { - "location": EndoscopyLocationOptions.RECTUM, - "classification": PolypClassificationOptions.IS, - "estimate of whole polyp size": "7", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.CAECUM, - "classification": PolypClassificationOptions.IS, - "estimate of whole polyp size": "3", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.YES, - "reason left in situ": PolypReasonLeftInSituOptions.POLYP_TYPE, - "polyp type left in situ": PolypTypeLeftInSituOptions.LYMPHOID_FOLLICLE, - }, - { - "location": EndoscopyLocationOptions.ILEUM, - "classification": PolypClassificationOptions.IS, - "estimate of whole polyp size": "2", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.DESCENDING_COLON, - "classification": PolypClassificationOptions.IS, - "estimate of whole polyp size": "4", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.COLD_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, }, - ] - - # And I add intervention 1 for polyps 1-5 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.COLD_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.BIOPSY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "intervention success": PolypInterventionSuccessOptions.SUCCESSFUL, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - ] - - # And I update histology details for polyps 1-5 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + 1, + ) + + # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -536,6 +500,35 @@ def test_scenario_15(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.RECTUM, + "classification": PolypClassificationOptions.IS, + "estimate of whole polyp size": "7", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -546,6 +539,35 @@ def test_scenario_15(page: Page) -> None: "polyp excision complete": PolypExcisionCompleteOptions.R1, "polyp size": "8", }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.IS, + "estimate of whole polyp size": "3", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.YES, + "reason left in situ": PolypReasonLeftInSituOptions.POLYP_TYPE, + "polyp type left in situ": PolypTypeLeftInSituOptions.LYMPHOID_FOLLICLE, + }, + 3, + ) + + # And I add intervention 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.BIOPSY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "intervention success": PolypInterventionSuccessOptions.SUCCESSFUL, + }, + 3, + ) + + # And I update histology details for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -556,6 +578,35 @@ def test_scenario_15(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 3, + ) + + # And I add new polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.ILEUM, + "classification": PolypClassificationOptions.IS, + "estimate of whole polyp size": "2", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 4, + ) + + # And I add intervention 1 for polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 4, + ) + + # And I update histology details for polyp 4 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -568,6 +619,35 @@ def test_scenario_15(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 4, + ) + + # And I add new polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.DESCENDING_COLON, + "classification": PolypClassificationOptions.IS, + "estimate of whole polyp size": "4", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 5, + ) + + # And I add intervention 1 for polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 5, + ) + + # And I update histology details for polyp 5 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -580,22 +660,18 @@ def test_scenario_15(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, - ] + 5, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, - ) + # Then the Investigation Dataset result message, which I will cancel, is "Abnormal" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("Abnormal") - # Then the Investigation Dataset result message is "Abnormal" - InvestigationDatasetsPage(page).expect_text_to_be_visible("Abnormal") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 4 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "4") @@ -764,7 +840,14 @@ def test_scenario_15(page: Page) -> None: page, "A410", "Post-Investigation Appointment Invitation Letter", - "A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -796,9 +879,17 @@ def test_scenario_15(page: Page) -> None: page, "A430", "Result Letters Following Post-investigation Appointment", - "A395 - Refer Another Diagnostic Test", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A395 Refer Another Diagnostic Test"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I select the advance episode option for "Record Contact with Patient" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_record_contact_with_patient_button() @@ -856,15 +947,28 @@ def test_scenario_15(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { "Person has current role": "Accredited Screening Colonoscopist", "Person has current role in organisation": "User's SC", - "Resect & Discard accreditation status": "None", + "Latest resect & discard accreditation start date": "Within the last 2 years", } query = PersonRepository().build_person_selection_query( criteria=criteria, person=None, required_person_count=1, user=user, subject=None @@ -876,57 +980,47 @@ def test_scenario_15(page: Page) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} - - # When there is a clinician who meets the following criteria: - criteria = { - "Person has current role": "Accredited Screening Colonoscopist", - "Person has current role in organisation": "User's SC", - "Latest resect & discard accreditation start date": "Within the last 2 years", - } - query = PersonRepository().build_person_selection_query( - criteria=criteria, person=None, required_person_count=1, user=user, subject=None - ) - logging.info(f"Final query: {query}") - df = OracleDB().execute_query(query) - person_name = ( - f"{df["person_family_name"].iloc[0]} {df["person_given_name"].iloc[0]}" + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} ) - # And I set the following fields and values within the Investigation Dataset for this subject: - general_information["testing clinician"] = person_name - # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.SIGMOID_COLON, "classification": PolypClassificationOptions.IS, @@ -935,35 +1029,31 @@ def test_scenario_15(page: Page) -> None: "optical diagnosis confidence": OpticalDiagnosisConfidenceOptions.LOW, "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, - } - ] + }, + 1, + ) # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, - "image id": "AUTO TEST POLYP 6 overall", - } - ] - ] + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO_RESECT_AND_DISCARD, + "image id": "AUTO TEST POLYP 6 overall", + }, + 1, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "Abnormal" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("Abnormal") # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - ) - - # Then the Investigation Dataset result message is "Abnormal" - InvestigationDatasetsPage(page).expect_text_to_be_visible("Abnormal") + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 4 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "4") diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_16.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_16.py index 47ece10c..446b1e31 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_16.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_16.py @@ -219,7 +219,14 @@ def test_scenario_16(page: Page) -> None: page, "A183", "Practitioner Clinic 1st Appointment", - "A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # And there is a "A183" letter batch for my subject with the exact title "GP Result (Abnormal)" @@ -422,6 +429,14 @@ def test_scenario_16(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) query = PersonRepository().build_person_selection_query( @@ -441,41 +456,55 @@ def test_scenario_16(page: Page) -> None: ) # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = {"drug_type1": DrugTypeOptions.MANNITOL, "drug_dose1": "3"} + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "retroverted view": YesNoOptions.NO, - "scope imager used": YesNoOptions.YES, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "retroverted view": YesNoOptions.NO, + "scope imager used": YesNoOptions.YES, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) - # I add new polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + # I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ANASTOMOSIS, "classification": PolypClassificationOptions.IP, @@ -483,55 +512,22 @@ def test_scenario_16(page: Page) -> None: "estimate of whole polyp size": "11", "left in situ": YesNoOptions.NO, }, + 1, + ) + + # I add interventions 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( { - "location": EndoscopyLocationOptions.CAECUM, - "classification": PolypClassificationOptions.LST_NG, - "polyp access": PolypAccessOptions.EASY, - "estimate of whole polyp size": "5", - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, - "classification": PolypClassificationOptions.LST_NG, - "polyp access": PolypAccessOptions.EASY, - "estimate of whole polyp size": "21", - "left in situ": YesNoOptions.NO, + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "excised": YesNoOptions.YES, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "retrieved": PolypInterventionRetrievedOptions.YES, }, - ] - - # I add interventions 1 for polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_interventions = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "excised": YesNoOptions.YES, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "retrieved": PolypInterventionRetrievedOptions.YES, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "excised": YesNoOptions.YES, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "excised": YesNoOptions.YES, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - "polyp appears fully resected endoscopically": YesNoOptions.YES, - } - ], - ] - - # I update histology details for polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + 1, + ) + + # I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of reporting": datetime.today(), "date of receipt": datetime.today(), @@ -544,6 +540,35 @@ def test_scenario_16(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.LST_NG, + "polyp access": PolypAccessOptions.EASY, + "estimate of whole polyp size": "5", + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # I add interventions 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "excised": YesNoOptions.YES, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of reporting": datetime.today(), "date of receipt": datetime.today(), @@ -556,26 +581,52 @@ def test_scenario_16(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 2, + ) + + # I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.LST_NG, + "polyp access": PolypAccessOptions.EASY, + "estimate of whole polyp size": "21", + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # I add interventions 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "excised": YesNoOptions.YES, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 3, + ) + + # I update histology details for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "pathology lost": YesNoOptions.YES, "reason pathology lost": ReasonPathologyLostOptions.LOST_IN_TRANSIT, }, - ] + 3, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - endoscopy_information=endoscopy_information, - drug_information=drug_information, - completion_information=completion_information, - failure_information=failure_information, - polyp_information=polyp_information, - polyp_intervention=polyp_interventions, - polyp_histology=polyp_histology, - ) + # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") - # Then the Investigation Dataset result message is "LNPCP" - InvestigationDatasetsPage(page).expect_text_to_be_visible(text="LNPCP") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 13 InvestigationDatasetsPage(page).assert_polyp_algorithm_size( @@ -687,7 +738,14 @@ def test_scenario_16(page: Page) -> None: page, "A410", "Post-Investigation Appointment Invitation Letter", - "A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -727,9 +785,17 @@ def test_scenario_16(page: Page) -> None: page, "A430", "Result Letters Following Post-investigation Appointment", - "A395 - Refer Another Diagnostic Test", ) + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A395 Refer Another Diagnostic Test"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I select the advance episode option for "Record Contact with Patient" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_record_contact_with_patient_button() diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_17.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_17.py index 3444ccc9..38759c34 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_17.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_17.py @@ -229,8 +229,16 @@ def test_scenario_17(page: Page) -> None: page=page, batch_description="Practitioner Clinic 1st Appointment", batch_type="A183", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, + ) + # When I switch users to BCSS "England" as user role "Specialist Screening Practitioner" LogoutPage(page).log_out(close_page=False) BasePage(page).go_to_log_in_page() @@ -344,17 +352,27 @@ def test_scenario_17(page: Page) -> None: # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # And I edit the Investigation Dataset for this subject SubjectScreeningSummaryPage(page).click_datasets_link() - # And I open all minimized sections on the dataset SubjectDatasetsPage(page).click_investigation_show_datasets() - # And I mark the Investigation Dataset as completed - # When I press the save Investigation Dataset button + + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { @@ -370,38 +388,49 @@ def test_scenario_17(page: Page) -> None: person_name = ( f"{df["person_family_name"].iloc[0]} {df["person_given_name"].iloc[0]}" ) + # And I set the following fields and values within the Investigation Dataset for this subject: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} - # And I add new polyp 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) + + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ANASTOMOSIS, "classification": PolypClassificationOptions.IP, @@ -409,53 +438,22 @@ def test_scenario_17(page: Page) -> None: "estimate of whole polyp size": "11", "left in situ": YesNoOptions.NO, }, + 1, + ) + + # And I add interventions 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( { - "location": EndoscopyLocationOptions.CAECUM, - "classification": PolypClassificationOptions.LST_NG, - "estimate of whole polyp size": "5", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, - "classification": PolypClassificationOptions.LST_NG, - "polyp access": PolypAccessOptions.EASY, - "estimate of whole polyp size": "21", - "left in situ": YesNoOptions.NO, + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "excised": YesNoOptions.YES, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "retrieved": PolypInterventionRetrievedOptions.YES, }, - ] - # And I add intervention for 3 polyps with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "excised": YesNoOptions.YES, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "retrieved": PolypInterventionRetrievedOptions.YES, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - "polyp appears fully resected endoscopically": YesNoOptions.YES, - } - ], - ] - # And I add histology for 3 polyps with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + 1, + ) + + # And I add histology 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of reporting": datetime.today(), "date of receipt": datetime.today(), @@ -468,6 +466,35 @@ def test_scenario_17(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "5", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add interventions 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # And I add histology 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of reporting": datetime.today(), "date of receipt": datetime.today(), @@ -480,87 +507,127 @@ def test_scenario_17(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.LST_NG, + "polyp access": PolypAccessOptions.EASY, + "estimate of whole polyp size": "21", + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # And I add interventions 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 3, + ) + + # And I add histology 1 for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "pathology lost": YesNoOptions.YES, "reason pathology lost": ReasonPathologyLostOptions.LOST_IN_TRANSIT, }, - ] - # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, + 3, ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" - InvestigationDatasetsPage(page).expect_text_to_be_visible("LNPCP") - # Then I confirm the Polyp Algorithm Size for Polyp 1,2 and 3 are 13,4,21 respectively - expected_size = 1 - expected_value = "13" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") - InvestigationDatasetsPage(page).assert_polyp_algorithm_size( - expected_size, expected_value - ) + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() + # Then I confirm the Polyp Algorithm Size for Polyp 1 is 13 + InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "13") + + # Then I confirm the Polyp Algorithm Size for Polyp 2 is 4 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(2, "4") + # Then I confirm the Polyp Algorithm Size for Polyp 3 is 21 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(3, "21") - # And I confirm the Polyp Category for Polyp 1,2,3 are "Advanced colorectal polyp", "Premalignant polyp" and "LNPCP" respectively + + # And I confirm the Polyp Category for Polyp 1 is "Advanced colorectal polyp" InvestigationDatasetsPage(page).assert_polyp_category( 1, "Advanced colorectal polyp" ) + # And I confirm the Polyp Category for Polyp 2 is "Premalignant polyp" InvestigationDatasetsPage(page).assert_polyp_category(2, "Premalignant polyp") + # And I confirm the Polyp Category for Polyp 3 is "LNPCP" InvestigationDatasetsPage(page).assert_polyp_category(3, "LNPCP") - # And I confirm the Episode Result is "Abnormal" - episode_result = "LNPCP" - EpisodeRepository().confirm_episode_result(nhs_no, episode_result) + + # And I confirm the Episode Result is "LNPCP" + EpisodeRepository().confirm_episode_result(nhs_no, "LNPCP") # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # And I advance the subject's episode for "Enter Diagnostic Test Outcome" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_enter_diagnostic_test_outcome_button() + # And I select Outcome of Diagnostic Test "Refer Symptomatic" DiagnosticTestOutcomePage(page).select_test_outcome_option( OutcomeOfDiagnosticTest.REFER_SYMPTOMATIC ) + # And I select Reason for Symptomatic Referral value "Corrective Surgery" DiagnosticTestOutcomePage(page).select_reason_for_symptomatic_referral_option( ReasonForSymptomaticReferral.CORRECTIVE_SURGERY ) + # And I save the Diagnostic Test Outcome information DiagnosticTestOutcomePage(page).click_save_button() + # Then my subject has been updated as follows: criteria = {"latest event status": "A315 Diagnostic Test Outcome Entered"} subject_assertion( nhs_no, criteria, ) + # When I advance the subject's episode for "Post-investigation Appointment Required" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage( page ).click_post_investigation_appointment_required_button() - # Then my subject has been updated as follows: + + # Then my subject has been updated as follows: subject_assertion( nhs_no, { "latest event status": "A360 Post-investigation Appointment Required", }, ) + # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # And I choose to book a practitioner clinic for my subject SubjectScreeningSummaryPage(page).click_book_practitioner_clinic_button() + # And I set the practitioner appointment date to "today" # And I book the "earliest" available practitioner appointment on this date book_post_investigation_appointment(page, "The Royal Hospital (Wolverhampton)") + # Then my subject has been updated as follows: subject_assertion( nhs_no, @@ -568,16 +635,15 @@ def test_scenario_17(page: Page) -> None: "latest event status": "A410 Post-investigation Appointment Made", }, ) + # And there is a "A410" letter batch for my subject with the exact title "Post-Investigation Appointment Invitation Letter" # When I process the open "A410 - Post-Investigation Appointment Invitation Letter" letter batch for my subject - letter_code = "A410" - letter_type = "Post-Investigation Appointment Invitation Letter" - batch_processing( page, - letter_code, - letter_type, + "A410", + "Post-Investigation Appointment Invitation Letter", ) + # Then my subject has been updated as follows: criteria = { "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" @@ -586,15 +652,20 @@ def test_scenario_17(page: Page) -> None: nhs_no, criteria, ) + # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # And I view the event history for the subject's latest episode SubjectScreeningSummaryPage(page).expand_episodes_list() SubjectScreeningSummaryPage(page).click_first_fobt_episode_link() + # And I view the latest practitioner appointment in the subject's episode EpisodeEventsAndNotesPage(page).click_most_recent_view_appointment_link() + # And I attend the subject's practitioner appointment "today" AppointmentDetailPage(page).mark_appointment_as_attended(datetime.today()) + # Then my subject has been updated as follows: criteria = { "latest episode includes event status": "A416 Post-investigation Appointment Attended ", @@ -607,19 +678,23 @@ def test_scenario_17(page: Page) -> None: # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # When I select the advance episode option for "MDT Referral Required" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_mdt_referral_required_button() - # # And I enter simple MDT information + + # And I enter simple MDT information ReferToMDTPage(page).enter_date_in_mdt_discussion_date_field(datetime.today()) ReferToMDTPage(page).select_mdt_location_lookup(1) ReferToMDTPage(page).click_record_mdt_appointment_button() - # Then my subject has been updated as follows: + + # Then my subject has been updated as follows: criteria = {"latest event status": "A348 MDT Referral Required"} subject_assertion( nhs_no, criteria, ) + # And there is a "A348" letter batch for my subject with the exact title "GP Letter Indicating Referral to MDT" # When I process the open "A348" letter batch for my subject batch_processing( @@ -627,6 +702,7 @@ def test_scenario_17(page: Page) -> None: "A348", "GP Letter Indicating Referral to MDT", ) + # Then my subject has been updated as follows: subject_assertion( nhs_no, @@ -637,9 +713,11 @@ def test_scenario_17(page: Page) -> None: # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) - # # And I select the advance episode option for "Patient Unfit, Handover into Symptomatic Care" + + # And I select the advance episode option for "Patient Unfit, Handover into Symptomatic Care" SubjectScreeningSummaryPage(page).click_advance_fobt_screening_episode_button() AdvanceFOBTScreeningEpisodePage(page).click_handover_into_symptomatic_care_button() + # And I fill in Handover into Symptomatic Care form for Patient Unfit for Treatment and Cease from programme HandoverIntoSymptomaticCarePage(page).select_referral_dropdown_option( "Referral to Patient's GP Practice" @@ -656,10 +734,12 @@ def test_scenario_17(page: Page) -> None: "latest event status": "A357 Patient Unfit, Handover into Symptomatic Care", }, ) + # And there is a "A357" letter batch for my subject with the exact title "Handover into Symptomatic Care, Patient Unfit" SubjectRepository().there_is_letter_batch_for_subject( nhs_no, "A357", "Handover into Symptomatic Care, Patient Unfit", True ) + # When I switch users to BCSS "England" as user role "Hub Manager" LogoutPage(page).log_out(close_page=False) BasePage(page).go_to_log_in_page() @@ -693,6 +773,7 @@ def test_scenario_17(page: Page) -> None: OrganisationSwitchPage(page).click_continue() if user_role is None: raise ValueError("User role is none") + # And I process the open "A357 - Handover into Symptomatic Care, Patient Unfit" letter batch for my subject batch_processing( page, diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_18.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_18.py index 9460ccdb..9023bd88 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_18.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_18.py @@ -247,7 +247,14 @@ def test_scenario_18(page: Page) -> None: page=page, batch_description="Practitioner Clinic 1st Appointment", batch_type="A183", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # And there is a "A183" letter batch for my subject with the exact title "GP Result (Abnormal)" @@ -533,11 +540,21 @@ def test_scenario_18(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -556,38 +573,47 @@ def test_scenario_18(page: Page) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) - # And I add new polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ANASTOMOSIS, "classification": PolypClassificationOptions.IP, @@ -595,55 +621,22 @@ def test_scenario_18(page: Page) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 1, + ) + + # And I add 1 intervention for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( { - "location": EndoscopyLocationOptions.CAECUM, - "classification": PolypClassificationOptions.LST_NG, - "estimate of whole polyp size": "5", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, - }, - { - "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, - "classification": PolypClassificationOptions.LST_NG, - "estimate of whole polyp size": "21", - "polyp access": PolypAccessOptions.EASY, - "left in situ": YesNoOptions.NO, + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, }, - ] - - # And I add 1 intervention for polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.YES, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - "polyp appears fully resected endoscopically": YesNoOptions.YES, - } - ], - ] - - # And I add histology for polyps 1-3 with the following fields and values within the Investigation Dataset for this subject: - polyp_histology = [ + 1, + ) + + # And I add histology for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -656,6 +649,35 @@ def test_scenario_18(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "5", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add 1 intervention for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # And I add histology for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "date of receipt": datetime.today(), "date of reporting": datetime.today(), @@ -668,28 +690,52 @@ def test_scenario_18(page: Page) -> None: "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, "polyp carcinoma": YesNoUncertainOptions.NO, }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "21", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # And I add 1 intervention for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 3, + ) + + # And I add histology for polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( { "pathology lost": YesNoOptions.YES, "reason pathology lost": ReasonPathologyLostOptions.LOST_IN_TRANSIT, }, - ] + 3, + ) - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") + # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - polyp_histology=polyp_histology, - ) - - # Then the Investigation Dataset result message is "LNPCP" - InvestigationDatasetsPage(page).expect_text_to_be_visible("LNPCP") + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 13 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "13") diff --git a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_8.py b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_8.py index c152f4ca..7a839db5 100644 --- a/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_8.py +++ b/tests/regression/regression_tests/fobt_regression_tests/test_fobt_scenario_8.py @@ -19,6 +19,11 @@ IVContrastAdministeredOptions, FailureReasonsOptions, InvestigationDatasetsPage, + BowelPreparationQualityOptions, + ComfortOptions, + EndoscopyLocationOptions, + InsufflationOptions, + OutcomeAtTimeOfProcedureOptions, ) from pages.datasets.subject_datasets_page import SubjectDatasetsPage from utils.user_tools import UserTools @@ -35,11 +40,6 @@ from pages.screening_subject_search.attend_diagnostic_test_page import ( AttendDiagnosticTestPage, ) -from utils.datasets.investigation_datasets import ( - get_default_general_information, - get_default_drug_information, - get_default_endoscopy_information, -) from utils.oracle.oracle import OracleDB from utils.oracle.subject_selector import SubjectSelector from utils.fit_kit import FitKitLogged, FitKitGeneration @@ -227,7 +227,14 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A183", batch_description="Practitioner Clinic 1st Appointment", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # And there is a "A183" letter batch for my subject with the exact title "GP Result (Abnormal)" @@ -235,7 +242,14 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A183", batch_description="GP Result (Abnormal)", - latest_event_status="A25 - 1st Colonoscopy Assessment Appointment Booked, letter sent", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A25 1st Colonoscopy Assessment Appointment Booked, letter sent" + }, ) # When I switch users to BCSS "England" as user role "Screening Centre Manager" @@ -336,6 +350,8 @@ def test_scenario_8(page: Page) -> None: user_role = UserTools.switch_user( page, "Screening Centre Manager", remember_user=True ) + if user_role is None: + raise ValueError("User cannot be assigned to a UserRoleType") # And I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) @@ -383,7 +399,14 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A397", batch_description="Discharge from screening round - no contact (letter to patient)", - latest_event_status="A391 - Patient Discharge Letter Printed - No Patient Contact", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A391 Patient Discharge Letter Printed - No Patient Contact" + }, ) # And there is a "A391" letter batch for my subject with the exact title "Discharge from screening round - no contact (letter to GP)" @@ -392,7 +415,6 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A391", batch_description="Discharge from screening round - no contact (letter to GP)", - latest_event_status="A351 - GP Discharge Letter Printed - No Patient Contact", ) # Then my subject has been updated as follows: @@ -527,63 +549,73 @@ def test_scenario_8(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "site": 1, - "practitioner": 1, - "testing clinician": 1, - "reporting radiologist": 2, - "fit for subsequent endoscopic referral": YesNoOptions.YES, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "site": 1, + "practitioner": 1, + "testing clinician": 1, + "reporting radiologist": 2, + "fit for subsequent endoscopic referral": YesNoOptions.YES, + } + ) # And I set the following fields and values within the Contrast, Tagging & Drug Information: # And I add the following Additional Bowel Preparation drugs and values within the Investigation Dataset for this subject: - contrast_tagging_and_drug = { - "iv buscopan administered": IVBuscopanAdministeredOptions.NO, - "contraindicated": YesNoOptions.NO, - "iv contrast administered": IVContrastAdministeredOptions.NO, - "tagging agent given": TaggingAgentDrugAdministeredOptions.YES, - "additional bowel preparation administered": AdditionalBowelPrepAdministeredOptions.YES, - "drug_type1": DrugTypeOptions.PICOLAX, - "drug_dose1": "1", - } + InvestigationDatasetCompletion(page).fill_out_contrast_tagging_and_drug_information( + { + "iv buscopan administered": IVBuscopanAdministeredOptions.NO, + "contraindicated": YesNoOptions.NO, + "iv contrast administered": IVContrastAdministeredOptions.NO, + "tagging agent given": TaggingAgentDrugAdministeredOptions.YES, + "additional bowel preparation administered": AdditionalBowelPrepAdministeredOptions.YES, + "drug_type1": DrugTypeOptions.PICOLAX, + "drug_dose1": "1", + } + ) # And I add the following "Tagging Agent Given" drugs and doses within the Investigation Dataset for this subject: - # | Gastrografin | 1 | - tagging_agent_given_drug_information = { - "drug_type1": DrugTypeOptions.GASTROGRAFIN, - "drug_dose1": "1", - } + InvestigationDatasetCompletion(page).fill_out_tagging_agent_given_drug_information( + {"drug_type1": DrugTypeOptions.GASTROGRAFIN, "drug_dose1": "1"} + ) # And I set the following fields and values within the Radiology Information: - # And I set the following fields and values within the Radiology Information: - radiology_information = { - "examination quality": ExaminationQualityOptions.GOOD, - "scan position": ScanPositionOptions.DUAL, - "procedure outcome": ProcedureOutcomeOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - "segmental inadequacy": SegmentalInadequacyOptions.NO, - "intracolonic summary code": IntracolonicSummaryCodeOptions.CX_INADEQUATE_STUDY, - } - - suspected_findings = { - "extracolonic summary code": ExtracolonicSummaryCodeOptions.E4_IMPORTANT_REQUIRES_ACTION, - } + InvestigationDatasetCompletion(page).fill_out_radiology_information( + { + "examination quality": ExaminationQualityOptions.GOOD, + "scan position": ScanPositionOptions.DUAL, + "procedure outcome": ProcedureOutcomeOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + "segmental inadequacy": SegmentalInadequacyOptions.NO, + "intracolonic summary code": IntracolonicSummaryCodeOptions.CX_INADEQUATE_STUDY, + } + ) + InvestigationDatasetCompletion(page).fill_out_suspected_findings( + { + "extracolonic summary code": ExtracolonicSummaryCodeOptions.E4_IMPORTANT_REQUIRES_ACTION, + } + ) # And I set the following radiology failure reasons within the Investigation Dataset for this subject: # | No failure reasons | NOTE - this can be left as default - there is only one option - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button - # And I press OK on my confirmation prompt - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - contrast_tagging_and_drug=contrast_tagging_and_drug, - tagging_agent_given_drug_information=tagging_agent_given_drug_information, - radiology_information=radiology_information, - suspected_findings=suspected_findings, - ) + # Then the Investigation Dataset result message, which I will cancel, is "Abnormal" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("Abnormal") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then my subject has been updated as follows: criteria = { @@ -662,7 +694,14 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A410", batch_description="Post-Investigation Appointment Invitation Letter", - latest_event_status="A415 - Post-investigation Appointment Invitation Letter Printed", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, ) # When I view the subject @@ -698,7 +737,11 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A430", batch_description="Result Letters Following Post-investigation Appointment", - latest_event_status="A395 - Refer Another Diagnostic Test", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, {"latest event status": "A395 Refer Another Diagnostic Test"} ) # When I view the subject @@ -818,10 +861,23 @@ def test_scenario_8(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I open all minimized sections on the dataset # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: # | Mannitol | 3 | - drug_information = get_default_drug_information() + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And I set the following fields and values within the Investigation Dataset for this subject: # | Screening Site | (Pick first option) | @@ -843,29 +899,50 @@ def test_scenario_8(page: Page) -> None: # | Insufflation | Air | # | Outcome at time of procedure | Leave department | # | Late outcome | No complications | - general_information = get_default_general_information() - endoscopy_information = get_default_endoscopy_information() - endoscopy_information["procedure type"] = "diagnostic" + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": 1, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: # | Pain | - failure_information = { - "failure reasons": FailureReasonsOptions.PAIN, - } - - # And I mark the Investigation Dataset as completed - # And I press the save Investigation Dataset button - # When I press the save Investigation Dataset button - # And I press OK on my confirmation prompt - InvestigationDatasetCompletion(page).complete_dataset_with_args( - general_information=general_information, - drug_information=drug_information, - endoscopy_information=endoscopy_information, - failure_information=failure_information, + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} ) + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button # Then the Investigation Dataset result message, which I will cancel, is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then my subject has been updated as follows: criteria = { @@ -940,7 +1017,11 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A318", batch_description="Result Letters - No Post-investigation Appointment", - latest_event_status="A380 - Failed Diagnostic Test - Refer Another", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, {"latest event status": "A380 Failed Diagnostic Test - Refer Another"} ) # When I view the subject @@ -959,17 +1040,23 @@ def test_scenario_8(page: Page) -> None: } subject_assertion(nhs_no, criteria) - # # And there is a "A397" letter batch for my subject with the exact title "Discharge from screening round - no contact (letter to patient)" - # # When I process the open "A397" letter batch for my subject - # # Then my subject has been updated as follows: + # And there is a "A397" letter batch for my subject with the exact title "Discharge from screening round - no contact (letter to patient)" + # When I process the open "A397" letter batch for my subject batch_processing( page=page, batch_type="A397", batch_description="Discharge from screening round - no contact (letter to patient)", - latest_event_status="A391 - Patient Discharge Letter Printed - No Patient Contact", ) - # # When I receive an SSPI update to change their date of birth to "73" years old + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A391 Patient Discharge Letter Printed - No Patient Contact" + }, + ) + + # When I receive an SSPI update to change their date of birth to "73" years old SSPIChangeSteps().sspi_update_to_change_dob_received(nhs_no, 73) # Then my subject has been updated as follows: @@ -984,7 +1071,6 @@ def test_scenario_8(page: Page) -> None: page=page, batch_type="A391", batch_description="Discharge from screening round - no contact (letter to GP)", - latest_event_status="A351 - GP Discharge Letter Printed - No Patient Contact", ) # Then my subject has been updated as follows: diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_10.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_10.py index c21f985f..ef461299 100644 --- a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_10.py +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_10.py @@ -243,6 +243,9 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: "Investigation Datasets" ) + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # Then I confirm the "Investigation Dataset" section of the dataset contains the field "Actual Type of Test" with the value of "Flexible Sigmoidoscopy" DatasetFieldUtil(page).assert_cell_to_right_has_expected_text( "Actual Type of Test", "Flexible Sigmoidoscopy" @@ -256,7 +259,6 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: ) # When I set the following fields and values within the Investigation Dataset for this subject: - InvestigationDatasetsPage(page).click_show_endoscopy_information() DatasetFieldUtil(page).populate_select_locator_for_field( "Endoscopist defined extent", EndoscopyLocationOptions.APPENDIX ) @@ -267,10 +269,12 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: ) # When I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -288,38 +292,46 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "therapeutic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following completion proof values within the Investigation Dataset for this subject: - completion_information = {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) - # And I add new polyps 1-2 with the following fields and values within the Investigation Dataset for this subject: - polyp_information = [ + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.CAECUM, "classification": PolypClassificationOptions.LST_NG, @@ -327,6 +339,23 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, + 1, + ) + + # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( { "location": EndoscopyLocationOptions.ASCENDING_COLON, "classification": PolypClassificationOptions.IIA, @@ -334,46 +363,33 @@ def test_scenario_10(page: Page, general_properties: dict) -> None: "polyp access": PolypAccessOptions.EASY, "left in situ": YesNoOptions.NO, }, - ] + 2, + ) - # And I add intervention 1 for polyps 1-2 with the following fields and values within the Investigation Dataset for this subject: - polyp_intervention = [ - [ - { - "modality": PolypInterventionModalityOptions.EMR, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO, - "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, - } - ], - [ - { - "modality": PolypInterventionModalityOptions.POLYPECTOMY, - "device": PolypInterventionDeviceOptions.HOT_SNARE, - "excised": YesNoOptions.YES, - "retrieved": PolypInterventionRetrievedOptions.NO, - "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, - "polyp appears fully resected endoscopically": YesNoUncertainOptions.UNCERTAIN, - } - ], - ] + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.NO, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoUncertainOptions.UNCERTAIN, + }, + 2, + ) # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "High-risk findings" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog( + "High-risk findings" + ) + # When I press the save Investigation Dataset button - InvestigationDatasetsPage(page).click_show_endoscopy_information() - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - completion_information=completion_information, - polyp_information=polyp_information, - polyp_intervention=polyp_intervention, - ) - - # Then the Investigation Dataset result message is "High-risk findings" - InvestigationDatasetsPage(page).assert_test_result("High-risk findings") + InvestigationDatasetsPage(page).click_save_dataset_button() # Then I confirm the Polyp Algorithm Size for Polyp 1 is 10 InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "10") diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_11.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_11.py new file mode 100644 index 00000000..419c1faf --- /dev/null +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_11.py @@ -0,0 +1,693 @@ +import logging +from datetime import datetime +import pytest +from playwright.sync_api import Page + +from classes.repositories.person_repository import PersonRepository +from classes.user.user import User +from pages.datasets.colonoscopy_dataset_page import ( + ColonoscopyDatasetsPage, + FitForColonoscopySspOptions, +) +from pages.datasets.investigation_dataset_page import ( + AdenomaSubTypeOptions, + BowelPreparationQualityOptions, + ComfortOptions, + CompletionProofOptions, + DrugTypeOptions, + EndoscopyLocationOptions, + FailureReasonsOptions, + InsufflationOptions, + InvestigationDatasetsPage, + LateOutcomeOptions, + OutcomeAtTimeOfProcedureOptions, + PolypAccessOptions, + PolypClassificationOptions, + PolypDysplasiaOptions, + PolypExcisionCompleteOptions, + PolypInterventionDeviceOptions, + PolypInterventionExcisionTechniqueOptions, + PolypInterventionModalityOptions, + PolypInterventionRetrievedOptions, + PolypTypeOptions, + ReasonPathologyLostOptions, + YesNoOptions, + YesNoUncertainOptions, +) +from pages.datasets.subject_datasets_page import SubjectDatasetsPage +from pages.logout.log_out_page import LogoutPage +from pages.screening_subject_search.advance_surveillance_episode_page import ( + AdvanceSurveillanceEpisodePage, +) +from pages.screening_subject_search.attend_diagnostic_test_page import ( + AttendDiagnosticTestPage, +) +from pages.screening_subject_search.contact_with_patient_page import ( + ContactWithPatientPage, +) +from pages.screening_subject_search.diagnostic_test_outcome_page import ( + DiagnosticTestOutcomePage, + OutcomeOfDiagnosticTest, + ReasonForOnwardReferral, + ReferralProcedureType, +) +from pages.screening_subject_search.subject_screening_summary_page import ( + SubjectScreeningSummaryPage, +) +from utils import screening_subject_page_searcher +from utils.batch_processing import batch_processing +from utils.calendar_picker import CalendarPicker +from utils.dataset_field_util import DatasetFieldUtil +from utils.generate_health_check_forms_util import GenerateHealthCheckFormsUtil +from utils.investigation_dataset import InvestigationDatasetCompletion +from utils.oracle.oracle import OracleDB +from utils.sspi_change_steps import SSPIChangeSteps +from utils.subject_assertion import subject_assertion +from utils.user_tools import UserTools + + +@pytest.mark.vpn_required +@pytest.mark.regression +@pytest.mark.surveillance_regression_tests +def test_scenario_11(page: Page, general_properties: dict) -> None: + """ + Scenario: 11: Close on existing LNPCP result + + X500-X505-A99-A59-A259-A315-A361-A323-A317-A318-A395-A99-A59-A306-A400-A157-C203 [SSCL52b] + + This scenario tests where a subject has had one diagnostic test and been referred for a second, which is cancelled. Then contact with the subject is lost and the episode is closed on the existing result of LNPCP. Below age at recall, the subject remains in Surveillance. + + Scenario summary: + + > Run surveillance invitations for 1 subject > X500 (3.1) + > SSPI update changes subject to below-age at recall + > Process X500 letter batch > X505 (3.1) + > Complete the colonoscopy assessment dataset - fit for colonoscopy + > Record patient contact โ€“ contacted, suitable for colonoscopy > A99 (3.1) + > Invite for diagnostic test > A59 (2.1) + > Attend diagnostic test > A259 (2.1) + > Complete investigation dataset โ€“ LNPCP (2.1) + > Enter diagnostic test outcome โ€“ refer another test > A315 (2.1) + > Post-investigation appointment not required > A361 (2.1) + > Record patient contact โ€“ post-investigation appointment not required > A323 (2.1) > A317 > A318 (2.5) + > Process A318 letter batch > A395 (2.5) + > Record patient contact โ€“ suitable for colonoscopy > A99 (2.3) + > Invite for diagnostic test > A59 (2.1) + > Cancel diagnostic test > A306 (2.1) + > Record patient contact โ€“ not contacted, close on existing result > A400 (2.2) + > Process A400 letter batch > A157 (2.2) > C203 (3.6) + > Check recall [SSCL52b] + """ + # Given I log in to BCSS "England" as user role "Screening Centre Manager" + user_role = UserTools.user_login( + page, "Screening Centre Manager at BCS001", return_role_type=True + ) + if user_role is None: + raise ValueError("User cannot be assigned to a UserRoleType") + + # When I run surveillance invitations for 1 subject + org_id = general_properties["eng_screening_centre_id"] + nhs_no = GenerateHealthCheckFormsUtil(page).invite_surveillance_subjects_early( + org_id + ) + logging.info(f"[SUBJECT RETRIEVAL] Subject's NHS Number: {nhs_no}") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest episode status": "Open", + "latest episode type": "Surveillance", + "latest event status": "X500 Selected For Surveillance", + "responsible screening centre code": "User's screening centre", + "subject has unprocessed SSPI updates": "No", + "subject has user DOB updates": "No", + }, + user_role, + ) + + # And I receive an SSPI update to change their date of birth to "44" years old + SSPIChangeSteps().sspi_update_to_change_dob_received(nhs_no, 44) + + # Then my subject has been updated as follows: + subject_assertion(nhs_no, {"subject age": "44"}) + + # And there is a "X500" letter batch for my subject with the exact title "Surveillance Selection" + # When I process the open "X500" letter batch for my subject + batch_processing( + page, + "X500", + "Surveillance Selection", + ) + + # Then my subject has been updated as follows: + subject_assertion(nhs_no, {"latest event status": "X505 HealthCheck Form Printed"}) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I edit the Colonoscopy Assessment Dataset for this subject + SubjectScreeningSummaryPage(page).click_datasets_link() + SubjectDatasetsPage(page).click_colonoscopy_show_datasets() + + # And I update the Colonoscopy Assessment Dataset with the following values: + ColonoscopyDatasetsPage(page).select_fit_for_colonoscopy_option( + FitForColonoscopySspOptions.YES + ) + ColonoscopyDatasetsPage(page).click_dataset_complete_radio_button_yes() + + # And I save the Colonoscopy Assessment Dataset + ColonoscopyDatasetsPage(page).save_dataset() + + # And I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I select the advance episode option for "Record Contact with Patient" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_record_contact_with_patient_button() + + # And I record contact with the subject with outcome "Suitable for Endoscopic Test" + ContactWithPatientPage(page).record_contact("Suitable for Endoscopic Test") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A99 Suitable for Endoscopic Test", + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I view the advance episode options + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + + # And I select Diagnostic Test Type "Limited Colonoscopy" + AdvanceSurveillanceEpisodePage(page).select_test_type_dropdown_option( + "Limited Colonoscopy" + ) + + # And I select Intended Extent "Ascending Colon" + AdvanceSurveillanceEpisodePage(page).select_intended_extent_dropdown_option( + "Ascending Colon" + ) + + # And I enter a Diagnostic Test First Offered Appointment Date of "today" + AdvanceSurveillanceEpisodePage(page).click_calendar_button() + CalendarPicker(page).v1_calender_picker(datetime.today()) + + # And I advance the subject's episode for "Invite for Diagnostic Test >>" + AdvanceSurveillanceEpisodePage(page).click_invite_for_diagnostic_test_button() + + page.wait_for_timeout(500) # Timeout to allow subject to update on the DB + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A59 Invited for Diagnostic Test", + }, + ) + + # When I select the advance episode option for "Attend Diagnostic Test" + AdvanceSurveillanceEpisodePage(page).click_attend_diagnostic_test_button() + + # And I attend the subject's diagnostic test today + AttendDiagnosticTestPage(page).click_calendar_button() + CalendarPicker(page).v1_calender_picker(datetime.today()) + AttendDiagnosticTestPage(page).click_save_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A259 Attended Diagnostic Test"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I edit the Investigation Dataset for this subject + SubjectScreeningSummaryPage(page).click_datasets_link() + SubjectDatasetsPage(page).click_investigation_show_datasets() + + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + + # Then I get a confirmation prompt that "contains" "The Endoscopist Defined Extent selected indicates that the diagnostic test type is Colonoscopy." + # When I press OK on my confirmation prompt + InvestigationDatasetsPage(page).assert_dialog_text( + "The Endoscopist Defined Extent selected indicates that the diagnostic test type is Colonoscopy.", + True, + ) + + # When I set the following fields and values within the Investigation Dataset for this subject: + DatasetFieldUtil(page).populate_select_locator_for_field( + "Endoscopist defined extent", EndoscopyLocationOptions.CAECUM + ) + + # Then I confirm the "Investigation Dataset" section of the dataset contains the field "Actual Type of Test" with the value of "Colonoscopy" + DatasetFieldUtil(page).assert_cell_to_right_has_expected_text( + "Actual Type of Test", "Colonoscopy" + ) + + # When I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) + + # And there is a clinician who meets the following criteria: + user = User.from_user_role_type(user_role) + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "User's SC", + "Resect & Discard accreditation status": "None", + } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=user, subject=None + ) + df = OracleDB().execute_query(query) + person_name = ( + f"{df["person_family_name"].iloc[0]} {df["person_given_name"].iloc[0]}" + ) + + # And I set the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) + + # And I set the following completion proof values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) + + # And I set the following failure reasons within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) + + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.SPLENIC_FLEXURE, + "classification": PolypClassificationOptions.IP, + "estimate of whole polyp size": "11", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 1, + ) + + # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + }, + 1, + ) + + # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( + { + "date of receipt": datetime.today(), + "date of reporting": datetime.today(), + "pathology provider": 1, + "pathologist": 1, + "polyp type": PolypTypeOptions.ADENOMA, + "adenoma sub type": AdenomaSubTypeOptions.NOT_REPORTED, + "polyp excision complete": PolypExcisionCompleteOptions.R1, + "polyp size": "13", + "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, + "polyp carcinoma": YesNoUncertainOptions.NO, + }, + 1, + ) + + # And I add new polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.CAECUM, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "5", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 2, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.EMR, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.EN_BLOC, + }, + 2, + ) + + # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( + { + "date of receipt": datetime.today(), + "date of reporting": datetime.today(), + "pathology provider": 1, + "pathologist": 1, + "polyp type": PolypTypeOptions.ADENOMA, + "adenoma sub type": AdenomaSubTypeOptions.TUBULAR_ADENOMA, + "polyp excision complete": PolypExcisionCompleteOptions.R1, + "polyp size": "4", + "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, + "polyp carcinoma": YesNoUncertainOptions.NO, + }, + 2, + ) + + # And I add new polyp 3 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.HEPATIC_FLEXURE, + "classification": PolypClassificationOptions.LST_NG, + "estimate of whole polyp size": "21", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 3, + ) + + # And I add intervention 1 for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.POLYPECTOMY, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 3, + ) + + # And I update histology details for polyp 2 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( + { + "pathology lost": YesNoOptions.YES, + "reason pathology lost": ReasonPathologyLostOptions.LOST_IN_TRANSIT, + }, + 3, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() + + # Then I confirm the Polyp Algorithm Size for Polyp 1 is 13 + InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "13") + + # And I confirm the Polyp Algorithm Size for Polyp 2 is 4 + InvestigationDatasetsPage(page).assert_polyp_algorithm_size(2, "4") + + # And I confirm the Polyp Algorithm Size for Polyp 3 is 21 + InvestigationDatasetsPage(page).assert_polyp_algorithm_size(3, "21") + + # And I confirm the Polyp Category for Polyp 1 is "Advanced colorectal polyp" + InvestigationDatasetsPage(page).assert_polyp_category( + 1, "Advanced colorectal polyp" + ) + + # And I confirm the Polyp Category for Polyp 2 is "Premalignant polyp" + InvestigationDatasetsPage(page).assert_polyp_category(2, "Premalignant polyp") + + # And I confirm the Polyp Category for Polyp 3 is "LNPCP" + InvestigationDatasetsPage(page).assert_polyp_category(3, "LNPCP") + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I select the advance episode option for "Enter Diagnostic Test Outcome" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_enter_diagnostic_test_outcome_button() + + # Then I confirm the Outcome Of Diagnostic Test dropdown has the following options: + DiagnosticTestOutcomePage(page).test_outcome_dropdown_contains_options( + [ + "Refer Another Diagnostic Test", + "Refer Symptomatic", + "Refer Surveillance (BCSP)", + ], + ) + + # When I select Outcome of Diagnostic Test "Refer Surveillance (BCSP)" + DiagnosticTestOutcomePage(page).select_test_outcome_option( + OutcomeOfDiagnosticTest.REFER_ANOTHER_DIAGNOSTIC_TEST + ) + + # And I select Radiological or Endoscopic Referral value "Endoscopic" + DiagnosticTestOutcomePage(page).select_referral_procedure_type( + ReferralProcedureType.ENDOSCOPIC + ) + + # Then I confirm the Reason for Onward Referral dropdown has the following options: + DiagnosticTestOutcomePage( + page + ).reason_for_onward_referral_dropdown_contains_options( + [ + "Polyp not Fully Excised", + "Check Polyp Site", + "Multiple Polyps, not all Removed", + "Histology Required", + "Unexplained Symptoms", + "Interventions Required", + "Incomplete Colonic Visualisation", + ] + ) + + # And I select Reason for Onward Referral value "Check Polyp Site" + DiagnosticTestOutcomePage(page).select_reason_for_onward_referral( + ReasonForOnwardReferral.CHECK_POLYP_SITE + ) + + # And I set any onward referring clinician + DiagnosticTestOutcomePage(page).select_valid_onward_referral_consultant_index(1) + + # And I save the Diagnostic Test Outcome + DiagnosticTestOutcomePage(page).click_save_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A315 Diagnostic Test Outcome Entered"}, + ) + + # When I advance the subject's episode for "Other Post-investigation Contact Required" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage( + page + ).click_other_post_investigation_contact_required_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A361 Other Post-investigation Contact Required"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I select the advance episode option for "Record other post-investigation contact" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage( + page + ).click_record_other_post_investigation_contact_button() + + # And I confirm the patient outcome dropdown has the following options: + ContactWithPatientPage(page).outcome_dropdown_contains_options( + [ + "Post-investigation Appointment Not Required", + "Post-investigation Appointment Required", + "No outcome", + ] + ) + + # And I record contact with the subject with outcome "Post-investigation Appointment Not Required" + ContactWithPatientPage(page).record_post_investigation_appointment_not_required() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A318 Post-investigation Appointment NOT Required - Result Letter Created" + }, + ) + + # And there is a "A318" letter batch for my subject with the exact title "Result Letters - No Post-investigation Appointment" + # When I process the open "A318" letter batch for my subject + batch_processing( + page, + "A318", + "Result Letters - No Post-investigation Appointment", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, {"latest event status": "A395 Refer Another Diagnostic Test"} + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # When I select the advance episode option for "Record Contact with Patient" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_record_contact_with_patient_button() + + # And I record contact with the subject with outcome "Suitable for Endoscopic Test" + ContactWithPatientPage(page).record_contact("Suitable for Endoscopic Test") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A99 Suitable for Endoscopic Test", + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I view the advance episode options + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + + # And I select Diagnostic Test Type "Colonoscopy" + AdvanceSurveillanceEpisodePage(page).select_test_type_dropdown_option("Colonoscopy") + + # And I enter a Diagnostic Test First Offered Appointment Date of "today" + AdvanceSurveillanceEpisodePage(page).click_calendar_button() + CalendarPicker(page).v1_calender_picker(datetime.today()) + + # And I advance the subject's episode for "Invite for Diagnostic Test >>" + AdvanceSurveillanceEpisodePage(page).click_invite_for_diagnostic_test_button() + + page.wait_for_timeout(500) # Timeout to allow subject to update on the DB + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A59 Invited for Diagnostic Test", + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I advance the subject's episode for "Cancel Diagnostic Test" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_cancel_diagnostic_test_button() + + # Then my subject has been updated as follows: + AdvanceSurveillanceEpisodePage(page).verify_latest_event_status_value( + "A306 - Cancel Diagnostic Test" + ) + + # And I select the advance episode option for "Record Contact with Patient" + AdvanceSurveillanceEpisodePage(page).click_record_contact_with_patient_button() + + # And I record contact with the subject with values: + ContactWithPatientPage(page).record_contact( + "Close Episode with Existing result", "No" + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A400 Follow-up Test Cancelled by Screening Centre"}, + ) + + # And there is a "A400" letter batch for my subject with the exact title "Follow-up Test Cancelled by Screening Centre" + # When I process the open "A400" letter batch for my subject + batch_processing( + page, + "A400", + "Follow-up Test Cancelled by Screening Centre", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "which diagnostic test": "Latest not-void test in latest episode", + "calculated fobt due date": "Unchanged", + "calculated lynch due date": "Null", + "calculated surveillance due date": "3 years from diagnostic test", + "ceased confirmation date": "Null", + "ceased confirmation details": "Null", + "ceased confirmation user id": "Null", + "clinical reason for cease": "Null", + "latest episode accumulated result": "LNPCP", + "latest episode recall calculation method": "Diagnostic test date", + "latest episode recall episode type": "Surveillance - LNPCP", + "latest episode recall surveillance type": "LNPCP", + "latest episode status": "Closed", + "latest episode status reason": "Episode Complete", + "latest event status": "A157 LNPCP", + "lynch due date": "Null", + "lynch due date date of change": "Unchanged", + "lynch due date reason": "Unchanged", + "screening due date": "Null", + "screening due date date of change": "Unchanged", + "screening due date reason": "Unchanged", + "screening status": "Surveillance", + "screening status date of change": "Unchanged", + "screening status reason": "Unchanged", + "surveillance due date": "Calculated Surveillance due date", + "surveillance due date date of change": "Today", + "surveillance due date reason": "Result - LNPCP", + "symptomatic procedure date": "Null", + "symptomatic procedure result": "Null", + "screening referral type": "Null", + }, + ) + + LogoutPage(page).log_out() diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_12.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_12.py new file mode 100644 index 00000000..533d3f18 --- /dev/null +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_12.py @@ -0,0 +1,558 @@ +import logging +from datetime import datetime +import pytest +from playwright.sync_api import Page + +from classes.repositories.person_repository import PersonRepository +from classes.user.user import User +from pages.datasets.colonoscopy_dataset_page import ( + ColonoscopyDatasetsPage, + FitForColonoscopySspOptions, +) +from pages.datasets.investigation_dataset_page import ( + AdenomaSubTypeOptions, + BowelPreparationQualityOptions, + ComfortOptions, + CompletionProofOptions, + DrugTypeOptions, + EndoscopyLocationOptions, + FailureReasonsOptions, + InsufflationOptions, + InvestigationDatasetsPage, + LateOutcomeOptions, + OutcomeAtTimeOfProcedureOptions, + PolypAccessOptions, + PolypClassificationOptions, + PolypDysplasiaOptions, + PolypExcisionCompleteOptions, + PolypInterventionDeviceOptions, + PolypInterventionExcisionTechniqueOptions, + PolypInterventionModalityOptions, + PolypInterventionRetrievedOptions, + PolypTypeOptions, + YesNoOptions, + YesNoUncertainOptions, +) +from pages.datasets.subject_datasets_page import SubjectDatasetsPage +from pages.logout.log_out_page import LogoutPage +from pages.screening_practitioner_appointments.appointment_detail_page import ( + AppointmentDetailPage, +) +from pages.screening_subject_search.advance_surveillance_episode_page import ( + AdvanceSurveillanceEpisodePage, +) +from pages.screening_subject_search.attend_diagnostic_test_page import ( + AttendDiagnosticTestPage, +) +from pages.screening_subject_search.contact_with_patient_page import ( + ContactWithPatientPage, +) +from pages.screening_subject_search.diagnostic_test_outcome_page import ( + DiagnosticTestOutcomePage, + OutcomeOfDiagnosticTest, + ReasonForSymptomaticReferral, +) +from pages.screening_subject_search.episode_events_and_notes_page import ( + EpisodeEventsAndNotesPage, +) +from pages.screening_subject_search.handover_into_symptomatic_care_page import ( + HandoverIntoSymptomaticCarePage, +) +from pages.screening_subject_search.subject_screening_summary_page import ( + SubjectScreeningSummaryPage, +) +from utils import screening_subject_page_searcher +from utils.appointments import book_post_investigation_appointment +from utils.batch_processing import batch_processing +from utils.calendar_picker import CalendarPicker +from utils.generate_health_check_forms_util import GenerateHealthCheckFormsUtil +from utils.investigation_dataset import InvestigationDatasetCompletion +from utils.oracle.oracle import OracleDB +from utils.sspi_change_steps import SSPIChangeSteps +from utils.subject_assertion import subject_assertion +from utils.user_tools import UserTools + + +@pytest.mark.vpn_required +@pytest.mark.regression +@pytest.mark.surveillance_regression_tests +def test_scenario_12(page: Page, general_properties: dict) -> None: + """ + Scenario: 12: Unsuitable for symptomatic (do not cease) + + X500-X505-A99-A259-A315-A360-A410-A415-A416-A316-A353-A372-A357-A356-C203 [SSCL21b] + + This scenario tests the episode pathway in which the subject is referred for a symptomatic procedure, but they are discharged as being unsuitable, with no MDT referral. The subject is not ceased from the programme as part of the handover. Being still in the age range, the subject is returned to FOBT screening. + + Because we cannot know if we will be inviting a subject who has had previous FOBT episodes, or only a bowel scope episode, it is impossible to check if they will be set to Call or Recall; we can only check that they are not longer in Surveillance status. + + Scenario summary: + + > Run surveillance invitations for 1 subject > X500 (3.1) + > SSPI update changes subject to in-age at recall + > Process X500 letter batch > X505 (3.1) + > Complete the colonoscopy assessment dataset - fit for colonoscopy + > Record patient contact โ€“ contacted, suitable for colonoscopy > A99 (3.1) + > Invite for diagnostic test > A59 (2.1) + > Attend diagnostic test > A259 (2.1) + > Complete investigation dataset โ€“ LNPCP (2.1) + > Enter diagnostic test outcome โ€“ refer symptomatic > A315 (2.1) + > Post-investigation appointment required > A360 (2.1) + > Book post-investigation appointment > A410 (2.4) + > Process A410 letter batch > A415 (2.4) + > Attend post-investigation appointment > A416 > A316 (2.4) + > MDT not required > A353 (2.6) + > Process A353 letter batch > A372 (2.6) + > Unsuitable for symptomatic procedure โ€“ handover to GP, no cease > A357 (2.6) + > Process A357 letter batch > A356 > (2.6) > C203 (1.13) + > Check recall [SSCL21b] + """ + # Given I log in to BCSS "England" as user role "Screening Centre Manager" + user_role = UserTools.user_login( + page, "Screening Centre Manager at BCS001", return_role_type=True + ) + if user_role is None: + raise ValueError("User cannot be assigned to a UserRoleType") + + # When I run surveillance invitations for 1 subject + org_id = general_properties["eng_screening_centre_id"] + nhs_no = GenerateHealthCheckFormsUtil(page).invite_surveillance_subjects_early( + org_id + ) + logging.info(f"[SUBJECT RETRIEVAL] Subject's NHS Number: {nhs_no}") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest episode status": "Open", + "latest episode type": "Surveillance", + "latest event status": "X500 Selected For Surveillance", + "responsible screening centre code": "User's screening centre", + "subject has unprocessed SSPI updates": "No", + "subject has user DOB updates": "No", + }, + user_role, + ) + + # And I receive an SSPI update to change their date of birth to "70" years old + SSPIChangeSteps().sspi_update_to_change_dob_received(nhs_no, 70) + + # Then my subject has been updated as follows: + subject_assertion(nhs_no, {"subject age": "70"}) + + # And there is a "X500" letter batch for my subject with the exact title "Surveillance Selection" + # When I process the open "X500" letter batch for my subject + batch_processing( + page, + "X500", + "Surveillance Selection", + ) + + # Then my subject has been updated as follows: + subject_assertion(nhs_no, {"latest event status": "X505 HealthCheck Form Printed"}) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I edit the Colonoscopy Assessment Dataset for this subject + SubjectScreeningSummaryPage(page).click_datasets_link() + SubjectDatasetsPage(page).click_colonoscopy_show_datasets() + + # And I update the Colonoscopy Assessment Dataset with the following values: + ColonoscopyDatasetsPage(page).select_fit_for_colonoscopy_option( + FitForColonoscopySspOptions.YES + ) + ColonoscopyDatasetsPage(page).click_dataset_complete_radio_button_yes() + + # And I save the Colonoscopy Assessment Dataset + ColonoscopyDatasetsPage(page).save_dataset() + + # And I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I select the advance episode option for "Record Contact with Patient" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_record_contact_with_patient_button() + + # And I record contact with the subject with outcome "Suitable for Endoscopic Test" + ContactWithPatientPage(page).record_contact("Suitable for Endoscopic Test") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A99 Suitable for Endoscopic Test", + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I view the advance episode options + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + + # And I select Diagnostic Test Type "Colonoscopy" + AdvanceSurveillanceEpisodePage(page).select_test_type_dropdown_option("Colonoscopy") + + # And I enter a Diagnostic Test First Offered Appointment Date of "today" + AdvanceSurveillanceEpisodePage(page).click_calendar_button() + CalendarPicker(page).v1_calender_picker(datetime.today()) + + # And I advance the subject's episode for "Invite for Diagnostic Test >>" + AdvanceSurveillanceEpisodePage(page).click_invite_for_diagnostic_test_button() + + page.wait_for_timeout(500) # Timeout to allow subject to update on the DB + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A59 Invited for Diagnostic Test", + }, + ) + + # When I select the advance episode option for "Attend Diagnostic Test" + AdvanceSurveillanceEpisodePage(page).click_attend_diagnostic_test_button() + + # And I attend the subject's diagnostic test today + AttendDiagnosticTestPage(page).click_calendar_button() + CalendarPicker(page).v1_calender_picker(datetime.today()) + AttendDiagnosticTestPage(page).click_save_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A259 Attended Diagnostic Test"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I edit the Investigation Dataset for this subject + SubjectScreeningSummaryPage(page).click_datasets_link() + SubjectDatasetsPage(page).click_investigation_show_datasets() + + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + + # When I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) + + # And there is a clinician who meets the following criteria: + user = User.from_user_role_type(user_role) + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "User's SC", + "Resect & Discard accreditation status": "None", + } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=user, subject=None + ) + df = OracleDB().execute_query(query) + person_name = ( + f"{df["person_family_name"].iloc[0]} {df["person_given_name"].iloc[0]}" + ) + + # And I set the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "therapeutic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.APPENDIX, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) + + # And I set the following completion proof values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_completion_information( + {"completion proof": CompletionProofOptions.VIDEO_APPENDIX} + ) + + # And I set the following failure reasons within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) + + # And I add new polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_information( + { + "location": EndoscopyLocationOptions.APPENDIX, + "classification": PolypClassificationOptions.ISP, + "estimate of whole polyp size": "19", + "polyp access": PolypAccessOptions.EASY, + "left in situ": YesNoOptions.NO, + }, + 1, + ) + + # And I add intervention 1 for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_intervention( + { + "modality": PolypInterventionModalityOptions.ESD, + "device": PolypInterventionDeviceOptions.HOT_SNARE, + "excised": YesNoOptions.YES, + "retrieved": PolypInterventionRetrievedOptions.YES, + "excision technique": PolypInterventionExcisionTechniqueOptions.PIECE_MEAL, + "polyp appears fully resected endoscopically": YesNoOptions.YES, + }, + 1, + ) + + # And I update histology details for polyp 1 with the following fields and values within the Investigation Dataset for this subject: + InvestigationDatasetCompletion(page).fill_polyp_x_histology( + { + "date of receipt": datetime.today(), + "date of reporting": datetime.today(), + "pathology provider": 1, + "pathologist": 1, + "polyp type": PolypTypeOptions.ADENOMA, + "adenoma sub type": AdenomaSubTypeOptions.VILLOUS_ADENOMA, + "polyp excision complete": PolypExcisionCompleteOptions.R1, + "polyp size": "20", + "polyp dysplasia": PolypDysplasiaOptions.NOT_REPORTED, + "polyp carcinoma": YesNoUncertainOptions.NO, + }, + 1, + ) + + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "LNPCP" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("LNPCP") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() + + # Then I confirm the Polyp Algorithm Size for Polyp 1 is 20 + InvestigationDatasetsPage(page).assert_polyp_algorithm_size(1, "20") + + # And I confirm the Polyp Category for Polyp 1 is "LNPCP" + InvestigationDatasetsPage(page).assert_polyp_category(1, "LNPCP") + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I select the advance episode option for "Enter Diagnostic Test Outcome" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage(page).click_enter_diagnostic_test_outcome_button() + + # Then I confirm the Outcome Of Diagnostic Test dropdown has the following options: + DiagnosticTestOutcomePage(page).test_outcome_dropdown_contains_options( + [ + "Refer Another Diagnostic Test", + "Refer Symptomatic", + "Refer Surveillance (BCSP)", + ], + ) + + # When I select Outcome of Diagnostic Test "Refer Symptomatic" + DiagnosticTestOutcomePage(page).select_test_outcome_option( + OutcomeOfDiagnosticTest.REFER_SYMPTOMATIC + ) + + # And I select Reason for Symptomatic Referral value "Suspected Cancer Surgery" + DiagnosticTestOutcomePage(page).select_reason_for_symptomatic_referral_option( + ReasonForSymptomaticReferral.SUSPECTED_CANCER_SURGERY + ) + + # And I save the Diagnostic Test Outcome + DiagnosticTestOutcomePage(page).click_save_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A315 Diagnostic Test Outcome Entered"}, + ) + + # When I advance the subject's episode for "Post-investigation Appointment Required" + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + AdvanceSurveillanceEpisodePage( + page + ).click_post_investigation_appointment_required_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A360 Post-investigation Appointment Required"}, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I choose to book a practitioner clinic for my subject + SubjectScreeningSummaryPage(page).click_book_practitioner_clinic_button() + + # And I set the practitioner appointment date to "today" + # And I book the earliest available post investigation appointment on this date + book_post_investigation_appointment(page, "The Royal Hospital (Wolverhampton)") + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + {"latest event status": "A410 Post-investigation Appointment Made"}, + ) + + # And there is a "A410" letter batch for my subject with the exact title "Post-Investigation Appointment Invitation Letter" + # When I process the open "A410" letter batch for my subject + batch_processing( + page, + "A410", + "Post-Investigation Appointment Invitation Letter", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A415 Post-investigation Appointment Invitation Letter Printed" + }, + ) + + # When I view the subject + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + + # And I view the event history for the subject's latest episode + SubjectScreeningSummaryPage(page).expand_episodes_list() + SubjectScreeningSummaryPage(page).click_first_surveillance_episode_link() + + # And I view the latest practitioner appointment in the subject's episode + EpisodeEventsAndNotesPage(page).click_most_recent_view_appointment_link() + + # And I attend the subject's practitioner appointment "today" + AppointmentDetailPage(page).mark_appointment_as_attended(datetime.today()) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest episode includes event status": "A416 Post-investigation Appointment Attended", + "latest event status": "A316 Post-investigation Appointment Attended", + }, + ) + + # When I view the advance episode options + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + + # And I advance the subject's episode for "MDT Referral Not Required" + AdvanceSurveillanceEpisodePage(page).click_mdt_referral_not_required_button() + + # Then my subject has been updated as follows: + subject_assertion(nhs_no, {"latest event status": "A353 MDT Referral Not Required"}) + + # And there is a "A353" letter batch for my subject with the exact title "GP Letter Indicating Referral to Symptomatic" + # When I process the open "A353" letter batch for my subject + batch_processing( + page, + "A353", + "GP Letter Indicating Referral to Symptomatic", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, {"latest event status": "A372 Refer Symptomatic, GP Letter Printed"} + ) + + # When I view the advance episode options + screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + SubjectScreeningSummaryPage(page).click_advance_surveillance_episode_button() + + # And I select the advance episode option for "Patient Unfit, Handover into Symptomatic Care" + AdvanceSurveillanceEpisodePage(page).click_handover_into_symptomatic_care_button() + + # I fill in Handover into Symptomatic Care form for Patient Unfit for Treatment and do not Cease + HandoverIntoSymptomaticCarePage(page).select_referral_dropdown_option( + "Referral to Patient's GP Practice" + ) + HandoverIntoSymptomaticCarePage(page).select_practitioner_from_index(1) + HandoverIntoSymptomaticCarePage(page).fill_notes("Handover notes - unfit") + HandoverIntoSymptomaticCarePage(page).select_cease_from_program(False) + HandoverIntoSymptomaticCarePage(page).click_save_button() + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "latest event status": "A357 Patient Unfit, Handover into Symptomatic Care", + }, + ) + + # And there is a "A357" letter batch for my subject with the exact title "Handover into Symptomatic Care, Patient Unfit" + # When I process the open "A357" letter batch for my subject + batch_processing( + page, + "A357", + "Handover into Symptomatic Care, Patient Unfit", + ) + + # Then my subject has been updated as follows: + subject_assertion( + nhs_no, + { + "which diagnostic test": "Only not-void test in latest episode", + "calculated fobt due date": "2 years from diagnostic test", + "calculated lynch due date": "Null", + "calculated surveillance due date": "Null", + "ceased confirmation date": "Null", + "ceased confirmation details": "Null", + "ceased confirmation user id": "Null", + "clinical reason for cease": "Null", + "latest episode accumulated result": "LNPCP", + "latest episode recall calculation method": "Diagnostic Test Date", + "latest episode recall episode type": "FOBT Screening", + "latest episode recall surveillance type": "Null", + "latest episode status": "Closed", + "latest episode status reason": "Discharged from Screening into Symptomatic care", + "latest event status": "A356 Handover into Symptomatic Care, Patient Unfit, GP Letter Printed", + "lynch due date": "Null", + "lynch due date date of change": "Unchanged", + "lynch due date reason": "Unchanged", + "screening due date": "Calculated FOBT due date", + "screening due date date of change": "Today", + "screening due date reason": "Discharged, Patient Unfit", + "screening status": "NOT: Surveillance", + "screening status date of change": "Today", + "screening status reason": "Discharged, Patient Unfit", + "surveillance due date": "Null", + "surveillance due date date of change": "Today", + "surveillance due date reason": "Discharged, Patient Unfit", + "symptomatic procedure date": "Null", + "symptomatic procedure result": "Patient is unfit for a symptomatic procedure at this time", + "screening referral type": "Null", + }, + ) + + LogoutPage(page).log_out() diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_4.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_4.py index 47fa3986..1833ec42 100644 --- a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_4.py +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_4.py @@ -215,11 +215,21 @@ def test_scenario_4(page: Page) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -238,46 +248,49 @@ def test_scenario_4(page: Page) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.PAIN} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} + ) - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - ) + # Then the Investigation Dataset result message, which I will cancel, is "No Result" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") - # Then the Investigation Dataset result message is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_5.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_5.py index c3e2329b..c03dfebf 100644 --- a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_5.py +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_5.py @@ -235,11 +235,21 @@ def test_scenario_5(page: Page, general_properties: dict) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -258,46 +268,49 @@ def test_scenario_5(page: Page, general_properties: dict) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.PAIN} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} + ) - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - ) + # Then the Investigation Dataset result message, which I will cancel, is "No Result" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") - # Then the Investigation Dataset result message is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_8.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_8.py index e510f314..de7bc46e 100644 --- a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_8.py +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_8.py @@ -2,7 +2,9 @@ from playwright.sync_api import Page from classes.repositories.subject_repository import SubjectRepository from pages.organisations.organisations_page import OrganisationSwitchPage -from pages.screening_subject_search.high_risk_findings_result_from_symptomatic_procedure_page import HighRiskFindingsResultFromSymptomaticProcedure +from pages.screening_subject_search.high_risk_findings_result_from_symptomatic_procedure_page import ( + HighRiskFindingsResultFromSymptomaticProcedure, +) from pages.screening_subject_search.refer_to_mdt_page import ReferToMDTPage from pages.screening_subject_search.reopen_episode_page import ReopenEpisodePage from pages.screening_subject_search.reopen_surveillance_episode_page import ( @@ -60,6 +62,7 @@ ReasonForSymptomaticReferral, ) + @pytest.mark.vpn_required @pytest.mark.regression @pytest.mark.surveillance_regression_tests @@ -349,11 +352,21 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -372,46 +385,49 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.PAIN} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} + ) - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - ) + # Then the Investigation Dataset result message, which I will cancel, is "No Result" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") - # Then the Investigation Dataset result message is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() # Then my subject has been updated as follows: subject_assertion( @@ -527,6 +543,7 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: "surveillance due date reason": "# Not checking - probably hasn't changed", } subject_assertion(nhs_no, criteria) + # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) @@ -542,9 +559,11 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: # And I select Diagnostic Test Type "Colonoscopy" AdvanceSurveillanceEpisodePage(page).select_test_type_dropdown_option("Colonoscopy") + # And I enter a Diagnostic Test First Offered Appointment Date of "today" AdvanceSurveillanceEpisodePage(page).click_calendar_button() CalendarPicker(page).v1_calender_picker(datetime.today()) + # And I advance the subject's episode for "Invite for Diagnostic Test >>" AdvanceSurveillanceEpisodePage(page).click_invite_for_diagnostic_test_button() @@ -556,10 +575,12 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: # When I select the advance episode option for "Attend Diagnostic Test" AdvanceSurveillanceEpisodePage(page).click_attend_diagnostic_test_button() + # And I attend the subject's diagnostic test today AttendDiagnosticTestPage(page).click_calendar_button() CalendarPicker(page).v1_calender_picker(datetime.today()) AttendDiagnosticTestPage(page).click_save_button() + # Then my subject has been updated as follows: subject_assertion( nhs_no, @@ -568,14 +589,22 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: # When I view the subject screening_subject_page_searcher.navigate_to_subject_summary_page(page, nhs_no) + # And I edit the Investigation Dataset for this subject SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) + # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) criteria = { @@ -591,44 +620,51 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: person_name = ( f"{df['person_family_name'].iloc[0]} {df['person_given_name'].iloc[0]}" ) + # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) + + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) + # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.PAIN} - # And I open all minimized sections on the dataset + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.PAIN} + ) + # And I mark the Investigation Dataset as completed + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() + # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - ) - # Then the Investigation Dataset result message is "No Result" - InvestigationDatasetsPage(page).expect_text_to_be_visible("No Result") - # Then my subject has been updated as follows: + # Then the Investigation Dataset result message, which I will cancel, is "No Result" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog("No Result") + + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() subject_assertion( nhs_no, @@ -732,9 +768,9 @@ def test_scenario_8(page: Page, general_properties: dict) -> None: ).click_high_risk_findings_result_from_symptomatic_procedure_button() # And I set the Date of Symptomatic Procedure to "yesterday" - HighRiskFindingsResultFromSymptomaticProcedure(page).enter_date_of_symptomatic_procedure( - datetime.today() - timedelta(days=1) - ) + HighRiskFindingsResultFromSymptomaticProcedure( + page + ).enter_date_of_symptomatic_procedure(datetime.today() - timedelta(days=1)) # And the Screening Interval is 36 months HighRiskFindingsResultFromSymptomaticProcedure(page).assert_text_in_alert_textbox( "recall interval of 36 months" diff --git a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_9.py b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_9.py index 04095eb2..8921db28 100644 --- a/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_9.py +++ b/tests/regression/regression_tests/surveillance_regression_tests/test_surveillance_scenario_9.py @@ -233,11 +233,21 @@ def test_scenario_9(page: Page, general_properties: dict) -> None: SubjectScreeningSummaryPage(page).click_datasets_link() SubjectDatasetsPage(page).click_investigation_show_datasets() + # Confirm on the investigation Datasets Page + InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text( + "Investigation Datasets" + ) + + # And I open all minimized sections on the dataset + InvestigationDatasetsPage(page).open_all_minimized_sections() + # And I add the following bowel preparation drugs and values within the Investigation Dataset for this subject: - drug_information = { - "drug_dose1": "3", - "drug_type1": DrugTypeOptions.MANNITOL, - } + InvestigationDatasetCompletion(page).fill_out_drug_information( + { + "drug_dose1": "3", + "drug_type1": DrugTypeOptions.MANNITOL, + } + ) # And there is a clinician who meets the following criteria: user = User.from_user_role_type(user_role) @@ -256,49 +266,52 @@ def test_scenario_9(page: Page, general_properties: dict) -> None: ) # And I set the following fields and values within the Investigation Dataset for this subject: - general_information = { - "practitioner": 1, - "site": 1, - "testing clinician": person_name, - "aspirant endoscopist": None, - } + InvestigationDatasetCompletion(page).fill_out_general_information( + { + "practitioner": 1, + "site": 1, + "testing clinician": person_name, + "aspirant endoscopist": None, + } + ) - endoscopy_information = { - "endoscope inserted": "yes", - "procedure type": "diagnostic", - "bowel preparation quality": BowelPreparationQualityOptions.GOOD, - "comfort during recovery": ComfortOptions.NO_DISCOMFORT, - "comfort during examination": ComfortOptions.NO_DISCOMFORT, - "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, - "scope imager used": YesNoOptions.YES, - "retroverted view": YesNoOptions.NO, - "start of intubation time": "09:00", - "start of extubation time": "09:30", - "end time of procedure": "10:00", - "scope id": "Autotest", - "insufflation": InsufflationOptions.AIR, - "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, - "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, - } + InvestigationDatasetCompletion(page).fill_endoscopy_information( + { + "endoscope inserted": "yes", + "procedure type": "diagnostic", + "bowel preparation quality": BowelPreparationQualityOptions.GOOD, + "comfort during recovery": ComfortOptions.NO_DISCOMFORT, + "comfort during examination": ComfortOptions.NO_DISCOMFORT, + "endoscopist defined extent": EndoscopyLocationOptions.DESCENDING_COLON, + "scope imager used": YesNoOptions.YES, + "retroverted view": YesNoOptions.NO, + "start of intubation time": "09:00", + "start of extubation time": "09:30", + "end time of procedure": "10:00", + "scope id": "Autotest", + "insufflation": InsufflationOptions.AIR, + "outcome at time of procedure": OutcomeAtTimeOfProcedureOptions.LEAVE_DEPARTMENT, + "late outcome": LateOutcomeOptions.NO_COMPLICATIONS, + } + ) # And I set the following failure reasons within the Investigation Dataset for this subject: - failure_information = {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + InvestigationDatasetCompletion(page).fill_out_failure_information( + {"failure reasons": FailureReasonsOptions.NO_FAILURE_REASONS} + ) - # And I open all minimized sections on the dataset # And I mark the Investigation Dataset as completed - # When I press the save Investigation Dataset button - InvestigationDatasetCompletion(page).complete_dataset_with_args( - endoscopy_information=endoscopy_information, - drug_information=drug_information, - general_information=general_information, - failure_information=failure_information, - ) + InvestigationDatasetsPage(page).check_dataset_complete_checkbox() - # Then the Investigation Dataset result message is "Normal (No Abnormalities Found)" - InvestigationDatasetsPage(page).expect_text_to_be_visible( + # When I press the save Investigation Dataset button + # Then the Investigation Dataset result message, which I will cancel, is "Normal (No Abnormalities Found)" + InvestigationDatasetsPage(page).click_save_dataset_button_assert_dialog( "Normal (No Abnormalities Found)" ) + # When I press the save Investigation Dataset button + InvestigationDatasetsPage(page).click_save_dataset_button() + # And I confirm the Episode Result is "Normal (No Abnormalities Found)" EpisodeRepository().confirm_episode_result( nhs_no, "Normal (No Abnormalities Found)" diff --git a/tests/regression/regression_tests/test_regression_test_setup_steps.py b/tests/regression/regression_tests/test_regression_test_setup_steps.py index 6156a4ee..c847ede1 100644 --- a/tests/regression/regression_tests/test_regression_test_setup_steps.py +++ b/tests/regression/regression_tests/test_regression_test_setup_steps.py @@ -16,10 +16,8 @@ set_org_parameter_value, check_parameter, ) -from utils.oracle.oracle_specific_functions.screening_colonoscopist import ( - build_accredited_screening_colonoscopist_query, - get_accredited_screening_colonoscopist_in_bcs001, -) +from classes.repositories.person_repository import PersonRepository +from utils.oracle.oracle import OracleDB def test_allow_10_minute_colonsocopy_assessment_appointments( @@ -56,17 +54,48 @@ def test_asc_with_current_resect_and_discard_accreditation( """ UserTools.user_login(page, "BCSS Bureau Staff at X26") - current_df = build_accredited_screening_colonoscopist_query("Current") - if current_df.empty: + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "BCS001", + "Resect & Discard Accreditation Status": "Current", + } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=None, subject=None + ) + logging.info(f"Final query: {query}") + current_df = OracleDB().execute_query(query) + + if not current_df.empty: pytest.skip( - "No Accredited Screening Colonoscopist with current Resect & Discard accreditation found." + "Accredited Screening Colonoscopist with current Resect & Discard accreditation found." ) - expired_df = build_accredited_screening_colonoscopist_query("Expiring soon") - if expired_df.empty: + + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "BCS001", + "Resect & Discard Accreditation Status": "Expiring soon", + } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=None, subject=None + ) + logging.info(f"Final query: {query}") + expired_df = OracleDB().execute_query(query) + + if not expired_df.empty: pytest.skip( - "No Accredited Screening Colonoscopist with expiring Resect & Discard accreditation found." + "Accredited Screening Colonoscopist with expiring Resect & Discard accreditation found." ) - person_df = get_accredited_screening_colonoscopist_in_bcs001() + + criteria = { + "Person has current role": "Accredited Screening Colonoscopist", + "Person has current role in organisation": "BCS001", + } + query = PersonRepository().build_person_selection_query( + criteria=criteria, person=None, required_person_count=1, user=None, subject=None + ) + logging.info(f"Final query: {query}") + person_df = OracleDB().execute_query(query) + if person_df.empty: pytest.fail("No Accredited Screening Colonoscopist found in the database.") @@ -75,10 +104,11 @@ def test_asc_with_current_resect_and_discard_accreditation( surname = person_df.iloc[0]["person_family_name"] forename = person_df.iloc[0]["person_given_name"] + person_id = person_df.iloc[0]["prs_id"] MaintainContactsPage(page).fill_surname_input_field(surname) MaintainContactsPage(page).fill_forenames_input_field(forename) MaintainContactsPage(page).click_search_button() - MaintainContactsPage(page).click_person_link_from_surname(surname) + MaintainContactsPage(page).select_person_by_id(person_id) EditContactPage(page).click_view_resect_and_discard_link() ResectAndDiscardAccreditationHistoryPage(page).verify_heading_is_correct() diff --git a/utils/investigation_dataset.py b/utils/investigation_dataset.py index 1f82e9ff..aedad4dd 100644 --- a/utils/investigation_dataset.py +++ b/utils/investigation_dataset.py @@ -82,6 +82,7 @@ def __init__(self, page: Page): self.failure_reasons_string = "Failure Reasons" self.excision_technique_string = "Excision Technique" self.outcome_at_time_of_procedure_string = "Outcome at time of procedure" + self.proof_parameters_string = "Proof Parameters" self.investigation_datasets_pom = InvestigationDatasetsPage(self.page) @@ -203,7 +204,7 @@ def default_investigation_dataset_forms_continuation(self) -> None: self.investigation_datasets_pom.click_show_completion_proof_information() # Completion Proof Information DatasetFieldUtil(self.page).populate_select_locator_for_field( - "Proof Parameters", CompletionProofOptions.PHOTO_ILEO + self.proof_parameters_string, CompletionProofOptions.PHOTO_ILEO ) def investigation_datasets_failure_reason(self) -> None: @@ -363,7 +364,6 @@ def complete_dataset_with_args( # Drug Information if drug_information is not None: - InvestigationDatasetsPage(self.page).click_show_drug_information() self.fill_out_drug_information(drug_information) if endoscopy_information: @@ -373,17 +373,13 @@ def complete_dataset_with_args( # Completion Proof Information if completion_information is not None: logging.info("Filling out completion proof information") - InvestigationDatasetsPage( - self.page - ).click_show_completion_proof_information() DatasetFieldUtil(self.page).populate_select_locator_for_field( - "Proof Parameters", completion_information["completion proof"] + self.proof_parameters_string, completion_information["completion proof"] ) # Failure Information if failure_information is not None: logging.info("Filling out failure information") - self.investigation_datasets_pom.click_show_failure_information() DatasetFieldUtil(self.page).populate_select_locator_for_field_inside_div( self.failure_reasons_string, "divFailureSection", @@ -424,14 +420,6 @@ def fill_out_suspected_findings(self, suspected_findings: dict) -> None: """ Populates the Suspected Findings section of the Investigation Dataset form. """ - logging.info("Starting fill_out_suspected_findings") - try: - logging.info("About to click suspected findings details") - self.investigation_datasets_pom.click_show_suspected_findings_details() - logging.info("Clicked suspected findings details successfully") - except Exception as e: - logging.error(f"Error clicking on Show Suspected Findings Details: {e}") - raise for key, value in suspected_findings.items(): match key: case "extracolonic summary code": @@ -500,12 +488,40 @@ def fill_out_general_information(self, general_information: dict) -> None: self.page ).select_aspirant_endoscopist_option_index(aspirant) + def fill_out_completion_information(self, completion_information: dict) -> None: + """ + This method completes the Completion Proof Information section of the investigation dataset. + Args: + completion_information (dict): A dictionary containing completion proof parameters. + """ + logging.info("Filling out completion proof information") + self.investigation_datasets_pom.click_show_completion_proof_information() + DatasetFieldUtil(self.page).populate_select_locator_for_field( + self.proof_parameters_string, completion_information["completion proof"] + ) + + def fill_out_failure_information(self, failure_information: dict) -> None: + """ + This method completes the Failure Information section of the investigation dataset. + Args: + failure_information (dict): A dictionary containing failure reasons and related information. + """ + logging.info("Filling out failure information") + DatasetFieldUtil(self.page).populate_select_locator_for_field_inside_div( + self.failure_reasons_string, + "divFailureSection", + failure_information["failure reasons"], + ) + def fill_out_contrast_tagging_and_drug_information( self, contrast_tagging_and_drug: dict ) -> None: + """ + This method completes the Contrast, Tagging & Drug Information section of the investigation dataset. + Args: + contrast_tagging_and_drug (dict): A dictionary containing contrast, tagging agent, and drug information. + """ logging.info("๐Ÿงช Filling out Contrast, Tagging & Drug Information") - self.investigation_datasets_pom.click_show_contrast_tagging_and_drug_information() - # Use for loop and match-case for endoscopy_information fields for key, value in contrast_tagging_and_drug.items(): match key: @@ -635,9 +651,6 @@ def fill_out_radiology_information(self, radiology_data: dict) -> None: """ logging.info("Filling out Radiology Information") - self.investigation_datasets_pom.click_show_radiology_information() - self.investigation_datasets_pom.click_show_radiology_failure_information() - # Use for loop and match-case for radiology data fields for key, value in radiology_data.items(): match key: @@ -722,8 +735,6 @@ def fill_endoscopy_information(self, endoscopy_information: dict) -> None: endoscopy_information (dict): A dictionary containing the endoscopy information to be filled in the form. """ # Endoscopy Information - self.investigation_datasets_pom.click_show_endoscopy_information() - # Use for loop and match-case for endoscopy_information fields for key, value in endoscopy_information.items(): match key: diff --git a/utils/subject_assertion.py b/utils/subject_assertion.py index d2ec850a..4630adbe 100644 --- a/utils/subject_assertion.py +++ b/utils/subject_assertion.py @@ -51,7 +51,11 @@ def subject_assertion( failed_criteria = [] criteria_keys = [key for key in criteria if key != nhs_number_string] for key in criteria_keys: + # Always include keys that start with 'which' (case-insensitive) in the query single_criteria = {nhs_number_string: nhs_number, key: criteria[key]} + for k in criteria_keys: + if k.lower().startswith("which") and k != key: + single_criteria[k] = criteria[k] query, bind_vars = builder.build_subject_selection_query( criteria=single_criteria, user=user, @@ -64,13 +68,10 @@ def subject_assertion( subject_nhs_number_string not in df.columns or nhs_number not in df[subject_nhs_number_string].values ): - actual_value = ( - df[key].iloc[0] if key in df.columns and not df.empty else "" - ) logging.warning( - f"[ASSERTION MISMATCH] Key: '{key}' | Expected: '{criteria[key]}' | Actual: '{actual_value}'" + f"[ASSERTION MISMATCH] Key: '{key}' | Expected: '{criteria[key]}'" ) - failed_criteria.append((key, criteria[key], actual_value)) + failed_criteria.append((key, criteria[key])) if failed_criteria: log_message = (