From 956f86fcede6be6e0a8869231da8bc9ccfb33f24 Mon Sep 17 00:00:00 2001 From: Valentina Novgorodtceva Date: Mon, 8 Apr 2024 12:25:17 +0700 Subject: [PATCH] test: admin can kick a member and delete message --- test/e2e/constants/community_settings.py | 1 + .../components/community/kick_member_popup.py | 16 +++ test/e2e/gui/main_window.py | 6 +- test/e2e/gui/objects_map/communities_names.py | 5 +- test/e2e/gui/objects_map/messaging_names.py | 1 + test/e2e/gui/objects_map/names.py | 3 + test/e2e/gui/screens/community_settings.py | 21 ++++ test/e2e/gui/screens/messages.py | 5 + .../e2e/tests/communities/test_communities.py | 119 +++++++++++++++++- 9 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 test/e2e/gui/components/community/kick_member_popup.py diff --git a/test/e2e/constants/community_settings.py b/test/e2e/constants/community_settings.py index 435be03f15..987f72e70a 100644 --- a/test/e2e/constants/community_settings.py +++ b/test/e2e/constants/community_settings.py @@ -33,6 +33,7 @@ class ToastMessages(Enum): CREATE_PERMISSION_TOAST = 'Community permission created' UPDATE_PERMISSION_TOAST = 'Community permission updated' DELETE_PERMISSION_TOAST = 'Community permission deleted' + KICKED_USER_TOAST = ' was kicked from ' class LimitWarnings(Enum): diff --git a/test/e2e/gui/components/community/kick_member_popup.py b/test/e2e/gui/components/community/kick_member_popup.py new file mode 100644 index 0000000000..7404c1ad64 --- /dev/null +++ b/test/e2e/gui/components/community/kick_member_popup.py @@ -0,0 +1,16 @@ +import allure + +from gui.components.base_popup import BasePopup +from gui.elements.button import Button +from gui.objects_map import names + + +class KickMemberPopup(BasePopup): + + def __init__(self): + super().__init__() + self._kick_confirm_button = Button(names.confirm_kick_StatusButton) + + @allure.step('Confirm kicking member') + def confirm_kicking(self): + self._kick_confirm_button.click() diff --git a/test/e2e/gui/main_window.py b/test/e2e/gui/main_window.py index ad1e3f94cb..2f002fce1c 100644 --- a/test/e2e/gui/main_window.py +++ b/test/e2e/gui/main_window.py @@ -50,11 +50,7 @@ class LeftPanel(QObject): for obj in driver.findAllObjects(self._community_template_button.real_name): community_names.append(obj.name) - if len(community_names) == 0: - raise LookupError( - 'Communities not found') - else: - return community_names + return community_names @property @allure.step('Get user badge color') diff --git a/test/e2e/gui/objects_map/communities_names.py b/test/e2e/gui/objects_map/communities_names.py index 20cc15e702..6f6abc3b8e 100644 --- a/test/e2e/gui/objects_map/communities_names.py +++ b/test/e2e/gui/objects_map/communities_names.py @@ -72,8 +72,9 @@ communityOverviewSettingsCommunityDescription_StatusBaseText = {"container": mai mainWindow_Edit_Community_StatusButton = {"container": statusDesktop_mainWindow, "objectName": "communityOverviewSettingsEditCommunityButton", "type": "StatusButton", "visible": True} # Members Settings View mainWindow_MembersSettingsPanel = {"container": mainWindow_communityLoader_Loader, "type": "MembersSettingsPanel", "unnamed": 1, "visible": True} -embersListViews_ListView = {"container": mainWindow_MembersSettingsPanel, "objectName": "CommunityMembersTabPanel_MembersListViews", "type": "ListView", "visible": True} -memberItem_StatusMemberListItem = {"container": embersListViews_ListView, "id": "memberItem", "type": "StatusMemberListItem", "unnamed": 1, "visible": True} +membersListViews_ListView = {"container": mainWindow_MembersSettingsPanel, "objectName": "CommunityMembersTabPanel_MembersListViews", "type": "ListView", "visible": True} +memberItem_StatusMemberListItem = {"container": membersListViews_ListView, "id": "memberItem", "type": "StatusMemberListItem", "unnamed": 1, "visible": True} +communitySettings_MembersTab_Member_Kick_Button = {"container": membersListViews_ListView, "objectName": "MemberListItem_KickButton", "type": "StatusButton", "visible": True} # Tokens View mainWindow_mintPanel_MintTokensSettingsPanel = {"container": mainWindow_StatusWindow, "id": "mintPanel", "type": "MintTokensSettingsPanel", "unnamed": 1, "visible": True} diff --git a/test/e2e/gui/objects_map/messaging_names.py b/test/e2e/gui/objects_map/messaging_names.py index 88ed9abbdb..b2273cdf9e 100644 --- a/test/e2e/gui/objects_map/messaging_names.py +++ b/test/e2e/gui/objects_map/messaging_names.py @@ -65,6 +65,7 @@ groupUserListPanel_StatusMemberListItem = {"container": mainWindow_userListPanel # Message quick actions mainWindow_chatLogView_StatusListView = {"container": statusDesktop_mainWindow, "objectName": "chatLogView", "type": "StatusListView", "visible": True} chatLogView_chatMessageViewDelegate_MessageView = {"container": mainWindow_chatLogView_StatusListView, "index": 0, "objectName": "chatMessageViewDelegate", "type": "MessageView", "visible": True} +chatMessageViewDelegate_deletedMessage_RowLayout = {"container": chatLogView_chatMessageViewDelegate_MessageView, "id": "deletedMessage", "type": "RowLayout", "unnamed": 1, "visible": True} chatMessageViewDelegate_StatusMessageQuickActions = {"container": chatLogView_chatMessageViewDelegate_MessageView, "type": "StatusMessageQuickActions", "unnamed": 1, "visible": True} chatMessageViewDelegate_pin_icon_StatusIcon = {"container": chatLogView_chatMessageViewDelegate_MessageView, "objectName": "pin-icon", "type": "StatusIcon", "visible": True} chatMessageViewDelegate_unpin_icon_StatusIcon = {"container": chatLogView_chatMessageViewDelegate_MessageView, "objectName": "unpin-icon", "type": "StatusIcon", "visible": True} diff --git a/test/e2e/gui/objects_map/names.py b/test/e2e/gui/objects_map/names.py index 7eb784219f..bb5da5a3d5 100644 --- a/test/e2e/gui/objects_map/names.py +++ b/test/e2e/gui/objects_map/names.py @@ -159,6 +159,9 @@ join_StatusButton = { "container": statusDesktop_mainWindow_overlay, "type": "St welcome_authenticate_StatusButton = {"container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "unnamed": 1, "visible": True} share_your_addresses_to_join_StatusButton = {"container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "unnamed": 1, "visible": True} +# Kick member popup +confirm_kick_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "CommunityMembers_KickModal_KickButton", "type": "StatusButton", "visible": True} + """ Settings """ # Send Contact Request diff --git a/test/e2e/gui/screens/community_settings.py b/test/e2e/gui/screens/community_settings.py index ee000e45af..2a91fa7dd2 100644 --- a/test/e2e/gui/screens/community_settings.py +++ b/test/e2e/gui/screens/community_settings.py @@ -6,6 +6,7 @@ import allure import driver from driver.objects_access import walk_children from gui.components.community.color_select_popup import ColorSelectPopup +from gui.components.community.kick_member_popup import KickMemberPopup from gui.components.community.tags_select_popup import TagsSelectPopup from gui.components.os.open_file_dialogs import OpenFileDialog from gui.components.picture_edit_popup import PictureEditPopup @@ -260,12 +261,32 @@ class MembersView(QObject): def __init__(self): super().__init__(communities_names.mainWindow_MembersSettingsPanel) self._member_list_item = QObject(communities_names.memberItem_StatusMemberListItem) + self._kick_member_button = Button(communities_names.communitySettings_MembersTab_Member_Kick_Button) @property @allure.step('Get community members') def members(self) -> typing.List[str]: return [str(member.title) for member in driver.findAllObjects(self._member_list_item.real_name)] + @allure.step('Get community member object') + def get_member_object(self, member_name: str): + for item in driver.findAllObjects(self._member_list_item.real_name): + if str(getattr(item, 'title', '')) == str(member_name): + return item + else: + raise LookupError(f'Member not found') + + @allure.step('Kick community member') + def kick_member(self, member_name: str): + time.sleep(3) + member = self.get_member_object(member_name) + QObject(real_name=driver.objectMap.realName(member)).hover() + self._kick_member_button.click() + kick_member_popup = KickMemberPopup() + assert kick_member_popup.exists + kick_member_popup.confirm_kicking() + + class TokensView(QObject): def __init__(self): diff --git a/test/e2e/gui/screens/messages.py b/test/e2e/gui/screens/messages.py index 812f419116..3f42b20cb2 100644 --- a/test/e2e/gui/screens/messages.py +++ b/test/e2e/gui/screens/messages.py @@ -173,6 +173,7 @@ class ChatView(QObject): def __init__(self): super().__init__(messaging_names.mainWindow_ChatColumnView) self._message_list_item = QObject(messaging_names.chatLogView_chatMessageViewDelegate_MessageView) + self._deleted_message = QObject(messaging_names.chatMessageViewDelegate_deletedMessage_RowLayout) @allure.step('Get messages') def messages(self, index: int) -> typing.List[Message]: @@ -185,6 +186,10 @@ class ChatView(QObject): _messages.append(Message(item)) return _messages + @allure.step('Get deleted message state') + def get_deleted_message_state(self): + return self._deleted_message.exists + def find_message_by_text(self, message_text: str, index: int): message = None started_at = time.monotonic() diff --git a/test/e2e/tests/communities/test_communities.py b/test/e2e/tests/communities/test_communities.py index 7234572b32..2e9c4ec793 100644 --- a/test/e2e/tests/communities/test_communities.py +++ b/test/e2e/tests/communities/test_communities.py @@ -1,9 +1,14 @@ +from copy import deepcopy +from datetime import datetime + import allure import pytest from allure_commons._allure import step import driver -from constants import ColorCodes +from constants import ColorCodes, UserAccount +from constants.community_settings import ToastMessages +from gui.screens.messages import MessagesScreen from . import marks import configs.testpath @@ -130,3 +135,115 @@ def test_edit_community(main_screen: MainWindow, params): assert community_info.name == params['name'] assert community_info.description == params['description'] assert '1' in community_info.members + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703252', 'Kick user') +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703254', 'Edit chat - Delete any message') +@pytest.mark.case(703252, 703252) +def test_community_admin_kick_member_and_delete_message(multiple_instances): + user_one: UserAccount = constants.user_account_one + user_two: UserAccount = constants.user_account_two + community_params = deepcopy(constants.community_params) + community_params['name'] = f'{datetime.now():%d%m%Y_%H%M%S}' + main_screen = MainWindow() + + with multiple_instances() as aut_one, multiple_instances() 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_screen.wait_until_appears(configs.timeouts.APP_LOAD_TIMEOUT_MSEC).prepare() + main_screen.authorize_user(account) + main_screen.hide() + + with step(f'User {user_two.name}, get chat key'): + aut_two.attach() + main_screen.prepare() + profile_popup = main_screen.left_panel.open_online_identifier().open_profile_popup_from_online_identifier() + chat_key = profile_popup.copy_chat_key + profile_popup.close() + main_screen.hide() + + with step(f'User {user_one.name}, send contact request to {user_two.name}'): + aut_one.attach() + main_screen.prepare() + settings = main_screen.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_screen.hide() + + with step(f'User {user_two.name}, accept contact request from {user_one.name}'): + aut_two.attach() + main_screen.prepare() + settings = main_screen.left_panel.open_settings() + messaging_settings = settings.left_panel.open_messaging_settings() + contacts_settings = messaging_settings.open_contacts_settings() + contacts_settings.accept_contact_request(user_one.name) + + with step(f'User {user_two.name}, create community and invite {user_one.name}'): + main_screen.create_community(community_params['name'], community_params['description'], + community_params['intro'], community_params['outro'], + community_params['logo']['fp'], community_params['banner']['fp']) + main_screen.left_panel.invite_people_in_community([user_one.name], 'Message', community_params['name']) + main_screen.hide() + + with step(f'User {user_one.name}, accept invitation from {user_two.name}'): + aut_one.attach() + main_screen.prepare() + messages_view = main_screen.left_panel.open_messages_screen() + chat = messages_view.left_panel.click_chat_by_name(user_two.name) + community_screen = chat.accept_community_invite(community_params['name'], '0') + + with step(f'User {user_one.name}, verify welcome community popup'): + welcome_popup = community_screen.left_panel.open_welcome_community_popup() + assert community_params['name'] in welcome_popup.title + assert community_params['intro'] == welcome_popup.intro + welcome_popup.join().authenticate(user_one.password) + assert driver.waitFor(lambda: not community_screen.left_panel.is_join_community_visible, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), 'Join community button not hidden' + messages_screen = MessagesScreen() + message_text = "Hi" + messages_screen.group_chat.send_message_to_group_chat(message_text) + main_screen.hide() + + with step(f'User {user_two.name}, delete member message of {user_one.name} and verify it was deleted'): + aut_two.attach() + main_screen.prepare() + community_screen = main_screen.left_panel.select_community(community_params['name']) + messages_screen = MessagesScreen() + message = messages_screen.chat.find_message_by_text(message_text, '0') + message.hover_message().delete_message() + assert messages_screen.chat.get_deleted_message_state + main_screen.hide() + + with step(f'User {user_one.name} verify that message was deleted by {user_two.name}'): + aut_one.attach() + main_screen.prepare() + assert driver.waitFor(lambda: messages_screen.chat.get_deleted_message_state, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC) + main_screen.hide() + + with step(f'User {user_two.name}, kick {user_one.name} from the community'): + aut_two.attach() + main_screen.prepare() + community_setting = community_screen.left_panel.open_community_settings() + community_setting.left_panel.open_members().kick_member(user_one.name) + + with step('Check toast message about kicked member'): + toast_messages = main_screen.wait_for_notification() + assert len(toast_messages) == 1, \ + f"Multiple toast messages appeared" + message = toast_messages[0] + assert message == user_one.name + ToastMessages.KICKED_USER_TOAST.value + community_params['name'], \ + f"Toast message is incorrect, current message is {message}" + + with step(f'User {user_two.name}, does not see {user_one.name} in members list'): + assert driver.waitFor(lambda: user_one.name not in community_screen.right_panel.members) + main_screen.hide() + + with step(f'User {user_one.name} is not in the community anymore'): + aut_one.attach() + main_screen.prepare() + assert driver.waitFor(lambda: len(main_screen.left_panel.communities) == 0, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC)