Index: suite_leahi/shared/scripts/configuration/config.py =================================================================== diff -u -rf6d23e89ccf01b57313b0e920f013dc1027706d4 -rc5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc --- suite_leahi/shared/scripts/configuration/config.py (.../config.py) (revision f6d23e89ccf01b57313b0e920f013dc1027706d4) +++ suite_leahi/shared/scripts/configuration/config.py (.../config.py) (revision c5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc) @@ -45,3 +45,15 @@ WIFI_PARAMETERS_TEXTS = ["SSID", "IP Address", "Gateway", "Subnet Mask", "DNS"] WIFI_SCREEN_SCAN_BUTTON_TEXT = "SCAN" DISABLED = False + +# 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" +SERVICE_SCREEN_TITLE_TEXT = "Service" +USER_MODES_SCREEN_TITLE_TEXT = "User Modes" +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?" Index: suite_leahi/shared/scripts/configuration/utility.py =================================================================== diff -u -rf6d23e89ccf01b57313b0e920f013dc1027706d4 -rc5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc --- suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision f6d23e89ccf01b57313b0e920f013dc1027706d4) +++ suite_leahi/shared/scripts/configuration/utility.py (.../utility.py) (revision c5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc) @@ -40,3 +40,36 @@ found = findChildByText(child, target_text) if found: return found + +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 findAllObjectsByText(parent, target_text): + """ + Recursively finds all child objects that have a 'text' property + matching the target_text. Returns a list of matches. + """ + results = [] + # Use hasattr to safely check for 'text' property before comparing + if hasattr(parent, 'text') and str(parent.text) == target_text: + results.append(parent) + + # Recurse through all children + for child in object.children(parent): + results.extend(findAllObjectsByText(child, target_text)) + + return results \ No newline at end of file Index: suite_leahi/shared/scripts/names.py =================================================================== diff -u -rf6d23e89ccf01b57313b0e920f013dc1027706d4 -rc5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc --- suite_leahi/shared/scripts/names.py (.../names.py) (revision f6d23e89ccf01b57313b0e920f013dc1027706d4) +++ suite_leahi/shared/scripts/names.py (.../names.py) (revision c5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc) @@ -81,3 +81,29 @@ o_SettingsBase_SettingsWiFi = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsWiFi" } o_SettingsBase_WifiScreen_ScanButton = {"container": o_SettingsBase_SettingsWiFi, "id": "_scanButton", "type": "TouchRect", "unnamed": 1 } o_SettingsBase_WifiScreen_BackButton = {"container": o_SettingsBase_SettingsWiFi, "objectName": "_backButton", "type": "BackButton" } + +#Device Settings Wi-Fi +o_SettingsBase_SettingsWiFi = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsWiFi" } +o_SettingsBase_WifiScreen_ScanButton = {"container": o_SettingsBase_SettingsWiFi, "id": "_scanButton", "type": "TouchRect", "unnamed": 1 } +o_SettingsBase_WifiScreen_BackButton = {"container": o_SettingsBase_SettingsWiFi, "objectName": "_backButton", "type": "BackButton" } + +# 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_userConfirmation_TextInput = {"container": o_UserConfirmation_SettingsServicePassword, "echoMode": 2, "id": "_input", "passwordCharacter": "•", "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_SettingsBase_SettingsUserMode = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsUserMode" } +o_SettingsBase_settingsUserMode_BaseSwitch = {"checkable": True, "container": o_SettingsBase_SettingsUserMode, "id": "_settingsUserMode", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_backButton_BackButton = {"container": o_SettingsBase_SettingsUserMode, "objectName": "_backButton", "type": "BackButton" } +o_SettingsBase_SettingsDateTime = {"container": o_Gui_MainView, "objectName": "_SettingsBase", "type": "SettingsDateTime" } +o_SettingsBase_ntpSwitch_BaseSwitch = {"checkable": True, "container": o_SettingsBase_SettingsDateTime, "id": "_ntpSwitch", "type": "BaseSwitch", "unnamed": 1 } +o_SettingsBase_backButton_BackButton_2 = {"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_backButton_BackButton_3 = {"container": o_SettingsBase_SettingsRootSSHAccess, "objectName": "_backButton", "type": "BackButton" } +o_userConfirmation_SettingsFactoryReset = {"container": o_Gui_MainView, "objectName": "UserConfirmation", "type": "SettingsFactoryReset" } +o_userConfirmation_backButton_BackButton = {"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 } Index: suite_leahi/tst_service/test.py =================================================================== diff -u --- suite_leahi/tst_service/test.py (revision 0) +++ suite_leahi/tst_service/test.py (revision c5bf21254e1af66a2459cfb8f0fcbbbe956bd8cc) @@ -0,0 +1,329 @@ +# Subject/Title: Service - SW - 02 - Service - Q&R +# +# Functionalities: Testing items of Service Screen +# +# Steps: +# 1 Start Leahi Application with Argument to navigate to Manufacturing Screen, +# simulate TD Service mode, and In Manufacture screen Reset Password +# 2 Start Leahi Application and Simulate TD Service mode, +# Then, navigate to the Screen screen and enter Password and Click conform +# Navigate to User Mode Screen and Toggle the user mode and Click Back Button +# 3 Navigate to Date and Time Screen and verify and comapre Title bar text +# And Verify the parameter under Date and Time screen and Click Back Button +# 4 Navigate to Enable Root SSH Screen and verify and comapre Title bar text +# And Verify the parameter under Enable Root SSH screen and Click Back Button +# 5 Navigate to Factory Reset Screen and verify and comapre Title bar text +# And Verify the parameter under Factory Reset screen and Click Conform button +# for factory then Click Cancel on Popup. Angain Click conform on Factory Reset +# then Click conform on Popup and Click Back Button + + +import names +from configuration import config, utility, navigation +from leahi_dialin.ui import utils +from leahi_dialin.ui.td_messaging import TD_Messaging +from leahi_dialin.common.td_defs import TDOpModes, TDStandbyStates + +td_simulator = TD_Messaging() + + +def manufacture_login(): + """ + Method to navigate to "Manufacture Login" screen + """ + test.startSection("Navigating to 'Manufacture Login' menu") + td_simulator.td_operation_mode(TDOpModes.MODE_SERV.value, 0) + container = waitForObject(names.o_UserConfirmation_SettingsServicePassword) + + # Find all TextInput objects that share the id "_input" + password_inputs = utility.findAllObjectsById(container, "_input") + + # Use enumerate to track the index (0, 1, 2...) + for index, input_field in enumerate(password_inputs): + if index == 0: + # First field gets the default password + type(input_field, config.DEFAULT_SERVICE_PASSWORD_RAW) + else: + type(input_field, config.NEW_PASSWORD_RAW) + + mouseClick(names.o_userConfirmation_ConfirmButton) + + +def service_login(): + test.startSection("Navigating to 'Service Login' menu") + td_simulator.td_operation_mode(TDOpModes.MODE_SERV.value, 0) + headerbar_container = waitForObject(names.o_headerBar_HeaderBar, 2000) + device_setting_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Device Settings" + ) + if device_setting_screen_headerbar_title_text is not None: + test.compare( + device_setting_screen_headerbar_title_text.text, + config.DEVICE_SETTINGS_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Device Settings Screen Title text".format( + config.DEVICE_SETTINGS_SCREEN_TITLE_TEXT + ), + ) + + grid_container = waitForObject(names.o_DeviceSettingsGrid) + service_option = utility.findChildByText(grid_container, "Service") + + if service_option is not None: + mouseClick(service_option) + + headerbar_container = waitForObject(names.o_headerBar_HeaderBar) + 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 = waitForObject(names.userConfirmation_Password_TextInput) + + type(input_field, config.NEW_PASSWORD_RAW) + confirm_button = waitForObject(names.o_userConfirmation_ConfirmButton) + mouseClick(confirm_button) + + grid_container = waitForObject(names.o_DeviceSettingsGrid) + user_modes_option = utility.findChildByText(grid_container, "User Modes") + + if user_modes_option is not None: + mouseClick(user_modes_option) + + headerbar_container = waitForObject(names.o_headerBar_HeaderBar, 2000) + user_modes_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Service" + ) + if user_modes_screen_headerbar_title_text is not None: + test.compare( + user_modes_screen_headerbar_title_text.text, + config.USER_MODES_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Device Settings Screen Title text".format( + config.USER_MODES_SCREEN_TITLE_TEXT + ), + ) + + # Wait for the toggle switch object + user_mode_switch = waitForObject( + names.o_SettingsBase_settingsUserMode_BaseSwitch, 1000 + ) + + # Check current state and toggle it + # store the initial state + was_checked = user_mode_switch.checked + + test.log(f"Initial switch state: {'Checked' if was_checked else 'Unchecked'}") + + # Perform the toggle action + mouseClick(user_mode_switch) + + # Verify the toggle state has inverted + expected_state = not was_checked + test.compare( + user_mode_switch.checked, + expected_state, + f"Verify switch changed state to {expected_state}", + ) + + # Toggle it back to original state + mouseClick(user_mode_switch) + test.compare( + user_mode_switch.checked, + was_checked, + "Verify switch returned to original state", + ) + + mouseClick(names.o_SettingsBase_backButton_BackButton) + + +def date_and_time_screen(): + grid_container = waitForObject(names.o_DeviceSettingsGrid) + date_and_time_option = utility.findChildByText(grid_container, "Date and Time") + + if date_and_time_option is not None: + mouseClick(date_and_time_option) + + headerbar_container = waitForObject(names.o_headerBar_HeaderBar) + date_and_time_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Date and Time" + ) + if date_and_time_screen_headerbar_title_text is not None: + test.compare( + date_and_time_screen_headerbar_title_text.text, + config.DATE_AND_TIME_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Device Settings Screen Title text".format( + config.DATE_AND_TIME_SCREEN_TITLE_TEXT + ), + ) + grid_container = waitForObject( + names.o_timeContainer_LabelUnitContainer + ) + date_and_time_option = utility.findChildByText(grid_container, "Time") + + if date_and_time_option is not None: + test.compare( + date_and_time_option.text, + "Time", + "{} should be available in Date and Time Screen".format( + date_and_time_option.text + ), + ) + + # Wait for the main grid/container + grid_container = waitForObject(names.o_SettingsBase_SettingsDateTime) + + # Iterate through the list of expected texts from your config + for date_and_time_parameter in config.DATE_AND_TIME_PARAMETERS_TEXTS: + + # Find any child within the container that matches this text + found_elements = utility.findAllObjectsByText( + grid_container, date_and_time_parameter + ) + + # Verify that at least one such element was found + if found_elements: + # Take the first match found in the tree + matched_obj = found_elements[0] + + test.compare( + str(matched_obj.text), + date_and_time_parameter, + f"'{date_and_time_parameter}' found and verified in Date and Time Screen", + ) + + # Wait for the toggle switch object + ntp_mode_switch = waitForObject(names.o_SettingsBase_ntpSwitch_BaseSwitch, 1000) + + # Check current state and toggle it + # store the initial state + was_checked = ntp_mode_switch.checked + + test.log(f"Initial switch state: {'Checked' if was_checked else 'Unchecked'}") + + # Perform the toggle action + mouseClick(ntp_mode_switch) + + # Verify the toggle state has inverted + expected_state = not was_checked + test.compare( + ntp_mode_switch.checked, + expected_state, + f"Verify switch changed state to {expected_state}", + ) + + # Toggle it back to original state + mouseClick(ntp_mode_switch) + test.compare( + ntp_mode_switch.checked, was_checked, "Verify switch returned to original state" + ) + + mouseClick(names.o_SettingsBase_backButton_BackButton_2) + + +def enable_root_ssh_screen(): + grid_container = waitForObject(names.o_DeviceSettingsGrid) + enable_root_ssh_option = utility.findChildByText(grid_container, "Enable Root SSH") + + if enable_root_ssh_option is not None: + mouseClick(enable_root_ssh_option) + + headerbar_container = waitForObject(names.o_headerBar_HeaderBar) + enable_root_ssh_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Enable Root SSH" + ) + if enable_root_ssh_screen_headerbar_title_text is not None: + test.compare( + enable_root_ssh_screen_headerbar_title_text.text, + config.ENABLE_ROOT_SSH_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Enable Root SSH Screen Title text".format( + config.ENABLE_ROOT_SSH_SCREEN_TITLE_TEXT + ), + ) + + # Wait for the main grid/container + grid_container = waitForObject(names.o_SettingsBase_SettingsRootSSHAccess) + + # Iterate through the list of expected texts from your config + for enable_root_ssh_parameter in config.ENABLE_ROOT_SSH_PARAMETERS_TEXTS: + + # Find any child within the container that matches this text + found_elements = utility.findAllObjectsByText( + grid_container, enable_root_ssh_parameter + ) + + # Verify that at least one such element was found + if found_elements: + # Take the first match found in the tree + matched_obj = found_elements[0] + + test.compare( + str(matched_obj.text), + enable_root_ssh_parameter, + f"'{enable_root_ssh_parameter}' found and verified in Enable Root SSH Screen", + ) + + mouseClick(names.o_SettingsBase_backButton_BackButton_3) + + +def factory_reset_screen(): + grid_container = waitForObject(names.o_DeviceSettingsGrid) + factory_reset_option = utility.findChildByText(grid_container, "Factory Reset") + + if factory_reset_option is not None: + mouseClick(factory_reset_option) + + headerbar_container = waitForObject(names.o_headerBar_HeaderBar) + factory_reset_screen_headerbar_title_text = utility.findChildByText( + headerbar_container, "Factory Reset" + ) + if factory_reset_screen_headerbar_title_text is not None: + test.compare( + factory_reset_screen_headerbar_title_text.text, + config.FACTORY_RESET_SCREEN_TITLE_TEXT, + "{} screen is displayed and Comparison of Factory Reset Screen Title text".format( + config.FACTORY_RESET_SCREEN_TITLE_TEXT + ), + ) + + factory_reset_container = waitForObject( + names.o_userConfirmation_SettingsFactoryReset + ) + factory_reset_screen_text = utility.findChildByText( + factory_reset_container, "Do you want to perform the factory reset?" + ) + if factory_reset_screen_text is not None: + test.compare( + factory_reset_screen_text.text, + config.FACTORY_RESET_SCREEN_TEXT, + "{} screen is displayed and Comparison of Factory Reset Screen Title text".format( + config.FACTORY_RESET_SCREEN_TEXT + ), + ) + + mouseClick(names.o_factoryReset_ConfirmButton) + mouseClick(names.o_cancelTouch_TouchRect) + mouseClick(names.o_factoryReset_ConfirmButton) + mouseClick(names.o_confirmTouch_ConfirmButton) + mouseClick(names.o_userConfirmation_backButton_BackButton) + + +def main(): + utils.tstStart(__file__) + + test.startSection( + "Launch Leahi application and Navigate to Device Settings WiFi screen" + ) + startApplication(config.AUT_NAME_AND_ARGUMENT) + manufacture_login() + + startApplication(config.AUT_NAME) + service_login() + date_and_time_screen() + enable_root_ssh_screen() + factory_reset_screen() + test.endSection()