Skip to content

Commit 9139c70

Browse files
committed
wip & added some methods and locators to subject_screening_summary_page
1 parent 5849263 commit 9139c70

File tree

3 files changed

+193
-3
lines changed

3 files changed

+193
-3
lines changed

pages/screening_subject_search/subject_screening_summary_page.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
from playwright.sync_api import Page, expect, Locator
23
from pages.base_page import BasePage
34
from enum import Enum
@@ -32,7 +33,9 @@ def __init__(self, page: Page):
3233
self.individual_letters = self.page.get_by_role(
3334
"link", name="Individual Letters"
3435
)
35-
self.retrieve_data_link = self.page.get_by_role("link", name="Retrieve Data from Spine")
36+
self.retrieve_data_link = self.page.get_by_role(
37+
"link", name="Retrieve Data from Spine"
38+
)
3639
self.patient_contacts = self.page.get_by_role("link", name="Patient Contacts")
3740
self.more = self.page.get_by_role("link", name="more")
3841
self.change_screening_status = self.page.get_by_label("Change Screening Status")
@@ -69,6 +72,16 @@ def __init__(self, page: Page):
6972
self.book_practitioner_clinic_button = self.page.get_by_role(
7073
"button", name="Book Practitioner Clinic"
7174
)
75+
self.subject_age_cell = self.page.locator(
76+
"table#subjectSummaryTable tr:nth-of-type(1) td:nth-of-type(2)"
77+
)
78+
79+
self.screening_status_cell = self.page.locator(
80+
"td.epihdr_label:text('Screening Status') + td.epihdr_data"
81+
)
82+
self.latest_event_status_cell = self.page.locator(
83+
"table#subjectSummaryTable tr:has(td:text('Latest Event Status')) td.epihdr_data"
84+
).nth(0)
7285

7386
def wait_for_page_title(self) -> None:
7487
"""Waits for the page to be the Subject Screening Summary"""
@@ -322,6 +335,58 @@ def navigate_to_spine_search(self) -> None:
322335
self.click(self.retrieve_data_link)
323336
self.page.goto(self.spine_url)
324337

338+
def assert_subject_age(self, expected_age: int) -> None:
339+
"""
340+
Asserts that the subject's age displayed in the demographics cell matches the expected value.
341+
342+
Args:
343+
expected_age (int): The age to verify against the UI.
344+
345+
Raises:
346+
AssertionError: If the age in the UI does not match the expected value.
347+
"""
348+
age_text = self.subject_age_cell.inner_text().strip()
349+
match = re.search(r"\(age\s+(\d+)\)", age_text)
350+
if not match:
351+
raise AssertionError(
352+
f"[AGE PARSE ERROR] Could not find age in text: '{age_text}'"
353+
)
354+
355+
actual_age = int(match.group(1))
356+
assert (
357+
actual_age == expected_age
358+
), f"[AGE MISMATCH] Expected age {expected_age}, but found {actual_age} in UI."
359+
360+
def assert_screening_status(self, expected_status: str) -> None:
361+
"""
362+
Asserts that the screening status displayed in the summary matches the expected value.
363+
364+
Args:
365+
expected_status (str): The expected screening status (e.g., 'Inactive').
366+
367+
Raises:
368+
AssertionError: If the status in the UI does not match the expected value.
369+
"""
370+
actual_status = self.screening_status_cell.inner_text().strip()
371+
assert (
372+
actual_status.lower() == expected_status.lower()
373+
), f"[SCREENING STATUS MISMATCH] Expected '{expected_status}', but found '{actual_status}' in UI."
374+
375+
def assert_latest_event_status(self, expected_status: str) -> None:
376+
"""
377+
Asserts that the latest event status displayed in the summary table matches the expected value.
378+
379+
Args:
380+
expected_status (str): The expected event status (e.g., 'S9 Pre-invitation Sent').
381+
382+
Raises:
383+
AssertionError: If the status in the UI does not match the expected value.
384+
"""
385+
actual_status = self.latest_event_status_cell.inner_text().strip()
386+
assert actual_status == expected_status, (
387+
f"[LATEST EVENT STATUS MISMATCH] Expected '{expected_status}', but found '{actual_status}' in UI."
388+
)
389+
325390
class ChangeScreeningStatusOptions(Enum):
326391
"""Enum for Change Screening Status options."""
327392

tests/regression/regression_tests/fobt_regression_tests/test_scenario_2.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
from utils.oracle.subject_creation_util import CreateSubjectSteps
66
from utils.user_tools import UserTools
77
from utils.subject_assertion import subject_assertion
8+
from utils.call_and_recall_utils import CallAndRecallUtils
9+
from utils import screening_subject_page_searcher
810
from pages.base_page import BasePage
11+
from pages.screening_subject_search.subject_screening_summary_page import (
12+
SubjectScreeningSummaryPage,
13+
)
14+
915

1016
@pytest.mark.wip
1117
@pytest.mark.fobt_regression_tests
@@ -31,6 +37,7 @@ def test_scenario_2(page: Page) -> None:
3137
> Process S158 letter batch > S159 (1.3) > C203 (1.13)
3238
> Check recall [SSCL4a]
3339
"""
40+
summary_page = SubjectScreeningSummaryPage(page)
3441
logging.info("[TEST START] Regression - fobt normal kit reading")
3542

3643
# Given I log in to BCSS "England" as user role "Hub Manager"
@@ -53,7 +60,7 @@ def test_scenario_2(page: Page) -> None:
5360
pytest.fail("Failed to create subject: NHS number not returned.")
5461

5562
# Then Comment: NHS number
56-
logging.info(f"Created subject's NHS number: {nhs_no}")
63+
logging.info(f"[SUBJECT CREATED] Created subject's NHS number: {nhs_no}")
5764

5865
# And my subject has been updated as follows:
5966
# Subject age 66
@@ -67,10 +74,20 @@ def test_scenario_2(page: Page) -> None:
6774
"screening status": "Inactive",
6875
},
6976
)
70-
logging.info("Updated subject details checked in the DB")
77+
logging.info("[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB")
78+
79+
# Navigate to subject profile in UI
80+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
81+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
7182

83+
# Assert subject details in the UI
84+
summary_page.assert_subject_age(66)
85+
summary_page.assert_screening_status("Inactive")
86+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
7287

7388
# When I run the FOBT failsafe trawl for my subject
89+
CallAndRecallUtils().run_failsafe(nhs_no)
90+
logging.info("[FAILSAFE TRAWL RUN]FOBT failsafe trawl run for subject")
7491

7592
# Then my subject has been updated as follows:
7693
# Subject has episodes No
@@ -94,6 +111,15 @@ def test_scenario_2(page: Page) -> None:
94111
"Screening Status Reason": "Failsafe Trawl",
95112
},
96113
)
114+
logging.info("[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB")
115+
116+
# Navigate to subject profile in UI
117+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
118+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
119+
120+
# Assert subject details in the UI
121+
summary_page.assert_screening_status("Call")
122+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
97123

98124
# When I invite my subject for FOBT screening
99125

@@ -110,6 +136,9 @@ def test_scenario_2(page: Page) -> None:
110136
},
111137
)
112138
# Then there is a "S1" letter batch for my subject with the exact title "Pre-invitation (FIT)"
139+
logging.info(
140+
"[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB & letter batch exists"
141+
)
113142

114143
# When I process the open "S1" letter batch for my subject
115144

@@ -121,6 +150,15 @@ def test_scenario_2(page: Page) -> None:
121150
"latest event status": "S9 Pre-invitation Sent",
122151
},
123152
)
153+
logging.info("[ASSERTIONS COMPLETE]Updated subject status checked in the DB")
154+
155+
# Navigate to subject profile in UI
156+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
157+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
158+
159+
# Assert subject details in the UI
160+
summary_page.assert_latest_event_status("S9 Pre-invitation Sent")
161+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
124162

125163
# When I run Timed Events for my subject
126164
# Then there is a "S9" letter batch for my subject with the exact title "Invitation & Test Kit (FIT)"
@@ -145,6 +183,15 @@ def test_scenario_2(page: Page) -> None:
145183
"latest event status": "S43 Kit Returned and Logged (Initial Test)",
146184
},
147185
)
186+
# Navigate to subject profile in UI
187+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
188+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
189+
190+
# Assert subject details in the UI
191+
summary_page.assert_latest_event_status(
192+
"S43 Kit Returned and Logged (Initial Test)"
193+
)
194+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
148195

149196
# When I read my subject's latest logged FIT kit as "NORMAL"
150197

@@ -156,6 +203,15 @@ def test_scenario_2(page: Page) -> None:
156203
"latest event status": "S2 Normal",
157204
},
158205
)
206+
logging.info("[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB")
207+
208+
# Navigate to subject profile in UI
209+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
210+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
211+
212+
# Assert subject details in the UI
213+
summary_page.assert_latest_event_status("S2 Normal")
214+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
159215
# And there is a "S2" letter batch for my subject with the exact title "Subject Result (Normal)"
160216

161217
# When I process the open "S2" letter batch for my subject
@@ -168,6 +224,15 @@ def test_scenario_2(page: Page) -> None:
168224
"latest event status": "S158 Subject Discharge Sent (Normal)",
169225
},
170226
)
227+
logging.info("[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB")
228+
229+
# Navigate to subject profile in UI
230+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
231+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
232+
233+
# Assert subject details in the UI
234+
summary_page.assert_latest_event_status("S158 Subject Discharge Sent (Normal)")
235+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")
171236
# And there is a "S158" letter batch for my subject with the exact title "GP Result (Normal)"
172237

173238
# When I process the open "S158" letter batch for my subject
@@ -231,3 +296,12 @@ def test_scenario_2(page: Page) -> None:
231296
"surveillance due date reason": "Unchanged",
232297
},
233298
)
299+
logging.info("[DB ASSERTIONS COMPLETE]Updated subject details checked in the DB")
300+
301+
# Navigate to subject profile in UI
302+
screening_subject_page_searcher.search_subject_by_nhs_number(page, nhs_no)
303+
logging.info("[SUBJECT VIEW] Subject loaded in UI")
304+
305+
# Assert subject details in the UI
306+
summary_page.assert_latest_event_status("S159 GP Discharge Sent (Normal)")
307+
logging.info("[UI ASSERTIONS COMPLETE]Updated subject details checked in the UI")

utils/call_and_recall_utils.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import logging
2+
import oracledb
3+
from utils.oracle.oracle import OracleDB
4+
5+
6+
class CallAndRecallUtils:
7+
"""
8+
This contains utility methods to do with Call and Recall
9+
"""
10+
11+
def __init__(self):
12+
self.oracledb = OracleDB()
13+
14+
def run_failsafe(self, nhs_no: str) -> None:
15+
"""
16+
Run the failsafe trawl for the given NHS number.
17+
Args:
18+
nhs_no: The NHS number of the subject
19+
"""
20+
subject_id = int(self.oracledb.get_subject_id_from_nhs_number(nhs_no))
21+
conn = self.oracledb.connect_to_db()
22+
conn.callTimeout = 30000 # Setting call timeout to 30 seconds
23+
cur = conn.cursor()
24+
25+
pi = cur.var(oracledb.NUMBER)
26+
pi.setvalue(0, subject_id)
27+
28+
out_cursor = cur.var(oracledb.CURSOR)
29+
30+
cur.execute(
31+
"""
32+
BEGIN
33+
pkg_fobt_call.p_failsafe_trawl(
34+
pi_subject_id => :pi,
35+
po_cur_error => :po
36+
);
37+
END;""",
38+
{"pi": str(subject_id), "po": out_cursor},
39+
)
40+
41+
result_cursor = out_cursor.getvalue()
42+
row = result_cursor.fetchone()
43+
assert (
44+
"The action was performed successfully" in row
45+
), f"Error when executing failsafe for {nhs_no}: {row}"
46+
47+
# Clean up
48+
result_cursor.close()
49+
cur.close()
50+
conn.close()
51+
logging.info(f"END: failsafe stored proc executed for {nhs_no}")

0 commit comments

Comments
 (0)