diff --git a/test/e2e/gui/components/profile_popup.py b/test/e2e/gui/components/profile_popup.py index 2d2ed045a5..55eca2c572 100644 --- a/test/e2e/gui/components/profile_popup.py +++ b/test/e2e/gui/components/profile_popup.py @@ -6,6 +6,7 @@ import constants import driver from gui.components.base_popup import BasePopup from gui.components.context_menu import ContextMenu +from gui.components.settings.nickname_popup import NicknamePopup from gui.components.settings.block_user_popup import BlockUserPopup from gui.components.settings.review_contact_request_popup import AcceptRequestFromProfile from gui.components.settings.send_contact_request_popup import SendContactRequestFromProfile @@ -111,6 +112,7 @@ class ProfilePopupFromMembers(ProfilePopup): self._menu_button = Button(names.menuButton_StatusFlatButton) self._block_user_menu_item = Button(names.block_user_StatusMenuItem) self._add_nickname_menu_item = Button(names.add_nickname_StatusMenuItem) + self._display_name = TextLabel(names.profileDialog_displayName_StatusBaseText) @allure.step('Click send request button') def send_request(self): @@ -154,3 +156,18 @@ class ProfilePopupFromMembers(ProfilePopup): def unblock_user(self): self._unblock_button.click() return UnblockUserPopup().wait_until_appears() + + @allure.step('Open add nickname popup from menu') + def add_nickname_from_menu(self): + self.click_menu_button() + self._add_nickname_menu_item.click() + return NicknamePopup().wait_until_appears() + + @allure.step('Remove nickname from menu') + def remove_nickname_from_menu(self): + self.click_menu_button() + self._add_nickname_menu_item.click() + + @allure.step('Get display name') + def get_display_name(self) -> str: + return self._display_name.text diff --git a/test/e2e/gui/components/settings/nickname_popup.py b/test/e2e/gui/components/settings/nickname_popup.py new file mode 100644 index 0000000000..c613522ba9 --- /dev/null +++ b/test/e2e/gui/components/settings/nickname_popup.py @@ -0,0 +1,39 @@ +import allure + +import configs +from gui.components.base_popup import BasePopup +from gui.elements.button import Button +from gui.elements.text_edit import TextEdit +from gui.objects_map import names + + +class NicknamePopup(BasePopup): + + def __init__(self): + super().__init__() + self._nickname_field = TextEdit(names.nickname_edit_TextEdit) + self._cancel_button = Button(names.cancel_nickname_StatusFlatButton) + self._add_nickname_button = Button(names.add_nickname_StatusButton) + self._remove_nickname = Button(names.remove_nickname_StatusFlatButton) + self._change_nickname = Button(names.change_nickname_StatusButton) + + @allure.step('Wait until appears {0}') + def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): + self._nickname_field.wait_until_appears(timeout_msec) + return self + + @allure.step('Enter nickname') + def enter_nickname(self, name: str): + self._nickname_field.text = name + + @allure.step('Add nickname') + def add_nickname(self): + self._add_nickname_button.click() + + @allure.step('Change nickname') + def change_nickname(self): + self._change_nickname.click() + + @allure.step('Remove nickname') + def remove_nickname(self): + self._remove_nickname.click() diff --git a/test/e2e/gui/objects_map/names.py b/test/e2e/gui/objects_map/names.py index e9d21e260f..2c35207633 100644 --- a/test/e2e/gui/objects_map/names.py +++ b/test/e2e/gui/objects_map/names.py @@ -110,6 +110,7 @@ menuButton_StatusFlatButton = {"checkable": False, "container": profileDialogVie block_user_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "blockUserStatusAction", "type": "StatusMenuItem", "visible": True} add_nickname_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "addEditNickNameStatusAction", "type": "StatusMenuItem", "visible": True} unblock_user_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "unblockUserProfileButton", "type": "StatusButton", "visible": True} +profileDialog_displayName_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "objectName": "ProfileDialog_displayName", "type": "StatusBaseText", "visible": True} # Share profile popup o_Image = {"container": statusDesktop_mainWindow_overlay, "objectName": "profileQRCodeImage", "type": "Image", "visible": True} @@ -235,6 +236,14 @@ unblock_StatusButton = {"checkable": False, "container": statusDesktop_mainWindo unblockingText_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "objectName": "unblockingText", "type": "StatusBaseText", "visible": True} cancel_StatusFlatButton_unblock = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "cancelButton", "type": "StatusFlatButton", "visible": True} +# Nickname popup +nicknameInput_StatusInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "nicknameInput", "type": "StatusInput", "visible": True} +nickname_edit_TextEdit = {"container": nicknameInput_StatusInput, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True} +add_nickname_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "addChangeNicknameButton", "type": "StatusButton", "visible": True} +cancel_nickname_StatusFlatButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "cancelButton", "type": "StatusFlatButton", "visible": True} +remove_nickname_StatusFlatButton = {"checkable": False, "container": o_Overlay, "objectName": "removeNicknameButton", "text": "Remove nickname", "type": "StatusFlatButton", "visible": True} +change_nickname_StatusButton = {"checkable": False, "container": o_Overlay, "objectName": "addChangeNicknameButton", "text": "Change nickname", "type": "StatusButton", "visible": True} + """ Common """ edit_TextEdit = {"container": statusDesktop_mainWindow_overlay, "type": "TextEdit", "unnamed": 1, "visible": True} diff --git a/test/e2e/gui/objects_map/settings_names.py b/test/e2e/gui/objects_map/settings_names.py index a18df318c9..0499395994 100644 --- a/test/e2e/gui/objects_map/settings_names.py +++ b/test/e2e/gui/objects_map/settings_names.py @@ -55,6 +55,9 @@ respond_to_ID_Request_StatusMenuItem = {"checkable": False, "container": statusD settingsContentBaseScrollView_Respond_to_ID_Request_StatusFlatButton = {"checkable": False, "container": mainWindow_ContactsView, "objectName": "verifyIdentity_StatusItem", "type": "StatusFlatButton", "unnamed": 1, "visible": True} contactsTabBar_Blocked_StatusTabButton = {"checkable": True, "container": mainWindow_ContactsView, "objectName": "ContactsView_Blocked_Button", "type": "StatusTabButton", "visible": True} unblock_user_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "unblock_StatusItem", "type": "StatusMenuItem", "visible": True} +edit_nickname_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "rename_StatusItem", "type": "StatusMenuItem", "visible": True} +remove_nickname_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "removeNickname_StatusItem", "type": "StatusMenuItem", "visible": True} +add_nickname_more_options_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "rename_StatusItem", "type": "StatusMenuItem", "visible": True} # Keycard Settings View mainWindow_KeycardView = {"container": statusDesktop_mainWindow, "type": "KeycardView", "unnamed": 1, "visible": True} diff --git a/test/e2e/gui/screens/settings_messaging.py b/test/e2e/gui/screens/settings_messaging.py index c93766a13f..7c39ef5eb0 100644 --- a/test/e2e/gui/screens/settings_messaging.py +++ b/test/e2e/gui/screens/settings_messaging.py @@ -120,7 +120,10 @@ class ContactsSettingsView(QObject): self._view_profile_item = QObject(settings_names.view_Profile_StatusMenuItem) self._respond_to_id_request_button = Button( settings_names.settingsContentBaseScrollView_Respond_to_ID_Request_StatusFlatButton) - self._unblock_item = Button(settings_names.unblock_user_StatusMenuItem) + self._unblock_item = QObject(settings_names.unblock_user_StatusMenuItem) + self._add_nickname_item = QObject(settings_names.add_nickname_more_options_StatusMenuItem) + self._edit_nickname_item = QObject(settings_names.edit_nickname_StatusMenuItem) + self._remove_nickname_item = QObject(settings_names.remove_nickname_StatusMenuItem) @property @allure.step('Get contact items') diff --git a/test/e2e/tests/user_guide_tests/test_add_edit_remove_nickname.py b/test/e2e/tests/user_guide_tests/test_add_edit_remove_nickname.py new file mode 100644 index 0000000000..9dc29ae119 --- /dev/null +++ b/test/e2e/tests/user_guide_tests/test_add_edit_remove_nickname.py @@ -0,0 +1,102 @@ +import allure +import pytest +from allure_commons._allure import step + +import constants +import driver +from constants import UserAccount +from constants.community_settings import BlockPopupWarnings, ToastMessages +from gui.main_window import MainWindow +from . import marks +import configs + +pytestmark = marks + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/738772', + "") +# @pytest.mark.case(738772) +@pytest.mark.parametrize('user_data_one, user_data_two, user_data_three', [ + (configs.testpath.TEST_USER_DATA / 'squisher', configs.testpath.TEST_USER_DATA / 'athletic', + configs.testpath.TEST_USER_DATA / 'nervous') +]) +def test_add_edit_remove_nickname(multiple_instances, user_data_one, user_data_two, user_data_three): + user_one: UserAccount = constants.user_account_one + user_two: UserAccount = constants.user_account_two + user_three: UserAccount = constants.user_account_three + timeout = configs.timeouts.UI_LOAD_TIMEOUT_MSEC + main_screen = MainWindow() + + with multiple_instances(user_data=user_data_one) as aut_one, multiple_instances( + user_data=user_data_two) as aut_two, multiple_instances(user_data=user_data_three) as aut_three: + with step(f'Launch multiple instances with authorized users {user_one.name}, {user_two.name}, {user_three}'): + for aut, account in zip([aut_one, aut_two, aut_three], [user_one, user_two, user_three]): + aut.attach() + main_screen.wait_until_appears(configs.timeouts.APP_LOAD_TIMEOUT_MSEC).prepare() + main_screen.authorize_user(account) + main_screen.hide() + + with step( + f'User {user_one.name}, block contact {user_two.name} from user profile and verify button Unblock appeared'): + aut_one.attach() + main_screen.prepare() + community_screen = main_screen.left_panel.select_community('Community with 2 users') + profile_popup = community_screen.right_panel.click_member(user_two.name) + block_popup = profile_popup.block_user() + warning_text = BlockPopupWarnings.BLOCK_WARNING_PART_1.value + user_two.name + BlockPopupWarnings.BLOCK_WARNING_PART_2.value + assert driver.waitFor(lambda: block_popup.get_warning_text() == warning_text, + timeout), f'Text is incorrect, actual text is {block_popup.get_warning_text()}, correct text is {warning_text}' + block_popup.block() + with step('Check that Unblock user button appeared'): + assert driver.waitFor(lambda: profile_popup.is_unblock_button_visible, + timeout), f"Unblock button did not appear" + main_screen.left_panel.click() + + with step('Check toast message about blocked member'): + toast_messages = main_screen.wait_for_notification() + message_1 = ToastMessages.REMOVED_CONTACT_TOAST.value + message_2 = user_two.name + ToastMessages.BLOCKED_USER_TOAST.value + assert driver.waitFor(lambda: message_1 in toast_messages, + timeout), f"Toast message {message_1} is incorrect, current message is {toast_messages}" + assert driver.waitFor(lambda: message_2 in toast_messages, + timeout), f"Toast message {message_2} is incorrect, current message is {toast_messages}" + main_screen.hide() + + with step(f'User {user_two.name} does not see {user_one.name} in contacts list'): + aut_two.attach() + main_screen.prepare() + contacts_settings = main_screen.left_panel.open_settings().left_panel.open_messaging_settings().open_contacts_settings() + assert driver.waitFor(lambda: user_one.name not in contacts_settings.contact_items, timeout) + main_screen.hide() + + with step( + f'User {user_one.name}, unblock {user_two.name} from contact settings and verify {user_two.name} was removed from blocked list'): + aut_one.attach() + main_screen.prepare() + contacts_settings = main_screen.left_panel.open_settings().left_panel.open_messaging_settings().open_contacts_settings() + unblock_popup = contacts_settings.open_blocked().open_more_options_popup(user_two.name).unblock_user() + warning_text = BlockPopupWarnings.UNBLOCK_TEXT_1.value + user_two.name + BlockPopupWarnings.UNBLOCK_TEXT_2.value + assert driver.waitFor(lambda: unblock_popup.get_warning_text() == warning_text, + timeout), f'Text is incorrect, actual text is {unblock_popup.get_warning_text()}, correct text is {warning_text}' + unblock_popup.unblock() + + with step('Check toast message about unblocked member'): + toast_messages = main_screen.wait_for_notification() + message_2 = user_two.name + ToastMessages.UNBLOCKED_USER_TOAST.value + assert driver.waitFor(lambda: message_2 in toast_messages, + timeout), f"Toast message {message_2} is incorrect, current message is {toast_messages}" + + with step( + f'User {user_one.name}, block stranger {user_three.name} from user profile and verify button Unblock appeared'): + community_screen = main_screen.left_panel.select_community('Community with 2 users') + profile_popup = community_screen.right_panel.click_member(user_three.name) + block_popup = profile_popup.block_user() + block_popup.block() + + with step('Check that Unblock user button appeared'): + assert driver.waitFor(lambda: profile_popup.is_unblock_button_visible, timeout), f"Unblock button did not appear" + + with step( + f'User {user_one.name}, unblock stranger {user_three.name} from user profile and verify that Unblock button dissapeared and send request is visible again'): + profile_popup.unblock_user().unblock() + assert driver.waitFor(lambda: profile_popup.is_send_request_button_visible(), timeout) diff --git a/ui/imports/shared/popups/NicknamePopup.qml b/ui/imports/shared/popups/NicknamePopup.qml index f29f212db6..96c4641cd0 100644 --- a/ui/imports/shared/popups/NicknamePopup.qml +++ b/ui/imports/shared/popups/NicknamePopup.qml @@ -34,6 +34,7 @@ CommonContactDialog { StatusInput { Layout.fillWidth: true id: nicknameInput + objectName: "nicknameInput" label: qsTr("Nickname") input.clearable: true text: root.nickname @@ -73,6 +74,7 @@ CommonContactDialog { } StatusBaseText { + objectName: "nicknameHelpText" Layout.fillWidth: true text: qsTr("Nicknames help you identify others and are only visible to you") wrapMode: Text.WordWrap @@ -82,11 +84,13 @@ CommonContactDialog { rightButtons: ObjectModel { StatusFlatButton { + objectName: "cancelButton" visible: !d.editMode text: qsTr("Cancel") onClicked: root.close() } StatusFlatButton { + objectName: "removeNicknameButton" visible: d.editMode borderColor: "transparent" type: StatusBaseButton.Type.Danger @@ -94,6 +98,7 @@ CommonContactDialog { onClicked: root.removeNicknameRequested() } StatusButton { + objectName: "addChangeNicknameButton" enabled: root.nickname !== nicknameInput.text && nicknameInput.valid text: d.editMode ? qsTr("Change nickname") : qsTr("Add nickname") onClicked: root.editDone(nicknameInput.text) diff --git a/ui/imports/shared/views/chat/ProfileContextMenu.qml b/ui/imports/shared/views/chat/ProfileContextMenu.qml index 51b6cc6322..3f11d231bd 100644 --- a/ui/imports/shared/views/chat/ProfileContextMenu.qml +++ b/ui/imports/shared/views/chat/ProfileContextMenu.qml @@ -219,6 +219,7 @@ StatusMenu { } StatusAction { + objectName: "removeNickname_StatusItem" text: qsTr("Remove nickname") icon.name: "delete" type: StatusAction.Type.Danger