Index: suite_leahi/shared/scripts/configuration/application_init.py =================================================================== diff -u -r4f71dc71ca95ab916947fafdc17c9e1e4f74c47e -r477260ff9a68fb041c2a18cb105267ef315b7c01 --- suite_leahi/shared/scripts/configuration/application_init.py (.../application_init.py) (revision 4f71dc71ca95ab916947fafdc17c9e1e4f74c47e) +++ suite_leahi/shared/scripts/configuration/application_init.py (.../application_init.py) (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -187,3 +187,33 @@ aut_version = aut_name_and_version.split(" ") aut_version_only = aut_version[1] return aut_version_only + +def update_advanced_mode_back_to_default(): + + base_path = Path.home() / "Public/luis/config/configurations/Settings/" + + source_file = base_path / "System.dflt" + target_file = base_path / "System.conf" + + # Read password from system.dflt + with open(source_file, 'r') as f: + for line in f: + if "AdvancedMode =" in line: + new_mode = line.split("=")[1].strip() + break + + # Read current system.conf lines + with open(target_file, 'r') as f: + conf_lines = f.readlines() + + # Update the password in system.conf memory + updated_lines = [] + for line in conf_lines: + if line.strip().startswith("AdvancedMode"): + updated_lines.append(f"AdvancedMode = {new_mode}\n") + else: + updated_lines.append(line) + + # Write back to system.conf + with open(target_file, 'w') as f: + f.writelines(updated_lines) Index: suite_leahi/shared/scripts/configuration/config.py =================================================================== diff -u -r75e3ab588237239452761d2ec90e8b3aec6a916b -r477260ff9a68fb041c2a18cb105267ef315b7c01 --- suite_leahi/shared/scripts/configuration/config.py (.../config.py) (revision 75e3ab588237239452761d2ec90e8b3aec6a916b) +++ suite_leahi/shared/scripts/configuration/config.py (.../config.py) (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -91,4 +91,20 @@ CONFIRM = "CONFIRM" NEXT ="Next" +# Settings Service +DEFAULT_SERVICE_PASSWORD_RAW = "Atal.Matal.22leh" # TODO need to update if we ever change the default +NEW_PASSWORD_RAW = "Test4.Ksah.sk43sa" +MANUFACTURING_SCREEN_TITLE_TEXT = "Manufacturing Setup" +SERVICE_SCREEN_TITLE_TEXT = "Service" +ADVANCED_MODES_SCREEN_TITLE_TEXT = "Advanced Mode" +DATE_AND_TIME_SCREEN_TITLE_TEXT = "Date and Time" +DATE_AND_TIME_PARAMETERS_TEXTS = ["NTP", "(Network Time Protocol)", "Time", "(HH:mm:ss)", "Date", "(MM/dd/yyyy)"] +ENABLE_ROOT_SSH_SCREEN_TITLE_TEXT = "Enable Root SSH" +ENABLE_ROOT_SSH_PARAMETERS_TEXTS = ["Enable SSH Login", "Enable Root Login"] +FACTORY_RESET_SCREEN_TITLE_TEXT = "Factory Reset" +FACTORY_RESET_SCREEN_TEXT = "Do you want to perform the factory reset?" +#Blood Set Auto Load +BLOOD_SET_AUTO_LOAD_REJECTION = "[1] Request is not allowed in the current operating mode" +BLOOD_SET_AUTO_EJECT_REJECTION = "[1] Request is not allowed in the current operating mode" + Index: suite_leahi/shared/scripts/configuration/navigation.py =================================================================== diff -u -rc7d96b722594bb29a7bbc3689715b90af6e3d616 -r477260ff9a68fb041c2a18cb105267ef315b7c01 --- suite_leahi/shared/scripts/configuration/navigation.py (.../navigation.py) (revision c7d96b722594bb29a7bbc3689715b90af6e3d616) +++ suite_leahi/shared/scripts/configuration/navigation.py (.../navigation.py) (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -34,6 +34,40 @@ ), ) +def navigate_to_device_settings_using_service_password(): + td_simulator.td_operation_mode(TDOpModes.MODE_STAN.value, 0) + headerbar_container = squish.waitForObject(names.o_mainMenu_MainMenu, 2000) + settings_menu_object = utility.findChildByText( + headerbar_container, "Settings" + ) + if settings_menu_object is not None: + squish.mouseClick(settings_menu_object) + + td_simulator.td_operation_mode(TDOpModes.MODE_SERV.value, 0) + grid_container = squish.waitForObject(names.o_DeviceSettingsGrid, 3000) + service_option = utility.findChildByText(grid_container, "Service") + + if service_option is not None: + squish.mouseClick(service_option) + + headerbar_container = squish.waitForObject(names.o_headerBar_HeaderBar, 3000) + service_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Service" + ) + if service_screen_headerbar_title_text is not None: + test.compare( + service_screen_headerbar_title_text.text, + config.SERVICE_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Device Settings Screen Title text".format( + config.SERVICE_SCREEN_TITLE_TEXT + ), + ) + input_field = squish.waitForObject(names.o_userConfirmation_TextInput, 3000) + + squish.type(input_field, config.DEFAULT_SERVICE_PASSWORD_RAW) + confirm_button = squish.waitForObject(names.o_userConfirmation_ConfirmButton, 3000) + squish.mouseClick(confirm_button) + def navigation_pageIndicator_step(vStep_name): """ Navigate to the specified page using the step indicator component. Index: suite_leahi/shared/scripts/configuration/utility.py =================================================================== diff -u -rc7d96b722594bb29a7bbc3689715b90af6e3d616 -r477260ff9a68fb041c2a18cb105267ef315b7c01 --- suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision c7d96b722594bb29a7bbc3689715b90af6e3d616) +++ suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -3,12 +3,19 @@ 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 +from leahi_dialin.common.td_defs import TDOpModes,TDTreatmentStates +from configuration import config, navigation +from leahi_dialin.ui import utils +from builtins import int as pyInt td =TD_Messaging() -from leahi_dialin.ui import utils -from builtins import int as pyInt + +def aut(*args): + """ + Joins the executable name and argument + into a single command string + """ + return " ".join(('leahi', *args)) def get_object_from_names(names_dict, error_message = "Missing object", timeout_ms = 200): """ Index: suite_leahi/shared/scripts/names.py =================================================================== diff -u -r0e16f6d7e1f8349a7ccf945c666f6fdab7752d16 -r477260ff9a68fb041c2a18cb105267ef315b7c01 --- suite_leahi/shared/scripts/names.py (.../names.py) (revision 0e16f6d7e1f8349a7ccf945c666f6fdab7752d16) +++ suite_leahi/shared/scripts/names.py (.../names.py) (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -6,7 +6,9 @@ o_Gui_MainView = { "type": "Gui::MainView", "unnamed": 1 } o_QQuickView = { "type": "QQuickView" } o_Overlay = {"container": o_QQuickView, "type": "Overlay" } - +o_mainMenu_MainMenu = {"container": o_Gui_MainView, "id": "_mainMenu", "type": "MainMenu", "unnamed": 1 } +o_headerBar_HeaderBar = {"container": o_Gui_MainView, "id": "_headerBar", "type": "HeaderBar", "unnamed": 1 } + # Solution Infusion o_standByScreen_MainHome = {"container": o_Gui_MainView, "type": "MainHome" } treatmentStack = {"container": o_Gui_MainView, "type": "TreatmentStack" } @@ -223,4 +225,37 @@ o_PreTreatmentCreate_pretreatmentPatientIDEntry_TextEntry = {"container": o_preTreatmentStack_PreTreatmentCreate_PreTreatmentCreate, "id": "_pretreatmentPatientIDEntry", "type": "TextEntry", "unnamed": 1 } o_preTreatmentStack_Text = {"container": o_preTreatmentStack_PreTreatmentStack, "type": "Text", "unnamed": 1 } o_preTreatmentStack_stepIndicator_StepIndicator = {"container": o_preTreatmentStack_PreTreatmentStack, "id": "_stepIndicator", "type": "StepIndicator", "unnamed": 1 } + +# Settings Service +o_SettingsStack_SettingsStack = {"container": o_Gui_MainView, "objectName": "_SettingsStack", "type": "SettingsStack", } +o_UserConfirmation_SettingsServicePassword = {"container": o_SettingsStack_SettingsStack, "objectName": "UserConfirmation", "type": "SettingsServicePassword", } +o_loginPage_Titletext = {"container": o_UserConfirmation_SettingsServicePassword, "id":"_titleText", "type": "Text", "unnamed": 1 } +o_userConfirmation_TextInput = {"container": o_UserConfirmation_SettingsServicePassword, "id": "_input", "type": "TextInput", "unnamed": 1 } +o_headerBar_HeaderBar = {"container": o_Gui_MainView, "id": "_headerBar", "type": "HeaderBar", "unnamed": 1 } +o_userConfirmation_ConfirmButton = {"container": o_UserConfirmation_SettingsServicePassword, "objectName": "_confirmButton", "type": "ConfirmButton", } +o_SettingsHome_confirmButton = {"container": o_SettingsHome, "objectName": "_confirmButton", "type": "ConfirmButton", } +o_SettingsBase_SettingsAdvancedMode = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsAdvancedMode", } +o_settingsAdvancedMode_BaseSwitch = {"container": o_SettingsBase_SettingsAdvancedMode, "id": "_settingsAdvancedMode", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_backButton_AdvancedMode = {"container": o_SettingsBase_SettingsAdvancedMode, "objectName": "_backButton", "type": "BackButton", } +o_SettingsBase_SettingsDateTime = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsDateTime", } +o_SettingsBase_ntpSwitch_BaseSwitch = {"container": o_SettingsBase_SettingsDateTime, "id": "_ntpSwitch", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_backButton_NTP_Switch = {"container": o_SettingsBase_SettingsDateTime, "objectName": "_backButton", "type": "BackButton", } +o_timeContainer_LabelUnitContainer = {"container": o_SettingsBase_SettingsDateTime, "id": "_timeContainer", "type": "LabelUnitContainer", "unnamed": 1 } +o_SettingsBase_SettingsRootSSHAccess = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsRootSSHAccess", } +o_SettingsBase_SSH_LoginSwitch = {"container": o_SettingsBase_SettingsRootSSHAccess, "id": "_settingsRootSSHAccess_SSHDSwitch", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_Root_LoginSwitch = {"container": o_SettingsBase_SettingsRootSSHAccess, "id": "_settingsRootSSHAccess_RootSwitch", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_backButton_RootSSH = {"container": o_SettingsBase_SettingsRootSSHAccess, "objectName": "_backButton", "type": "BackButton", } +o_userConfirmation_SettingsFactoryReset = {"container": o_Gui_MainView, "objectName": "UserConfirmation", "type": "SettingsFactoryReset", } +o_userConfirmation_backButton_FactoryReset = {"container": o_userConfirmation_SettingsFactoryReset, "objectName": "_backButton", "type": "BackButton", } +o_factoryReset_ConfirmButton = {"container": o_userConfirmation_SettingsFactoryReset, "objectName": "_confirmButton", "type": "ConfirmButton", } +o_cancelTouch_TouchRect = {"container": o_Overlay, "id": "_cancelTouch", "type": "TouchRect", "unnamed": 1 } +o_confirmTouch_ConfirmButton = {"container": o_Overlay, "id": "_confirmTouch", "type": "ConfirmButton", "unnamed": 1 } + +#Helpers +o_PreTreatmentSampleStack_PreTreatmentWaterSample = {"container": o_preTreatmentStack_PreTreatmentStack, "objectName": "_PreTreatmentSampleStack", "type": "PreTreatmentWaterSample", } +o_PreTreatmentSampleStack_button_TouchRect = {"container": o_PreTreatmentSampleStack_PreTreatmentWaterSample, "id": "_button", "type": "TouchRect", "unnamed": 1 } +o_preTreatmentStack_repeater_Repeater = {"container": o_preTreatmentStack_PreTreatmentStack, "id": "repeater", "type": "Repeater", "unnamed": 1 } +o_PreTreatmentCreate_bpMeasurementIntervalControl_ValueAdjusterCustom= {"container": o_preTreatmentStack_PreTreatmentCreate_PreTreatmentCreate, "id": "_bpMeasurementIntervalControl", "type": "ValueAdjusterCustom", "unnamed": 1 } +o_preTreatmentStack_confirmButton_ConfirmButton = {"container": o_preTreatmentStack_PreTreatmentStack, "objectName": "_confirmButton", "type": "ConfirmButton", "visible": True } +o_PostTreatmentStack_PostTreatmentStack = {"container": o_Gui_MainView, "objectName": "_PostTreatmentStack", "type": "PostTreatmentStack", } Index: suite_leahi/tst_blood_set_auto/test.py =================================================================== diff -u --- suite_leahi/tst_blood_set_auto/test.py (revision 0) +++ suite_leahi/tst_blood_set_auto/test.py (revision 477260ff9a68fb041c2a18cb105267ef315b7c01) @@ -0,0 +1,240 @@ +# Subject/Title: Blood Set Auto-Load and Auto-Eject - SW - 02 - Q&R +# +# Functionalities: Testing of Blood Set Auto Load and Eject +# +# Steps: +# 1 Handle bloodSetAutoLoad sent messages from UI and handle bloodSetAutoEject sent messages from UI +# Update Advanced Mode back to default +# 2 Start Leahi Application and simulate TD standby mode and navigate to the Installation Page +# Click on Auto Load Button in UI and Verify FW receives the request, Test Rejection Reason +# Test No Rejection and Navigate Create Rx and Fill it, Validate it and Confirm it +# simulate TD Treatment mode and simulate TD Post Treatment mode, Click on Auto Load Button in UI +# And Verify FW receives the request, Test Rejection Reason and Test No Rejection +# Navigate to Device settings using service password and Toggle Advanced Mode Switch +# Navigate to Pre-Treatment No Concentrate Page, instead 3 Installation pages single Installation Page displayed + +import names +import re +from configuration import config, utility, navigation, application_init +from leahi_dialin.ui import utils +from leahi_dialin.ui.td_messaging import TD_Messaging +from leahi_dialin.common.td_defs import TDOpModes, TDTreatmentStates +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols import CAN +from leahi_dialin.utils import conversions + +td_simulator = TD_Messaging() + +# handler for messages from UI to FW +def handle_blood_set_auto_request(message, timestamp=0.0): + """ + Called when the user requests to firmware from UI + @return: None + """ + message = message["message"] + index = MsgFieldPositions.START_POS_FIELD_1 + state, index = conversions.bytearray_to_integer(message, index) + + +def main(): + utils.tstStart(__file__) + test.startSection("Blood Set Auto Load and Eject") + td_interface = TD_Messaging() + can_interface = td_interface.can_interface + global bloodSetAutoLoad + global bloodSetAutoEject + + # handle bloodSetAutoLoad sent messages from UI + if can_interface is not None: + channel_id = CAN.DenaliChannels.ui_to_td_ch_id + message_id = MsgIds.MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST.value + can_interface.register_receiving_publication_function( + channel_id, message_id, handle_blood_set_auto_request + ) + + # handle bloodSetAutoEject sent messages from UI + if can_interface is not None: + channel_id = CAN.DenaliChannels.ui_to_td_ch_id + message_id = MsgIds.MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST.value + can_interface.register_receiving_publication_function( + channel_id, message_id, handle_blood_set_auto_request + ) + + application_init.update_advanced_mode_back_to_default() + startApplication(utility.aut("-q")) + td_simulator.td_operation_mode(TDOpModes.MODE_STAN.value) + mouseClick(waitForObject(names.o_createTreatmentRect_TouchRect, 3000)) + td_simulator.td_operation_mode(TDOpModes.MODE_PRET.value) + + pre_treatment = waitForObjectExists( + names.o_preTreatmentStack_PreTreatmentStack, 3000 + ) + mouseClick(utility.findChildByText(pre_treatment, "Next")) + mouseClick(utility.findChildByText(pre_treatment, "Auto Load")) + test.verify( + waitFor("'bloodSetAutoLoad == 1'", 5000), "Testing UI -> TD message Auto Load" + ) + + td_simulator.td_blood_set_auto_load_response(1) + auto_load_reject_notification = utility.findChildByText( + pre_treatment, config.BLOOD_SET_AUTO_LOAD_REJECTION + ) + auto_load_reject_notification_text = str(auto_load_reject_notification.text) + digit = re.sub(r"^.*?\[(\d+)\].*$", r"\1", auto_load_reject_notification_text) + + if digit: + digit_int = int(float(digit)) + test.compare(1, digit_int, f"Rejection reason number comparison for reason {1}") + test.log(f"Rejection reason text is {auto_load_reject_notification_text}") + td_simulator.td_blood_set_auto_load_response(0) + + stepcount = waitForObjectExists(names.o_preTreatmentStack_repeater_Repeater) + + td_simulator.td_blood_set_auto_load_response(vRejectionReason=0) + stepId = waitForObjectExists(names.o_preTreatmentStack_stepIndicator_StepIndicator) + values = utility.findAllObjectsById(stepId, "_text") + if stepcount.count == 9: + for input_field in values[3:]: + if str(input_field.text) == "Water Sample": + mouseClick( + waitForObject(names.o_PreTreatmentSampleStack_button_TouchRect) + ) + if str(input_field.text) == config.CREATERX: + break + else: + Nextbutton = utility.setObjectText( + obj=names.o_preTreatmentStack_Text, text=config.NEXT + ) + mouseClick(Nextbutton) + else: + for input_field in values[3:]: + test.log(str(input_field.text)) + if str(input_field.text) == "Water Sample": + mouseClick( + waitForObject(names.o_PreTreatmentSampleStack_button_TouchRect) + ) + + if str(input_field.text) == config.CREATERX: + break + else: + Nextbutton = utility.setObjectText( + obj=names.o_preTreatmentStack_Text, text=config.NEXT + ) + mouseClick(Nextbutton) + + mouseClick( + waitForObject(names.o_PreTreatmentCreate_pretreatmentPatientIDEntry_TextEntry) + ) + waitForObject( + names.o_PreTreatmentCreate_pretreatmentPatientIDEntry_TextEntry + ).text = "abcd" + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_bloodFlowRateControl_ValueAdjuster, 50 + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_dialysateFlowRateControl_ValueAdjuster, 50 + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_durationControl_ValueAdjuster, 60 + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_heparinBolusVolumeControl_ValueAdjuster, "0.2" + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_heparinDispensingRateControl_ValueAdjuster, "0.2" + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_heparinStopTimeControl_ValueAdjuster, 60 + ) + utility.select_different_dropdown( + names.o_PreTreatmentCreate_acidConcentrateComboBox_BaseComboBox, + config.ACID_CONCENTRATE, + 2, + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_dialysateTemperatureControl_ValueAdjuster, 37.0 + ) + utility.select_different_dropdown( + names.o_PreTreatmentCreate_dialyzerTypeComboBox_BaseComboBox, + config.DIALYZER_TYPE, + 2, + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_salineBolusVolumeControl_ValueAdjuster, 100 + ) + utility.set_value_based_on_target( + names.o_PreTreatmentCreate_bpMeasurementIntervalControl_ValueAdjusterCustom, 6.0 + ) + utility.select_different_dropdown( + names.o_PreTreatmentCreate_bicarbonateConcentrateComboBox_BaseComboBox, + config.BICARBONATE, + 0, + ) + + pre_treatment = waitForObjectExists( + names.o_preTreatmentStack_PreTreatmentStack, 3000 + ) + validate_button = utility.findChildByText(pre_treatment, "Validate") + mouseClick(validate_button) + td_simulator.td_Treatment_Parameters_Validation(vAccepted=1) + + mouseClick( + waitForObjectExists(names.o_preTreatmentStack_confirmButton_ConfirmButton, 3000) + ) + mouseClick(utility.findChildByText(pre_treatment, "Next")) + mouseClick(utility.findChildByText(pre_treatment, "Start")) + td_simulator.td_operation_mode(TDOpModes.MODE_TREA.value, 0) + td_simulator.td_tx_state( + TDTreatmentStates.TREATMENT_DIALYSIS_STATE.value, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ) + td_simulator.td_operation_mode(TDOpModes.MODE_POST.value, 0) + post_treatment = waitForObjectExists( + names.o_PostTreatmentStack_PostTreatmentStack, 3000 + ) + mouseClick(utility.findChildByText(post_treatment, "Auto Eject")) + test.verify( + waitFor("'bloodSetAutoEject == 1'", 5000), "Testing UI -> TD message Auto Eject" + ) + td_simulator.td_blood_set_auto_eject_response(1) + auto_eject_reject_notification = utility.findChildByText( + post_treatment, config.BLOOD_SET_AUTO_EJECT_REJECTION + ) + auto_eject_reject_notification_text = str(auto_eject_reject_notification.text) + digit = re.sub(r"^.*?\[(\d+)\].*$", r"\1", auto_eject_reject_notification_text) + + if digit: + digit_int = int(float(digit)) + test.compare(1, digit_int, f"Rejection reason number comparison for reason {1}") + test.log(f"Rejection reason text is {auto_eject_reject_notification_text}") + + td_simulator.td_blood_set_auto_eject_response(0) + + td_simulator.td_operation_mode(TDOpModes.MODE_INIT.value, 0) + navigation.navigate_to_device_settings_using_service_password() + grid_container = waitForObject(names.o_DeviceSettingsGrid, 2000) + mouseClick(utility.findChildByText(grid_container, "Advanced Mode")) + + advanced_mode_switch = waitForObject(names.o_settingsAdvancedMode_BaseSwitch, 1000) + # Check current state and toggle Advanced Mode Switch and store the initial state + was_checked = advanced_mode_switch.checked + test.log( + f"Initial Advanced Mode switch state: {'Checked' if was_checked else 'Unchecked'}" + ) + # Perform the toggle action + mouseClick(advanced_mode_switch) + mouseClick(waitForObjectExists(names.o_SettingsBase_backButton_AdvancedMode, 3000)) + + main_menu_container = waitForObject(names.o_mainMenu_MainMenu, 2000) + mouseClick(utility.findChildByText(main_menu_container, "Prescriptions")) + mouseClick(utility.findChildByText(main_menu_container, "Treatment")) + mouseClick(waitForObject(names.o_createTreatmentRect_TouchRect, 2000)) + td_simulator.td_operation_mode(TDOpModes.MODE_PRET.value) + pre_treatment = waitForObjectExists( + names.o_preTreatmentStack_PreTreatmentStack, 3000 + ) + mouseClick(utility.findChildByText(pre_treatment, "Auto Load")) + + td_simulator.td_blood_set_auto_load_response(0) + + mouseClick(utility.findChildByText(pre_treatment, "Next")) + test.endSection()