Index: suite_leahi/shared/scripts/configuration/utility.py =================================================================== diff -u -rf6d23e89ccf01b57313b0e920f013dc1027706d4 -rc7d96b722594bb29a7bbc3689715b90af6e3d616 --- suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision f6d23e89ccf01b57313b0e920f013dc1027706d4) +++ suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision c7d96b722594bb29a7bbc3689715b90af6e3d616) @@ -1,6 +1,14 @@ import squish import test import object +import names +from leahi_dialin.ui.td_messaging import TD_Messaging +from leahi_dialin.common.td_defs import TDOpModes,TDTreatmentStates +from configuration import config, navigation + +td =TD_Messaging() +from leahi_dialin.ui import utils +from builtins import int as pyInt def get_object_from_names(names_dict, error_message = "Missing object", timeout_ms = 200): """ @@ -12,20 +20,45 @@ return squish.waitForObject(names_dict, timeout_ms) except LookupError: test.fail("ERROR : " + error_message) - return None + return None + +def get_bullet_object(screen_obj, num): + """ + To obtain a bullet object based on occurrence provided. + @param screen_obj: provides the container on which the bullet must be present + @param num: provides the occurrence value + @returns a real name object + """ + names.o_bullet_object["container"] = screen_obj + names.o_bullet_object["occurrence"] = num + 1 + return names.o_bullet_object -def setObjectText(obj, text): +def get_text_object(screen_obj, txt): + """ + To obtain a text object based on text provided + @param screen_obj: provides the container on which the txt must be present + @returns a real name object + """ + names.o_text_object["container"] = screen_obj + names.o_text_object["text"] = txt + return names.o_text_object + +def setObjectText(text,obj): + """ + Method to set object property based on text + @param text : (string) treatment parameter text + """ obj["text"] = text - return obj - + return obj + def findObjectById(parent, id): """ Recursively searches for a child object by its id. Returns the found object or None if not found. """ if str(parent.id) == id: return parent - + for child in object.children(parent): found = findObjectById(child, id) if found: @@ -40,3 +73,208 @@ found = findChildByText(child, target_text) if found: return found + +def set_value_based_on_target(obj, target_value): + """ + obj: dictionary containing object paths + Example: + { + "value_obj": ":mainTreatmentScreen.PressureText", + "left_arrow": ":mainTreatmentScreen.LeftArrow", + "right_arrow": ":mainTreatmentScreen.RightArrow" + } + + target_value: integer or string number, e.g. 220 + """ + target_value = target_value + + # Wait for all objects + parent_obj = squish.waitForObjectExists(obj) + # change range as per your screen count + + left_arrow = findObjectById(parent_obj, "_leftArrow") + right_arrow =findObjectById(parent_obj, "_rightArrow") + + # Read current value (supports invisible text too) + + current_value = round(float(squish.findObject(obj).value),1) + + # Determine direction + while current_value != float(target_value): + if current_value < float(target_value): + squish.mouseClick(squish.waitForObject(right_arrow)) + + elif current_value > float(target_value): + squish.mouseClick(squish.waitForObject(left_arrow)) + + current_value = round(float(squish.findObject(obj).value),1) + + test.log(f"Updated value: {current_value}") + + test.log(f"✅ Target value reached: {current_value}") + +def select_different_dropdown(object,type,whichTypeIndex): + """ + Selects a value from a dropdown using a doc string. + + """ + type_combo_box = get_object_from_names(object, error_message="Combo box object is missing") + if type_combo_box is not None: + squish.mouseClick(squish.waitForObjectExists(object)) + + type_option = get_object_from_names(setObjectText(obj = names.o_option_combo_box,text = type[whichTypeIndex]),error_message=f"Option {type[whichTypeIndex]} object is missing",timeout_ms=5000) + if type_option is not None: + squish.mouseClick(type_option) + return True + return False # default return if not successful + +def verify_create_treatment_parameters(): + test.startSection("Pre treatment parameters") + navigation.navigation_pageIndicator_step(config.CREATERX) + squish.mouseClick(squish.waitForObject(names.o_PreTreatmentCreate_pretreatmentPatientIDEntry_TextEntry)) + squish.waitForObject(names.o_PreTreatmentCreate_pretreatmentPatientIDEntry_TextEntry).text ="abcd" + set_value_based_on_target(names.o_PreTreatmentCreate_bloodFlowRateControl_ValueAdjuster, 60) + set_value_based_on_target(names.o_PreTreatmentCreate_dialysateFlowRateControl_ValueAdjuster, 75) + set_value_based_on_target(names.o_PreTreatmentCreate_durationControl_ValueAdjuster, 75) + set_value_based_on_target(names.o_PreTreatmentCreate_heparinBolusVolumeControl_ValueAdjuster, 0.4) + set_value_based_on_target(names.o_PreTreatmentCreate_heparinDispensingRateControl_ValueAdjuster, 0.5) + set_value_based_on_target(names.o_PreTreatmentCreate_heparinStopTimeControl_ValueAdjuster, 60) + select_different_dropdown(names.o_PreTreatmentCreate_acidConcentrateComboBox_BaseComboBox,config.ACID_CONCENTRATE,2) + set_value_based_on_target(names.o_PreTreatmentCreate_dialysateTemperatureControl_ValueAdjuster,37.0) + select_different_dropdown(names.o_PreTreatmentCreate_dialyzerTypeComboBox_BaseComboBox,config.DIALYZER_TYPE,2) + set_value_based_on_target(names.o_PreTreatmentCreate_salineBolusVolumeControl_ValueAdjuster, 200) + select_different_dropdown(names.o_PreTreatment_vitalsCombobox_BaseCombobox,config.VITALS,1) + select_different_dropdown(names.o_PreTreatmentCreate_bicarbonateConcentrateComboBox_BaseComboBox,config.BICARBONATE,0) + Validatebutton = setObjectText(obj = names.o_preTreatmentStack_Text, text =config.VALIDATE) + squish.mouseClick(squish.waitForObject(Validatebutton)) + td.td_Treatment_Parameters_Validation( vAccepted = 1, + vBloodFlowRateRejectReason = 0, + vDialysateFlowRateRejectReason = 0, + vTreatmentDurationRejectReason = 0, + vSalineBolusVolumeRejectReason = 0, + vHeparinStopTimeRejectReason = 0, + vHeparinTypeRejectReason = 0, + vAcidConcentrateRejectReason = 0, + vBicarbonateConcentrateRejectReason = 0, + vDialyzerTypeRejectReason = 0, + vBloodPressureMeasureIntervalRejectReason = 0, + vRinsebackFlowRateRejectReason = 0, + vRinsebackVolumeRejectReason = 0, + vArterialPressureLimitWindowRejectReason = 0, + vVenousPressureLimitWindowRejectReason = 0, + vVenousPressureLimitAsymtrcRejectReason = 0, + vTransmembranePressureLimitWindowRejectReason = 0, + vDialysateTempRejectReason = 0, + vHeparinDispensingRateRejectReason = 0, + vHeparinBolusVolumeRejectReason = 0 + ) + + confirmButton = setObjectText(obj = names.o_preTreatmentStack_Text,text = config.CONFIRM ) + squish.mouseClick(squish.waitForObject(confirmButton)) + test.endSection() + +def findAllObjectsById(parent, target_id): + """ + Recursively finds all child objects by their id property. + Returns a list of all matching objects found. + """ + results = [] + + # Use hasattr to safely check for 'id' property + if hasattr(parent, 'id') and str(parent.id) == target_id: + results.append(parent) + + # Recurse through all children to collect all instances + for child in object.children(parent): + results.extend(findAllObjectsById(child, target_id)) + + return results + + + + + +def set_value_with_slider(value_field_obj, slider_obj,parameter): + """ + Opens the slider and moves it gradually to the target value (step of 10). + Uses controlled arrow key input for fine adjustment. + """ + + try: + value_field = waitForObject(value_field_obj,1000) + test.log(f"Opening slider for {parameter}...") + squish.mousePress(value_field, squish.Qt.LeftButton) + value = value_field.value + + # If not visible, try left long-press + if not object.exists(slider_obj): + test.log(f"{parameter}: Slider not opened by left-click, trying long left-press...") + squish.mousePress(value_field, squish.Qt.LeftButton) + + if not object.exists(slider_obj): + test.fail(f"{parameter}: Slider did not appear.") + + slider = waitForObject(slider_obj) + test.log(f"{parameter}: Slider appeared successfully.") + squish.mousePress(slider,squish.Qt.LeftButton) + final_value = waitForObject(value_field_obj).value + test.verify(final_value!= value, f"{parameter} slider adjusted correctly to {final_value}") + squish.mouseRelease(slider, squish.Qt.LeftButton) + + if object.exists(slider_obj): + test.log(f"Waiting for {parameter} slider to close...") + + waitFor(lambda: not object.exists(slider_obj), 1000) + except LookupError as e: + test.fail(f"{parameter}: LookupError - {e}") + +def click_left_until_off(object_name): + """ + Method to perform the left arrow untill the value + becomes off + """ + parent_obj = waitForObject(object_name) + left_arrow = findObjectById(parent_obj, "_leftArrow") + + # Loop until the value becomes "off" + while findObject(object_name).value != 0.0: + squish.mouseClick(waitForObject(left_arrow)) + utils.waitForGUI(0.2) # Small delay to allow UI to update + + return None + +def get_object_color(names_dict, error_message = "Missing object color", timeout_ms = 2000): + """ + To get an object color with try..except catching to prevent script errors when the object is not found on the GUI + @param names_dict - the dictionary element from the names.py file (ie: names.some_variable_name_of_element) + @returns the object with corresponding dictionary, otherwise "None" + """ + try: + return squish.waitForObject(names_dict, timeout_ms).color.name + except LookupError: + test.fail("ERROR : " + error_message) + + return None +def get_object_source_path(names_dict, error_message = "Missing object source path", timeout_ms = 2000): + """ + To get an object source path with try..except catching to prevent script errors when the object is not found on the GUI + @param names_dict - the dictionary element from the names.py file (ie: names.some_variable_name_of_element) + @returns the object with corresponding dictionary, otherwise "None" + """ + try: + return squish.waitForObject(names_dict, timeout_ms).source.path + except LookupError: + return None + test.fail("ERROR : " + error_message) + +def get_object_text(names_dict, error_message = "Missing object text", timeout_ms = 2000): + """ + To get an object text string with try..except catching to prevent script errors when the object is not found on the GUI + @param names_dict - the dictionary element from the names.py file (ie: names.some_variable_name_of_element) + @returns the object with corresponding dictionary, otherwise "None" + """ + try: + return squish.waitForObject(names_dict, timeout_ms).text + except LookupError: + test.fail("ERROR : " + error_message) + return None \ No newline at end of file