diff --git a/test/ui-test/src/drivers/SquishDriverVerification.py b/test/ui-test/src/drivers/SquishDriverVerification.py index 18af12b01e..3ea713f678 100644 --- a/test/ui-test/src/drivers/SquishDriverVerification.py +++ b/test/ui-test/src/drivers/SquishDriverVerification.py @@ -1,4 +1,7 @@ from drivers.SquishDriver import * +from remotesystem import RemoteSystem +import time +import platform # The default maximum timeout to find ui object _MAX_WAIT_OBJ_TIMEOUT = 5000 @@ -6,6 +9,9 @@ _MAX_WAIT_OBJ_TIMEOUT = 5000 # The default minimum timeout to find ui object _MIN_WAIT_OBJ_TIMEOUT = 500 +# The default maximum timeout to wait for close the app in seconds +_MAX_WAIT_CLOSE_APP_TIMEOUT = 20 + def verify_screen(objName: str, timeout: int=_MAX_WAIT_OBJ_TIMEOUT): result = is_loaded_visible_and_enabled(objName, timeout) @@ -41,3 +47,38 @@ def verify_text_does_not_contain(text: str, substring: str): def verify_text(text1: str, text2: str): test.compare(text1, text2, "Text 1: " + text1 + "\nText 2: " + text2) + +def process_terminated(pid): + try: + remotesys = RemoteSystem() + except: + return False + try: + if platform.system() == "Windows": + if "ProcessId" in remotesys.execute(["wmic", "PROCESS", "where", "ProcessId=%s" % pid, "GET", "ProcessId"])[1]: + return False + if platform.system() == "Darwin" or platform.system() == "Linux": + res = remotesys.execute(["ps", "-p", "%s" % pid]) + return res[0] != "0" + except: + return True + return False + +def verify_the_app_is_closed(pid: int): + closed = False + timeout = False + closingStarted = time.time() + try: + while not process_terminated(pid): + now = time.time() + if now - closingStarted > _MAX_WAIT_CLOSE_APP_TIMEOUT: + timeout = True + break + test.log("Process still exists: PID: %s" % pid) + time.sleep(1) + if not timeout: + closed = True + except: + closed = False + + verify(closed, "app closed") diff --git a/test/ui-test/src/screens/SettingsScreen.py b/test/ui-test/src/screens/SettingsScreen.py index 47c89fa9fc..50f4eb6d31 100644 --- a/test/ui-test/src/screens/SettingsScreen.py +++ b/test/ui-test/src/screens/SettingsScreen.py @@ -17,6 +17,7 @@ from .StatusMainScreen import MainScreenComponents class SidebarComponents(Enum): ADVANCED_OPTION: str = "advanced_StatusBaseText" WALLET_ITEM: str = "wallet_AppMenu_StatusNavigationListItem" + SIGN_OUT_AND_QUIT: str = "sign_out_Quit_ExtraMenu_StatusNavigationListItem" class AdvancedOptionScreen(Enum): @@ -30,10 +31,15 @@ class WalletSettingsScreen(Enum): DELETE_ACCOUNT_CONFIRM: str = "settings_Wallet_AccountView_DeleteAccount_Confirm" NETWORKS_ITEM: str = "settings_Wallet_MainView_Networks" TESTNET_TOGGLE: str = "settings_Wallet_NetworksView_TestNet_Toggle" + + +class ConfirmationDialog(Enum): + SIGN_OUT_CONFIRMATION: str = "signOutConfirmation_StatusButton" class SettingsScreen: - + __pid = 0 + def __init__(self): verify_screen(SidebarComponents.ADVANCED_OPTION.value) @@ -88,4 +94,12 @@ class SettingsScreen: for index in range(accounts.count): if(accounts.itemAtIndex(index).objectName == account_name): return index - return -1 \ No newline at end of file + return -1 + + def sign_out_and_quit_the_app(self, pid: int): + SettingsScreen.__pid = pid + click_obj_by_name(SidebarComponents.SIGN_OUT_AND_QUIT.value) + click_obj_by_name(ConfirmationDialog.SIGN_OUT_CONFIRMATION.value) + + def verify_the_app_is_closed(self): + verify_the_app_is_closed(SettingsScreen.__pid) \ No newline at end of file diff --git a/test/ui-test/testSuites/suite_status/shared/scripts/sections/settings_names.py b/test/ui-test/testSuites/suite_status/shared/scripts/sections/settings_names.py index 4018d3eb8d..4fbab6c2d7 100644 --- a/test/ui-test/testSuites/suite_status/shared/scripts/sections/settings_names.py +++ b/test/ui-test/testSuites/suite_status/shared/scripts/sections/settings_names.py @@ -21,3 +21,7 @@ generatedAccounts_ListView = {"container": statusDesktop_mainWindow, "objectName # Advanced Settings: walletSettingsLineButton = {"container": statusDesktop_mainWindow, "objectName": "WalletSettingsLineButton", "type": "StatusSettingsLineButton", "visible": True} i_understand_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "text": "I understand", "type": "StatusBaseText", "unnamed": 1, "visible": True} + +# Extra Settings: +sign_out_Quit_ExtraMenu_StatusNavigationListItem = {"container": mainWindow_ScrollView, "objectName": "Sign out & Quit-ExtraMenu", "type": "StatusNavigationListItem", "visible": True} +signOutConfirmation_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "signOutConfirmation", "type": "StatusButton", "visible": True} \ No newline at end of file diff --git a/test/ui-test/testSuites/suite_status/shared/steps/settingsSteps.py b/test/ui-test/testSuites/suite_status/shared/steps/settingsSteps.py index b11893d249..3f9490fc44 100644 --- a/test/ui-test/testSuites/suite_status/shared/steps/settingsSteps.py +++ b/test/ui-test/testSuites/suite_status/shared/steps/settingsSteps.py @@ -40,3 +40,11 @@ def step(context: any, address: str): def step(context: any, account_name): _settingsScreen.verify_no_account(account_name) +@When("the user clicks on Sign out and Quit") +def step(context: any): + ctx = currentApplicationContext() + _settingsScreen.sign_out_and_quit_the_app(ctx.pid) + +@Then("the app is closed") +def step(context: any): + _settingsScreen.verify_the_app_is_closed() \ No newline at end of file diff --git a/test/ui-test/testSuites/suite_status/suite.conf b/test/ui-test/testSuites/suite_status/suite.conf index 99c3db9c06..61e25493ea 100644 --- a/test/ui-test/testSuites/suite_status/suite.conf +++ b/test/ui-test/testSuites/suite_status/suite.conf @@ -5,6 +5,6 @@ HOOK_SUB_PROCESSES=false IMPLICITAUTSTART=0 LANGUAGE=Python OBJECTMAPSTYLE=script -TEST_CASES=tst_statusLoginPassword tst_basicChatFlow tst_wallet tst_communityFlows tst_groupChat tst_transaction +TEST_CASES=tst_statusLoginPassword tst_basicChatFlow tst_wallet tst_communityFlows tst_groupChat tst_transaction tst_settingsMenu VERSION=3 WRAPPERS=Qt diff --git a/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.feature b/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.feature new file mode 100644 index 0000000000..97124e4bb9 --- /dev/null +++ b/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.feature @@ -0,0 +1,14 @@ +Feature: Status Desktop Settings Menu + + As a user I want to login the app go to Settings and go through all settings menu + checking the result of each menu item + + Background: Sign up and open settings section + Given A first time user lands on the status desktop and generates new key + When user signs up with username tester123 and password TesTEr16843/!@00 + Then the user lands on the signed in app + When the user opens app settings screen + + Scenario: The user quits the app + When the user clicks on Sign out and Quit + Then the app is closed \ No newline at end of file diff --git a/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.py b/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.py new file mode 100644 index 0000000000..75e47d0b33 --- /dev/null +++ b/test/ui-test/testSuites/suite_status/tst_settingsMenu/test.py @@ -0,0 +1,8 @@ +source(findFile('scripts', 'python/bdd.py')) + +setupHooks('../shared/scripts/bdd_hooks.py') +collectStepDefinitions('./steps', '../shared/steps') + +def main(): + testSettings.throwOnFailure = True + runFeatureFile('test.feature') diff --git a/ui/app/AppLayouts/Profile/panels/MenuPanel.qml b/ui/app/AppLayouts/Profile/panels/MenuPanel.qml index 39e4b03649..a4d6ae6ce4 100644 --- a/ui/app/AppLayouts/Profile/panels/MenuPanel.qml +++ b/ui/app/AppLayouts/Profile/panels/MenuPanel.qml @@ -100,6 +100,7 @@ Column { Repeater { id: extraMenuItems delegate: StatusNavigationListItem { + objectName: model.text + "-ExtraMenu" itemId: model.subsection title: model.text icon.name: model.icon diff --git a/ui/app/AppLayouts/Profile/views/LeftTabView.qml b/ui/app/AppLayouts/Profile/views/LeftTabView.qml index 9b6d2cafa4..e22cfc9fa8 100644 --- a/ui/app/AppLayouts/Profile/views/LeftTabView.qml +++ b/ui/app/AppLayouts/Profile/views/LeftTabView.qml @@ -72,6 +72,7 @@ Item { ConfirmationDialog { id: confirmDialog + confirmButtonObjectName: "signOutConfirmation" header.title: qsTr("Sign out") confirmationText: qsTr("Make sure you have your account password and seed phrase stored. Without them you can lock yourself out of your account and lose funds.") confirmButtonLabel: qsTr("Sign out & Quit")