Skip to content

Commit 2f995d0

Browse files
authored
Merge pull request #801 from NHSDigital/use-components
Use composition/components over inheritance/mixins
2 parents 14858c3 + 7fcfdf0 commit 2f995d0

23 files changed

+211
-195
lines changed

mavis/test/fixtures/helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def wrapper(vaccine: Vaccine, batch_name: str = "ABC123"):
3131
vaccines_page.navigate()
3232
vaccines_page.click_add_batch(vaccine)
3333
add_batch_page.fill_name(batch_name)
34-
add_batch_page.fill_expiry_date(get_offset_date(1))
34+
add_batch_page.date.fill_expiry_date(get_offset_date(1))
3535
add_batch_page.confirm()
3636
return batch_name
3737

@@ -193,7 +193,7 @@ def wrapper(
193193
dashboard_page.click_mavis()
194194
dashboard_page.click_programmes()
195195
programmes_list_page.click_programme_for_current_year(programme)
196-
programme_overview_page.click_children_tab()
196+
programme_overview_page.tabs.click_children_tab()
197197
programme_children_page.search_for_child(child)
198198
programme_children_page.click_child(child)
199199
child_record_page.click_vaccination_details(programme)

mavis/test/fixtures/pages.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ def programmes_list_page(page: Page) -> ProgrammesListPage:
168168

169169

170170
@pytest.fixture
171-
def programme_overview_page(page: Page, test_data: TestData) -> ProgrammeOverviewPage:
172-
return ProgrammeOverviewPage(page, test_data)
171+
def programme_overview_page(page: Page) -> ProgrammeOverviewPage:
172+
return ProgrammeOverviewPage(page)
173173

174174

175175
@pytest.fixture

mavis/test/pages/children.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def check_children_aged_out_of_programmes(self) -> None:
117117
self.children_aged_out_of_programmes_checkbox.check()
118118

119119

120-
class ChildRecordTabsMixin:
120+
class ChildRecordTabs:
121121
def __init__(self, page: Page) -> None:
122122
self.page = page
123123
self.child_record_tab = page.get_by_role("link", name="Child record")
@@ -129,9 +129,10 @@ def click_activity_log(self) -> None:
129129
self.activity_log_tab.get_by_role("strong").wait_for()
130130

131131

132-
class ChildRecordPage(ChildRecordTabsMixin):
132+
class ChildRecordPage:
133133
def __init__(self, page: Page) -> None:
134-
super().__init__(page)
134+
self.page = page
135+
self.tabs = ChildRecordTabs(page)
135136

136137
vaccinations_card = page.locator("section").filter(
137138
has=page.get_by_role("heading", name="Vaccinations"),
@@ -270,9 +271,10 @@ def archive_child_record(self) -> None:
270271
expect(self.page.get_by_text("Archive reason")).to_be_visible()
271272

272273

273-
class ChildActivityLogPage(ChildRecordTabsMixin):
274+
class ChildActivityLogPage:
274275
def __init__(self, page: Page) -> None:
275-
super().__init__(page)
276+
self.page = page
277+
self.tabs = ChildRecordTabs(page)
276278
self.manually_matched_card = self.page.get_by_text(
277279
"Consent response manually matched with child record",
278280
)

mavis/test/pages/programmes.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from playwright.sync_api import Page
66

77
from mavis.test.annotations import step
8-
from mavis.test.data import TestData
98
from mavis.test.models import Child, DeliverySite, Programme, ReportFormat
109
from mavis.test.utils import get_current_datetime_compact
1110

@@ -24,7 +23,7 @@ def click_programme_for_current_year(self, programme: Programme) -> None:
2423
self.current_year_programmes_card.get_by_role("link", name=programme).click()
2524

2625

27-
class ProgrammeTabsMixin:
26+
class ProgrammeTabs:
2827
def __init__(self, page: Page) -> None:
2928
self.page = page
3029
self.children_tab = page.get_by_label("Secondary menu").get_by_role(
@@ -45,11 +44,10 @@ def click_sessions_tab(self) -> None:
4544
self.sessions_tab.get_by_role("strong").wait_for()
4645

4746

48-
class ProgrammeOverviewPage(ProgrammeTabsMixin):
49-
def __init__(self, page: Page, test_data: TestData) -> None:
50-
super().__init__(page)
47+
class ProgrammeOverviewPage:
48+
def __init__(self, page: Page) -> None:
5149
self.page = page
52-
self.test_data = test_data
50+
self.tabs = ProgrammeTabs(page)
5351

5452
self.review_link = page.get_by_role("link", name="Review")
5553
self.edit_vaccination_record_button = page.get_by_role(
@@ -171,14 +169,17 @@ def _download_and_verify_report_headers(self, expected_headers: str) -> None:
171169
raise AssertionError(error_message)
172170

173171

174-
class ProgrammeSessionsPage(ProgrammeTabsMixin):
172+
class ProgrammeSessionsPage:
175173
def __init__(self, page: Page) -> None:
176-
super().__init__(page)
174+
self.page = page
175+
self.tabs = ProgrammeTabs(page)
177176

178177

179-
class ProgrammeChildrenPage(ProgrammeTabsMixin):
178+
class ProgrammeChildrenPage:
180179
def __init__(self, page: Page) -> None:
181-
super().__init__(page)
180+
self.page = page
181+
self.tabs = ProgrammeTabs(page)
182+
182183
self.import_child_records_link = page.get_by_text("Import child records")
183184
self.search_textbox = page.get_by_role("textbox", name="Search")
184185
self.search_button = page.get_by_role("button", name="Search")

mavis/test/pages/reports.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
)
1515

1616

17-
class ReportsTabsMixin:
17+
class ReportsTabs:
1818
def __init__(self, page: Page) -> None:
1919
self.page = page
2020
self.vaccinations_tab = page.get_by_label("Secondary menu").get_by_role(
@@ -35,9 +35,11 @@ def click_download_data_tab(self) -> None:
3535
self.download_data_tab.get_by_role("strong").wait_for()
3636

3737

38-
class ReportsVaccinationsPage(ReportsTabsMixin):
38+
class ReportsVaccinationsPage:
3939
def __init__(self, page: Page) -> None:
40-
super().__init__(page)
40+
self.page = page
41+
self.tabs = ReportsTabs(page)
42+
4143
self.cohort_heading = self.page.get_by_role(
4244
"heading", name="Cohort", exact=True
4345
)
@@ -109,9 +111,11 @@ def get_expected_cohort_and_percentage_strings(
109111
return str(total), str(unvaccinated_pct), str(vaccinated_pct)
110112

111113

112-
class ReportsDownloadPage(ReportsTabsMixin):
114+
class ReportsDownloadPage:
113115
def __init__(self, page: Page) -> None:
114-
super().__init__(page)
116+
self.page = page
117+
self.tabs = ReportsTabs(page)
118+
115119
self.aggregate_data_radio = self.page.get_by_role(
116120
"radio", name="Aggregate vaccination data"
117121
)

mavis/test/pages/sessions.py

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
)
3131

3232

33-
class SearchBarMixin:
33+
class SearchComponent:
3434
def __init__(
3535
self,
3636
page: Page,
@@ -48,7 +48,7 @@ def __init__(
4848
name="Archived records",
4949
)
5050

51-
def _get_patient_card_locator(self, child: Child) -> Locator:
51+
def get_patient_card_locator(self, child: Child) -> Locator:
5252
return self.page.locator(
5353
f'div.nhsuk-card.app-card.app-card--compact:has(h4:has-text("{child!s}"))'
5454
)
@@ -70,15 +70,15 @@ def verify_search(self) -> None:
7070

7171
def search_and_click_child(self, child: Child) -> None:
7272
self.search_for(str(child))
73-
child_locator = self._get_patient_card_locator(child).get_by_role(
73+
child_locator = self.get_patient_card_locator(child).get_by_role(
7474
"link", name=str(child)
7575
)
7676
reload_until_element_is_visible(self.page, child_locator)
7777
child_locator.click()
7878

7979
def search_for_child_that_should_not_exist(self, child: Child) -> None:
8080
self.search_for(str(child))
81-
child_locator = self._get_patient_card_locator(child).get_by_role(
81+
child_locator = self.get_patient_card_locator(child).get_by_role(
8282
"link", name=str(child)
8383
)
8484
expect(child_locator).not_to_be_visible()
@@ -112,7 +112,7 @@ def check_note_appears_in_search(self, child: Child, note: str) -> None:
112112
expect(next_element.get_by_role("blockquote")).to_have_text(note)
113113

114114

115-
class SessionsTabsMixin:
115+
class SessionsTabs:
116116
def __init__(
117117
self,
118118
page: Page,
@@ -146,14 +146,12 @@ def click_record_vaccinations_tab(self) -> None:
146146
def click_children_tab(self) -> None:
147147
self._select_tab("Children")
148148

149-
@step("Click on Triage tab")
150-
def click_triage_tab(self) -> None:
151-
self._select_tab("Triage")
152149

153-
154-
class SessionsPsdPage(SearchBarMixin, SessionsTabsMixin):
150+
class SessionsPsdPage:
155151
def __init__(self, page: Page) -> None:
156-
super().__init__(page)
152+
self.page = page
153+
self.search = SearchComponent(page)
154+
self.tabs = SessionsTabs(page)
157155

158156
self.add_new_psds_link = self.page.get_by_role(
159157
"link",
@@ -166,16 +164,16 @@ def __init__(self, page: Page) -> None:
166164

167165
@step("Check {1} has PSD")
168166
def check_child_has_psd(self, child: Child) -> None:
169-
child_with_psd_locator = self._get_patient_card_locator(child).get_by_text(
170-
"PSD added"
171-
)
167+
child_with_psd_locator = self.search.get_patient_card_locator(
168+
child
169+
).get_by_text("PSD added")
172170
reload_until_element_is_visible(self.page, child_with_psd_locator)
173171

174172
@step("Check {1} does not have PSD")
175173
def check_child_does_not_have_psd(self, child: Child) -> None:
176-
child_without_psd_locator = self._get_patient_card_locator(child).get_by_text(
177-
"PSD not added"
178-
)
174+
child_without_psd_locator = self.search.get_patient_card_locator(
175+
child
176+
).get_by_text("PSD not added")
179177
reload_until_element_is_visible(self.page, child_without_psd_locator)
180178

181179
@step("Click Add new PSDs")
@@ -194,9 +192,10 @@ def verify_psd_banner_has_patients(self, number_of_patients: int) -> None:
194192
reload_until_element_is_visible(self.page, psd_banner)
195193

196194

197-
class SessionsSearchPage(SearchBarMixin):
195+
class SessionsSearchPage:
198196
def __init__(self, page: Page) -> None:
199-
super().__init__(page)
197+
self.page = page
198+
self.search = SearchComponent(page)
200199

201200
@step("Click on {2} session at {1}")
202201
def click_session_for_programme_group(
@@ -209,8 +208,8 @@ def click_session_for_programme_group(
209208
else:
210209
self.page.get_by_role("checkbox", name=str(programme)).uncheck()
211210

212-
self.search_textbox.fill(str(location))
213-
self.search_button.click()
211+
self.search.search_textbox.fill(str(location))
212+
self.search.search_button.click()
214213

215214
self.page.get_by_role("link", name=str(location)).first.click()
216215

@@ -221,9 +220,11 @@ def click_session_for_programme_group(
221220
)
222221

223222

224-
class SessionsOverviewPage(SessionsTabsMixin):
223+
class SessionsOverviewPage:
225224
def __init__(self, page: Page) -> None:
226225
self.page = page
226+
self.tabs = SessionsTabs(page)
227+
227228
self.schedule_sessions_link = self.page.get_by_role(
228229
"link",
229230
name="Schedule sessions",
@@ -265,7 +266,7 @@ def get_all_totals(self, programme: Programme) -> dict[str, int]:
265266
}
266267

267268
def check_all_totals(self, totals: dict[str, int]) -> None:
268-
self.click_overview_tab()
269+
self.tabs.click_overview_tab()
269270
for category, expected_total in totals.items():
270271
actual_total = self.get_total_for_category(category)
271272
assert actual_total == expected_total, (
@@ -597,9 +598,12 @@ def answer_whether_psd_should_be_enabled(self, answer: str) -> None:
597598
).get_by_label(answer).check()
598599

599600

600-
class SessionsChildrenPage(SearchBarMixin, SessionsTabsMixin):
601+
class SessionsChildrenPage:
601602
def __init__(self, page: Page) -> None:
602-
super().__init__(page)
603+
self.page = page
604+
self.tabs = SessionsTabs(page)
605+
self.search = SearchComponent(page)
606+
603607
self.needs_consent_radio = self.page.get_by_role(
604608
"radio",
605609
name="Needs consent",
@@ -657,7 +661,7 @@ def verify_child_shows_correct_flu_consent_method(
657661
reload_until_element_is_visible(self.page, method_locator)
658662

659663
def get_flu_consent_status_locator_from_search(self, child: Child) -> Locator:
660-
child_locator = self._get_patient_card_locator(child)
664+
child_locator = self.search.get_patient_card_locator(child)
661665
flu_consent_section = child_locator.locator("p:has-text('Flu')")
662666
reload_until_element_is_visible(self.page, flu_consent_section)
663667

@@ -668,14 +672,17 @@ def expect_has_a_refusal_to_be_selected(self) -> None:
668672
expect(self.has_a_refusal_radio).to_be_checked()
669673

670674

671-
class SessionsRegisterPage(SearchBarMixin, SessionsTabsMixin):
675+
class SessionsRegisterPage:
672676
def __init__(self, page: Page) -> None:
673-
super().__init__(page)
677+
self.page = page
678+
self.tabs = SessionsTabs(page)
679+
self.search = SearchComponent(page)
680+
674681
self.attending_button = self.page.get_by_role("button", name="Attending").first
675682

676683
def register_child_as_attending(self, child: Child) -> None:
677-
self.click_register_tab()
678-
self.search_for(str(child))
684+
self.tabs.click_register_tab()
685+
self.search.search_for(str(child))
679686
reload_until_element_is_visible(
680687
self.page, self.page.get_by_role("link", name=str(child)).first
681688
)
@@ -686,9 +693,11 @@ def click_on_attending(self) -> None:
686693
self.attending_button.click()
687694

688695

689-
class SessionsRecordVaccinationsPage(SearchBarMixin, SessionsTabsMixin):
696+
class SessionsRecordVaccinationsPage:
690697
def __init__(self, page: Page) -> None:
691-
super().__init__(page)
698+
self.page = page
699+
self.tabs = SessionsTabs(page)
700+
self.search = SearchComponent(page)
692701

693702

694703
class SessionsPatientPage:

mavis/test/pages/vaccines.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from mavis.test.models import Vaccine
77

88

9-
class BatchExpiryDateMixin:
9+
class BatchExpiryDate:
1010
def __init__(self, page: Page) -> None:
1111
self.expiry_day_textbox = page.get_by_role("textbox", name="Day")
1212
self.expiry_month_textbox = page.get_by_role("textbox", name="Month")
@@ -19,11 +19,10 @@ def fill_expiry_date(self, value: date) -> None:
1919
self.expiry_year_textbox.fill(str(value.year))
2020

2121

22-
class AddBatchPage(BatchExpiryDateMixin):
22+
class AddBatchPage:
2323
def __init__(self, page: Page) -> None:
24-
super().__init__(page)
25-
2624
self.page = page
25+
self.date = BatchExpiryDate(page)
2726

2827
self.name_textbox = page.get_by_role("textbox", name="Batch")
2928
self.confirm_button = page.get_by_role("button", name="Add batch")
@@ -43,11 +42,10 @@ def confirm(self) -> None:
4342
self.confirm_button.click()
4443

4544

46-
class EditBatchPage(BatchExpiryDateMixin):
45+
class EditBatchPage:
4746
def __init__(self, page: Page) -> None:
48-
super().__init__(page)
49-
5047
self.page = page
48+
self.date = BatchExpiryDate(page)
5149

5250
self.confirm_button = page.get_by_role("button", name="Save changes")
5351
self.success_alert = page.get_by_role("alert", name="Success").filter(

0 commit comments

Comments
 (0)