@@ -99,6 +99,13 @@ def __init__(self, page: Page):
9999 self .antibiotics_administered_string = "Antibiotics Administered"
100100 self .other_drugs_administered_string = "Other Drugs Administered"
101101
102+ # Other:
103+ self .list_of_multi_line_fields = [
104+ "failure reasons" ,
105+ "early complications" ,
106+ "late complications" ,
107+ ]
108+
102109 def select_site_lookup_option (self , option : str ) -> None :
103110 """
104111 This method is designed to select a site from the site lookup options.
@@ -628,7 +635,7 @@ def get_dataset_section(self, dataset_section_name: str) -> Optional[Locator]:
628635 Args:
629636 dataset_section_name (str): The name of the dataset section to locate.
630637 Returns:
631- Optioanl [Locator]: A Playwright Locator for the matching section if visible, or None if not found or not visible.
638+ Optional [Locator]: A Playwright Locator for the matching section if visible, or None if not found or not visible.
632639 """
633640 logging .info (f"START: Looking for section '{ dataset_section_name } '" )
634641
@@ -1172,6 +1179,167 @@ def get_drug_dosage_text_locator(self, drug_type: str, drug_number: int) -> Loca
11721179 locator_prefix = "#HILITE_spanAntibioticDosageUnit"
11731180 return self .page .locator (f"{ locator_prefix } { drug_number } " )
11741181
1182+ def does_field_contain_expected_value (
1183+ self ,
1184+ dataset_area : str ,
1185+ dataset_subsection : str | None ,
1186+ field_name : str ,
1187+ expected_value : str ,
1188+ ) -> None :
1189+ """
1190+ Checks if the specified field contains the expected value in the given dataset area and subsection.
1191+ Args:
1192+ dataset_area (str): The dataset section name.
1193+ dataset_subsection (str | None): The dataset subsection name.
1194+ field_name (str): The field label to check.
1195+ expected_value (str): The expected value to look for.
1196+ """
1197+ logging .debug (
1198+ f"START: does_field_contain_expected_value({ dataset_area } , { dataset_subsection } , { field_name } , { expected_value } )"
1199+ )
1200+ field_and_value_found = False
1201+ map_of_field_and_elements = self .map_fields_and_values (
1202+ dataset_area , dataset_subsection
1203+ )
1204+ actual_value = map_of_field_and_elements .get (field_name .lower ())
1205+ if actual_value is not None :
1206+ actual_value = actual_value .replace ("\xa0 " , "" ).replace (" " , "" )
1207+ if actual_value .replace (" " , "" ) == "" :
1208+ actual_value = ""
1209+ if expected_value .lower () in actual_value .lower ():
1210+ field_and_value_found = True
1211+ else :
1212+ raise ValueError (
1213+ f"Value not as expected. Expected: { expected_value } , Actual: '{ actual_value } '"
1214+ )
1215+ else :
1216+ raise ValueError (
1217+ f"Field '{ field_name } ' not found in the dataset area '{ dataset_area } ' and subsection '{ dataset_subsection } '."
1218+ )
1219+ logging .debug ("END: does_field_contain_expected_value" )
1220+ if field_and_value_found :
1221+ logging .info (
1222+ f"[UI ASSERTIONS COMPLETE] Value as expected. Expected: { expected_value } , Actual: '{ actual_value } '"
1223+ )
1224+
1225+ def map_fields_and_values (
1226+ self , dataset_section : str , dataset_subsection : str | None
1227+ ) -> dict [str , str ]:
1228+ """
1229+ Maps field labels to their values for a given dataset section and subsection.
1230+ Args:
1231+ dataset_section (str): The name of the dataset section.
1232+ dataset_subsection (str | None): The name of the dataset subsection.
1233+ Returns:
1234+ dict[str, str]: A dictionary mapping field labels to their corresponding values.
1235+ """
1236+ logging .debug ("start: map_fields_and_values()" )
1237+ fields_and_elements = self .map_fields_and_elements (
1238+ dataset_section , dataset_subsection
1239+ )
1240+ fields_with_values = {}
1241+
1242+ for field_label , element in fields_and_elements .items ():
1243+ # Find all child elements
1244+ value_list = element .locator ("xpath=.//*" ).all ()
1245+ field_value = ""
1246+ if not value_list :
1247+ field_value = element .inner_text ()
1248+ else :
1249+ for value_from_list in value_list :
1250+ tag_name = value_from_list .evaluate (
1251+ "el => el.tagName.toLowerCase()"
1252+ )
1253+ if tag_name == "select" :
1254+ # Get selected option text
1255+ selected_option = value_from_list .locator ("option:checked" )
1256+ field_value += selected_option .inner_text ()
1257+ elif tag_name == "li" :
1258+ input_elem = value_from_list .locator ("input" )
1259+ if input_elem .is_checked ():
1260+ label_elem = value_from_list .locator ("label" )
1261+ field_value = label_elem .inner_text ()
1262+ elif tag_name == "input" :
1263+ input_type = value_from_list .get_attribute ("type" )
1264+ if input_type == "text" :
1265+ field_value += value_from_list .input_value ()
1266+ elif tag_name == "p" :
1267+ field_value += value_from_list .inner_text ()
1268+ else :
1269+ logging .debug (
1270+ f"tag type not specified, tag ignored = { tag_name } "
1271+ )
1272+ fields_with_values [field_label ] = field_value
1273+
1274+ logging .debug ("end: map_fields_and_values()" )
1275+ return fields_with_values
1276+
1277+ def map_fields_and_elements (
1278+ self , dataset_section : str , dataset_subsection : Optional [str ] = None
1279+ ) -> dict [str , Locator ]:
1280+ """
1281+ Maps field labels to their corresponding Playwright Locator elements for a given dataset section and subsection.
1282+ Args:
1283+ dataset_section (str): The name of the dataset section.
1284+ dataset_subsection (Optional[str]): The name of the dataset subsection, if any.
1285+ Returns:
1286+ dict[str, Locator]: A dictionary mapping field labels to their corresponding Locator elements.
1287+ """
1288+ logging .debug (
1289+ f"start: map_fields_and_elements({ dataset_section } , { dataset_subsection } )"
1290+ )
1291+ fields_and_elements = {}
1292+
1293+ previous_field = ""
1294+ field_name = ""
1295+ line_counter = 2
1296+
1297+ if dataset_subsection is None :
1298+ section = self .get_dataset_section (dataset_section )
1299+ else :
1300+ section = self .get_dataset_subsection (dataset_section , dataset_subsection )
1301+
1302+ if section is None :
1303+ raise ValueError (
1304+ f"Section '{ dataset_section } '{ ' / ' + dataset_subsection if dataset_subsection else '' } not found."
1305+ )
1306+
1307+ list_of_rows = section .locator (".noTableRow" ).all ()
1308+
1309+ for row in list_of_rows :
1310+ elements_in_row = row .locator ("xpath=.//*" ).all ()
1311+ element_to_map = None
1312+
1313+ for element in elements_in_row :
1314+ element_class = element .get_attribute ("class" ) or ""
1315+ if "label" in element_class :
1316+ previous_field = field_name
1317+ field_name = element .inner_text ().lower ().replace (" ?" , "" ).strip ()
1318+ if field_name in fields_and_elements :
1319+ name_counter = 2
1320+ while f"{ field_name } ({ name_counter } )" in fields_and_elements :
1321+ name_counter += 1
1322+ field_name = f"{ field_name } ({ name_counter } )"
1323+ elif "userInput" in element_class :
1324+ element_to_map = element
1325+
1326+ if field_name .replace (" " , "" ) != "" :
1327+ fields_and_elements [field_name ] = element_to_map
1328+ line_counter = 2
1329+ else :
1330+ if (
1331+ hasattr (self , "list_of_multi_line_fields" )
1332+ and previous_field in self .list_of_multi_line_fields
1333+ ):
1334+ field_name = previous_field
1335+ fields_and_elements [f"{ field_name } ({ line_counter } )" ] = (
1336+ element_to_map
1337+ )
1338+ line_counter += 1
1339+
1340+ logging .debug ("end: map_fields_and_elements()" )
1341+ return fields_and_elements
1342+
11751343
11761344def normalize_label (text : str ) -> str :
11771345 """
0 commit comments