Test(Community) Join community via owner invite

#96
This commit is contained in:
Vladimir Druzhinin 2023-09-11 20:24:13 +02:00
parent 8ebc0143d4
commit 26b77dba45
37 changed files with 730 additions and 103 deletions

9
test/e2e/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
configs/_local.py
.idea/
/squish_server.ini
*.pyc
tmp/

View File

@ -19,7 +19,3 @@ if APP_DIR is None:
if system.IS_WIN and 'bin' not in APP_DIR:
exit('Please use launcher from "bin" folder in "APP_DIR"')
APP_DIR = SystemPath(APP_DIR)
# Application will be stuck after the first test execution if set to False
# We need to investigate more time on it.
ATTACH_MODE = True

View File

@ -3,5 +3,5 @@ import os
LOG_LEVEL = logging.DEBUG
DEV_BUILD = False
ATTACH_MODE = False
APP_DIR = os.getenv('APP_DIR')

View File

@ -2,5 +2,5 @@ import logging
LOG_LEVEL = logging.DEBUG
DEV_BUILD = False
ATTACH_MODE = False
APP_DIR = None

View File

@ -4,3 +4,4 @@ UI_LOAD_TIMEOUT_SEC = 5
UI_LOAD_TIMEOUT_MSEC = UI_LOAD_TIMEOUT_SEC * 1000
PROCESS_TIMEOUT_SEC = 10
APP_LOAD_TIMEOUT_MSEC = 60000
MESSAGING_TIMEOUT_SEC = 60

View File

@ -3,14 +3,15 @@ from collections import namedtuple
import configs
UserAccount = namedtuple('User', ['name', 'password', 'seed_phrase'])
user_account_default = UserAccount('squisher', '*P@ssw0rd*', [
user_account_one = UserAccount('squisher', '*P@ssw0rd*', [
'rail', 'witness', 'era', 'asthma', 'empty', 'cheap', 'shed', 'pond', 'skate', 'amount', 'invite', 'year'
])
user_account_one = UserAccount('tester123', 'TesTEr16843/!@00', [])
user_account_two = UserAccount('Athletic', 'TesTEr16843/!@00', [])
user_account_two = UserAccount('athletic', '*P@ssw0rd*', [
'measure', 'cube', 'cousin', 'debris', 'slam', 'ignore', 'seven', 'hat', 'satisfy', 'frown', 'casino', 'inflict'
])
user_account_three = UserAccount('Nervous', 'TesTEr16843/!@00', [])
default_community_params = {
community_params = {
'name': 'Name',
'description': 'Description',
'logo': {'fp': configs.testpath.TEST_FILES / 'tv_signal.png', 'zoom': None, 'shift': None},
@ -22,4 +23,4 @@ default_community_params = {
UserCommunityInfo = namedtuple('CommunityInfo', ['name', 'description', 'members', 'image'])
UserChannel = namedtuple('Channel', ['name', 'image', 'selected'])
account_list_item = namedtuple('AccountListItem', ['name', 'color', 'emoji'])
account_list_item = namedtuple('AccountListItem', ['name', 'color', 'emoji'])

View File

@ -1,3 +1,5 @@
from datetime import datetime
import allure
import squish
@ -7,6 +9,7 @@ from configs.system import IS_LIN
from driver import context
from driver.server import SquishServer
from scripts.utils import system_path, local_system
from scripts.utils.system_path import SystemPath
class AUT:
@ -14,7 +17,8 @@ class AUT:
self,
app_path: system_path.SystemPath = configs.APP_DIR,
host: str = '127.0.0.1',
port: int = configs.squish.AUT_PORT
port: int = configs.squish.AUT_PORT,
user_data: SystemPath = None
):
super(AUT, self).__init__()
self.path = app_path
@ -23,11 +27,19 @@ class AUT:
self.ctx = None
self.pid = None
self.aut_id = self.path.name if IS_LIN else self.path.stem
self.app_data = configs.testpath.STATUS_DATA / f'app_{datetime.now():%H%M%S_%f}'
self.user_data = user_data
driver.testSettings.setWrappersForApplication(self.aut_id, ['Qt'])
def __str__(self):
return type(self).__qualname__
def __enter__(self):
return self.launch()
def __exit__(self, *args):
self.detach().stop()
@allure.step('Attach Squish to Test Application')
def attach(self, timeout_sec: int = configs.timeouts.PROCESS_TIMEOUT_SEC, attempt: int = 2):
if self.ctx is None:
@ -44,30 +56,33 @@ class AUT:
def detach(self):
if self.ctx is not None:
squish.currentApplicationContext().detach()
assert squish.waitFor(lambda: not self.ctx.isRunning, configs.timeouts.PROCESS_TIMEOUT_SEC)
self.ctx = None
return self
@allure.step('Close application')
def stop(self):
local_system.kill_process(self.pid)
local_system.kill_process(self.pid, verify=True)
@allure.step("Start application")
def launch(self, *args) -> 'AUT':
def launch(self) -> 'AUT':
if self.user_data is not None:
self.user_data.copy_to(self.app_data / 'data')
SquishServer().set_aut_timeout()
if configs.ATTACH_MODE:
SquishServer().add_attachable_aut('AUT', self.port)
command = [
configs.testpath.SQUISH_DIR / 'bin' / 'startaut',
f'--port={self.port}',
f'"{self.path}"'
] + list(args)
configs.testpath.SQUISH_DIR / 'bin' / 'startaut',
f'--port={self.port}',
f'"{self.path}"',
f'-d={self.app_data}'
]
local_system.execute(command)
else:
SquishServer().add_executable_aut(self.aut_id, self.path.parent)
command = [self.aut_id] + list(args)
self.ctx = squish.startApplication(
' '.join(command), configs.timeouts.PROCESS_TIMEOUT_SEC)
command = [self.aut_id, f'-d={self.app_data}']
self.ctx = squish.startApplication(' '.join(command), configs.timeouts.PROCESS_TIMEOUT_SEC)
self.attach()
self.pid = self.ctx.pid

View File

@ -1,6 +1,5 @@
import logging
import typing
from subprocess import CalledProcessError
import configs.testpath
from scripts.utils import local_system
@ -35,7 +34,7 @@ class SquishServer:
def stop(self):
if self.pid is not None:
local_system.kill_process(self.pid)
self.pid = None
self.pid = None
# https://doc-snapshots.qt.io/squish/cli-squishserver.html
def configuring(self, action: str, options: typing.Union[int, str, list]):

View File

@ -11,5 +11,5 @@ class BasePopup(QObject):
@allure.step('Close')
def close(self):
driver.nativeType('<Escape>')
driver.type(self.object, '<Escape>')
self.wait_until_hidden()

View File

@ -0,0 +1,27 @@
import allure
import configs
from gui.components.base_popup import BasePopup
from gui.elements.qt.button import Button
from gui.elements.qt.object import QObject
from gui.elements.qt.text_edit import TextEdit
class AuthenticatePopup(BasePopup):
def __init__(self):
super().__init__()
self._content = QObject('keycardSharedPopupContent_KeycardPopupContent')
self._passwort_text_edit = TextEdit('password_PlaceholderText')
self._authenticate_button = Button('authenticate_StatusButton')
@allure.step('Wait until appears {0}')
def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC):
self._content.wait_until_appears(timeout_msec)
return self
@allure.step('Authenticate actions with password {0}')
def authenticate(self, password: str):
self._passwort_text_edit.type_text(password)
self._authenticate_button.click()
self.wait_until_hidden()

View File

@ -0,0 +1,54 @@
import typing
import allure
import configs.timeouts
import driver
from gui.components.base_popup import BasePopup
from gui.elements.qt.button import Button
from gui.elements.qt.object import QObject
from gui.elements.qt.text_edit import TextEdit
class InviteContactsPopup(BasePopup):
def __init__(self):
super().__init__()
self._member_item = QObject('o_StatusMemberListItem')
self._next_button = Button('next_StatusButton')
self._message_text_edit = TextEdit('communityProfilePopupInviteMessagePanel_MessageInput_TextEdit')
self._invited_member_item = QObject('o_StatusMemberListItem_2')
self._send_button = Button('send_1_invite_StatusButton')
@property
@allure.step('Get contacts')
def contacts(self) -> typing.List[str]:
return [str(getattr(user, 'title', '')) for user in driver.findAllObjects(self._member_item.real_name)]
@property
@allure.step('Invite contacts')
def invited_contacts(self) -> typing.List[str]:
return [str(getattr(user, 'title', '')) for user in driver.findAllObjects(self._invited_member_item.real_name)]
def invite(self, contacts: typing.List[str], message: str):
for contact in contacts:
assert driver.waitFor(lambda: contact in self.contacts, configs.timeouts.UI_LOAD_TIMEOUT_MSEC), \
f'Contact: {contact} not found in {self.contacts}'
selected = []
for member in driver.findAllObjects(self._member_item.real_name):
if str(getattr(member, 'title', '')) in contacts:
driver.mouseClick(member)
selected.append(member.title)
assert len(contacts) == len(selected), f'Selected contacts: {selected}, expected: {contacts}'
self._next_button.click()
self._message_text_edit.text = message
for contact in contacts:
assert driver.waitFor(lambda: contact in self.invited_contacts, configs.timeouts.UI_LOAD_TIMEOUT_MSEC), \
f'Contact: {contact} not found in {self.invited_contacts}'
self._send_button.click()
self.wait_until_hidden()

View File

@ -0,0 +1,39 @@
import allure
from gui.components.community.authenticate_popup import AuthenticatePopup
from gui.components.base_popup import BasePopup
from gui.elements.qt.button import Button
from gui.elements.qt.object import QObject
from gui.elements.qt.text_label import TextLabel
from scripts.tools.image import Image
class WelcomeCommunityPopup(BasePopup):
def __init__(self):
super().__init__()
self._title_text_label = TextLabel('headerTitle_StatusBaseText')
self._community_icon = QObject('image_StatusImage')
self._intro_text_label = TextLabel('intro_StatusBaseText')
self._select_address_button = Button('select_addresses_to_share_StatusFlatButton')
self._join_button = Button('join_StatusButton')
@property
@allure.step('Get title')
def title(self) -> str:
return self._title_text_label.text
@property
@allure.step('Get community icon')
def community_icon(self) -> Image:
return self._community_icon.image
@property
@allure.step('Get community intro')
def intro(self) -> str:
return self._intro_text_label.text
@allure.step('Join community')
def join(self) -> AuthenticatePopup:
self._join_button.click()
return AuthenticatePopup().wait_until_appears()

View File

@ -1,4 +1,5 @@
import allure
import pyperclip
import constants
import driver
@ -18,6 +19,7 @@ class ProfilePopup(BasePopup):
self._edit_profile_button = Button('ProfilePopup_editButton')
self._chat_key_text_label = TextLabel('https_status_app_StatusBaseText')
self._emoji_hash = QObject('profileDialog_userEmojiHash_EmojiHash')
self._chat_key_copy_button = Button('copy_icon_StatusIcon')
@property
@allure.step('Get profile image')
@ -53,6 +55,12 @@ class ProfilePopup(BasePopup):
def emoji_hash(self) -> Image:
return self._emoji_hash.image
@property
@allure.step('Get chat key')
def chat_key(self) -> str:
self._chat_key_copy_button.click()
return pyperclip.paste()
@allure.step('Verify: user image contains text')
def is_user_image_contains(self, text: str):
# To remove all artifacts, the image cropped.

View File

@ -0,0 +1,21 @@
import allure
from gui.components.base_popup import BasePopup
from gui.elements.qt.button import Button
from gui.elements.qt.text_edit import TextEdit
class SendContactRequest(BasePopup):
def __init__(self):
super().__init__()
self._chat_key_text_edit = TextEdit('sendContactRequestModal_ChatKey_Input_TextEdit')
self._message_text_edit = TextEdit('sendContactRequestModal_SayWhoYouAre_Input_TextEdit')
self._send_button = Button('send_Contact_Request_StatusButton')
@allure.step('Send contact request')
def send(self, chat_key: str, message: str):
self._chat_key_text_edit.text = chat_key
self._message_text_edit.text = message
self._send_button.click()
self.wait_until_hidden()

View File

@ -3,7 +3,7 @@ import allure
import configs
import constants.wallet
import driver
from gui.components.authenticate_popup import AuthenticatePopup
from gui.components.wallet.authenticate_popup import AuthenticatePopup
from gui.components.base_popup import BasePopup
from gui.components.emoji_popup import EmojiPopup
from gui.elements.qt.button import Button

View File

@ -11,9 +11,12 @@ _logger = logging.getLogger(__name__)
class BaseObject:
def __init__(self, name: str):
def __init__(self, name: str, real_name: [str, dict] = None):
self.symbolic_name = name
self.real_name = getattr(objects_map, name)
if real_name:
self.real_name = real_name
else:
self.real_name = getattr(objects_map, name)
def __str__(self):
return f'{type(self).__qualname__}({self.symbolic_name})'

View File

@ -14,8 +14,8 @@ _logger = logging.getLogger(__name__)
class QObject(BaseObject):
def __init__(self, name: str):
super().__init__(name)
def __init__(self, name, real_name: [str, dict] = None):
super().__init__(name, real_name)
self._image = Image(self.real_name)
def __str__(self):
@ -80,7 +80,7 @@ class QObject(BaseObject):
@allure.step('Get visible {0}')
def is_visible(self) -> bool:
try:
return driver.waitForObject(self.real_name, 0).visible
return driver.waitForObjectExists(self.real_name, 0).visible
except (AttributeError, LookupError, RuntimeError):
return False

View File

@ -11,6 +11,7 @@ _logger = logging.getLogger(__name__)
class Window(QObject):
def prepare(self) -> 'Window':
self.show()
self.maximize()
self.on_top_level()
return self
@ -38,3 +39,11 @@ class Window(QObject):
@allure.step("Close {0}")
def close(self):
driver.toplevel_window.close(self.real_name)
@allure.step("Show {0}")
def show(self):
driver.waitForObjectExists(self.real_name).setVisible(True)
@allure.step("Hide {0}")
def hide(self):
driver.waitForObjectExists(self.real_name).setVisible(False)

View File

@ -7,6 +7,7 @@ import configs
import constants
import driver
from constants import UserAccount
from gui.components.community.invite_contacts import InviteContactsPopup
from gui.components.onboarding.before_started_popup import BeforeStartedPopUp
from gui.components.onboarding.welcome_status_popup import WelcomeStatusPopup
from gui.components.splash_screen import SplashScreen
@ -16,6 +17,7 @@ from gui.elements.qt.object import QObject
from gui.elements.qt.window import Window
from gui.screens.community import CommunityScreen
from gui.screens.community_portal import CommunitiesPortal
from gui.screens.messages import MessagesScreen
from gui.screens.onboarding import AllowNotificationsView, WelcomeView, TouchIDAuthView, LoginView
from gui.screens.settings import SettingsScreen
from gui.screens.wallet import WalletScreen
@ -29,10 +31,12 @@ class LeftPanel(QObject):
def __init__(self):
super(LeftPanel, self).__init__('mainWindow_StatusAppNavBar')
self._profile_button = Button('mainWindow_ProfileNavBarButton')
self._messages_button = Button('messages_navbar_StatusNavBarTabButton')
self._communities_portal_button = Button('communities_Portal_navbar_StatusNavBarTabButton')
self._community_template_button = Button('statusCommunityMainNavBarListView_CommunityNavBarButton')
self._settings_button = Button('settings_navbar_StatusNavBarTabButton')
self._wallet_button = Button('wallet_navbar_StatusNavBarTabButton')
self._community_invite_people_context_item = QObject('invite_People_StatusMenuItem')
@property
@allure.step('Get communities names')
@ -47,6 +51,11 @@ class LeftPanel(QObject):
def user_badge_color(self) -> str:
return str(self._profile_button.object.badge.color.name)
@allure.step('Open messages screen')
def open_messages_screen(self) -> MessagesScreen:
self._messages_button.click()
return MessagesScreen().wait_until_appears()
@allure.step('Open user canvas')
def open_user_canvas(self) -> UserCanvas:
self._profile_button.click()
@ -86,6 +95,12 @@ class LeftPanel(QObject):
def get_community_logo(self, name: str) -> Image:
return Image(driver.objectMap.realName(self._get_community(name)))
@allure.step('Invite people in community')
def invite_people_in_community(self, contacts: typing.List[str], message: str, community_name: str):
driver.mouseClick(self._get_community(community_name), driver.Qt.RightButton)
self._community_invite_people_context_item.click()
InviteContactsPopup().wait_until_appears().invite(contacts, message)
@allure.step('Open settings')
def open_settings(self) -> CommunitiesPortal:
self._settings_button.click()
@ -96,6 +111,7 @@ class LeftPanel(QObject):
self._wallet_button.click()
return WalletScreen().wait_until_appears()
class MainWindow(Window):
def __init__(self):
@ -103,7 +119,7 @@ class MainWindow(Window):
self.left_panel = LeftPanel()
@allure.step('Sign Up user')
def sign_up(self, user_account: UserAccount = constants.user.user_account_one):
def sign_up(self, user_account: UserAccount = constants.user.community_params):
if configs.system.IS_MAC:
AllowNotificationsView().wait_until_appears().allow()
BeforeStartedPopUp().get_started()
@ -128,3 +144,19 @@ class MainWindow(Window):
if not configs.DEV_BUILD:
WelcomeStatusPopup().wait_until_appears().confirm()
return self
@allure.step('Authorize user')
def authorize_user(self, user_account) -> 'MainWindow':
self.prepare()
assert isinstance(user_account, UserAccount)
if LoginView().is_visible:
return self.log_in(user_account)
else:
return self.sign_up(user_account)
@allure.step('Create community')
def create_community(self, params: dict) -> CommunityScreen:
communities_portal = self.left_panel.open_communities_portal()
create_community_form = communities_portal.open_create_community_popup()
app_screen = create_community_form.create(params)
return app_screen

View File

@ -1,6 +1,7 @@
from .community_names import *
from .component_names import *
from .main_names import *
from .messages_names import *
from .onboarding_names import *
from .os_names import *
from .settings_names import *

View File

@ -22,6 +22,7 @@ channel_identicon_StatusSmartIdenticon = {"container": None, "id": "identicon",
channel_name_StatusBaseText = {"container": None, "type": "StatusBaseText", "unnamed": 1, "visible": True}
mainWindow_createChannelOrCategoryBtn_StatusBaseText = {"container": mainWindow_communityColumnView_CommunityColumnView, "objectName": "createChannelOrCategoryBtn", "type": "StatusBaseText", "visible": True}
create_channel_StatusMenuItem = {"container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "createCommunityChannelBtn", "type": "StatusMenuItem", "visible": True}
mainWindow_Join_Community_StatusButton = {"checkable": False, "container": mainWindow_communityColumnView_CommunityColumnView, "id": "joinCommunityButton", "text": "Join Community", "type": "StatusButton", "unnamed": 1, "visible": True}
# Tool Bar
mainWindow_statusToolBar_StatusToolBar = {"container": mainWindow_communityLoader_Loader, "objectName": "statusToolBar", "type": "StatusToolBar", "visible": True}
@ -76,3 +77,7 @@ communityEditPanelScrollView_pinMessagesToggle_StatusCheckBox = {"checkable": Tr
communityEditPanelScrollView_editCommunityIntroInput_TextEdit = {"container": mainWindow_communityEditPanelScrollView_EditSettingsPanel, "objectName": "editCommunityIntroInput", "type": "TextEdit", "visible": True}
communityEditPanelScrollView_editCommunityOutroInput_TextEdit = {"container": mainWindow_communityEditPanelScrollView_EditSettingsPanel, "objectName": "editCommunityOutroInput", "type": "TextEdit", "visible": True}
mainWindow_Save_changes_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow, "objectName": "settingsDirtyToastMessageSaveButton", "text": "Save changes", "type": "StatusButton", "visible": True}
# User List Panel
mainWindow_UserListPanel = {"container": statusDesktop_mainWindow, "type": "UserListPanel", "unnamed": 1, "visible": True}
userListPanel_StatusMemberListItem = {"container": mainWindow_UserListPanel, "type": "StatusMemberListItem", "unnamed": 1, "visible": True}

View File

@ -1,8 +1,7 @@
from objectmaphelper import *
from .main_names import statusDesktop_mainWindow
from .main_names import statusDesktop_mainWindow_overlay
from .main_names import statusDesktop_mainWindow_overlay_popup2
from .main_names import statusDesktop_mainWindow_overlay, statusDesktop_mainWindow, \
statusDesktop_mainWindow_overlay_popup2
# Scroll
o_Flickable = {"container": statusDesktop_mainWindow_overlay, "type": "Flickable", "unnamed": 1, "visible": True}
@ -61,6 +60,8 @@ ProfilePopup_SendContactRequestButton = {"container": statusDesktop_mainWindow_o
profileDialog_userEmojiHash_EmojiHash = {"container": statusDesktop_mainWindow_overlay, "objectName": "ProfileDialog_userEmojiHash", "type": "EmojiHash", "visible": True}
edit_TextEdit = {"container": statusDesktop_mainWindow_overlay, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
https_status_app_StatusBaseText = {"container": edit_TextEdit, "type": "StatusBaseText", "unnamed": 1, "visible": True}
copy_icon_StatusIcon = {"container": statusDesktop_mainWindow_overlay, "objectName": "copy-icon", "type": "StatusIcon", "visible": True}
# Welcome Status Popup
agreeToUse_StatusCheckBox = {"checkable": True, "container": statusDesktop_mainWindow_overlay, "id": "agreeToUse", "type": "StatusCheckBox", "unnamed": 1, "visible": True}
@ -92,12 +93,37 @@ createCommunityIntroMessageInput_TextEdit = {"container": statusDesktop_mainWind
createCommunityOutroMessageInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "createCommunityOutroMessageInput", "type": "TextEdit", "visible": True}
createCommunityFinalBtn_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "createCommunityFinalBtn", "type": "StatusButton", "visible": True}
# Community channel popup:
# Community Channel Popup:
createOrEditCommunityChannelNameInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "createOrEditCommunityChannelNameInput", "type": "TextEdit", "visible": True}
createOrEditCommunityChannelDescriptionInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "createOrEditCommunityChannelDescriptionInput", "type": "TextEdit", "visible": True}
createOrEditCommunityChannelBtn_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "createOrEditCommunityChannelBtn", "type": "StatusButton", "visible": True}
createOrEditCommunityChannel_EmojiButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "StatusChannelPopup_emojiButton", "type": "StatusRoundButton", "visible": True}
# Invite Contacts Popup
communityProfilePopupInviteFrindsPanel = {"container": statusDesktop_mainWindow_overlay, "objectName": "CommunityProfilePopupInviteFrindsPanel_ColumnLayout", "type": "ProfilePopupInviteFriendsPanel", "visible": True}
communityProfilePopupInviteMessagePanel = {"container": statusDesktop_mainWindow_overlay, "objectName": "CommunityProfilePopupInviteMessagePanel_ColumnLayout", "type": "ProfilePopupInviteMessagePanel", "visible": True}
o_StatusMemberListItem = {"container": communityProfilePopupInviteFrindsPanel, "type": "StatusMemberListItem", "unnamed": 1, "visible": True}
next_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "InviteFriendsToCommunityPopup_NextButton", "text": "Next", "type": "StatusButton", "visible": True}
communityProfilePopupInviteMessagePanel_MessageInput_TextEdit = {"container": communityProfilePopupInviteMessagePanel, "objectName": "CommunityProfilePopupInviteMessagePanel_MessageInput", "type": "TextEdit", "visible": True}
send_1_invite_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "InviteFriendsToCommunityPopup_SendButton", "text": "Send 1 invite", "type": "StatusButton", "visible": True}
o_StatusMemberListItem_2 = {"container": communityProfilePopupInviteMessagePanel, "type": "StatusMemberListItem", "unnamed": 1, "visible": True}
# Welcome community
headerTitle_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "objectName": "headerTitle", "type": "StatusBaseText", "visible": True}
image_StatusImage = {"container": statusDesktop_mainWindow_overlay, "id": "image", "type": "StatusImage", "unnamed": 1, "visible": True}
intro_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "text": "Intro", "type": "StatusBaseText", "unnamed": 1, "visible": True}
select_addresses_to_share_StatusFlatButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "type": "StatusFlatButton", "unnamed": 1, "visible": True}
join_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "unnamed": 1, "visible": True}
""" Settings """
# Send Contact Request
sendContactRequestModal_ChatKey_Input_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "SendContactRequestModal_ChatKey_Input", "type": "TextEdit", "visible": True}
sendContactRequestModal_SayWhoYouAre_Input_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "SendContactRequestModal_SayWhoYouAre_Input", "type": "TextEdit", "visible": True}
send_Contact_Request_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "SendContactRequestModal_Send_Button", "type": "StatusButton", "visible": True}
""" Common """
# Select Color Popup
@ -155,6 +181,12 @@ mainWallet_AddEditAccountPopup_AccountEmoji = {"container": statusDesktop_mainWi
o_StatusDialogBackground = {"container": statusDesktop_mainWindow_overlay, "type": "StatusDialogBackground", "unnamed": 1, "visible": True}
delete_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "deleteChatConfirmationDialogDeleteButton", "type": "StatusButton", "visible": True}
# Authenticate Popup
keycardSharedPopupContent_KeycardPopupContent = {"container": statusDesktop_mainWindow_overlay, "objectName": "KeycardSharedPopupContent", "type": "KeycardPopupContent", "visible": True}
password_PlaceholderText = {"container": statusDesktop_mainWindow_overlay, "type": "PlaceholderText", "unnamed": 1, "visible": True}
authenticate_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "PrimaryButton", "type": "StatusButton", "visible": True}
# Shared Popup
sharedPopup_Popup_Content = {"container": statusDesktop_mainWindow, "objectName": "KeycardSharedPopupContent", "type": "Item"}
sharedPopup_Password_Input = {"container": sharedPopup_Popup_Content, "objectName": "keycardPasswordInput", "type": "TextField"}

View File

@ -1,4 +1,4 @@
statusDesktop_mainWindow = {"name": "mainWindow", "type": "StatusWindow", "visible": True}
statusDesktop_mainWindow = {"name": "mainWindow", "type": "StatusWindow"}
statusDesktop_mainWindow_overlay = {"container": statusDesktop_mainWindow, "type": "Overlay", "unnamed": 1, "visible": True}
statusDesktop_mainWindow_overlay_popup2 = {"container": statusDesktop_mainWindow_overlay, "occurrence": 2, "type": "PopupItem", "unnamed": 1, "visible": True}
scrollView_StatusScrollView = {"container": statusDesktop_mainWindow_overlay, "id": "scrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True}
@ -16,6 +16,7 @@ settings_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWin
mainWindow_ProfileNavBarButton = {"container": statusDesktop_mainWindow, "objectName": "statusProfileNavBarTabButton", "type": "StatusNavBarTabButton", "visible": True}
mainWindow_statusCommunityMainNavBarListView_ListView = {"container": statusDesktop_mainWindow, "objectName": "statusCommunityMainNavBarListView", "type": "ListView", "visible": True}
statusCommunityMainNavBarListView_CommunityNavBarButton = {"checkable": True, "container": mainWindow_statusCommunityMainNavBarListView_ListView, "objectName": "CommunityNavBarButton", "type": "StatusNavBarTabButton", "visible": True}
invite_People_StatusMenuItem = {"container": statusDesktop_mainWindow_overlay, "enabled": True, "objectName": "invitePeople", "type": "StatusMenuItem", "visible": True}
# Banners
secureYourSeedPhraseBanner_ModuleWarning = {"container": statusDesktop_mainWindow, "objectName": "secureYourSeedPhraseBanner", "type": "ModuleWarning", "visible": True}

View File

@ -0,0 +1,23 @@
from .main_names import statusDesktop_mainWindow
mainWindow_chatView_ChatView = {"container": statusDesktop_mainWindow, "id": "chatView", "type": "ChatView", "unnamed": 1, "visible": True}
# Left Panel
mainWindow_contactColumnLoader_Loader = {"container": mainWindow_chatView_ChatView, "id": "contactColumnLoader", "type": "Loader", "unnamed": 1, "visible": True}
mainWindow_startChatButton_StatusIconTabButton = {"checkable": True, "container": mainWindow_contactColumnLoader_Loader, "objectName": "startChatButton", "type": "StatusIconTabButton", "visible": True}
mainWindow_search_edit_TextEdit = {"container": mainWindow_contactColumnLoader_Loader, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
mainWindow_scrollView_StatusScrollView = {"container": mainWindow_contactColumnLoader_Loader, "id": "scrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True}
scrollView_Flickable = {"container": mainWindow_scrollView_StatusScrollView, "type": "Flickable", "unnamed": 1, "visible": True}
scrollView_ContactsColumnView_chatList_StatusChatList = {"container": mainWindow_scrollView_StatusScrollView, "objectName": "ContactsColumnView_chatList", "type": "StatusChatList", "visible": True}
chatList_ListView = {"container": statusDesktop_mainWindow, "objectName": "chatListItems", "type": "StatusListView", "visible": True}
# Tool Bar
mainWindow_statusToolBar_StatusToolBar = {"container": mainWindow_chatView_ChatView, "objectName": "statusToolBar", "type": "StatusToolBar", "visible": True}
# Chat View
mainWindow_ChatColumnView = {"container": mainWindow_chatView_ChatView, "type": "ChatColumnView", "unnamed": 1, "visible": True}
mainWindow_chatLogView_StatusListView = {"container": mainWindow_ChatColumnView, "objectName": "chatLogView", "type": "StatusListView", "visible": True}
chatLogView_chatMessageViewDelegate_MessageView = {"container": mainWindow_chatLogView_StatusListView, "objectName": "chatMessageViewDelegate", "type": "MessageView", "visible": True, "enabled": True}
# User List Panel
mainWindow_UserListPanel = {"container": mainWindow_chatView_ChatView, "type": "UserListPanel", "unnamed": 1, "visible": True}
userListPanel_StatusMemberListItem = {"container": mainWindow_UserListPanel, "type": "StatusMemberListItem", "unnamed": 1, "visible": True}

View File

@ -13,10 +13,19 @@ scrollView_AppMenuItem_StatusNavigationListItem = {"container": mainWindow_scrol
mainWindow_CommunitiesView = {"container": statusDesktop_mainWindow, "type": "CommunitiesView", "unnamed": 1, "visible": True}
mainWindow_settingsContentBaseScrollView_StatusScrollView = {"container": mainWindow_CommunitiesView, "objectName": "settingsContentBaseScrollView", "type": "StatusScrollView", "visible": True}
settingsContentBaseScrollView_listItem_StatusListItem = {"container": mainWindow_settingsContentBaseScrollView_StatusScrollView, "id": "listItem", "type": "StatusListItem", "unnamed": 1, "visible": True}
# Templates to generate Real Name in test
settings_iconOrImage_StatusSmartIdenticon = {"id": "iconOrImage", "type": "StatusSmartIdenticon", "unnamed": 1, "visible": True}
settings_Name_StatusTextWithLoadingState = {"type": "StatusTextWithLoadingState", "unnamed": 1, "visible": True}
settings_statusListItemSubTitle = {"objectName": "statusListItemSubTitle", "type": "StatusTextWithLoadingState", "visible": True}
settings_member_StatusTextWithLoadingState = {"text": "1 member", "type": "StatusTextWithLoadingState", "unnamed": 1, "visible": True}
settings_StatusFlatButton = {"type": "StatusFlatButton", "unnamed": 1, "visible": True}
# Messaging View
mainWindow_MessagingView = {"container": statusDesktop_mainWindow, "type": "MessagingView", "unnamed": 1, "visible": True}
contactsListItem_btn_StatusContactRequestsIndicatorListItem = {"container": mainWindow_MessagingView, "objectName": "MessagingView_ContactsListItem_btn", "type": "StatusContactRequestsIndicatorListItem", "visible": True}
# Contacts View
mainWindow_ContactsView = {"container": statusDesktop_mainWindow, "type": "ContactsView", "unnamed": 1, "visible": True}
mainWindow_Send_contact_request_to_chat_key_StatusButton = {"checkable": False, "container": mainWindow_ContactsView, "objectName": "ContactsView_ContactRequest_Button", "type": "StatusButton", "visible": True}
contactsTabBar_Pending_Requests_StatusTabButton = {"checkable": True, "container": mainWindow_ContactsView, "objectName": "ContactsView_PendingRequest_Button", "type": "StatusTabButton", "visible": True}
settingsContentBaseScrollView_ContactListPanel = {"container": mainWindow_ContactsView, "objectName": "ContactListPanel_ListView", "type": "StatusListView", "visible": True}

View File

@ -6,6 +6,7 @@ from allure_commons._allure import step
import driver
from constants import UserChannel
from gui.components.community.community_channel_popups import EditChannelPopup, NewChannelPopup
from gui.components.community.welcome_community import WelcomeCommunityPopup
from gui.components.delete_popup import DeletePopup
from gui.elements.qt.button import Button
from gui.elements.qt.list import List
@ -23,6 +24,7 @@ class CommunityScreen(QObject):
self.left_panel = LeftPanel()
self.tool_bar = ToolBar()
self.chat = Chat()
self.right_panel = Members()
@allure.step('Create channel')
def create_channel(self, name: str, description: str, emoji: str = None):
@ -109,6 +111,7 @@ class LeftPanel(QObject):
self._channel_icon_template = QObject('channel_identicon_StatusSmartIdenticon')
self._channel_or_category_button = Button('mainWindow_createChannelOrCategoryBtn_StatusBaseText')
self._create_channel_menu_item = Button('create_channel_StatusMenuItem')
self._join_community_button = Button('mainWindow_Join_Community_StatusButton')
@property
@allure.step('Get community logo')
@ -125,6 +128,11 @@ class LeftPanel(QObject):
def members(self) -> str:
return self._members_text_label.text
@property
@allure.step('Get Join button visible attribute')
def is_join_community_visible(self) -> bool:
return self._join_community_button.is_visible
@property
@allure.step('Get channels')
def channels(self) -> typing.List[UserChannel]:
@ -165,6 +173,11 @@ class LeftPanel(QObject):
return
raise LookupError('Channel not found')
@allure.step('Open join community popup')
def open_welcome_community_popup(self):
self._join_community_button.click()
return WelcomeCommunityPopup().wait_until_appears()
class Chat(QObject):
@ -188,3 +201,15 @@ class Chat(QObject):
@allure.step('Get channel welcome note')
def channel_welcome_note(self) -> str:
return self._channel_welcome_label.text
class Members(QObject):
def __init__(self):
super().__init__('mainWindow_UserListPanel')
self._member_item = QObject('userListPanel_StatusMemberListItem')
@property
@allure.step('Get all members')
def members(self) -> typing.List[str]:
return [str(member.statusListItemTitle.text) for member in driver.findAllObjects(self._member_item.real_name)]

View File

@ -1,9 +1,8 @@
import allure
from gui.components.community.create_community_popups import CreateCommunitiesBanner
from gui.components.community.create_community_popups import CreateCommunitiesBanner, CreateCommunityPopup
from gui.elements.qt.button import Button
from gui.elements.qt.object import QObject
from gui.screens.community import CommunityScreen
class CommunitiesPortal(QObject):
@ -13,6 +12,6 @@ class CommunitiesPortal(QObject):
self._create_community_button = Button('mainWindow_Create_New_Community_StatusButton')
@allure.step('Open create community popup')
def open_create_community_popup(self) -> CommunityScreen:
def open_create_community_popup(self) -> CreateCommunityPopup:
self._create_community_button.click()
return CreateCommunitiesBanner().wait_until_appears().open_create_community_popup()

View File

@ -0,0 +1,124 @@
import time
import typing
import allure
import configs
import driver
from driver.objects_access import walk_children
from gui.elements.qt.button import Button
from gui.elements.qt.list import List
from gui.elements.qt.object import QObject
from gui.elements.qt.scroll import Scroll
from gui.elements.qt.text_edit import TextEdit
from gui.screens.community import CommunityScreen
from scripts.tools.image import Image
class LeftPanel(QObject):
def __init__(self):
super().__init__('mainWindow_contactColumnLoader_Loader')
self._start_chat_button = Button('mainWindow_startChatButton_StatusIconTabButton')
self._search_text_edit = TextEdit('mainWindow_search_edit_TextEdit')
self._scroll = Scroll('scrollView_Flickable')
self._contacts_list = List('chatList_ListView')
@property
@allure.step('Get contacts')
def contacts(self) -> typing.List[str]:
return self._contacts_list.get_values('objectName')
@allure.step('Open chat')
def open_chat(self, contact: str):
assert driver.waitFor(lambda: contact in self.contacts), f'Contact: {contact} not found in {self.contacts}'
self._contacts_list.select(contact, 'objectName')
return ChatView()
class ToolBar(QObject):
def __init__(self):
super().__init__('mainWindow_statusToolBar_StatusToolBar')
class Message:
def __init__(self, obj):
self.object = obj
self.date: typing.Optional[str] = None
self.time: typing.Optional[str] = None
self.icon: typing.Optional[Image] = None
self.from_user: typing.Optional[str] = None
self.text: typing.Optional[str] = None
self._join_community_button: typing.Optional[Button] = None
self.community_invitation: dict = {}
self.init_ui()
def init_ui(self):
for child in walk_children(self.object):
if getattr(child, 'objectName', '') == 'StatusDateGroupLabel':
self.date = str(child.text)
elif getattr(child, 'objectName', '') == 'communityName':
self.community_invitation['name'] = str(child.text)
elif getattr(child, 'objectName', '') == 'communityDescription':
self.community_invitation['description'] = str(child.text)
elif getattr(child, 'objectName', '') == 'communityMembers':
self.community_invitation['members'] = str(child.text)
else:
match getattr(child, 'id', ''):
case 'profileImage':
self.icon = Image(driver.objectMap.realName(child))
case 'primaryDisplayName':
self.from_user = str(child.text)
case 'timestampText':
self.time = str(child.text)
case 'chatText':
self.text = str(child.text)
case 'joinBtn':
self._join_community_button = Button(name='', real_name=driver.objectMap.realName(child))
@allure.step('Join community')
def join_community(self):
assert self._join_community_button is not None, 'Join button not found'
self._join_community_button.click()
return CommunityScreen().wait_until_appears()
class ChatView(QObject):
def __init__(self):
super().__init__('mainWindow_ChatColumnView')
self._message_list_item = QObject('chatLogView_chatMessageViewDelegate_MessageView')
@property
@allure.step('Get messages')
def messages(self) -> typing.List[Message]:
_messages = []
for item in driver.findAllObjects(self._message_list_item.real_name):
if getattr(item, 'isMessage', False):
_messages.append(Message(item))
return _messages
@allure.step('Accept community invitation')
def accept_community_invite(self, community: str) -> 'CommunityScreen':
message = None
started_at = time.monotonic()
while message is None:
for _message in self.messages:
if _message.community_invitation.get('name', '') == community:
message = _message
break
if time.monotonic() - started_at > configs.timeouts.MESSAGING_TIMEOUT_SEC:
raise LookupError(f'Invitation not found')
return message.join_community()
class MessagesScreen(QObject):
def __init__(self):
super().__init__('mainWindow_chatView_ChatView')
self.left_panel = LeftPanel()
self.tool_bar = ToolBar()
self.chat = ChatView()

View File

@ -1,32 +1,130 @@
import time
import typing
import allure
import configs.timeouts
import driver
from constants import UserCommunityInfo
from driver import objects_access
from driver.objects_access import walk_children
from gui.components.settings.send_contact_request_popup import SendContactRequest
from gui.elements.qt.button import Button
from gui.elements.qt.list import List
from gui.elements.qt.object import QObject
from gui.elements.qt.text_label import TextLabel
from gui.screens.community_settings import CommunitySettingsScreen
from gui.screens.messages import MessagesScreen
from scripts.tools.image import Image
class SettingsScreen(QObject):
class LeftPanel(QObject):
def __init__(self):
super().__init__('mainWindow_ProfileLayout')
super().__init__('mainWindow_LeftTabView')
self._settings_section_template = QObject('scrollView_AppMenuItem_StatusNavigationListItem')
def _open_settings(self, index: int):
self._settings_section_template.real_name['objectName'] = f'{index}-AppMenuItem'
self._settings_section_template.click()
@allure.step('Open messaging settings')
def open_messaging_settings(self) -> 'MessagingSettingsView':
self._open_settings(3)
return MessagingSettingsView()
@allure.step('Open communities settings')
def open_communities_settings(self):
def open_communities_settings(self) -> 'CommunitiesSettingsView':
self._open_settings(12)
return CommunitiesSettingsView()
class SettingsScreen(QObject):
def __init__(self):
super().__init__('mainWindow_ProfileLayout')
self.left_panel = LeftPanel()
class MessagingSettingsView(QObject):
def __init__(self):
super().__init__('mainWindow_MessagingView')
self._contacts_button = Button('contactsListItem_btn_StatusContactRequestsIndicatorListItem')
@allure.step('Open contacts settings')
def open_contacts_settings(self) -> 'ContactsSettingsView':
self._contacts_button.click()
return ContactsSettingsView().wait_until_appears()
class PendingRequest:
def __init__(self, obj):
self.object = obj
self.icon: typing.Optional[Image] = None
self.contact: typing.Optional[Image] = None
self._accept_button: typing.Optional[Button] = None
self._reject_button: typing.Optional[Button] = None
self._open_canvas_button: typing.Optional[Button] = None
self.init_ui()
def __repr__(self):
return self.contact
def init_ui(self):
for child in walk_children(self.object):
if str(getattr(child, 'id', '')) == 'iconOrImage':
self.icon = Image(driver.objectMap.realName(child))
elif str(getattr(child, 'id', '')) == 'menuButton':
self._open_canvas_button = Button(name='', real_name=driver.objectMap.realName(child))
elif str(getattr(child, 'objectName', '')) == 'checkmark-circle-icon':
self._accept_button = Button(name='', real_name=driver.objectMap.realName(child))
elif str(getattr(child, 'objectName', '')) == 'close-circle-icon':
self._reject_button = Button(name='', real_name=driver.objectMap.realName(child))
elif str(getattr(child, 'id', '')) == 'statusListItemTitle':
self.contact = str(child.text)
def accept(self) -> MessagesScreen:
assert self._accept_button is not None, 'Button not found'
self._accept_button.click()
return MessagesScreen().wait_until_appears()
class ContactsSettingsView(QObject):
def __init__(self):
super().__init__('mainWindow_ContactsView')
self._contact_request_button = Button('mainWindow_Send_contact_request_to_chat_key_StatusButton')
self._pending_request_tab = Button('contactsTabBar_Pending_Requests_StatusTabButton')
self._pending_requests_list = List('settingsContentBaseScrollView_ContactListPanel')
@property
@allure.step('Get all pending requests')
def pending_requests(self) -> typing.List[PendingRequest]:
self._pending_request_tab.click()
return [PendingRequest(item) for item in self._pending_requests_list.items]
@allure.step('Open contacts request form')
def open_contact_request_form(self) -> SendContactRequest:
self._contact_request_button.click()
return SendContactRequest().wait_until_appears()
@allure.step('Accept contact request')
def accept_contact_request(
self, contact: str, timeout_sec: int = configs.timeouts.MESSAGING_TIMEOUT_SEC) -> MessagesScreen:
self._pending_request_tab.click()
started_at = time.monotonic()
request = None
while request is None:
requests = self.pending_requests
for _request in requests:
if _request.contact == contact:
request = _request
assert time.monotonic() - started_at < timeout_sec, f'Contact: {contact} not found in {requests}'
return request.accept()
class CommunitiesSettingsView(QObject):
def __init__(self):

View File

@ -7,3 +7,4 @@ pytesseract==0.3.10
atomacos==3.3.0; platform_system == "Darwin"
allure-pytest==2.13.2
testrail-api==1.12.0
pyperclip==1.8.2

View File

@ -23,9 +23,25 @@ def find_process_by_port(port: int) -> int:
pass
def wait_for_close(pid: int, timeout_sec: int = configs.timeouts.PROCESS_TIMEOUT_SEC):
started_at = time.monotonic()
while True:
if pid in [proc.pid for proc in psutil.process_iter()]:
time.sleep(1)
if time.monotonic() - started_at > timeout_sec:
raise RuntimeError(f'Process with PID: {pid} not closed')
else:
break
@allure.step('Kill process')
def kill_process(pid):
os.kill(pid, signal.SIGILL if IS_WIN else signal.SIGKILL)
def kill_process(pid, verify: bool = False):
try:
os.kill(pid, signal.SIGILL if IS_WIN else signal.SIGKILL)
except ProcessLookupError as err:
_logger.debug(err)
if verify:
wait_for_close(pid)
@allure.step('System execute command')

View File

@ -1,5 +1,3 @@
from datetime import datetime
import pytest
import configs
@ -7,33 +5,39 @@ import constants
from constants import UserAccount
from driver.aut import AUT
from gui.main_window import MainWindow
from gui.screens.onboarding import LoginView
from scripts.utils import system_path
@pytest.fixture()
def aut() -> AUT:
if not configs.APP_DIR.exists():
pytest.exit(f"Application not found: {configs.APP_DIR}")
_aut = AUT()
yield _aut
from scripts.utils.system_path import SystemPath
@pytest.fixture
def user_data(request) -> system_path.SystemPath:
user_data = configs.testpath.STATUS_DATA / f'app_{datetime.now():%H%M%S_%f}' / 'data'
if hasattr(request, 'param'):
fp = request.param
if isinstance(fp, str):
fp = configs.testpath.TEST_USER_DATA / fp / 'data'
assert fp.is_dir()
fp.copy_to(user_data)
yield user_data
return fp
@pytest.fixture
def aut(user_data) -> AUT:
if not configs.APP_DIR.exists():
pytest.exit(f"Application not found: {configs.APP_DIR}")
_aut = AUT(user_data=user_data)
yield _aut
@pytest.fixture()
def multiple_instance():
def _aut(user_data: SystemPath = None) -> AUT:
if not configs.APP_DIR.exists():
pytest.exit(f"Application not found: {configs.APP_DIR}")
return AUT(user_data=user_data)
yield _aut
@pytest.fixture
def main_window(aut: AUT, user_data):
aut.launch(f'-d={user_data.parent}')
aut.launch()
yield MainWindow().wait_until_appears().prepare()
aut.detach().stop()
@ -44,22 +48,11 @@ def user_account(request) -> UserAccount:
user_account = request.param
assert isinstance(user_account, UserAccount)
else:
user_account = constants.user.user_account_default
user_account = constants.user.user_account_one
yield user_account
@pytest.fixture
def main_screen(user_account: UserAccount, main_window: MainWindow) -> MainWindow:
if LoginView().is_visible:
yield main_window.log_in(user_account)
else:
yield main_window.sign_up(user_account)
@pytest.fixture
def community(main_screen, request) -> dict:
community_params = request.param
communities_portal = main_screen.left_panel.open_communities_portal()
create_community_form = communities_portal.open_create_community_popup()
create_community_form.create(community_params)
return community_params
main_window.authorize_user(user_account)
return main_window

View File

@ -1,3 +1,4 @@
from copy import deepcopy
from datetime import datetime
import allure
@ -5,7 +6,9 @@ import pytest
from allure_commons._allure import step
import configs.testpath
import constants.user
import constants
import driver
from constants import UserAccount
from gui.main_window import MainWindow
from gui.screens.community import CommunityScreen
from scripts.tools import image
@ -15,7 +18,7 @@ pytestmark = allure.suite("Communities")
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703084', 'Create community')
@pytest.mark.case(703084)
@pytest.mark.parametrize('params', [constants.user.default_community_params])
@pytest.mark.parametrize('params', [constants.community_params])
def test_create_community(user_account, main_screen: MainWindow, params):
with step('Create community'):
communities_portal = main_screen.left_panel.open_communities_portal()
@ -46,7 +49,7 @@ def test_create_community(user_account, main_screen: MainWindow, params):
with step('Verify community parameters in community settings screen'):
settings_screen = main_screen.left_panel.open_settings()
community_settings = settings_screen.open_communities_settings()
community_settings = settings_screen.left_panel.open_communities_settings()
community = community_settings.get_community_info(params['name'])
assert community.name == params['name']
assert community.description == params['description']
@ -56,19 +59,19 @@ def test_create_community(user_account, main_screen: MainWindow, params):
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703056', 'Edit community separately')
@pytest.mark.case(703056)
@pytest.mark.parametrize('community', [constants.user.default_community_params], indirect=True)
@pytest.mark.parametrize('community_params', [
{
'name': f'Name_{datetime.now():%H%M%S}',
'description': f'Description_{datetime.now():%H%M%S}',
'color': '#ff7d46',
},
{
'name': f'Name_{datetime.now():%H%M%S}',
'description': f'Description_{datetime.now():%H%M%S}',
'color': '#ff7d46',
},
])
def test_edit_community_separately(main_screen, community: dict, community_params):
def test_edit_community_separately(main_screen, community_params):
main_screen.create_community(constants.community_params)
with step('Edit community name'):
community_screen = main_screen.left_panel.select_community(community['name'])
community_screen = main_screen.left_panel.select_community(constants.community_params['name'])
community_setting = community_screen.left_panel.open_community_settings()
edit_community_form = community_setting.left_panel.open_overview().open_edit_community_view()
edit_community_form.edit({'name': community_params['name']})
@ -77,7 +80,7 @@ def test_edit_community_separately(main_screen, community: dict, community_param
overview_setting = community_setting.left_panel.open_overview()
assert overview_setting.name == community_params['name']
with step('Description is correct'):
assert overview_setting.description == constants.default_community_params['description']
assert overview_setting.description == constants.community_params['description']
with step('Edit community name'):
edit_community_form = overview_setting.open_edit_community_view()
@ -92,7 +95,6 @@ def test_edit_community_separately(main_screen, community: dict, community_param
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703057', 'Edit community')
@pytest.mark.case(703057)
@pytest.mark.parametrize('community', [constants.user.default_community_params], indirect=True)
@pytest.mark.parametrize('params', [
{
'name': 'Updated Name',
@ -105,10 +107,11 @@ def test_edit_community_separately(main_screen, community: dict, community_param
'outro': 'Updated Outro'
}
])
def test_edit_community(main_screen: MainWindow, community: dict, params):
def test_edit_community(main_screen: MainWindow, params):
main_screen.create_community(constants.community_params)
with step('Edit community'):
community_screen = main_screen.left_panel.select_community(community['name'])
community_screen = main_screen.left_panel.select_community(constants.community_params['name'])
community_setting = community_screen.left_panel.open_community_settings()
edit_community_form = community_setting.left_panel.open_overview().open_edit_community_view()
edit_community_form.edit(params)
@ -132,7 +135,7 @@ def test_edit_community(main_screen: MainWindow, community: dict, params):
with step('Verify community parameters in community settings screen'):
settings_screen = main_screen.left_panel.open_settings()
community_settings = settings_screen.open_communities_settings()
community_settings = settings_screen.left_panel.open_communities_settings()
community_info = community_settings.communities[0]
assert community_info.name == params['name']
assert community_info.description == params['description']
@ -142,11 +145,10 @@ def test_edit_community(main_screen: MainWindow, community: dict, params):
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703049', 'Create community channel')
@pytest.mark.case(703049)
@pytest.mark.parametrize('community', [constants.user.default_community_params], indirect=True)
@pytest.mark.parametrize('channel_name, channel_description, channel_emoji', [('Channel', 'Description', 'sunglasses')])
def test_create_community_channel(main_screen: MainWindow, community: dict, channel_name, channel_description,
channel_emoji):
community_screen = main_screen.left_panel.select_community(community['name'])
def test_create_community_channel(main_screen: MainWindow, channel_name, channel_description, channel_emoji):
main_screen.create_community(constants.community_params)
community_screen = main_screen.left_panel.select_community(constants.community_params['name'])
community_screen.create_channel(channel_name, channel_description, channel_emoji)
with step('Verify channel'):
@ -161,9 +163,9 @@ def test_create_community_channel(main_screen: MainWindow, community: dict, chan
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703050', 'Edit community channel')
@pytest.mark.case(703050)
@pytest.mark.parametrize('community', [constants.user.default_community_params], indirect=True)
@pytest.mark.parametrize('channel_name, channel_description, channel_emoji', [('Channel', 'Description', 'sunglasses')])
def test_edit_community_channel(community: dict, channel_name, channel_description, channel_emoji):
def test_edit_community_channel(main_screen, channel_name, channel_description, channel_emoji):
main_screen.create_community(constants.community_params)
community_screen = CommunityScreen()
with step('Verify General channel'):
@ -189,10 +191,94 @@ def test_edit_community_channel(community: dict, channel_name, channel_descripti
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703051', 'Delete community channel')
@pytest.mark.case(703051)
@pytest.mark.parametrize('community', [constants.user.default_community_params], indirect=True)
def test_delete_community_channel(community: dict):
def test_delete_community_channel(main_screen):
main_screen.create_community(constants.community_params)
with step('Delete channel'):
CommunityScreen().delete_channel('general')
with step('Verify channel is not exists'):
assert not CommunityScreen().left_panel.channels
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703510', 'Join community via owner invite')
@pytest.mark.case(703510)
@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_join_community_via_owner_invite(multiple_instance, user_data_one, user_data_two):
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_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()
settings = main_window.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)
main_window.hide()
with step(f'User {user_one.name}, create community and {user_two.name}'):
aut_one.attach()
main_window.prepare()
main_window.create_community(community_params)
main_window.left_panel.invite_people_in_community([user_two.name], 'Message', community_params['name'])
main_window.hide()
with step(f'User {user_two.name}, accept invitation from {user_one.name}'):
aut_two.attach()
main_window.prepare()
messages_view = main_window.left_panel.open_messages_screen()
chat = messages_view.left_panel.open_chat(user_one.name)
community_screen = chat.accept_community_invite(community_params['name'])
with step(f'User {user_two.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'
with step(f'User {user_two.name}, see two members in community members list'):
assert user_one.name in community_screen.right_panel.members
assert driver.waitFor(lambda: user_two.name in community_screen.right_panel.members)
assert '2' in community_screen.left_panel.members
main_window.hide()
with step(f'User {user_one.name}, see two members in community members list'):
aut_one.attach()
main_window.prepare()
assert user_one.name in community_screen.right_panel.members
assert driver.waitFor(lambda: user_two.name in community_screen.right_panel.members)
assert '2' in community_screen.left_panel.members

View File

@ -108,7 +108,7 @@ def test_generate_new_keys(main_window, keys_screen, user_name: str, password, u
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703039', 'Import: 12 word seed phrase')
@pytest.mark.case(703039)
@pytest.mark.parametrize('user_account', [constants.user.user_account_default])
@pytest.mark.parametrize('user_account', [constants.user.user_account_two])
def test_import_seed_phrase(keys_screen, main_window, user_account):
with step('Open import seed phrase view and enter seed phrase'):
input_view = keys_screen.open_import_seed_phrase_view().open_seed_phrase_input_view()

View File

@ -7,7 +7,7 @@ from allure import step
import configs.timeouts
import constants
import driver
from gui.components.authenticate_popup import AuthenticatePopup
from gui.components.wallet.authenticate_popup import AuthenticatePopup
from gui.components.signing_phrase_popup import SigningPhrasePopup
from gui.main_window import MainWindow