66
77
88class 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
125160class 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
200193class 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 ()
0 commit comments