Skip to content

Commit c96c44c

Browse files
adrianoaru-nhsAndyg79
authored andcommitted
Feature/bcss 20600 selenium to playwright regression subject demographic (#99)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> Converting the subject demographic tests from the selenium framework into python. ## Context <!-- Why is this change required? What problem does it solve? --> Allows for the running of the subject demographic tests to be done on playwright. ## 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 b9ef56f commit c96c44c

File tree

8 files changed

+587
-9
lines changed

8 files changed

+587
-9
lines changed

pages/base_page.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,20 +249,24 @@ def safe_accept_dialog(self, locator: Locator) -> None:
249249
except Exception as e:
250250
logging.error(f"Click failed: {e}")
251251

252-
253252
def assert_dialog_text(self, expected_text: str) -> None:
254253
"""
255254
Asserts that a dialog appears and contains the expected text.
256255
If no dialog appears, logs an error.
257256
Args:
258257
expected_text (str): The text that should be present in the dialog.
259258
"""
259+
self._dialog_assertion_error = None
260260

261-
def handle_dialog(dialog):
261+
def handle_dialog(dialog: Dialog):
262+
logging.info(f"Dialog appeared with message: {dialog.message}")
262263
actual_text = dialog.message
263-
assert (
264-
actual_text == expected_text
265-
), f"Expected '{expected_text}', but got '{actual_text}'"
264+
try:
265+
assert (
266+
actual_text == expected_text
267+
), f"Expected '{expected_text}', but got '{actual_text}'"
268+
except AssertionError as e:
269+
self._dialog_assertion_error = e
266270
dialog.dismiss() # Dismiss dialog
267271

268272
self.page.once("dialog", handle_dialog)

pages/screening_subject_search/subject_demographic_page.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,41 @@ def __init__(self, page: Page):
1818
self.update_subject_data_button = self.page.get_by_role(
1919
"button", name="Update Subject Data"
2020
)
21+
self.temporary_address_show_link = (
22+
self.page.locator("font")
23+
.filter(has_text="Temporary Address show")
24+
.get_by_role("link")
25+
)
26+
self.temporary_address_valid_from_calendar_button = self.page.locator(
27+
"#UI_SUBJECT_ALT_FROM_0_LinkOrButton"
28+
)
29+
self.temporary_address_valid_to_calendar_button = self.page.locator(
30+
"#UI_SUBJECT_ALT_TO_0_LinkOrButton"
31+
)
32+
self.temporary_address_valid_from_text_box = self.page.get_by_role(
33+
"textbox", name="Valid from"
34+
)
35+
self.temporary_address_valid_to_text_box = self.page.get_by_role(
36+
"textbox", name="Valid to"
37+
)
38+
self.temporary_address_address_line_1 = self.page.locator(
39+
"#UI_SUBJECT_ALT_ADDR1_0"
40+
)
41+
self.temporary_address_address_line_2 = self.page.locator(
42+
"#UI_SUBJECT_ALT_ADDR2_0"
43+
)
44+
self.temporary_address_address_line_3 = self.page.locator(
45+
"#UI_SUBJECT_ALT_ADDR3_0"
46+
)
47+
self.temporary_address_address_line_4 = self.page.locator(
48+
"#UI_SUBJECT_ALT_ADDR4_0"
49+
)
50+
self.temporary_address_address_line_5 = self.page.locator(
51+
"#UI_SUBJECT_ALT_ADDR5_0"
52+
)
53+
self.temporary_address_postcode = self.page.locator(
54+
"#UI_SUBJECT_ALT_POSTCODE_0"
55+
)
2156

2257
def is_forename_filled(self) -> bool:
2358
"""
@@ -99,3 +134,53 @@ def get_dob_field_value(self) -> str:
99134
str: The subject's date of birth as a string
100135
"""
101136
return self.dob_field.input_value()
137+
138+
def update_temporary_address(self, dict: dict) -> None:
139+
"""
140+
Updates the temporary address fields with the provided dictionary values.
141+
Args:
142+
dict (dict): A dictionary containing the temporary address details.
143+
Expected keys: 'valid_from', 'valid_to', 'address_line_1',
144+
'address_line_2', 'address_line_3', 'address_line_4', 'address_line_5'.
145+
"""
146+
# Click the link to show the temporary address fields
147+
if self.temporary_address_show_link.is_visible():
148+
# If the link is visible, click it to show the temporary address fields
149+
self.click(self.temporary_address_show_link)
150+
151+
# Update the valid from date
152+
if "valid_from" in dict:
153+
if dict["valid_from"] is None:
154+
self.temporary_address_valid_from_text_box.fill("")
155+
else:
156+
CalendarPicker(self.page).calendar_picker_ddmmyyyy(
157+
dict["valid_from"], self.temporary_address_valid_from_text_box
158+
)
159+
160+
# Update the valid to date
161+
if "valid_to" in dict:
162+
if dict["valid_to"] is None:
163+
self.temporary_address_valid_to_text_box.fill("")
164+
else:
165+
CalendarPicker(self.page).calendar_picker_ddmmyyyy(
166+
dict["valid_to"], self.temporary_address_valid_to_text_box
167+
)
168+
169+
# Fill in the address lines
170+
if "address_line_1" in dict:
171+
self.temporary_address_address_line_1.fill(dict["address_line_1"])
172+
if "address_line_2" in dict:
173+
self.temporary_address_address_line_2.fill(dict["address_line_2"])
174+
if "address_line_3" in dict:
175+
self.temporary_address_address_line_3.fill(dict["address_line_3"])
176+
if "address_line_4" in dict:
177+
self.temporary_address_address_line_4.fill(dict["address_line_4"])
178+
if "address_line_5" in dict:
179+
self.temporary_address_address_line_5.fill(dict["address_line_5"])
180+
181+
# Fill in the postcode
182+
if "postcode" in dict:
183+
self.temporary_address_postcode.fill(dict["postcode"])
184+
185+
# Click the update subject data button to save changes
186+
self.update_subject_data_button.click()

pages/screening_subject_search/subject_screening_summary_page.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ def __init__(self, page: Page):
5454
self.advance_fobt_screening_episode_button = self.page.get_by_role(
5555
"button", name="Advance FOBT Screening Episode"
5656
)
57+
self.temporary_address_icon = self.page.get_by_role(
58+
"link", name="The person has a current"
59+
)
60+
self.temporary_address_popup = self.page.locator("#idTempAddress")
61+
self.close_button = self.page.get_by_role("img", name="close")
5762

5863
def wait_for_page_title(self) -> None:
5964
"""Waits for the page to be the Subject Screening Summary"""
@@ -71,9 +76,7 @@ def verify_subject_search_results_title_subject_screening_summary(self) -> None:
7176

7277
def verify_subject_search_results_title_subject_search_results(self) -> None:
7378
"""Verify that the subject search results title contains 'Subject Search Results'."""
74-
self.bowel_cancer_screening_page_title_contains_text(
75-
"Subject Search Results"
76-
)
79+
self.bowel_cancer_screening_page_title_contains_text("Subject Search Results")
7780

7881
def get_latest_event_status_cell(self, latest_event_status: str) -> Locator:
7982
"""Get the latest event status cell by its name."""
@@ -192,6 +195,38 @@ def click_advance_fobt_screening_episode_button(self) -> None:
192195
except Exception as e:
193196
pytest.fail(f"Unable to advance the episode: {e}")
194197

198+
def verify_temporary_address_popup_visible(self) -> None:
199+
"""Verify that the temporary address popup is visible."""
200+
try:
201+
expect(self.temporary_address_popup).to_be_visible()
202+
logging.info("Temporary address popup is visible")
203+
except Exception as e:
204+
pytest.fail(f"Temporary address popup is not visible: {e}")
205+
206+
def click_temporary_address_icon(self) -> None:
207+
"""Click on the temporary address icon."""
208+
self.click(self.temporary_address_icon)
209+
210+
def verify_temporary_address_icon_visible(self) -> None:
211+
"""Verify that the temporary address icon is visible."""
212+
try:
213+
expect(self.temporary_address_icon).to_be_visible()
214+
logging.info("Temporary address icon is visible")
215+
except Exception as e:
216+
pytest.fail(f"Temporary address icon is not visible when it should be: {e}")
217+
218+
def verify_temporary_address_icon_not_visible(self) -> None:
219+
"""Verify that the temporary address icon is not visible."""
220+
try:
221+
expect(self.temporary_address_icon).not_to_be_visible()
222+
logging.info("Temporary address icon is not visible as expected")
223+
except Exception as e:
224+
pytest.fail(f"Temporary address icon is visible when it should not be: {e}")
225+
226+
def click_close_button(self) -> None:
227+
"""Click on the close button in the temporary address popup."""
228+
self.click(self.close_button)
229+
195230

196231
class ChangeScreeningStatusOptions(Enum):
197232
"""Enum for Change Screening Status options."""

pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ markers =
3939
vpn_required: for tests that require a VPN connection
4040
regression: tests that are part of the regression test suite
4141
call_and_recall: tests that are part of the call and recall test suite
42+
subject_tests: tests that are part of the subject tests suite
43+
subject_search: tests that are part of the subject search test suite

0 commit comments

Comments
 (0)