Skip to content

Commit 3d7f937

Browse files
Merge branch 'main' of github.com:NHSDigital/bcss-playwright into feature/BCSS-19549-playwright-compartment5-codegen
2 parents 434f238 + 0a2f6d5 commit 3d7f937

16 files changed

+302
-68
lines changed

pages/base_page.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from playwright.sync_api import Page, expect, Locator
1+
from playwright.sync_api import Page, expect, Locator, Dialog
22
import logging
33

44

@@ -167,3 +167,25 @@ def click(self, locator: Locator) -> None:
167167
f"Failed to click element with error: {locatorClickError}, trying again..."
168168
)
169169
locator.click()
170+
171+
def _accept_dialog(self, dialog: Dialog) -> None:
172+
"""
173+
This method is used to accept dialogs
174+
If it has already been accepted then it is ignored
175+
"""
176+
try:
177+
dialog.accept()
178+
except Exception:
179+
logging.warning("Dialog already handled")
180+
181+
def safe_accept_dialog(self, locator: Locator) -> None:
182+
"""
183+
Safely accepts a dialog triggered by a click, avoiding the error:
184+
playwright._impl._errors.Error: Dialog.accept: Cannot accept dialog which is already handled!
185+
If no dialog appears, continues without error.
186+
"""
187+
self.page.once("dialog", self._accept_dialog)
188+
try:
189+
self.click(locator)
190+
except Exception as e:
191+
logging.error(f"Click failed: {e}")

pages/gfobt_test_kits/gfobt_test_kit_logging_page.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pages.base_page import BasePage
33

44

5-
class TestKitLogging(BasePage):
5+
class GFOBTTestKitLogging(BasePage):
66
def __init__(self, page: Page):
77
super().__init__(page)
88
self.page = page

pages/gfobt_test_kits/gfobt_test_kit_quality_control_reading_page.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pages.base_page import BasePage
33

44

5-
class TestKitQualityControlReading(BasePage):
5+
class GFOBTTestKitQualityControlReading(BasePage):
66
def __init__(self, page: Page):
77
super().__init__(page)
88
self.page = page
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from playwright.sync_api import Page, expect
22
from pages.base_page import BasePage
3+
from utils.table_util import TableUtils
34

45

56
class BookAppointmentPage(BasePage):
@@ -9,24 +10,24 @@ def __init__(self, page: Page):
910
# Book Appointment - page locators
1011
self.screening_center_dropdown = page.locator("#UI_NEW_SCREENING_CENTRE")
1112
self.site_dropdown = page.locator("#UI_NEW_SITE")
12-
self.day_with_available_slots = page.locator(
13-
'input.twoColumnCalendar[style*="background-color: rgb(102, 255, 153);"]'
14-
).last
1513
self.appointment_time_radio_button = page.locator(
1614
page.get_by_role("radio", name="UI_NEW_SLOT_SELECTION_ID")
1715
)
1816
self.save_button = page.get_by_role("button", name="Save")
17+
self.appointments_table = TableUtils(self.page, "#displayRS")
18+
self.current_month_displayed = self.page.locator("#MONTH_AND_YEAR")
19+
20+
self.appointment_cell_locators = self.page.locator("input.twoColumnCalendar")
21+
self.available_background_colour = "rgb(102, 255, 153)"
22+
self.some_available_background_colour = "rgb(255, 220, 144)"
1923

2024
def select_screening_centre_dropdown_option(self, screening_centre: str) -> None:
2125
self.screening_center_dropdown.select_option(label=screening_centre)
2226

23-
def select_site_dropdown_option(self, screening_site: str) -> None:
27+
def select_site_dropdown_option(self, screening_site: str | list) -> None:
2428
self.site_dropdown.select_option(label=screening_site)
2529
self.site_dropdown.press("Enter")
2630

27-
def choose_day_with_available_slots(self) -> None:
28-
self.click(self.day_with_available_slots)
29-
3031
def choose_appointment_time(self) -> None:
3132
self.appointment_time_radio_button.check()
3233

@@ -35,3 +36,6 @@ def click_save_button(self) -> None:
3536

3637
def appointment_booked_confirmation_is_displayed(self, message: str) -> None:
3738
expect(self.page.get_by_text(message)).to_be_visible()
39+
40+
def get_current_month_displayed(self) -> str:
41+
return self.current_month_displayed.text_content()

pages/screening_practitioner_appointments/colonoscopy_assessment_appointments_page.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,22 @@ def __init__(self, page: Page):
88
self.page = page
99
# Colonoscopy Assessment Appointments - page locators
1010
self.page_header = self.page.locator("#page-title")
11+
self.page_header_with_title = self.page.locator(
12+
"#page-title",
13+
has_text="Patients that Require Colonoscopy Assessment Appointments",
14+
)
1115
self.nhs_number_filter_text_field = self.page.locator("#nhsNumberFilter")
1216

1317
def verify_page_header(self) -> None:
1418
expect(self.page_header).to_contain_text(
1519
"Patients that Require Colonoscopy Assessment Appointments"
1620
)
1721

22+
def wait_for_page_header(self) -> None:
23+
self.page_header_with_title.wait_for()
24+
1825
def filter_by_nhs_number(self, nhs_number: str) -> None:
26+
self.click(self.nhs_number_filter_text_field)
1927
self.nhs_number_filter_text_field.fill(nhs_number)
2028
self.nhs_number_filter_text_field.press("Enter")
2129

pages/screening_practitioner_appointments/screening_practitioner_appointments.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ def go_to_view_appointments_page(self) -> None:
3434

3535
def go_to_patients_that_require_page(self) -> None:
3636
self.click(self.patients_that_require_page)
37+
38+
def go_to_set_availability_page(self) -> None:
39+
self.click(self.set_availability_link)

pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ markers =
3232
compartment1: only for compartment 1
3333
compartment2: only for compartment 2
3434
compartment3: only for compartment 3
35+
compartment4: only for compartment 4
36+
compartment1_plan_creation: to run the plan creation for compartment 1
3537
vpn_required: for tests that require a VPN connection

tests/smokescreen/bcss_smokescreen_tests.properties

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,11 @@
2626
# ----------------------------------
2727
# compartment 4
2828
# ----------------------------------
29-
# c4_eng_org_id=23159
30-
# c4_eng_centre_name=Wolverhampton
31-
# c4_eng_site_name=Royal Hospital
32-
# c4_eng_practitioner_id=243
33-
# c4_eng_practitioner_name=Arvind, Vanaja
34-
# c4_eng_practitioner_name=Macarena, Gave #use this for anonymised
35-
# c4_eng_practitioner_id_for_rebooking=870
36-
# c4_eng_practitioner_name_for_rebookings=Burns, Harriet
29+
c4_eng_weeks_to_make_available = 6
30+
c4_eng_centre_name=BCS001 - Wolverhampton Bowel Cancer Screening Centre
31+
c4_eng_site_name1=THE ROYAL HOSPITAL (WOLVERHAMPTON)
32+
c4_eng_site_name2=The Royal Hospital (Wolverhampton)
33+
c4_eng_practitioner_name=Astonish, Ethanol
3734

3835
# ----------------------------------
3936
# compartment 6
@@ -76,7 +73,7 @@
7673
# compartment 4
7774
# ----------------------------------
7875
# # note there is a max of 16 slots available each day
79-
# c4_eng_number_of_appointments_to_book=6
76+
c4_eng_number_of_appointments_to_book=6
8077

8178
# ----------------------------------
8279
# compartment 5

tests/smokescreen/test_compartment_4.py

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
from utils.calendar_picker import CalendarPicker
2929
from utils.batch_processing import batch_processing
3030
from datetime import datetime
31+
from utils.oracle.oracle_specific_functions import get_subjects_for_appointments
32+
from utils.nhs_number_tools import NHSNumberTools
33+
import logging
3134

3235

3336
@pytest.fixture
@@ -48,67 +51,92 @@ def test_compartment_4(page: Page, smokescreen_properties: dict) -> None:
4851
Finally it processes the necessary batches to send out the letters and checks the subjects satus has been updated to what is expected
4952
"""
5053

51-
# Add method of getting test data using the query below. To remove once subject retrieval logic is created
52-
"""select tk.kitid, ss.subject_nhs_number, se.screening_subject_id
53-
from tk_items_t tk
54-
inner join ep_subject_episode_t se on se.screening_subject_id = tk.screening_subject_id
55-
inner join screening_subject_t ss on ss.screening_subject_id = se.screening_subject_id
56-
inner join sd_contact_t c on c.nhs_number = ss.subject_nhs_number
57-
where se.latest_event_status_id = 11132
58-
and tk.logged_in_flag = 'Y'
59-
and se.episode_status_id = 11352
60-
and ss.screening_status_id != 4008
61-
and tk.logged_in_at = 23159
62-
and c.hub_id = 23159
63-
and tk.tk_type_id = 2
64-
and tk.datestamp > add_months(sysdate,-24)
65-
order by ss.subject_nhs_number desc"""
54+
subjects_df = get_subjects_for_appointments(
55+
smokescreen_properties["c4_eng_number_of_appointments_to_book"]
56+
)
6657

58+
logging.info(
59+
f"Compartment 4 - Setting up appointments for {smokescreen_properties["c4_eng_weeks_to_make_available"]} Weeks"
60+
)
6761
UserTools.user_login(page, "Screening Centre Manager at BCS001")
6862
BasePage(page).go_to_screening_practitioner_appointments_page()
6963
ScreeningPractitionerAppointmentsPage(page).go_to_set_availability_page()
7064
SetAvailabilityPage(page).go_to_practitioner_availability_page()
7165
PractitionerAvailabilityPage(page).select_site_dropdown_option(
72-
"THE ROYAL HOSPITAL (WOLVERHAMPTON)"
66+
smokescreen_properties["c4_eng_site_name1"]
7367
)
7468
PractitionerAvailabilityPage(page).select_practitioner_dropdown_option(
75-
"Astonish, Ethanol"
69+
smokescreen_properties["c4_eng_practitioner_name"]
7670
)
7771
PractitionerAvailabilityPage(page).click_calendar_button()
78-
CalendarPicker(page).select_day(
79-
datetime.today()
80-
) # This will make it so that we can only run this test once a day, or we need to restore the DB back to the snapshot
72+
CalendarPicker(page).select_day(datetime.today())
8173
PractitionerAvailabilityPage(page).click_show_button()
8274
PractitionerAvailabilityPage(page).enter_start_time("09:00")
8375
PractitionerAvailabilityPage(page).enter_end_time("17:15")
8476
PractitionerAvailabilityPage(page).click_calculate_slots_button()
85-
PractitionerAvailabilityPage(page).enter_number_of_weeks("6")
77+
PractitionerAvailabilityPage(page).enter_number_of_weeks(
78+
smokescreen_properties["c4_eng_weeks_to_make_available"]
79+
)
8680
PractitionerAvailabilityPage(page).click_save_button()
8781
PractitionerAvailabilityPage(page).slots_updated_message_is_displayed(
88-
"Slots Updated for 6 Weeks"
82+
f"Slots Updated for {smokescreen_properties["c4_eng_weeks_to_make_available"]} Weeks"
8983
)
9084
Logout(page).log_out(close_page=False)
9185

86+
logging.info(
87+
f"Compartment 4 - Booking {smokescreen_properties["c4_eng_number_of_appointments_to_book"]} subjects to appointments"
88+
)
9289
ScreeningPractitionerAppointmentsPage(page).go_to_log_in_page()
9390
UserTools.user_login(page, "Hub Manager State Registered at BCS01")
91+
9492
BasePage(page).go_to_screening_practitioner_appointments_page()
9593
ScreeningPractitionerAppointmentsPage(page).go_to_patients_that_require_page()
96-
# Add for loop to loop x times (depends on how many we want to run it for) 70 - 79
97-
ColonoscopyAssessmentAppointments(page).filter_by_nhs_number("999 205 6339")
98-
ColonoscopyAssessmentAppointments(page).click_nhs_number_link("999 205 6339")
99-
BookAppointmentPage(page).select_screening_centre_dropdown_option(
100-
"BCS001 - Wolverhampton Bowel Cancer Screening Centre"
101-
)
102-
BookAppointmentPage(page).select_site_dropdown_option("Holly Hall Clinic (? km)")
103-
BookAppointmentPage(page).choose_day_with_available_slots()
104-
# page.locator("#UI_NEW_SLOT_SELECTION_ID_359119").check()
105-
# Will be revisited as part of Utilities update
106-
BookAppointmentPage(page).choose_appointment_time()
107-
BookAppointmentPage(page).click_save_button()
108-
BookAppointmentPage(page).appointment_booked_confirmation_is_displayed(
109-
"Appointment booked"
110-
)
11194

95+
for subject_num in range(
96+
int(smokescreen_properties["c4_eng_number_of_appointments_to_book"])
97+
):
98+
nhs_number = subjects_df["subject_nhs_number"].iloc[subject_num]
99+
logging.info(f"Booking appointment for: {nhs_number}")
100+
101+
nhs_number_spaced = NHSNumberTools().spaced_nhs_number(nhs_number)
102+
ColonoscopyAssessmentAppointments(page).filter_by_nhs_number(nhs_number)
103+
ColonoscopyAssessmentAppointments(page).click_nhs_number_link(nhs_number_spaced)
104+
BookAppointmentPage(page).select_screening_centre_dropdown_option(
105+
smokescreen_properties["c4_eng_centre_name"]
106+
)
107+
BookAppointmentPage(page).select_site_dropdown_option(
108+
[
109+
f"{smokescreen_properties["c4_eng_site_name2"]} (? km)",
110+
f"{smokescreen_properties["c4_eng_site_name2"]} (? km) (attended)",
111+
]
112+
)
113+
114+
current_month_displayed = BookAppointmentPage(
115+
page
116+
).get_current_month_displayed()
117+
CalendarPicker(page).book_first_eligble_appointment(
118+
current_month_displayed,
119+
BookAppointmentPage(page).appointment_cell_locators,
120+
[
121+
BookAppointmentPage(page).available_background_colour,
122+
BookAppointmentPage(page).some_available_background_colour,
123+
],
124+
)
125+
BookAppointmentPage(page).appointments_table.click_first_input_in_column(
126+
"Appt/Slot Time"
127+
)
128+
BasePage(page).safe_accept_dialog(BookAppointmentPage(page).save_button)
129+
try:
130+
BookAppointmentPage(page).appointment_booked_confirmation_is_displayed(
131+
"Appointment booked"
132+
)
133+
logging.info(f"Appointment successfully booked for: {nhs_number}")
134+
except Exception as e:
135+
pytest.fail(f"Appointment not booked successfully: {e}")
136+
BasePage(page).click_back_button()
137+
ColonoscopyAssessmentAppointments(page).wait_for_page_header()
138+
139+
logging.info("Compartment 4 - Sending out appointment invitations")
112140
batch_processing(
113141
page,
114142
"A183",

tests/test_gfobt_test_kits_page.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
from pages.base_page import BasePage
55
from pages.gfobt_test_kits.gfobt_test_kits_page import GFOBTTestKits
6-
from pages.gfobt_test_kits.gfobt_test_kit_logging_page import TestKitLogging
6+
from pages.gfobt_test_kits.gfobt_test_kit_logging_page import GFOBTTestKitLogging
77
from pages.gfobt_test_kits.gfobt_test_kit_quality_control_reading_page import (
8-
TestKitQualityControlReading,
8+
GFOBTTestKitQualityControlReading,
99
)
1010
from pages.gfobt_test_kits.gfobt_view_test_kit_result import ViewTestKitResult
1111
from pages.gfobt_test_kits.gfobt_create_qc_kit_page import (
@@ -27,6 +27,7 @@ def before_each(page: Page):
2727
# Go to gFOBT test kits page
2828
BasePage(page).go_to_gfobt_test_kits_page()
2929

30+
3031
@pytest.mark.smoke
3132
def test_gfobt_test_kit_page_navigation(page: Page) -> None:
3233
"""
@@ -35,12 +36,12 @@ def test_gfobt_test_kit_page_navigation(page: Page) -> None:
3536
"""
3637
# Test kit logging page opens as expected
3738
GFOBTTestKits(page).go_to_test_kit_logging_page()
38-
TestKitLogging(page).verify_test_kit_logging_title()
39+
GFOBTTestKitLogging(page).verify_test_kit_logging_title()
3940
BasePage(page).click_back_button()
4041

4142
# Test kit reading page opens as expected
4243
GFOBTTestKits(page).go_to_test_kit_reading_page()
43-
TestKitQualityControlReading(page).verify_test_kit_logging_tile()
44+
GFOBTTestKitQualityControlReading(page).verify_test_kit_logging_tile()
4445
BasePage(page).click_back_button()
4546

4647
# View test kit result page opens as expected

0 commit comments

Comments
 (0)