Skip to content

Commit de63e84

Browse files
adrianoaru-nhsAndyg79
authored andcommitted
Feature/bcss 21278 selenium to playwright regression test setup (#121)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> Migrating the scenarios from RegressionTestSetupSteps.feature in the playwright repo ## Context <!-- Why is this change required? What problem does it solve? --> Migrating the scenarios from RegressionTestSetupSteps.feature in the playwright repo ## 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 4e4fedb commit de63e84

File tree

8 files changed

+417
-32
lines changed

8 files changed

+417
-32
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from playwright.sync_api import Page
2+
from pages.base_page import BasePage
3+
from utils.table_util import TableUtils
4+
5+
6+
class EditContactPage(BasePage):
7+
"""Edit Contact Page locators, and methods for interacting with the page"""
8+
9+
def __init__(self, page: Page):
10+
super().__init__(page)
11+
self.page = page
12+
# Edit Contact - page locators, methods
13+
self.view_resect_and_discard_link = self.page.get_by_role(
14+
"link", name="View Resect and Discard"
15+
)
16+
17+
self.edit_contact_table = TableUtils(self.page, "#displayRS")
18+
19+
def click_view_resect_and_discard_link(self) -> None:
20+
"""Clicks on the 'View Resect and Discard' link"""
21+
self.click(self.view_resect_and_discard_link)
22+
23+
def assert_value_for_label_in_edit_contact_table(
24+
self, label_text: str, expected_text: str
25+
) -> None:
26+
"""
27+
Asserts that the vlaue for a label is as expected in the edit contact table
28+
29+
Args:
30+
label_text (str): The label text to look for in the first cell of a row.
31+
expected_text (str): The text expected inside the adjacent cell.
32+
"""
33+
self.edit_contact_table.verify_value_for_label(label_text, expected_text)

pages/contacts_list/maintain_contacts_page.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from playwright.sync_api import Page, expect
1+
from playwright.sync_api import Page
22
from pages.base_page import BasePage
3+
from utils.table_util import TableUtils
34

45

56
class MaintainContactsPage(BasePage):
@@ -10,6 +11,57 @@ def __init__(self, page: Page):
1011
self.page = page
1112
# Maintain Contacts - page locators, methods
1213

14+
self.surname_input_field = self.page.locator("#selPersonSurname")
15+
self.forenames_input_field = self.page.locator("#selPersonForenames")
16+
self.user_code_input_field = self.page.locator("#selUserCode")
17+
self.search_button = self.page.get_by_role("button", name="Search")
18+
19+
self.search_table = TableUtils(self.page, "#displayRS")
20+
1321
def verify_maintain_contacts_title(self) -> None:
1422
"""Verify the Maintain Contacts page title is displayed correctly"""
1523
self.bowel_cancer_screening_page_title_contains_text("Maintain Contacts")
24+
25+
def fill_surname_input_field(self, surname: str) -> None:
26+
"""
27+
Fill the surname input field with the provided surname
28+
Args:
29+
surname (str): The surname of the subject
30+
"""
31+
self.surname_input_field.fill(surname)
32+
33+
def fill_forenames_input_field(self, forenames: str) -> None:
34+
"""
35+
Fill the forenames input field with the provided forenames
36+
Args:
37+
forenames (str): The forenames of the subject
38+
"""
39+
self.forenames_input_field.fill(forenames)
40+
41+
def fill_user_code_input_field(self, user_code: str) -> None:
42+
"""
43+
Fill the user code input field with the provided user code
44+
Args:
45+
user_code (str): The user code of the subject
46+
"""
47+
self.user_code_input_field.fill(user_code)
48+
49+
def click_search_button(self) -> None:
50+
"""Click the search button to perform a search"""
51+
self.click(self.search_button)
52+
53+
def click_person_link_from_surname(self, surname: str) -> None:
54+
"""
55+
Clicks on the link containing the person's surname to go to the edit contact page
56+
Args:
57+
surname (str): The surname of the subject
58+
"""
59+
self.click(self.page.get_by_role("link", name=surname).last)
60+
61+
def click_person_link_from_forename(self, forename: str) -> None:
62+
"""
63+
Clicks on the link containing the person's surname to go to the edit contact page
64+
Args:
65+
forename (str): The forename of the subject
66+
"""
67+
self.click(self.page.get_by_role("link", name=forename).last)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from playwright.sync_api import Page, expect
2+
from datetime import datetime
3+
from pages.base_page import BasePage
4+
from utils.calendar_picker import CalendarPicker
5+
6+
7+
class ResectAndDiscardAccreditationHistoryPage(BasePage):
8+
"""Resect And Discard Accreditation History 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+
# Resect And Discard Accreditation History - page locators, methods
14+
self.heading = self.page.get_by_role("heading", name="Resect and Discard")
15+
self.add_accreditation_button = self.page.get_by_role(
16+
"button", name="+ Add Accreditation"
17+
)
18+
self.save_button = self.page.get_by_role("button", name="Save")
19+
self.changes_saved_text = self.page.get_by_text("×Saved Changes")
20+
21+
def verify_heading_is_correct(self) -> None:
22+
"""Verifies the heading is visible and contains 'View Resect and Discard'"""
23+
expect(self.heading).to_be_visible()
24+
25+
def verify_add_accreditation_button_exists(self) -> None:
26+
"""Verifies that the 'Add Accreditation' button exists"""
27+
expect(self.add_accreditation_button).to_be_visible()
28+
29+
def click_add_accreditation_button(self) -> None:
30+
"""Clicks the 'Add Accreditation' button"""
31+
self.click(self.add_accreditation_button)
32+
33+
def click_save_button(self) -> None:
34+
"""Clicks the 'Save' button"""
35+
self.click(self.save_button)
36+
37+
def verify_changes_saved(self) -> None:
38+
"""Verifies the new period added has been saved"""
39+
expect(self.changes_saved_text).to_be_visible()
40+
41+
def add_new_period_of_resect_and_discard_accerditation(
42+
self, date: datetime
43+
) -> None:
44+
"""
45+
Adds a new period of resect and discard accreditation
46+
Args:
47+
date (datetime): The date the period starts
48+
"""
49+
self.click_add_accreditation_button()
50+
CalendarPicker(self.page).v2_calendar_picker(date)
51+
self.click_save_button()
52+
self.verify_changes_saved()
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import pytest
2+
import logging
3+
from datetime import datetime, timedelta
4+
from dateutil.relativedelta import relativedelta
5+
from playwright.sync_api import Page
6+
from pages.base_page import BasePage
7+
from pages.contacts_list.contacts_list_page import ContactsListPage
8+
from pages.contacts_list.maintain_contacts_page import MaintainContactsPage
9+
from pages.contacts_list.edit_contact_page import EditContactPage
10+
from pages.contacts_list.resect_and_discard_accreditation_history_page import (
11+
ResectAndDiscardAccreditationHistoryPage,
12+
)
13+
from pages.logout.log_out_page import LogoutPage
14+
from utils.user_tools import UserTools
15+
from utils.oracle.oracle_specific_functions import (
16+
set_org_parameter_value,
17+
check_parameter,
18+
build_accredited_screening_colonoscopist_query,
19+
get_accredited_screening_colonoscopist_in_bcs001,
20+
)
21+
22+
23+
def test_allow_10_minute_colonsocopy_assessment_appointments(
24+
page: Page, general_properties: dict
25+
) -> None:
26+
"""
27+
Scenario: 1: Allow 10 minute colonoscopy assessment appointments between 7am and 8pm at BCS001
28+
29+
Given I log in to BCSS "England" as user role "Screening Centre Manager"
30+
And I set the value of parameter 12 to "10" for my organisation with immediate effect
31+
And I set the value of parameter 28 to "07:00" for my organisation with immediate effect
32+
And I set the value of parameter 29 to "20:00" for my organisation with immediate effect
33+
"""
34+
UserTools.user_login(page, "Screening Centre Manager at BCS001")
35+
org_id = general_properties["eng_screening_centre_id"]
36+
param_12_set_correctly = check_parameter(12, org_id, "10")
37+
param_28_set_correctly = check_parameter(28, org_id, "07:00")
38+
param_29_set_correctly = check_parameter(29, org_id, "20:00")
39+
if not param_12_set_correctly:
40+
set_org_parameter_value(12, "10", org_id)
41+
if not param_28_set_correctly:
42+
set_org_parameter_value(28, "07:00", org_id)
43+
if not param_29_set_correctly:
44+
set_org_parameter_value(29, "20:00", org_id)
45+
46+
LogoutPage(page).log_out()
47+
48+
49+
def test_asc_with_current_resect_and_discard_accreditation(
50+
page: Page,
51+
) -> None:
52+
"""
53+
Scenario: 2: Ensure there is an Accredited Screening Colonoscopist with current Resect & Discard accreditation
54+
"""
55+
UserTools.user_login(page, "BCSS Bureau Staff at X26")
56+
57+
current_df = build_accredited_screening_colonoscopist_query("Current")
58+
if current_df.empty:
59+
pytest.skip(
60+
"No Accredited Screening Colonoscopist with current Resect & Discard accreditation found."
61+
)
62+
expired_df = build_accredited_screening_colonoscopist_query("Expiring soon")
63+
if expired_df.empty:
64+
pytest.skip(
65+
"No Accredited Screening Colonoscopist with expiring Resect & Discard accreditation found."
66+
)
67+
person_df = get_accredited_screening_colonoscopist_in_bcs001()
68+
if person_df.empty:
69+
pytest.fail("No Accredited Screening Colonoscopist found in the database.")
70+
71+
BasePage(page).go_to_contacts_list_page()
72+
ContactsListPage(page).go_to_maintain_contacts_page()
73+
74+
surname = person_df.iloc[0]["person_family_name"]
75+
forename = person_df.iloc[0]["person_given_name"]
76+
MaintainContactsPage(page).fill_surname_input_field(surname)
77+
MaintainContactsPage(page).fill_forenames_input_field(forename)
78+
MaintainContactsPage(page).click_search_button()
79+
MaintainContactsPage(page).click_person_link_from_surname(surname)
80+
81+
EditContactPage(page).click_view_resect_and_discard_link()
82+
ResectAndDiscardAccreditationHistoryPage(page).verify_heading_is_correct()
83+
ResectAndDiscardAccreditationHistoryPage(
84+
page
85+
).verify_add_accreditation_button_exists()
86+
yesterday = datetime.today() - timedelta(days=1)
87+
ResectAndDiscardAccreditationHistoryPage(
88+
page
89+
).add_new_period_of_resect_and_discard_accerditation(date=yesterday)
90+
91+
BasePage(page).click_back_button()
92+
end_date = yesterday + relativedelta(years=2)
93+
EditContactPage(page).assert_value_for_label_in_edit_contact_table(
94+
"Resect & Discard Accreditation?",
95+
f"Current: ends {end_date.strftime('%d/%m/%Y')}",
96+
)
97+
logging.info(f"Test person used in this scenario is: {forename} {surname}")

tests/regression/subject/episodes/datasets/investigation/endoscopy/polypcategories/test_setup.py

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
update_kit_service_management_entity,
5151
execute_fit_kit_stored_procedures,
5252
set_org_parameter_value,
53-
get_org_parameter_value,
53+
check_parameter,
5454
)
5555
from utils.oracle.subject_selection_query_builder import SubjectSelectionQueryBuilder
5656
from utils.screening_subject_page_searcher import (
@@ -173,30 +173,6 @@ def test_setup_subjects_as_a259(page: Page, subjects_to_run_for: int) -> None:
173173
LogoutPage(page).log_out()
174174

175175

176-
def check_parameter(param_id: int, org_id: str, expected_param_value: str) -> bool:
177-
"""
178-
Check if the organization parameter is set correctly.
179-
Args:
180-
param_id (int): The ID of the parameter to check.
181-
org_id (str): The ID of the organization.
182-
expected_param_value (str): The expected value of the parameter.
183-
184-
Returns:
185-
bool: True if the parameter is set correctly, False otherwise.
186-
"""
187-
df = get_org_parameter_value(param_id, org_id)
188-
for _, row in df.iterrows():
189-
val_matches = str(row["val"]) == expected_param_value
190-
audit_reason_matches = row["audit_reason"] == "AUTOMATED TESTING - ADD"
191-
192-
if val_matches and audit_reason_matches:
193-
logging.info(f"Parameter {param_id} is set correctly: {row['val']}")
194-
return True
195-
196-
logging.warning(f"Parameter {param_id} is not set correctly, updating parameter.")
197-
return False
198-
199-
200176
def setup_appointments(page: Page) -> None:
201177
"""
202178
Set up appointments for multiple practitioners at a screening centre.

users.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,11 @@
110110
"roles": [
111111
"Wolverhampton SC"
112112
]
113+
},
114+
"BCSS Bureau Staff at X26": {
115+
"username": "BCSS33",
116+
"roles": [
117+
"BCSS Bureau Staff at X26"
118+
]
113119
}
114120
}

0 commit comments

Comments
 (0)