From 47d70565d5473913ae6742f12f9e4dab03be7ce5 Mon Sep 17 00:00:00 2001 From: Valentina1133 <141633821+Valentina1133@users.noreply.github.com> Date: Tue, 28 Nov 2023 16:26:05 +0400 Subject: [PATCH] Test/test settings messaging identity verification (#341) * test: test_messaging_settings_identity_verification added * chore: skipped test_settings_include_in_total_balance --- constants/messaging.py | 1 + .../settings/respond_to_id_request_popup.py | 49 ++++++++++++ .../settings/verify_identity_popup.py | 38 +++++++++ gui/objects_map/component_names.py | 12 +++ gui/objects_map/settings_names.py | 6 +- gui/screens/settings_messaging.py | 46 ++++++++++- ...essaging_settings_identity_verification.py | 80 +++++++++++++++++++ ...s_watched_addr_include_in_total_balance.py | 1 + 8 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 gui/components/settings/respond_to_id_request_popup.py create mode 100644 gui/components/settings/verify_identity_popup.py create mode 100644 tests/settings/settings_messaging/test_messaging_settings_identity_verification.py diff --git a/constants/messaging.py b/constants/messaging.py index da1f60f..36d93c2 100644 --- a/constants/messaging.py +++ b/constants/messaging.py @@ -6,3 +6,4 @@ class Messaging(Enum): CONTACT_REQUEST_SENT = 'Contact Request Sent' NO_FRIENDS_ITEM = 'You don’t have any contacts yet' NEW_CONTACT_REQUEST = 'New Contact Request' + MESSAGE_NOTE_IDENTITY_REQUEST = 'Ask a question that only the real athletic will be able to answer e.g. a question about a shared experience, or ask athletic to enter a code or phrase you have sent to them via a different communication channel (phone, post, etc...).' diff --git a/gui/components/settings/respond_to_id_request_popup.py b/gui/components/settings/respond_to_id_request_popup.py new file mode 100644 index 0000000..0415261 --- /dev/null +++ b/gui/components/settings/respond_to_id_request_popup.py @@ -0,0 +1,49 @@ +import allure + +import configs +import driver +from gui.components.base_popup import BasePopup +from gui.elements.button import Button +from gui.elements.object import QObject +from gui.elements.text_edit import TextEdit + + +class RespondToIDRequestPopup(BasePopup): + + def __init__(self): + super().__init__() + self._message_input = QObject('messageInput_StatusInput') + self._answer_to_verification_request_field = TextEdit('edit_TextEdit') + self._send_answer_button = Button('send_Answer_StatusButton') + self._refuse_verification_button = Button('refuse_Verification_StatusButton') + self._change_answer_button = Button('change_answer_StatusFlatButton') + self._close_button = Button('close_StatusButton') + + @property + @allure.step('Get message note from identity verification request') + def message_note(self) -> str: + return str(self._message_input.object.placeholderText) + + @property + @allure.step('Get send answer button enabled state') + def is_send_answer_button_enabled(self) -> bool: + return driver.waitForObjectExists(self._send_answer_button.real_name, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC).enabled + + @property + @allure.step('Get change answer button visible state') + def is_change_answer_button_visible(self) -> bool: + return self._change_answer_button.is_visible + + @allure.step('Click send answer button') + def send_answer(self): + self._send_answer_button.click() + + @allure.step('Type message in verification answer') + def type_message(self, value: str): + self._answer_to_verification_request_field.text = value + return self + + @allure.step('Close identification answer popup') + def close(self): + self._close_button.click() diff --git a/gui/components/settings/verify_identity_popup.py b/gui/components/settings/verify_identity_popup.py new file mode 100644 index 0000000..e22154a --- /dev/null +++ b/gui/components/settings/verify_identity_popup.py @@ -0,0 +1,38 @@ +import allure + +import configs +import driver +from gui.components.base_popup import BasePopup +from gui.elements.object import QObject +from gui.elements.text_edit import TextEdit + + +class VerifyIdentityPopup(BasePopup): + + def __init__(self): + super().__init__() + self._message_input = QObject('messageInput_StatusInput') + self._identity_verification_text_field = TextEdit('profileSendContactRequestModal_sayWhoYouAreInput_TextEdit') + self._send_verification_button = TextEdit('send_verification_request_StatusButton') + + @property + @allure.step('Get message note from identity verification request') + def message_note(self) -> str: + return str(self._message_input.object.placeholderText) + + @property + @allure.step('Get send verification button enabled state') + def is_send_verification_button_enabled(self) -> bool: + return driver.waitForObjectExists(self._send_verification_button.real_name, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC).enabled + + @allure.step('Click send verification button') + def send_verification(self): + self._send_verification_button.click() + self.wait_until_hidden() + return self + + @allure.step('Type message in verification request') + def type_message(self, value: str): + self._identity_verification_text_field.text = value + return self diff --git a/gui/objects_map/component_names.py b/gui/objects_map/component_names.py index c89fea7..544467c 100644 --- a/gui/objects_map/component_names.py +++ b/gui/objects_map/component_names.py @@ -349,3 +349,15 @@ switchTabBar_24_words_StatusSwitchTabButton = {"checkable": True, "container": s i_understand_the_key_pair_on_this_Keycard_will_be_deleted_StatusCheckBox = {"checkable": True, "container": statusDesktop_mainWindow_overlay, "id": "confirmation", "type": "StatusCheckBox", "visible": True} statusSmartIdenticonLetter_StatusLetterIdenticon = {"container": statusDesktop_mainWindow_overlay, "objectName": "statusSmartIdenticonLetter", "type": "StatusLetterIdenticon", "visible": True} secondary_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "id": "secondaryButton", "type": "StatusButton", "unnamed": 1, "visible": True} + +# Verify identity popup +profileSendContactRequestModal_sayWhoYouAreInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "ProfileSendContactRequestModal_sayWhoYouAreInput", "type": "TextEdit", "visible": True} +send_verification_request_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "ProfileSendContactRequestModal_sendContactRequestButton", "type": "StatusButton", "visible": True} +close_icon_StatusIcon = {"container": statusDesktop_mainWindow_overlay, "objectName": "close-icon", "type": "StatusIcon", "visible": True} +messageInput_StatusInput = {"container": statusDesktop_mainWindow_overlay, "id": "messageInput", "type": "StatusInput", "unnamed": 1, "visible": True} + +# Respond to ID request popup +send_Answer_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "sendAnswerButton", "type": "StatusButton", "visible": True} +refuse_Verification_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "refuseVerificationButton", "type": "StatusButton", "unnamed": 1, "visible": True} +change_answer_StatusFlatButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "changeAnswerButton", "type": "StatusFlatButton", "visible": True} +close_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "closeButton", "type": "StatusButton", "visible": True} diff --git a/gui/objects_map/settings_names.py b/gui/objects_map/settings_names.py index 2adf898..18f2985 100644 --- a/gui/objects_map/settings_names.py +++ b/gui/objects_map/settings_names.py @@ -1,4 +1,4 @@ -from gui.objects_map.main_names import statusDesktop_mainWindow +from gui.objects_map.main_names import statusDesktop_mainWindow, statusDesktop_mainWindow_overlay from objectmaphelper import * mainWindow_ProfileLayout = {"container": statusDesktop_mainWindow, "objectName": "profileStatusSectionLayout", "type": "StatusSectionLayout", "visible": True} @@ -40,6 +40,10 @@ settingsContentBaseScrollView_receivedRequests_ContactsListPanel = {"container": settingsContentBaseScrollView_mutualContacts_ContactsListPanel = {"container": mainWindow_ContactsView, "id": "mutualContacts", "type": "ContactsListPanel", "unnamed": 1, "visible": True} settingsContentBaseScrollView_Invite_friends_StatusButton = {"checkable": False, "container": mainWindow_ContactsView, "type": "StatusButton", "unnamed": 1, "visible": True} settingsContentBaseScrollView_NoFriendsRectangle = {"container": mainWindow_ContactsView, "type": "NoFriendsRectangle", "unnamed": 1, "visible": True} +view_Profile_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "viewProfile_StatusItem", "type": "StatusMenuItem", "visible": True} +verify_Identity_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "verifyIdentity_StatusItem", "type": "StatusMenuItem", "visible": True} +respond_to_ID_Request_StatusMenuItem = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "pendingIdentity_StatusItem", "type": "StatusMenuItem", "visible": True} +settingsContentBaseScrollView_Respond_to_ID_Request_StatusFlatButton = {"checkable": False, "container": mainWindow_ContactsView, "objectName": "verifyIdentity_StatusItem", "type": "StatusFlatButton", "unnamed": 1, "visible": True} # Keycard Settings View mainWindow_KeycardView = {"container": statusDesktop_mainWindow, "type": "KeycardView", "unnamed": 1, "visible": True} diff --git a/gui/screens/settings_messaging.py b/gui/screens/settings_messaging.py index 76ba4e2..634995f 100644 --- a/gui/screens/settings_messaging.py +++ b/gui/screens/settings_messaging.py @@ -6,7 +6,9 @@ import allure import configs.timeouts import driver from driver.objects_access import walk_children +from gui.components.settings.respond_to_id_request_popup import RespondToIDRequestPopup from gui.components.settings.send_contact_request_popup import SendContactRequest +from gui.components.settings.verify_identity_popup import VerifyIdentityPopup from gui.elements.button import Button from gui.elements.list import List @@ -56,15 +58,30 @@ class ContactItem: elif str(getattr(child, 'objectName', '')) == 'chat-icon': self._chat_button = Button(name='', real_name=driver.objectMap.realName(child)) + @allure.step('Accept request') def accept(self) -> MessagesScreen: assert self._accept_button is not None, 'Button not found' self._accept_button.click() return MessagesScreen().wait_until_appears() + @allure.step('Reject request') def reject(self): assert self._reject_button is not None, 'Button not found' self._reject_button.click() + @allure.step('Open more options popup') + def open_more_options_popup(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC, attempt: int = 2): + try: + self._open_canvas_button.click() + driver.waitFor(lambda: ContactsSettingsView()._view_profile_item.is_visible, timeout_msec) + return self + except: + if attempt: + self._open_canvas_button.click(attempt - 1) + return self + else: + raise f"Popup didn't appear" + class ContactsSettingsView(QObject): @@ -80,13 +97,17 @@ class ContactsSettingsView(QObject): self._contacts_panel = QObject('settingsContentBaseScrollView_mutualContacts_ContactsListPanel') self._invite_friends_button = QObject('settingsContentBaseScrollView_Invite_friends_StatusButton') self._no_friends_item = QObject('settingsContentBaseScrollView_NoFriendsRectangle') + # more options on contact + self._verify_identity_item = QObject('verify_Identity_StatusMenuItem') + self._respond_to_id_request_item = QObject('respond_to_ID_Request_StatusMenuItem') + self._view_profile_item = QObject('view_Profile_StatusMenuItem') + self._respond_to_id_request_button = Button('settingsContentBaseScrollView_Respond_to_ID_Request_StatusFlatButton') @property @allure.step('Get contact items') def contact_items(self) -> typing.List[ContactItem]: return [ContactItem(item) for item in self._contacts_items_list.items] - @property @allure.step('Get title of list with sent pending requests') def pending_request_sent_list_title(self) -> str: @@ -115,10 +136,12 @@ class ContactsSettingsView(QObject): @allure.step('Open pending requests tab') def open_pending_requests(self): self._pending_request_tab.click() + return self @allure.step('Open contacts tab') def open_contacts(self): self._contacts_tab.click() + return self @allure.step('Open contacts request form') def open_contact_request_form(self) -> SendContactRequest: @@ -132,7 +155,6 @@ class ContactsSettingsView(QObject): @allure.step('Accept contact request') def find_contact_in_list( self, contact: str, timeout_sec: int = configs.timeouts.MESSAGING_TIMEOUT_SEC): - self.open_pending_requests() started_at = time.monotonic() request = None while request is None: @@ -146,11 +168,31 @@ class ContactsSettingsView(QObject): @allure.step('Accept contact request') def accept_contact_request(self, contact: str, timeout_sec: int = configs.timeouts.MESSAGING_TIMEOUT_SEC) -> MessagesScreen: + self.open_pending_requests() request = self.find_contact_in_list(contact, timeout_sec) return request.accept() @allure.step('Reject contact request') def reject_contact_request( self, contact: str, timeout_sec: int = configs.timeouts.MESSAGING_TIMEOUT_SEC): + self.open_pending_requests() request = self.find_contact_in_list(contact, timeout_sec) request.reject() + + @allure.step('Open verify identity popup') + def open_more_options_popup( + self, contact: str, timeout_sec: int = configs.timeouts.MESSAGING_TIMEOUT_SEC, attempts: int = 2): + request = self.find_contact_in_list(contact, timeout_sec) + request.open_more_options_popup() + return self + + def verify_identity(self): + self._verify_identity_item.click() + return VerifyIdentityPopup().wait_until_appears() + + def is_respond_to_id_request_visible(self) -> bool: + return self._respond_to_id_request_item.is_visible + + def respond_to_id_request(self): + self._respond_to_id_request_item.click() + return RespondToIDRequestPopup().wait_until_appears() diff --git a/tests/settings/settings_messaging/test_messaging_settings_identity_verification.py b/tests/settings/settings_messaging/test_messaging_settings_identity_verification.py new file mode 100644 index 0000000..607d3de --- /dev/null +++ b/tests/settings/settings_messaging/test_messaging_settings_identity_verification.py @@ -0,0 +1,80 @@ +import time + +import allure +import pytest +from allure_commons._allure import step + +import configs.testpath +import constants +from constants import UserAccount +from constants.messaging import Messaging +from gui.main_window import MainWindow + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/704611', 'Reply to identity request') +@pytest.mark.case(704611) +@pytest.mark.parametrize('user_data_one, user_data_two', [ + (configs.testpath.TEST_USER_DATA / 'user_account_one', configs.testpath.TEST_USER_DATA / 'user_account_two') +]) +def test_messaging_settings_identity_verification(multiple_instance, user_data_one, user_data_two): + user_one: UserAccount = constants.user_account_one + user_two: UserAccount = constants.user_account_two + main_window = MainWindow() + + with multiple_instance() as aut_one, multiple_instance() as aut_two: + with step(f'Launch multiple instances with authorized users {user_one.name} and {user_two.name}'): + for aut, account in zip([aut_one, aut_two], [user_one, user_two]): + aut.attach() + main_window.wait_until_appears(configs.timeouts.APP_LOAD_TIMEOUT_MSEC).prepare() + main_window.authorize_user(account) + main_window.hide() + + with step(f'User {user_two.name}, get chat key'): + aut_two.attach() + main_window.prepare() + profile_popup = main_window.left_panel.open_user_canvas().open_profile_popup() + chat_key = profile_popup.chat_key + profile_popup.close() + main_window.hide() + + with step(f'User {user_one.name}, send contact request to {user_two.name}'): + aut_one.attach() + main_window.prepare() + settings = main_window.left_panel.open_settings() + messaging_settings = settings.left_panel.open_messaging_settings() + contacts_settings = messaging_settings.open_contacts_settings() + contact_request_popup = contacts_settings.open_contact_request_form() + contact_request_popup.send(chat_key, f'Hello {user_two.name}') + main_window.hide() + + with step(f'User {user_two.name}, accept contact request from {user_one.name}'): + aut_two.attach() + main_window.prepare() + contacts_settings = main_window.left_panel.open_settings().left_panel.open_messaging_settings().open_contacts_settings() + contacts_settings.open_pending_requests().accept_contact_request(user_one.name) + + with step(f'Verify that contact appeared in contacts list of {user_two.name} in messaging settings'): + contacts_settings = main_window.left_panel.open_settings().left_panel.open_messaging_settings().open_contacts_settings() + contacts_settings.open_contacts() + main_window.hide() + + with step(f'Send verify identity request from {user_one.name} to {user_two.name}'): + aut_one.attach() + main_window.prepare() + verify_identity_popup = contacts_settings.open_contacts().open_more_options_popup( + user_two.name).verify_identity() + assert verify_identity_popup.message_note == Messaging.MESSAGE_NOTE_IDENTITY_REQUEST.value + assert not verify_identity_popup.is_send_verification_button_enabled + verify_identity_popup.type_message('Hi. Is that you?').send_verification() + main_window.hide() + + with step(f'Check incoming identity request for {user_two.name}'): + aut_two.attach() + main_window.prepare() + time.sleep(2) + respond_identity_popup = contacts_settings.open_more_options_popup(user_one.name).respond_to_id_request() + respond_identity_popup.type_message('Hi. Yes, its me').send_answer() + + with step(f'Answer has been sent {user_two.name}'): + assert respond_identity_popup.is_change_answer_button_visible + respond_identity_popup.close() diff --git a/tests/settings/settings_wallet/test_wallet_settings_watched_addr_include_in_total_balance.py b/tests/settings/settings_wallet/test_wallet_settings_watched_addr_include_in_total_balance.py index 1991329..73991dc 100644 --- a/tests/settings/settings_wallet/test_wallet_settings_watched_addr_include_in_total_balance.py +++ b/tests/settings/settings_wallet/test_wallet_settings_watched_addr_include_in_total_balance.py @@ -20,6 +20,7 @@ from gui.screens.settings_wallet import WalletSettingsView pytest.param('0x7f1502605A2f2Cc01f9f4E7dd55e549954A8cD0C', ''.join(random.choices(string.ascii_letters + string.digits, k=20))) ]) +@pytest.mark.skip(reason="https://github.com/status-im/desktop-qa-automation/issues/343") def test_settings_include_in_total_balance(main_screen: MainWindow, name, watched_address): with (step('Open wallet on main screen and check the total balance for new account is 0')): wallet_main_screen = main_screen.left_panel.open_wallet()