Skip to content

Commit 90ab847

Browse files
Merge branch 'main' of github.com:NHSDigital/bcss-playwright into feature/BCSS-21164-selenium-to-playwright-endoscopyinvestigationdatasetsceanrios-1-10
# Conflicts: # pytest.ini # users.json
2 parents 3a4add6 + 4fbc663 commit 90ab847

File tree

7 files changed

+1202
-2
lines changed

7 files changed

+1202
-2
lines changed

classes/diagnosis_date_reason_type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,6 @@ def get_valid_value_id(self) -> Optional[int]:
9898

9999
def get_description(self) -> str:
100100
"""
101-
Returns the description for the diagnosis date reason.
101+
Returns the description for the diagnosis date reason
102102
"""
103103
return self._description

pages/screening_subject_search/advance_fobt_screening_episode_page.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def __init__(self, page: Page):
1717
self.calendar_button = self.page.get_by_role("button", name="Calendar")
1818
self.test_type_dropdown = self.page.locator("#UI_EXT_TEST_TYPE_2233")
1919
self.test_type_dropdown_2 = self.page.locator("#UI_EXT_TEST_TYPE_4325")
20+
self.advance_checkbox = self.page.get_by_label("There are some events available which should only be used in exceptional circumstances. If you wish to see them, check this box")
2021
self.invite_for_diagnostic_test_button = self.page.get_by_role(
2122
"button", name="Invite for Diagnostic Test >>"
2223
)
@@ -111,3 +112,7 @@ def click_record_diagnosis_date_button(self) -> None:
111112
def click_record_contact_with_patient_button(self) -> None:
112113
"""Click the 'Record Contact with Patient' button."""
113114
self.click(self.record_contact_with_patient_button)
115+
116+
def check_advance_checkbox(self) -> None:
117+
"""Selects the 'Advance FOBT' checkbox"""
118+
self.advance_checkbox.check()

pages/screening_subject_search/record_diagnosis_date_page.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,22 @@ def enter_date_in_diagnosis_date_field(self, date: datetime) -> None:
2222
"""
2323
self.click(self.diagnosis_date_field)
2424
CalendarPicker(self.page).v2_calendar_picker(date)
25-
self.diagnosis_date_field.press("Enter")
25+
self.diagnosis_date_field.press("Tab")
2626

2727
def click_save_button(self) -> None:
2828
"""Clicks the save button."""
2929
self.click(self.save_button)
30+
31+
def get_alert_message(self) -> str:
32+
"""
33+
Retrieve the visible alert message from the page, if any.
34+
35+
Returns:
36+
str: The inner text of the alert element if it's visible;
37+
otherwise, an empty string.
38+
"""
39+
self.alert_message = self.page.get_by_role("alert")
40+
if self.alert_message.is_visible():
41+
return self.alert_message.inner_text()
42+
else:
43+
return ""
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import logging
2+
import pytest
3+
from playwright.sync_api import Page, expect
4+
from pages.base_page import BasePage
5+
from typing import Dict
6+
7+
class SubjectEpisodeEventsAndNotesPage(BasePage):
8+
"""Episode Events and Notes Page locators, and methods for interacting with the page."""
9+
10+
def __init__(self, page: Page):
11+
super().__init__(page)
12+
self.page = page
13+
# List of episode events and notes - page locators
14+
self.latest_event_status_cell = self.page.locator(
15+
"table >> td.epihdr_data"
16+
).nth(
17+
0
18+
) # if it's the first one
19+
self.latest_event_cell = self.page.get_by_role(
20+
"cell", name="Record Diagnosis Date", exact=True
21+
)
22+
self.latest_diagnosis_cell = self.page.locator(
23+
"td[align='center']:has-text('Diag Date :')"
24+
)
25+
26+
# Episode details (Replace with actual selectors only for scenario 17)
27+
self.latest_episode_status = self.page.locator("#latestEpisodeStatus")
28+
self.latest_episode_has_diagnosis_date = self.page.locator(
29+
"#latestEpisodeHasDiagnosisDate"
30+
)
31+
self.latest_episode_diagnosis_reason = self.page.locator(
32+
"#latestEpisodeDiagnosisDateReason"
33+
)
34+
self.process_sspi_update_button = self.page.get_by_text("Process SSPI Update")
35+
self.deduction_reason_dropdown = self.page.locator("#deductionReason")
36+
self.confirm_sspi_update_button = self.page.get_by_text("Confirm")
37+
38+
def expected_episode_event_is_displayed(self, event_description: str) -> None:
39+
"""Check if the expected episode event is displayed on the page."""
40+
expect(
41+
self.page.get_by_role("cell", name=event_description, exact=True)
42+
).to_be_visible()
43+
44+
def get_latest_event_details(self) -> dict:
45+
"""
46+
Retrieves key details for the latest episode entry from the UI.
47+
48+
Returns:
49+
dict: A dictionary containing the following keys:
50+
- "latest_event_status" (str): The current status text of the latest event.
51+
- "event" (str): A description or name of the latest event.
52+
- "item" (str): Details related to the latest diagnosis item.
53+
54+
Raises:
55+
pytest.fail: If any of the UI elements cannot be read, the test fails immediately.
56+
"""
57+
try:
58+
status_text = self.latest_event_status_cell.inner_text()
59+
event_text = self.latest_event_cell.inner_text()
60+
diagnosis_text = self.latest_diagnosis_cell.first.inner_text()
61+
logging.debug(f"DEBUG: {event_text}, {status_text}, {diagnosis_text}")
62+
except Exception as e:
63+
pytest.fail(f"Failed to read latest episode event details from UI: {e}")
64+
return {
65+
"latest_event_status": status_text,
66+
"event": event_text,
67+
"item": diagnosis_text,
68+
}
69+
70+
def validate_event_status_is_not_A50(self, event_details: dict) -> None:
71+
"""Validates that latest_event_status does not contain 'A50'."""
72+
latest_status = event_details.get("latest_event_status")
73+
logging.info(f"Validating Latest Event Status: {latest_status}")
74+
75+
if latest_status is None:
76+
pytest.fail("Missing 'latest_event_status' in event_details.")
77+
elif "A50" in str(latest_status):
78+
pytest.fail(
79+
f"Invalid status detected: 'A50' is not allowed. Received: '{latest_status}'"
80+
)
81+
logging.info(f"Status '{latest_status}' is allowed.")
82+
83+
def is_record_diagnosis_date_option_available(self) -> bool:
84+
"""
85+
Check if the 'Record Diagnosis Date' option is available on the page
86+
87+
Returns:
88+
bool: True if the option is available, False otherwise.
89+
"""
90+
try:
91+
return self.page.get_by_role(
92+
"button", name="Record Diagnosis Date"
93+
).is_visible()
94+
except Exception as e:
95+
logging.error(f"Record Diagnosis Date option not found: {e}")
96+
return False
97+
98+
def is_amend_diagnosis_date_option_available(self) -> bool:
99+
"""
100+
Check if the 'Amend Diagnosis Date' option is available on the page.
101+
102+
Returns:
103+
bool: True if the option is available, False otherwise.
104+
"""
105+
try:
106+
return self.page.get_by_role(
107+
"button", name="Amend Diagnosis Date"
108+
).is_visible()
109+
except Exception as e:
110+
logging.error(f"Error checking for 'Amend Diagnosis Date' option: {e}")
111+
return False
112+
113+
def process_sspi_update_for_death(self, deduction_reason: str) -> None:
114+
"""
115+
Submits an SSPI update for a death-related deduction reason through the UI workflow.
116+
117+
Args:
118+
deduction_reason (str): The label of the deduction reason to select from the dropdown.
119+
120+
Steps:
121+
- Clicks the SSPI update button.
122+
- Selects the specified deduction reason from the dropdown.
123+
- Confirms the SSPI update by clicking the confirmation button.
124+
"""
125+
self.process_sspi_update_button.click()
126+
self.deduction_reason_dropdown.select_option(label=deduction_reason)
127+
self.confirm_sspi_update_button.click()
128+
129+
def get_latest_episode_details(self) -> Dict[str, str]:
130+
"""
131+
Retrieve details of the latest episode from the UI elements.
132+
133+
Returns:
134+
Dict[str, str]: A dictionary containing:
135+
- 'latest_episode_status': The status text of the latest episode.
136+
- 'latest_episode_has_diagnosis_date': Indicator of whether a diagnosis date is present.
137+
- 'latest_episode_diagnosis_date_reason': Reason explaining the diagnosis date status.
138+
"""
139+
return {
140+
"latest_episode_status": self.latest_episode_status.inner_text(),
141+
"latest_episode_has_diagnosis_date": self.latest_episode_has_diagnosis_date.inner_text(),
142+
"latest_episode_diagnosis_date_reason": self.latest_episode_diagnosis_reason.inner_text(),
143+
}

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ markers =
4747
skip_before_test: tests that will not use the before_test fixture
4848
bcss_additional_tests: tests that are part of the BCSS Additional Tests test suite
4949
colonoscopy_dataset_tests: tests that are part of the colonoscopy datasets test suite
50+
fobt_diagnosis_date_entry_tests: tests that are part of fobt subject episodes record diagnosis date

0 commit comments

Comments
 (0)