Skip to content

Commit ee3caf2

Browse files
committed
Merge branch 'feature/BCSS-20574-investigate-use-of-ai-to-assist-code-conversion' into feature/BCSS-20580-selenium-to-playwright-call-and-recall
I started working on call and recall as part of the investigate ai... ticket. Merging into new branch to better link it to the jira ticket for this work
2 parents 6d0a049 + be92907 commit ee3caf2

File tree

9 files changed

+422
-0
lines changed

9 files changed

+422
-0
lines changed

pages/call_and_recall/create_a_plan_page.py

Lines changed: 69 additions & 0 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 CreateAPlanPage(BasePage):
@@ -23,6 +24,19 @@ def __init__(self, page: Page):
2324
self.save_note_button = self.page.locator("#saveNote").get_by_role(
2425
"button", name="Save"
2526
)
27+
# Create A Plan Table Locators
28+
self.weekly_invitation_rate_field_on_table = self.page.locator(
29+
"#invitationRateField"
30+
)
31+
self.invitations_sent_value = self.page.locator(
32+
"#invitationPlan > tbody > tr:nth-child(1) > td:nth-child(8)"
33+
)
34+
self.resulting_position_value = self.page.locator(
35+
"#invitationPlan > tbody > tr:nth-child(1) > td:nth-child(9)"
36+
)
37+
38+
# Initialize TableUtils for different tables
39+
self.create_a_plan_table = TableUtils(page, "#invitationPlan")
2640

2741
def click_set_all_button(self) -> None:
2842
"""Clicks the Set all button to set all values"""
@@ -59,3 +73,58 @@ def click_save_note_button(self) -> None:
5973
def verify_create_a_plan_title(self) -> None:
6074
"""Verifies the Create a Plan page title"""
6175
self.bowel_cancer_screening_page_title_contains_text("View a plan")
76+
77+
def verify_weekly_invitation_rate_for_weeks(
78+
self, start_week: int, end_week: int, expected_weekly_rate: str
79+
) -> None:
80+
"""
81+
Verifies that the weekly invitation rate is correctly calculated and displayed for the specified range of weeks.
82+
83+
Args:
84+
start_week (int): The starting week of the range.
85+
end_week (int): The ending week of the range.
86+
expected_weekly_rate (str): The expected weekly invitation rate.
87+
"""
88+
# Get the current weekly invitation rate for the starting week
89+
weekly_invitation_rate = self.page.query_selector_all(
90+
"css:nth-child(" + str(start_week) + ") .text"
91+
)[0].inner_text()
92+
assert (
93+
weekly_invitation_rate == expected_weekly_rate
94+
), f"Expected weekly invitation rate '{expected_weekly_rate}' for week {start_week} but got '{weekly_invitation_rate}'"
95+
96+
# Verify the rate for the specified range of weeks
97+
for week in range(start_week + 1, end_week + 1):
98+
weekly_rate_locator = f".week-{week} .text"
99+
assert (
100+
self.page.query_selector_all(weekly_rate_locator)[0].inner_text()
101+
== expected_weekly_rate
102+
), f"Week {week} invitation rate should be '{expected_weekly_rate}', but found '{self.page.query_selector_all(weekly_rate_locator)[0].inner_text()}'"
103+
104+
def increment_invitation_rate_and_verify_changes(self) -> None:
105+
"""
106+
Increments the invitation rate by 1, then verifies that both the 'Invitations Sent' and 'Resulting Position' have increased by 1.
107+
"""
108+
# Get the current value of the Weekly Invitation Rate field
109+
current_value = int(
110+
self.create_a_plan_table.get_cell_value("Invitation Rate", 0)
111+
)
112+
# Increments by 1, fills the field with the new value, and Tabs out of the field
113+
new_value = str(current_value + 1)
114+
locator = self.weekly_invitation_rate_field_on_table
115+
locator.fill(new_value)
116+
locator.press("Tab")
117+
118+
# Verifies 'Invitations Sent' has increased by 1
119+
initial_invitations_sent = int(self.invitations_sent_value.inner_text())
120+
assert (
121+
int(self.invitations_sent_value.inner_text())
122+
== initial_invitations_sent + 1
123+
), "Invitations Sent did not increase by 1."
124+
125+
# Verifies 'Resulting Position' has increased by 1
126+
initial_resulting_position = int(self.resulting_position_value.inner_text())
127+
assert (
128+
int(self.resulting_position_value.inner_text())
129+
== initial_resulting_position - 1
130+
), "Resulting Position did not decrease by 1."

pages/call_and_recall/non_invitations_days_page.py

Lines changed: 48 additions & 0 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.date_time_utils import DateTimeUtils
34

45

56
class NonInvitationDaysPage(BasePage):
@@ -9,7 +10,54 @@ def __init__(self, page: Page):
910
super().__init__(page)
1011
self.page = page
1112
# Non Invitation Days - page locators, methods
13+
self.enter_note_field = self.page.get_by_role("textbox", name="note")
14+
self.enter_date_field = self.page.get_by_role("textbox", name="date")
15+
self.add_non_invitation_day_button = self.page.get_by_role(
16+
"button", name="Add Non-Invitation Day"
17+
)
18+
self.non_invitation_day_delete_button = self.page.get_by_role(
19+
"button", name="Delete"
20+
)
21+
self.created_on_date_locator = self.page.locator("#displayRS")
1222

1323
def verify_non_invitation_days_tile(self) -> None:
1424
"""Verifies the page title of the Non Invitation Days page"""
1525
self.bowel_cancer_screening_page_title_contains_text("Non-Invitation Days")
26+
27+
def enter_date(self, date: str) -> None:
28+
"""Enters a date in the date input field
29+
Args:
30+
date (str): The date to enter in the field, formatted as 'dd/mm/yyyy'.
31+
"""
32+
self.enter_date_field.fill(date)
33+
34+
def enter_note(self, note: str) -> None:
35+
"""Enters a note in the note input field
36+
Args:
37+
note (str): The note to enter in the field.
38+
"""
39+
self.enter_note_field.fill(note)
40+
41+
def click_add_non_invitation_day_button(self) -> None:
42+
"""Clicks the Add Non-Invitation Day button"""
43+
self.click(self.add_non_invitation_day_button)
44+
45+
def click_delete_button(self) -> None:
46+
"""Clicks the Delete button for a non-invitation day"""
47+
self.click(self.non_invitation_day_delete_button)
48+
49+
def verify_date_is_visible(self) -> None:
50+
"""Verifies that the specified date is visible on the page
51+
Args:
52+
date (str): The date to verify, formatted as 'dd/mm/yyyy'.
53+
"""
54+
date = DateTimeUtils.current_datetime("dd/mm/yyyy")
55+
expect(self.created_on_date_locator).to_have_text(date)
56+
57+
def verify_date_is_not_visible(self) -> None:
58+
"""Verifies that the specified date is not visible on the page
59+
Args:
60+
date (str): The date to verify, formatted as 'dd/mm/yyyy'.
61+
"""
62+
date = DateTimeUtils.current_datetime("dd/mm/yyyy")
63+
expect(self.created_on_date_locator).not_to_have_text(date)

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ markers =
3737
compartment6: only for compartment 6
3838
compartment1_plan_creation: to run the plan creation for compartment 1
3939
vpn_required: for tests that require a VPN connection
40+
regression: tests that are part of the regression test suite

tests/bcss_tests.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ forename=Pentagram
2121
surname=Absurd
2222
subject_dob=11/01/1934
2323
episode_closed_date=22/09/2020
24+
25+
# ----------------------------------
26+
# CALL AND RECALL TEST DATA
27+
# ----------------------------------
28+
daily_invitation_rate=28
29+
weekly_invitation_rate=28
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import pytest
2+
from playwright.sync_api import Page
3+
from pages.base_page import BasePage
4+
from pages.call_and_recall.call_and_recall_page import CallAndRecallPage
5+
from pages.call_and_recall.invitations_monitoring_page import InvitationsMonitoringPage
6+
from pages.call_and_recall.invitations_plans_page import InvitationsPlansPage
7+
from pages.call_and_recall.create_a_plan_page import CreateAPlanPage
8+
from utils.user_tools import UserTools
9+
10+
11+
@pytest.fixture(scope="function", autouse=True)
12+
def before_each(page: Page):
13+
"""
14+
Before every test is executed, this fixture logs in to BCSS as a test user and navigates to the call and recall page
15+
"""
16+
# Log in to BCSS
17+
UserTools.user_login(page, "Hub Manager State Registered at BCS01")
18+
19+
# Go to call and recall page
20+
BasePage(page).go_to_call_and_recall_page()
21+
22+
23+
@pytest.mark.regression
24+
@pytest.mark.call_and_recall
25+
def test_set_create_a_plan_daily_rate(page: Page, general_properties: dict) -> None:
26+
"""
27+
Verifies that a user is able to click on the Set all button and enter a daily rate.
28+
"""
29+
# When I go to "Invitations Monitoring - Screening Centre"
30+
CallAndRecallPage(page).go_to_planning_and_monitoring_page()
31+
32+
# And I click the link text "BCS001"
33+
InvitationsMonitoringPage(page).go_to_invitation_plan_page(
34+
general_properties["screening_centre_code"]
35+
)
36+
# And I click the "Create a Plan" button
37+
InvitationsPlansPage(page).go_to_create_a_plan_page()
38+
39+
# And I click the set all button
40+
CreateAPlanPage(page).click_set_all_button()
41+
42+
# And I enter "28" in the input box with id "dailyRate"
43+
CreateAPlanPage(page).fill_daily_invitation_rate_field(
44+
general_properties["daily_invitation_rate"]
45+
)
46+
47+
# And I click the "Update" button
48+
CreateAPlanPage(page).click_update_button()
49+
50+
# And I click the "Save" button
51+
CreateAPlanPage(page).click_save_button()
52+
53+
# Then the Weekly Invitation Rate for weeks 1 to 83 is set correctly
54+
# based on a set all daily rate of 28
55+
CreateAPlanPage(page).verify_weekly_invitation_rate_for_weeks(1, 83, "28")
56+
57+
58+
@pytest.mark.regression
59+
@pytest.mark.call_and_recall
60+
def test_create_invitation_plan_weekly_rate(
61+
page: Page, general_properties: dict
62+
) -> None:
63+
"""
64+
Verifies that a user can set a weekly invitation rate in Create a Plan.
65+
"""
66+
67+
# When I go to "Invitations Monitoring - Screening Centre"
68+
CallAndRecallPage(page).go_to_planning_and_monitoring_page()
69+
70+
# And I click the link text "BCS001"
71+
InvitationsMonitoringPage(page).go_to_invitation_plan_page(
72+
general_properties["screening_centre_code"]
73+
)
74+
# And I click the "Create a Plan" button
75+
InvitationsPlansPage(page).go_to_create_a_plan_page()
76+
77+
# And I click the set all button
78+
CreateAPlanPage(page).click_set_all_button()
79+
80+
# And I enter "130" in the input box with id "weeklyRate"
81+
CreateAPlanPage(page).fill_weekly_invitation_rate_field(
82+
general_properties["weekly_invitation_rate"]
83+
)
84+
85+
# And I click the "Update" button
86+
CreateAPlanPage(page).click_update_button()
87+
88+
# And I click the "Save" button
89+
CreateAPlanPage(page).click_save_button()
90+
91+
# And the Weekly Invitation Rate for weeks 1 to 83 is set to the set all weekly rate of 130
92+
CreateAPlanPage(page).verify_weekly_invitation_rate_for_weeks(1, 83, "130")
93+
94+
95+
@pytest.mark.regression
96+
@pytest.mark.call_and_recall
97+
def test_update_invitation_rate_weekly(page: Page, tests_properties: dict) -> None:
98+
"""
99+
Verifies that a Hub Manager State Registered is able to update a weekly Invitation rate
100+
and the Cumulative 'Invitations sent' and 'Resulting Position' values are updated.
101+
"""
102+
103+
# When I go to "Invitations Monitoring - Screening Centre"
104+
CallAndRecallPage(page).go_to_planning_and_monitoring_page()
105+
106+
# And I click the link text "BCS001"
107+
InvitationsMonitoringPage(page).go_to_invitation_plan_page(
108+
tests_properties["screening_centre_code"]
109+
)
110+
111+
# And I click the "Create a Plan" button
112+
InvitationsPlansPage(page).go_to_create_a_plan_page()
113+
114+
# When I increase the Weekly Invitation Rate for week 1 by 1 and tab out of the cell
115+
# Then the Cumulative Invitations Sent is incremented by 1 for week 1
116+
# And the Cumulative Resulting Position is incremented by 1 for week 1
117+
CreateAPlanPage(page).increment_invitation_rate_and_verify_changes()
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
from playwright.sync_api import Page
3+
from pages.base_page import BasePage
4+
from pages.call_and_recall.call_and_recall_page import CallAndRecallPage
5+
from pages.call_and_recall.invitations_monitoring_page import InvitationsMonitoringPage
6+
from pages.call_and_recall.generate_invitations_page import GenerateInvitationsPage
7+
from pages.call_and_recall.non_invitations_days_page import NonInvitationDaysPage
8+
from pages.call_and_recall.invitations_plans_page import InvitationsPlansPage
9+
from pages.call_and_recall.create_a_plan_page import CreateAPlanPage
10+
from utils.user_tools import UserTools
11+
12+
13+
@pytest.fixture(scope="function", autouse=True)
14+
def before_each(page: Page):
15+
"""
16+
Before every test is executed, this fixture logs in to BCSS as a test user and navigates to the call and recall page
17+
"""
18+
# Log in to BCSS
19+
UserTools.user_login(page, "Hub Manager at BCS01")
20+
21+
# Go to call and recall page
22+
BasePage(page).go_to_call_and_recall_page()
23+
24+
25+
# Scenario: Run FOBT invitations and process the S1 letter batch
26+
# Many feature scenarios need a subject at S9.
27+
# When I generate invitations
28+
# And I view the active batch list
29+
# And I view the "Original" type "Open" status active letter batch for "S1" "Pre-invitation (FIT)"
30+
# And I prepare the letter batch
31+
# And I retrieve and confirm the letters
32+
# Then there is a subject who meets the following criteria:
33+
# | Latest episode kit class | FIT |
34+
# | Latest event status | S9 |
35+
# | Latest episode type | FOBT |
36+
# | Subject hub code | BCS01 |
37+
38+
# Scenario: User generates invitations for screening episodes (#3)
39+
# # Version copied from now-deleted UserPathway.feature - duplicate steps etc need to be sorted out
40+
# Given I log in to BCSS "England" as user role "Hub Manager - State Registered"
41+
# When I navigate to the Call and Recall > Generate Invitations Page
42+
# And I press the Generate Invitations button and generate invitations
43+
# Then Invitations are successfully generated
44+
45+
46+
@pytest.mark.regression
47+
@pytest.mark.call_and_recall
48+
def test_generate_fobt_invitations(page: Page) -> None:
49+
"""
50+
Verifies that a user can generate FOBT invitations and process the S1 letter batch.
51+
"""
52+
CallAndRecallPage(page).go_to_generate_invitations_page()
53+
GenerateInvitationsPage(page).click_generate_invitations_button()
54+
55+
GenerateInvitationsPage(page).view_active_batch_list()
56+
GenerateInvitationsPage(page).view_original_open_status_batch(
57+
"S1", "Pre-invitation (FIT)"
58+
)
59+
GenerateInvitationsPage(page).prepare_letter_batch()
60+
GenerateInvitationsPage(page).retrieve_and_confirm_letters()
61+
62+
GenerateInvitationsPage(page).verify_subject_meets_criteria(
63+
kit_class="FIT", event_status="S9", episode_type="FOBT", hub_code="BCS01"
64+
)

0 commit comments

Comments
 (0)