Skip to content

Commit 2aa8cd1

Browse files
Adding scenarios 15 & 16 from feature file (#119)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> Migrating scenario 15 - 16 from the EndoscopyInvestigationDatasetScenarios feature file: 15: Scenario: Check the validation of the Scope ID field in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset 16: Scenario: Check the behaviour of the Endoscope Inserted fields in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset ## Context <!-- Why is this change required? What problem does it solve? --> Migrating scenario 15 - 16 from the EndoscopyInvestigationDatasetScenarios feature file: 15: Scenario: Check the validation of the Scope ID field in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset 16: Scenario: Check the behaviour of the Endoscope Inserted fields in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [x] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I am familiar with the [contributing guidelines](https://github.com/nhs-england-tools/playwright-python-blueprint/blob/main/CONTRIBUTING.md) - [x] I have followed the code style of the project - [x] I have added tests to cover my changes (where appropriate) - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.
1 parent eb01fb8 commit 2aa8cd1

File tree

2 files changed

+239
-5
lines changed

2 files changed

+239
-5
lines changed

pages/datasets/investigation_dataset_page.py

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,14 @@ def check_endoscope_inserted_yes(self) -> None:
250250
This method is designed to check the endoscope inserted yes option.
251251
It checks the endoscope inserted yes option.
252252
"""
253-
self.endoscope_inserted_yes.check()
253+
self.click(self.endoscope_inserted_yes)
254254

255255
def check_endoscope_inserted_no(self) -> None:
256256
"""
257257
This method is designed to check the endoscope inserted no option.
258258
It checks the endoscope inserted no option.
259259
"""
260-
self.endoscope_inserted_no.check()
260+
self.click(self.endoscope_inserted_no)
261261

262262
def select_therapeutic_procedure_type(self) -> None:
263263
"""
@@ -546,12 +546,13 @@ def is_dataset_section_present(self, dataset_section_name: str) -> bool | None:
546546
def get_dataset_section(self, dataset_section_name: str) -> Locator | None:
547547
"""
548548
Retrieves a dataset section by matching its header text.
549+
Only returns the locator if the section is visible.
549550
Searches through all elements representing dataset sections, looking for one whose
550551
first <h4> header text matches the provided section name (case-insensitive).
551552
Args:
552553
dataset_section_name (str): The name of the dataset section to locate.
553554
Returns:
554-
Locator | None: A Playwright Locator for the matching section, or None if not found.
555+
Locator | None: A Playwright Locator for the matching section if visible, or None if not found or not visible.
555556
"""
556557
logging.info(f"START: Looking for section '{dataset_section_name}'")
557558

@@ -562,15 +563,62 @@ def get_dataset_section(self, dataset_section_name: str) -> Locator | None:
562563
header = section.locator("h4")
563564
if header.count() > 0:
564565
header_text = header.first.inner_text().strip().lower()
565-
if header_text == dataset_section_name.strip().lower():
566+
if (
567+
header_text == dataset_section_name.strip().lower()
568+
and section.is_visible()
569+
):
566570
section_found = section
567571
break
568572

569573
logging.info(
570-
f"Dataset section '{dataset_section_name}' found: {section_found is not None}"
574+
f"Dataset section '{dataset_section_name}' found and visible: {section_found is not None}"
571575
)
572576
return section_found
573577

578+
def is_dataset_section_on_page(
579+
self, dataset_section: str | List[str], should_be_present: bool = True
580+
) -> None:
581+
"""
582+
Asserts whether the specified dataset section(s) are present or not on the page.
583+
Args:
584+
dataset_section (str or List[str]): The name of the dataset section to check for presence,
585+
or a list of section names.
586+
Examples:
587+
"Investigation Dataset"
588+
["Investigation Dataset", "Drug Information", "Endoscopy Information"]
589+
should_be_present (bool): If True, asserts the section(s) are present.
590+
If False, asserts the section(s) are not present.
591+
Raises:
592+
AssertionError: If the actual presence does not match should_be_present.
593+
"""
594+
if isinstance(dataset_section, str):
595+
section_found = self.get_dataset_section(dataset_section) is not None
596+
if should_be_present:
597+
assert (
598+
section_found
599+
), f"Expected section '{dataset_section}' to be present, but it was not found."
600+
logging.info(f"Section '{dataset_section}' is present as expected.")
601+
else:
602+
assert (
603+
not section_found
604+
), f"Expected section '{dataset_section}' to be absent, but it was found."
605+
logging.info(f"Section '{dataset_section}' is absent as expected.")
606+
elif isinstance(dataset_section, list):
607+
for section_name in dataset_section:
608+
section_found = self.get_dataset_section(section_name) is not None
609+
if should_be_present:
610+
assert (
611+
section_found
612+
), f"Expected section '{section_name}' to be present, but it was not found."
613+
logging.info(f"Section '{section_name}' is present as expected.")
614+
else:
615+
assert (
616+
not section_found
617+
), f"Expected section '{section_name}' to be absent, but it was found."
618+
logging.info(f"Section '{section_name}' is absent as expected.")
619+
else:
620+
raise TypeError("dataset_section must be a string or a list of strings.")
621+
574622
def get_dataset_subsection(
575623
self, dataset_section_name: str, dataset_subsection_name: str
576624
) -> Locator | None:
@@ -1417,6 +1465,19 @@ class OtherDrugsAdministeredDrugTypeOptions(StrEnum):
14171465
PROPOFOL = "17960~mg"
14181466

14191467

1468+
class EndoscopeNotInsertedOptions(StrEnum):
1469+
"""Enum for why endoscope not inserted options"""
1470+
1471+
CLINICAL_REASON_ON_PR = "200541~Abnormalities allowed"
1472+
CONSENT_REFUSED = "200542"
1473+
EQUIPMENT_FAILURE = "200544"
1474+
NO_BOWEL_PREPERATION = "200543"
1475+
PATIENT_UNSUITABLE = "200545"
1476+
SERVICE_INTERRUPTION = "203000"
1477+
SOLID_STOLL_ON_PR = "200546"
1478+
UNSCHEDULED_ATTENDANCE_TIME = "203001"
1479+
1480+
14201481
# Registry of all known Enums to search when matching string values
14211482
ALL_ENUMS: List[type[Enum]] = [
14221483
obj

tests/regression/subject/episodes/datasets/investigation/endoscopy/test_endoscopy_investigation_dataset_scenarios.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
YesNoDrugOptions,
2020
AntibioticsAdministeredDrugTypeOptions,
2121
OtherDrugsAdministeredDrugTypeOptions,
22+
EndoscopeNotInsertedOptions,
2223
)
2324
from classes.user import User
2425
from classes.subject import Subject
@@ -2426,6 +2427,178 @@ def test_check_dropdown_lists_and_default_field_values_in_endoscopy_information_
24262427
LogoutPage(page).log_out()
24272428

24282429

2430+
@pytest.mark.regression
2431+
@pytest.mark.vpn_required
2432+
@pytest.mark.investigation_dataset_tests
2433+
@pytest.mark.bcss_additional_tests
2434+
@pytest.mark.colonoscopy_dataset_tests
2435+
def test_validation_of_scope_id_field_in_endoscopy_information_section(
2436+
page: Page,
2437+
) -> None:
2438+
"""
2439+
Scenario: Check the validation of the Scope ID field in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset
2440+
Scope ID can't contain invalid characters. This validation is both immediate and on save.
2441+
"""
2442+
nhs_no = get_subject_with_new_colonoscopy_investigation_dataset()
2443+
UserTools.user_login(page, "Screening Centre Manager at BCS001")
2444+
BasePage(page).go_to_screening_subject_search_page()
2445+
search_subject_episode_by_nhs_number(page, nhs_no)
2446+
SubjectScreeningSummaryPage(page).click_datasets_link()
2447+
SubjectDatasetsPage(page).click_investigation_show_datasets()
2448+
2449+
InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text(
2450+
"Investigation Datasets"
2451+
)
2452+
InvestigationDatasetsPage(page).click_show_endoscopy_information()
2453+
2454+
InvestigationDatasetsPage(page).assert_dialog_text(
2455+
'Certain characters may not be used in the Scope ID field. Please remove the following: <>,",&,¬,£'
2456+
)
2457+
DatasetFieldUtil(page).populate_input_locator_for_field("Scope ID", '<> " & ¬ £')
2458+
InvestigationDatasetsPage(page).assert_dialog_text(
2459+
'Certain characters may not be used in the Scope ID field. Please remove the following: <>,",&,¬,£'
2460+
)
2461+
InvestigationDatasetsPage(page).click_save_dataset_button()
2462+
2463+
LogoutPage(page).log_out()
2464+
2465+
2466+
@pytest.mark.regression
2467+
@pytest.mark.vpn_required
2468+
@pytest.mark.investigation_dataset_tests
2469+
@pytest.mark.bcss_additional_tests
2470+
@pytest.mark.colonoscopy_dataset_tests
2471+
def test_behaviour_of_edoscope_inserted_fields_in_endoscopy_information_section(
2472+
page: Page,
2473+
) -> None:
2474+
"""
2475+
Scenario: Check the behaviour of the Endoscope Inserted fields in the Endoscopy Information section in an incomplete Colonoscopy investigation dataset
2476+
"""
2477+
nhs_no = get_subject_with_new_colonoscopy_investigation_dataset()
2478+
UserTools.user_login(page, "Screening Centre Manager at BCS001")
2479+
BasePage(page).go_to_screening_subject_search_page()
2480+
search_subject_episode_by_nhs_number(page, nhs_no)
2481+
SubjectScreeningSummaryPage(page).click_datasets_link()
2482+
SubjectDatasetsPage(page).click_investigation_show_datasets()
2483+
2484+
InvestigationDatasetsPage(page).bowel_cancer_screening_page_title_contains_text(
2485+
"Investigation Datasets"
2486+
)
2487+
2488+
logging.info("STEP: By default Endoscope Inserted = Yes")
2489+
InvestigationDatasetsPage(page).click_show_endoscopy_information()
2490+
2491+
DatasetFieldUtil(page).assert_radio_to_right_is_selected(
2492+
"Endoscope Inserted", "Yes"
2493+
)
2494+
sections_to_check = [
2495+
"Failure Information",
2496+
"Polyp Information",
2497+
"Colorectal Cancer Information",
2498+
"Complication Information",
2499+
"Other Findings",
2500+
]
2501+
InvestigationDatasetsPage(page).is_dataset_section_on_page(sections_to_check)
2502+
2503+
logging.info(
2504+
"STEP: Changing Endoscope Inserted to No removes most fields and sections"
2505+
)
2506+
2507+
InvestigationDatasetsPage(page).check_endoscope_inserted_no()
2508+
DatasetFieldUtil(page).assert_radio_to_right_is_selected("Endoscope Inserted", "No")
2509+
DatasetFieldUtil(page).assert_cell_to_right_has_expected_text(
2510+
"Why Endoscope Not Inserted", ""
2511+
)
2512+
dropdown_values = [
2513+
"Clinical reason on PR",
2514+
"Consent refused",
2515+
"Equipment failure",
2516+
"No bowel preparation",
2517+
"Patient unsuitable",
2518+
"Service interruption",
2519+
"Solid stool on PR",
2520+
"Unscheduled attendance time",
2521+
]
2522+
DatasetFieldUtil(page).assert_select_to_right_has_values(
2523+
"Why Endoscope Not Inserted", dropdown_values
2524+
)
2525+
field_names = [
2526+
"Procedure type",
2527+
"Bowel preparation quality",
2528+
"Comfort during examination",
2529+
"Comfort during recovery",
2530+
"Intended extent of examination",
2531+
"Endoscopist defined extent",
2532+
"Scope imager used",
2533+
"Retroverted view",
2534+
"Start of intubation time",
2535+
"Start of extubation time",
2536+
"End time of procedure",
2537+
"Withdrawal time",
2538+
"Scope ID",
2539+
"Detection Assistant (AI) Used?",
2540+
"Insufflation",
2541+
"Outcome at time of procedure",
2542+
"Late outcome",
2543+
]
2544+
InvestigationDatasetsPage(page).are_fields_on_page(
2545+
"Endoscopy Information", None, field_names, False
2546+
)
2547+
sections_to_check = [
2548+
"Failure Information",
2549+
"Complication Information",
2550+
]
2551+
InvestigationDatasetsPage(page).is_dataset_section_on_page(sections_to_check, False)
2552+
2553+
logging.info(
2554+
"STEP: For most Why Endoscope Not Inserted values, polyps, cancers or other findings cannot be recorded"
2555+
)
2556+
2557+
DatasetFieldUtil(page).populate_select_locator_for_field(
2558+
"Why Endoscope Not Inserted", EndoscopeNotInsertedOptions.EQUIPMENT_FAILURE
2559+
)
2560+
DatasetFieldUtil(page).assert_cell_to_right_has_expected_text(
2561+
"Why Endoscope Not Inserted", "Equipment failure"
2562+
)
2563+
sections_to_check = [
2564+
"Polyp Information",
2565+
"Colorectal Cancer Information",
2566+
"Other Findings",
2567+
]
2568+
InvestigationDatasetsPage(page).is_dataset_section_on_page(sections_to_check, False)
2569+
2570+
logging.info(
2571+
"STEP: Why Endoscope Not Inserted values 'Clinical reason on PR' does allow polyps, cancers or other findings to be recorded"
2572+
)
2573+
2574+
DatasetFieldUtil(page).populate_select_locator_for_field(
2575+
"Why Endoscope Not Inserted", EndoscopeNotInsertedOptions.CLINICAL_REASON_ON_PR
2576+
)
2577+
DatasetFieldUtil(page).assert_cell_to_right_has_expected_text(
2578+
"Why Endoscope Not Inserted", "Clinical reason on PR"
2579+
)
2580+
InvestigationDatasetsPage(page).is_dataset_section_on_page(sections_to_check)
2581+
2582+
logging.info(
2583+
"STEP: Endoscope Inserted can only be changed back to Yes if there is no Why Endoscope Not Inserted value"
2584+
)
2585+
2586+
InvestigationDatasetsPage(page).assert_dialog_text(
2587+
"You cannot change 'Endoscope inserted' to 'Yes' as details have been entered for Why Endoscope Not Inserted."
2588+
)
2589+
InvestigationDatasetsPage(page).check_endoscope_inserted_yes()
2590+
2591+
DatasetFieldUtil(page).populate_select_locator_for_field(
2592+
"Why Endoscope Not Inserted", ""
2593+
)
2594+
InvestigationDatasetsPage(page).check_endoscope_inserted_yes()
2595+
DatasetFieldUtil(page).assert_radio_to_right_is_selected(
2596+
"Endoscope Inserted", "Yes"
2597+
)
2598+
2599+
LogoutPage(page).log_out()
2600+
2601+
24292602
# Helper Functions
24302603

24312604

0 commit comments

Comments
 (0)