Skip to content

Commit 6e1bdc2

Browse files
committed
Added manage_archived_batch pom
Added tests for basic archived batch list functionality Refactored BatchListPage
1 parent d7e394a commit 6e1bdc2

File tree

4 files changed

+176
-97
lines changed

4 files changed

+176
-97
lines changed

pages/communication_production/batch_list_page.py

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66

77

88
class BatchListPage(BasePage):
9-
"""Batch List Page locators, and methods for interacting with the page"""
9+
"""Shared base class for both Active and Archived Batch List Pages."""
1010

11-
def __init__(self, page: Page):
11+
def __init__(self, page: Page, table_selector: str = "table#batchList"):
1212
super().__init__(page)
1313
self.page = page
14-
# Batch List - page filters
14+
self.table_selector = table_selector
15+
16+
# Common filters
1517
self.id_filter = self.page.locator("#batchIdFilter")
1618
self.type_filter = self.page.locator("#batchTypeFilter")
1719
self.original_filter = self.page.locator("#originalBatchIdFilter")
@@ -33,61 +35,94 @@ def __init__(self, page: Page):
3335
)
3436
self.deadline_date_clear_button = self.page.get_by_role("cell", name="Clear")
3537

38+
def assert_column_present(self, column_name: str) -> None:
39+
"""Asserts that the specified column is present in the table header."""
40+
headers = list(
41+
TableUtils(self.page, self.table_selector).get_table_headers().values()
42+
)
43+
assert (
44+
column_name in headers
45+
), f"Column '{column_name}' not found in table headers"
46+
47+
def assert_column_sortable(self, column_name: str) -> None:
48+
"""Asserts that the specified column is marked as sortable in the UI."""
49+
sort_locator = self.page.locator(
50+
f"{self.table_selector} thead tr:first-child th span.dt-column-title",
51+
has_text=column_name,
52+
)
53+
assert (
54+
sort_locator.count() > 0
55+
), f"Sortable header not found for column '{column_name}'"
56+
assert (
57+
sort_locator.first.get_attribute("role") == "button"
58+
), f"Column '{column_name}' is not sortable"
59+
60+
def assert_column_filterable(self, column_name: str) -> None:
61+
"""Asserts that the specified column has a filter control in the second header row."""
62+
table = TableUtils(self.page, self.table_selector)
63+
column_index = (
64+
table.get_column_index(column_name) - 1
65+
) # Convert 1-based to 0-based
66+
67+
filter_locator = (
68+
self.page.locator(f"{self.table_selector} thead tr:nth-child(2) th")
69+
.nth(column_index)
70+
.locator("input, select, div.input-group")
71+
)
72+
assert (
73+
filter_locator.count() > 0
74+
), f"Filter control not found for column '{column_name}'"
75+
76+
def assert_batch_table_visible(self) -> None:
77+
"""Asserts that the batch list table is present and rendered."""
78+
expect(self.page.locator(self.table_selector)).to_be_visible()
79+
3680
def verify_batch_list_page_title(self, text) -> None:
37-
"""Verify the Batch List page title is displayed as expected"""
81+
"""Verify the Batch List page title is displayed as expected."""
3882
self.bowel_cancer_screening_page_title_contains_text(text)
3983

4084
def verify_table_data(self, value) -> None:
41-
"""Verify the table data is displayed as expected"""
85+
"""Verify the table data is displayed as expected."""
4286
expect(self.table_data.filter(has_text=value)).to_be_visible()
4387

88+
# Shared filter entry methods
4489
def enter_id_filter(self, search_text: str) -> None:
45-
"""Enter text in the ID filter and press Enter"""
4690
self.id_filter.fill(search_text)
4791
self.id_filter.press("Enter")
4892

4993
def enter_type_filter(self, search_text: str) -> None:
50-
"""Enter text in the Type filter and press Enter"""
5194
self.type_filter.fill(search_text)
5295
self.type_filter.press("Enter")
5396

5497
def enter_original_filter(self, search_text: str) -> None:
55-
"""Enter text in the Original filter and press Enter"""
5698
self.original_filter.fill(search_text)
5799
self.original_filter.press("Enter")
58100

59101
def enter_event_code_filter(self, search_text: str) -> None:
60-
"""Enter text in the Event Code filter and press Enter"""
61102
self.event_code_filter.fill(search_text)
62103
self.event_code_filter.press("Enter")
63104

64105
def enter_description_filter(self, search_text: str) -> None:
65-
"""Enter text in the Description filter and press Enter"""
66106
self.description_filter.fill(search_text)
67107
self.description_filter.press("Enter")
68108

69109
def enter_batch_split_by_filter(self, search_text: str) -> None:
70-
"""Enter text in the 'Batch Split By' filter and press Enter"""
71110
self.batch_split_by_filter.fill(search_text)
72111
self.batch_split_by_filter.press("Enter")
73112

74113
def enter_screening_centre_filter(self, search_text: str) -> None:
75-
"""Enter text in the Screening Centre filter and press Enter"""
76114
self.screening_centre_filter.fill(search_text)
77115
self.screening_centre_filter.press("Enter")
78116

79117
def enter_count_filter(self, search_text: str) -> None:
80-
"""Enter text in the Count filter and press Enter"""
81118
self.count_filter.fill(search_text)
82119
self.count_filter.press("Enter")
83120

84121
def enter_deadline_date_filter(self, date: datetime) -> None:
85-
"""Enter a date in the Deadline Date filter and press Enter"""
86122
self.click(self.deadline_calendar_picker)
87123
CalendarPicker(self.page).v2_calendar_picker(date)
88124

89125
def clear_deadline_filter_date(self) -> None:
90-
"""Clear the date in the Deadline Date filter"""
91126
self.click(self.deadline_calendar_picker)
92127
self.click(self.deadline_date_clear_button)
93128

@@ -123,82 +158,48 @@ def open_letter_batch(
123158

124159

125160
class ActiveBatchListPage(BatchListPage):
126-
"""Active Batch List Page locators, and methods for interacting with the Active Batch List page"""
127-
128-
def __init__(self, page):
129-
super().__init__(page)
130-
131-
def assert_column_present(self, column_name: str) -> None:
132-
"""Asserts that the specified column is present in the table header."""
133-
headers = list(
134-
TableUtils(self.page, "table#batchList").get_table_headers().values()
135-
)
136-
assert (
137-
column_name in headers
138-
), f"Column '{column_name}' not found in table headers"
139-
140-
def assert_column_sortable(self, column_name: str) -> None:
141-
"""Asserts that the specified column is marked as sortable in the UI."""
142-
sort_locator = self.page.locator(
143-
"table#batchList thead tr:first-child th span.dt-column-title",
144-
has_text=column_name,
145-
)
146-
assert (
147-
sort_locator.count() > 0
148-
), f"Sortable header not found for column '{column_name}'"
149-
assert (
150-
sort_locator.first.get_attribute("role") == "button"
151-
), f"Column '{column_name}' is not sortable"
152-
153-
def assert_column_filterable(self, column_name: str) -> None:
154-
"""Asserts that the specified column has a filter control in the second header row."""
155-
table = TableUtils(self.page, "table#batchList")
156-
column_index = (
157-
table.get_column_index(column_name) - 1
158-
) # Convert 1-based to 0-based
161+
"""Active Batch List Page-specific methods."""
159162

160-
filter_locator = (
161-
self.page.locator("table#batchList thead tr:nth-child(2) th")
162-
.nth(column_index)
163-
.locator("input, select, div.input-group")
164-
)
165-
assert (
166-
filter_locator.count() > 0
167-
), f"Filter control not found for column '{column_name}'"
168-
169-
def assert_batch_table_visible(self) -> None:
170-
"""Asserts that the batch list table is present and rendered."""
171-
expect(self.page.locator("table#batchList")).to_be_visible()
163+
def __init__(self, page: Page):
164+
super().__init__(page, table_selector="table#batchList")
172165

173166
def select_first_active_batch(self) -> None:
174167
"""Clicks the first batch ID link in the active batch list."""
175-
first_batch_link = self.page.locator("table#batchList tbody tr td.id a").first
176-
assert first_batch_link.count() > 0, "No active batch links found"
177-
first_batch_link.click()
168+
first_link = self.page.locator(f"{self.table_selector} tbody tr td.id a").first
169+
assert first_link.count() > 0, "No active batch links found"
170+
first_link.click()
178171

179172
def is_batch_present(self, batch_type: str) -> bool:
180173
"""Checks if a batch of the given type exists in the active batch list."""
181-
locator = self.page.locator(f"table#batchList tbody tr td", has_text=batch_type)
174+
locator = self.page.locator(
175+
f"{self.table_selector} tbody tr td", has_text=batch_type
176+
)
182177
return locator.count() > 0
183178

184179
def prepare_batch(self, batch_type: str) -> None:
185180
"""Finds and clicks the Prepare button for the specified batch type."""
186181
row = (
187-
self.page.locator("table#batchList tbody tr")
182+
self.page.locator(f"{self.table_selector} tbody tr")
188183
.filter(has=self.page.locator("td", has_text=batch_type))
189184
.first
190185
)
191186

192187
prepare_button = row.locator("a", has_text="Prepare").first
193188
expect(prepare_button).to_be_visible()
194189
prepare_button.click()
195-
196-
# Optional: wait for row to disappear
197190
expect(row).not_to_be_visible(timeout=5000)
198191

199192

200193
class ArchivedBatchListPage(BatchListPage):
201-
"""Archived Batch List Page locators, and methods for interacting with the Archived Batch List page"""
194+
"""Archived Batch List Page-specific setup."""
202195

203-
def __init__(self, page):
204-
super().__init__(page)
196+
def __init__(self, page: Page):
197+
super().__init__(page, table_selector="table#batchList")
198+
199+
def select_first_archived_batch(self) -> None:
200+
"""Clicks the first batch ID link in the archived batch list."""
201+
first_batch_link = self.page.locator(
202+
f"{self.table_selector} tbody tr td.id a"
203+
).first
204+
assert first_batch_link.count() > 0, "No archived batch links found"
205+
first_batch_link.click()

pages/communication_production/manage_active_batch_page.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,3 @@ def assert_batch_details_visible(self) -> None:
3535
"""Asserts that the Manage Active Batch screen has loaded by checking the page title."""
3636
page_title = self.page.locator("#page-title")
3737
expect(page_title).to_have_text("Manage Active Batch")
38-
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from playwright.sync_api import Page
2+
from pages.base_page import BasePage
3+
from playwright.sync_api import expect
4+
5+
6+
class ManageArchivedBatchPage(BasePage):
7+
"""Page object for the Manage Archived Batch Screen."""
8+
9+
def __init__(self, page: Page):
10+
super().__init__(page)
11+
12+
def assert_batch_details_visible(self) -> None:
13+
"""Verifies the Manage Archived Batch page has loaded."""
14+
header = self.page.locator("#page-title")
15+
expect(header).to_have_text("Manage Archived Batch")
Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,90 @@
1-
# @BCSSAdditionalTests @LettersTests
2-
# Feature: Basic Archived Batch List functionality
3-
4-
# Scenario: Check headings on Archived Batch List Screen
5-
# Given I log in to BCSS "England" as user role "HubManager"
6-
# When I view the archived batch list
7-
# Then the table contains a sortable and filterable column for "ID"
8-
# And the table contains a sortable and filterable column for "Type"
9-
# And the table contains a sortable and filterable column for "Original"
10-
# And the table contains a sortable and filterable column for "Letter Group"
11-
# And the table contains a sortable and filterable column for "Event Code"
12-
# And the table contains a sortable and filterable column for "Description"
13-
# And the table contains a sortable and filterable column for "Batch Split By"
14-
# And the table contains a sortable and filterable column for "Screening Centre"
15-
# And the table contains a sortable and filterable column for "Status"
16-
# And the table contains a sortable and filterable column for "Priority"
17-
# And the table contains a sortable and filterable column for "Date On Letter"
18-
# And the table contains a sortable and filterable column for "Date Archived"
19-
# And the table contains a sortable and filterable column for "Count"
20-
21-
22-
# Scenario: Check navigation from Archived Batch List Screen to Manage Archived Batch Screen
23-
# Given I log in to BCSS "England" as user role "HubManager"
24-
# When I view the archived batch list
25-
# And I select an archived batch
26-
# Then I view the details of an archived batch
1+
import pytest
2+
from playwright.sync_api import Page
3+
from pages.base_page import BasePage
4+
from pages.communication_production.communications_production_page import (
5+
CommunicationsProductionPage,
6+
)
7+
from pages.communication_production.batch_list_page import (
8+
ArchivedBatchListPage,
9+
)
10+
from utils.user_tools import UserTools
11+
from pages.communication_production.manage_archived_batch_page import (
12+
ManageArchivedBatchPage,
13+
)
14+
15+
16+
@pytest.fixture
17+
def select_user(page: Page):
18+
def _login_as(user_role: str):
19+
# Log in with the specified user
20+
UserTools.user_login(page, user_role)
21+
# Navigate to Active Batch List
22+
BasePage(page).go_to_communications_production_page()
23+
CommunicationsProductionPage(page).go_to_archived_batch_list_page()
24+
return page
25+
26+
return _login_as
27+
28+
29+
@pytest.mark.letters_tests
30+
@pytest.mark.regression
31+
def test_headings_on_archived_batch_list_screen(select_user) -> None:
32+
"""
33+
Scenario: Check headings on Archived Batch List Screen
34+
Given I log in to BCSS "England" as user role "HubManager"
35+
When I view the archived batch list
36+
Then the table contains a sortable and filterable column for each expected header
37+
"""
38+
page = select_user("Hub Manager at BCS01")
39+
40+
archived_batch_list_page = ArchivedBatchListPage(page)
41+
42+
expected_columns = [
43+
"ID",
44+
"Type",
45+
"Original",
46+
"Letter Group",
47+
"Event Code",
48+
"Description",
49+
"Batch Split By",
50+
"Screening Centre",
51+
"Status",
52+
"Priority",
53+
"Date On Letter",
54+
"Date Archived",
55+
"Count",
56+
]
57+
58+
for column in expected_columns:
59+
# Step 1: Ensure the column is present
60+
archived_batch_list_page.assert_column_present(column)
61+
62+
# Step 2: Assert sortable UI attribute is present
63+
archived_batch_list_page.assert_column_sortable(column)
64+
65+
# Step 3: Assert filterable control is rendered
66+
archived_batch_list_page.assert_column_filterable(column)
67+
68+
69+
@pytest.mark.letters_tests
70+
@pytest.mark.regression
71+
def test_navigation_to_manage_archived_batch_screen(select_user) -> None:
72+
"""
73+
Scenario: Check navigation from Archived Batch List Screen to Manage Archived Batch Screen
74+
Given I log in to BCSS "England" as user role "HubManager"
75+
When I view the archived batch list
76+
And I select an archived batch
77+
Then I view the details of an archived batch
78+
"""
79+
page = select_user("Hub Manager at BCS01")
80+
archived_batch_list_page = ArchivedBatchListPage(page)
81+
82+
# Step 1: Ensure the archived batch table is visible
83+
archived_batch_list_page.assert_batch_table_visible()
84+
85+
# Step 2: Click into the first available archived batch
86+
archived_batch_list_page.select_first_archived_batch()
87+
88+
# Step 3: Assert navigation to the Manage Archived Batch page
89+
manage_batch_page = ManageArchivedBatchPage(page)
90+
manage_batch_page.assert_batch_details_visible()

0 commit comments

Comments
 (0)