test(suite_settings/tst_userIdentity): Fix test on display name, bio and social links (#10226)

- scroll profile settings view added 
- method to add links fixed
- SettingProfile class moved from Settings class
This commit is contained in:
Vladimir Druzhinin 2023-04-24 11:39:07 +02:00 committed by GitHub
parent 9993685b5a
commit 7757c3b47d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 378 additions and 191 deletions

View File

@ -17,8 +17,11 @@ import object
# IMPORTANT: It is necessary to import manually the Squish drivers module by module. # IMPORTANT: It is necessary to import manually the Squish drivers module by module.
# More info in: https://kb.froglogic.com/display/KB/Article+-+Using+Squish+functions+in+your+own+Python+modules+or+packages # More info in: https://kb.froglogic.com/display/KB/Article+-+Using+Squish+functions+in+your+own+Python+modules+or+packages
import squish import squish
import toplevelwindow
from objectmaphelper import Wildcard from objectmaphelper import Wildcard
from .elements import * # noqa
# The default maximum timeout to find ui object # The default maximum timeout to find ui object
_MAX_WAIT_OBJ_TIMEOUT = 5000 _MAX_WAIT_OBJ_TIMEOUT = 5000
@ -30,6 +33,7 @@ _SEARCH_IMAGES_PATH = "../shared/searchImages/"
def start_application(app_name: str): def start_application(app_name: str):
squish.startApplication(app_name) squish.startApplication(app_name)
toplevelwindow.ToplevelWindow(squish.waitForObject(names.statusDesktop_mainWindow)).maximize()
# Waits for the given object is loaded, visible and enabled. # Waits for the given object is loaded, visible and enabled.
@ -491,5 +495,5 @@ def wait_for(py_condition_to_check: str, timeout_msec: int = 500):
squish.waitFor(py_condition_to_check, timeout_msec) squish.waitFor(py_condition_to_check, timeout_msec)
def wait_util_hidden(object_name: str, timeout_msec: int = _MAX_WAIT_OBJ_TIMEOUT) -> bool: def wait_until_hidden(object_name: str, timeout_msec: int = _MAX_WAIT_OBJ_TIMEOUT) -> bool:
return squish.waitFor(lambda: not is_displayed(object_name), timeout_msec) return squish.waitFor(lambda: not is_displayed(object_name), timeout_msec)

View File

@ -120,4 +120,7 @@ def image_present(imageName: str, tolerant: bool = True, threshold: int = 99.5,
test.imagePresent(imageName, {"tolerant": tolerant, "threshold": threshold, "minScale": minScale, "maxScale": maxScale, "multiscale": multiscale}, searchRegion) test.imagePresent(imageName, {"tolerant": tolerant, "threshold": threshold, "minScale": minScale, "maxScale": maxScale, "multiscale": multiscale}, searchRegion)
def passes(text: str): def passes(text: str):
test.passes(text) test.passes(text)
def compare_text(expected: str, actual: str):
test.compare(expected, actual, f'Actual value "{actual}" not equals to expected: {expected}')

View File

@ -0,0 +1,5 @@
from .base_element import BaseElement
from .button import Button
from .scroll import Scroll
from .text_edit import TextEdit
from .text_label import TextLabel

View File

@ -0,0 +1,67 @@
import typing
import names
import object
import squish
class BaseElement:
def __init__(self, object_name):
self.object_name = getattr(names, object_name)
@property
def object(self):
return squish.waitForObject(self.object_name)
@property
def existent(self):
return squish.waitForObjectExists(self.object_name)
@property
def bounds(self) -> squish.UiTypes.ScreenRectangle:
return object.globalBounds(self.object)
@property
def width(self) -> int:
return int(self.bounds.width)
@property
def height(self) -> int:
return int(self.bounds.height)
@property
def center(self) -> squish.UiTypes.ScreenPoint:
return self.bounds.center()
@property
def is_selected(self) -> bool:
return self.object.selected
@property
def is_visible(self) -> bool:
try:
return squish.waitForObject(self.object_name, 500).visible
except LookupError:
return False
def click(
self,
x: typing.Union[int, squish.UiTypes.ScreenPoint] = None,
y: typing.Union[int, squish.UiTypes.ScreenPoint] = None,
button: squish.MouseButton = None
):
squish.mouseClick(
self.object,
x or self.width // 2,
y or self.height // 2,
button or squish.MouseButton.LeftButton
)
def wait_utill_appears(self, timeout_sec: int = 5):
assert squish.waitFor(lambda: self.is_visible, timeout_sec * 1000), 'Object is not visible'
return self
def wait_utill_hidden(self, timeout_sec: int = 5):
assert squish.waitFor(lambda: not self.is_visible, timeout_sec * 1000), 'Object is not hidden'

View File

@ -0,0 +1,5 @@
from .base_element import BaseElement
class Button(BaseElement):
pass

View File

@ -0,0 +1,20 @@
import time
import squish
from .base_element import BaseElement
class Scroll(BaseElement):
def vertical_scroll_to(self, element: BaseElement, timeout_sec: int = 5):
started_at = time.monotonic()
step = 10
direction = 1
while not element.is_visible:
step *= 2
direction *= -1
squish.flick(self.object, 0, step * direction)
time.sleep(0.1)
if time.monotonic() - started_at > timeout_sec:
raise LookupError(f'Object not found: {element.object_name}')

View File

@ -0,0 +1,28 @@
import squish
from .base_element import BaseElement
class TextEdit(BaseElement):
@property
def text(self) -> str:
return str(self.object.text)
@text.setter
def text(self, value: str):
self.clear()
self.type_text(value)
assert squish.waitFor(lambda: self.text == value)
def type_text(self, value: str):
squish.type(self.object, value)
assert squish.waitFor(lambda: self.text == value), \
f'Type text failed, value in field: "{self.text}", expected: {value}'
return self
def clear(self):
self.object.clear()
assert squish.waitFor(lambda: not self.text), \
f'Field did not cleared, value in field: "{self.text}"'
return self

View File

@ -0,0 +1,8 @@
from .base_element import BaseElement
class TextLabel(BaseElement):
@property
def text(self) -> str:
return str(self.object.text)

View File

@ -19,6 +19,8 @@ from utils.ObjectAccess import *
from .StatusMainScreen import MainScreenComponents from .StatusMainScreen import MainScreenComponents
from .StatusMainScreen import authenticate_popup_enter_password from .StatusMainScreen import authenticate_popup_enter_password
from .components.cahange_password_popup import ChangePasswordPopup
from .components.social_links_popup import SocialLinksPopup
class SettingsScreenComponents(Enum): class SettingsScreenComponents(Enum):
@ -92,32 +94,6 @@ class WalletSettingsScreen(Enum):
BACKUP_SEED_PHRASE_BUTTON: str = "settings_Wallet_MainView_BackupSeedPhrase" BACKUP_SEED_PHRASE_BUTTON: str = "settings_Wallet_MainView_BackupSeedPhrase"
class ProfileSettingsScreen(Enum):
DISPLAY_NAME: str = "displayName_TextEdit"
BIO: str = "bio_TextEdit"
TWITTER_SOCIAL_LINK: str = "twitter_TextEdit"
PERSONAL_SITE_SOCIAL_LINK: str = "personalSite_TextEdit"
OPEN_SOCIAL_LINKS_DIALOG: str = "addMoreSocialLinks_StatusIconTextButton"
CLOSE_SOCIAL_LINKS_DIALOG: str = "closeButton_StatusHeaderAction"
TWITTER_SOCIAL_LINK_IN_DIALOG: str = "twitter_popup_TextEdit"
PERSONAL_SITE_LINK_IN_DIALOG: str = "personalSite_popup_TextEdit"
GITHUB_SOCIAL_LINK_IN_DIALOG: str = "github_popup_TextEdit"
YOUTUBE_SOCIAL_LINK_IN_DIALOG: str = "youtube_popup_TextEdit"
DISCORD_SOCIAL_LINK_IN_DIALOG: str = "discord_popup_TextEdit"
TELEGRAM_SOCIAL_LINK_IN_DIALOG: str = "telegram_popup_TextEdit"
CUSTOM_LINK_IN_DIALOG: str = "customLink_popup_TextEdit"
CUSTOM_URL_IN_DIALOG: str = "customUrl_popup_TextEdit"
CHANGE_PASSWORD_BUTTON: str = "change_password_button"
class ChangePasswordMenu(Enum):
CHANGE_PASSWORD_CURRENT_PASSWORD_INPUT: str = "change_password_menu_current_password"
CHANGE_PASSWORD_NEW_PASSWORD_INPUT: str = "change_password_menu_new_password"
CHANGE_PASSWORD_NEW_PASSWORD_CONFIRM_INPUT: str = "change_password_menu_new_password_confirm"
CHANGE_PASSWORD_SUBMIT_BUTTON: str = "change_password_menu_submit_button"
CHANGE_PASSWORD_SUCCESS_MENU_SIGN_OUT_QUIT_BUTTON: str = "change_password_success_menu_sign_out_quit_button"
class ConfirmationDialog(Enum): class ConfirmationDialog(Enum):
SIGN_OUT_CONFIRMATION: str = "signOutConfirmation_StatusButton" SIGN_OUT_CONFIRMATION: str = "signOutConfirmation_StatusButton"
@ -148,6 +124,15 @@ class SettingsScreen:
def __init__(self): def __init__(self):
verify_screen(SidebarComponents.ADVANCED_OPTION.value) verify_screen(SidebarComponents.ADVANCED_OPTION.value)
self._profile_view = ProfileSettingsView()
self._profile_button = Button('profile_StatusNavigationListItem')
@property
def profile_settings(self) -> 'ProfileSettingsView':
if not self._profile_button.is_selected:
verify_object_enabled(SidebarComponents.PROFILE_OPTION.value)
self._profile_button.click()
return self._profile_view
def open_advanced_settings(self): def open_advanced_settings(self):
click_obj_by_name(SidebarComponents.ADVANCED_OPTION.value) click_obj_by_name(SidebarComponents.ADVANCED_OPTION.value)
@ -298,109 +283,6 @@ class SettingsScreen:
return return
verify(False, "Community left") verify(False, "Community left")
def open_profile_settings(self):
verify_object_enabled(SidebarComponents.PROFILE_OPTION.value)
click_obj_by_name(SidebarComponents.PROFILE_OPTION.value)
def verify_display_name(self, display_name: str):
verify_text_matching(ProfileSettingsScreen.DISPLAY_NAME.value, display_name)
def set_display_name(self, display_name: str):
click_obj_by_name(ProfileSettingsScreen.DISPLAY_NAME.value)
name_changed = setText(ProfileSettingsScreen.DISPLAY_NAME.value, display_name)
verify(name_changed, "set display name")
click_obj_by_name(SettingsScreenComponents.SAVE_BUTTON.value)
self.verify_display_name(display_name)
def verify_bio(self, bio: str):
verify_text_matching(ProfileSettingsScreen.BIO.value, bio)
def set_bio(self, bio: str):
click_obj_by_name(ProfileSettingsScreen.BIO.value)
verify(setText(ProfileSettingsScreen.BIO.value, bio), "set bio")
click_obj_by_name(SettingsScreenComponents.SAVE_BUTTON.value)
self.verify_bio(bio)
def set_social_links(self, table):
twitter = ""
personal_site = ""
github = ""
youtube = ""
discord = ""
telegram = ""
custom_link_text = ""
custom_link = ""
if table is not None:
verify_equals(8, len(table)) # Expecting 8 as social media link fields to verify
twitter = table[0][0]
personal_site = table[1][0]
github = table[2][0]
youtube = table[3][0]
discord = table[4][0]
telegram = table[5][0]
custom_link_text = table[6][0]
custom_link = table[7][0]
click_obj_by_name(ProfileSettingsScreen.OPEN_SOCIAL_LINKS_DIALOG.value)
click_obj_by_name(ProfileSettingsScreen.TWITTER_SOCIAL_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.TWITTER_SOCIAL_LINK_IN_DIALOG.value, twitter), "set twitter")
click_obj_by_name(ProfileSettingsScreen.PERSONAL_SITE_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.PERSONAL_SITE_LINK_IN_DIALOG.value, personal_site), "set personal site")
click_obj_by_name(ProfileSettingsScreen.GITHUB_SOCIAL_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.GITHUB_SOCIAL_LINK_IN_DIALOG.value, github), "set github")
click_obj_by_name(ProfileSettingsScreen.YOUTUBE_SOCIAL_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.YOUTUBE_SOCIAL_LINK_IN_DIALOG.value, youtube), "set youtube")
click_obj_by_name(ProfileSettingsScreen.DISCORD_SOCIAL_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.DISCORD_SOCIAL_LINK_IN_DIALOG.value, discord), "set discord")
click_obj_by_name(ProfileSettingsScreen.TELEGRAM_SOCIAL_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.TELEGRAM_SOCIAL_LINK_IN_DIALOG.value, telegram), "set telegram")
click_obj_by_name(ProfileSettingsScreen.CUSTOM_LINK_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.CUSTOM_LINK_IN_DIALOG.value, custom_link_text), "set custom link name")
click_obj_by_name(ProfileSettingsScreen.CUSTOM_URL_IN_DIALOG.value)
verify(setText(ProfileSettingsScreen.CUSTOM_URL_IN_DIALOG.value, custom_link), "set custom link url")
click_obj_by_name(ProfileSettingsScreen.CLOSE_SOCIAL_LINKS_DIALOG.value)
click_obj_by_name(SettingsScreenComponents.SAVE_BUTTON.value)
def verify_social_links(self, table):
twitter = ""
personal_site = ""
github = ""
youtube = ""
discord = ""
telegram = ""
custom_link_text = ""
custom_link = ""
if table is not None:
verify_equals(8, len(table)) # Expecting 8 as social media link fields to verify
twitter = table[0][0]
personal_site = table[1][0]
github = table[2][0]
youtube = table[3][0]
discord = table[4][0]
telegram = table[5][0]
custom_link_text = table[6][0]
custom_link = table[7][0]
verify_text_matching(ProfileSettingsScreen.TWITTER_SOCIAL_LINK.value, twitter)
verify_text_matching(ProfileSettingsScreen.PERSONAL_SITE_SOCIAL_LINK.value, personal_site)
click_obj_by_name(ProfileSettingsScreen.OPEN_SOCIAL_LINKS_DIALOG.value)
verify_text_matching(ProfileSettingsScreen.TWITTER_SOCIAL_LINK_IN_DIALOG.value, twitter)
verify_text_matching(ProfileSettingsScreen.PERSONAL_SITE_LINK_IN_DIALOG.value, personal_site)
verify_text_matching(ProfileSettingsScreen.GITHUB_SOCIAL_LINK_IN_DIALOG.value, github)
verify_text_matching(ProfileSettingsScreen.YOUTUBE_SOCIAL_LINK_IN_DIALOG.value, youtube)
verify_text_matching(ProfileSettingsScreen.DISCORD_SOCIAL_LINK_IN_DIALOG.value, discord)
verify_text_matching(ProfileSettingsScreen.TELEGRAM_SOCIAL_LINK_IN_DIALOG.value, telegram)
verify_text_matching(ProfileSettingsScreen.CUSTOM_LINK_IN_DIALOG.value, custom_link_text)
verify_text_matching(ProfileSettingsScreen.CUSTOM_URL_IN_DIALOG.value, custom_link)
click_obj_by_name(ProfileSettingsScreen.CLOSE_SOCIAL_LINKS_DIALOG.value)
def check_backup_seed_phrase_workflow(self): def check_backup_seed_phrase_workflow(self):
click_obj_by_name(WalletSettingsScreen.BACKUP_SEED_PHRASE_BUTTON.value) click_obj_by_name(WalletSettingsScreen.BACKUP_SEED_PHRASE_BUTTON.value)
@ -447,22 +329,10 @@ class SettingsScreen:
click_obj_by_name(BackupSeedPhrasePopup.CONFIRM_YOU_STORED_BUTTON.value) click_obj_by_name(BackupSeedPhrasePopup.CONFIRM_YOU_STORED_BUTTON.value)
def verify_seed_phrase_indicator_not_visible(self): def verify_seed_phrase_indicator_not_visible(self):
assert wait_util_hidden( assert wait_until_hidden(
WalletSettingsScreen.BACKUP_SEED_PHRASE_BUTTON.value, WalletSettingsScreen.BACKUP_SEED_PHRASE_BUTTON.value,
), "Backup seed phrase settings button is visible" ), "Backup seed phrase settings button is visible"
def change_user_password(self, oldPassword: str, newPassword: str):
get_and_click_obj(ProfileSettingsScreen.CHANGE_PASSWORD_BUTTON.value)
type_text(ChangePasswordMenu.CHANGE_PASSWORD_CURRENT_PASSWORD_INPUT.value, oldPassword)
type_text(ChangePasswordMenu.CHANGE_PASSWORD_NEW_PASSWORD_INPUT.value, newPassword)
type_text(ChangePasswordMenu.CHANGE_PASSWORD_NEW_PASSWORD_CONFIRM_INPUT.value, newPassword)
click_obj_by_name(ChangePasswordMenu.CHANGE_PASSWORD_SUBMIT_BUTTON.value)
click_obj_by_name(ChangePasswordMenu.CHANGE_PASSWORD_SUCCESS_MENU_SIGN_OUT_QUIT_BUTTON.value)
def add_contact_by_chat_key(self, chat_key: str, who_you_are: str): def add_contact_by_chat_key(self, chat_key: str, who_you_are: str):
click_obj_by_name(ContactsViewScreen.CONTACT_REQUEST_CHAT_KEY_BTN.value) click_obj_by_name(ContactsViewScreen.CONTACT_REQUEST_CHAT_KEY_BTN.value)
@ -508,3 +378,111 @@ class SettingsScreen:
click_obj(delegate) click_obj(delegate)
return return
verify(False, "Community not found") verify(False, "Community not found")
class ProfileSettingsView(BaseElement):
def __init__(self):
super(ProfileSettingsView, self).__init__('mainWindow_MyProfileView')
self._display_name_text_field = TextEdit('displayName_TextEdit')
self._bio_text_field = TextEdit('bio_TextEdit')
self._scroll_view = Scroll('settingsContentBase_ScrollView')
self._add_more_links_label = TextLabel('addMoreSocialLinks')
self._save_button = Button('settingsSave_StatusButton')
self._links_list = BaseElement('linksView')
self._change_password_button = Button('change_password_button')
@property
def display_name(self) -> str:
self._scroll_view.vertical_scroll_to(self._display_name_text_field)
return self._display_name_text_field.text
@display_name.setter
def display_name(self, value: str):
self._scroll_view.vertical_scroll_to(self._display_name_text_field)
self._display_name_text_field.text = value
self.save_changes()
@property
def bio(self) -> str:
self._scroll_view.vertical_scroll_to(self._display_name_text_field)
return self._bio_text_field.text
@bio.setter
def bio(self, value: str):
self._scroll_view.vertical_scroll_to(self._display_name_text_field)
self._bio_text_field.text = value
self.save_changes()
@property
def social_links(self) -> dict:
self._scroll_view.vertical_scroll_to(self._add_more_links_label)
links = {}
for link_name in walk_children(self._links_list.existent):
if getattr(link_name, 'id', '') == 'draggableDelegate':
for link_value in walk_children(link_name):
if getattr(link_value, 'id', '') == 'textMouseArea':
links[str(link_name.title)] = str(object.parent(link_value).text)
return links
@social_links.setter
def social_links(self, table):
verify_equals(8, len(table)) # Expecting 8 as social media link fields to verify
links = {
'Twitter': [table[0][0]],
'Personal Site': [table[1][0]],
'Github': [table[2][0]],
'YouTube': [table[3][0]],
'Discord': [table[4][0]],
'Telegram': [table[5][0]],
'Custom link': [table[6][0], table[7][0]],
}
for network, link in links.items():
social_links_popup = self.open_social_links_popup()
social_links_popup.add_link(network, link)
def save_changes(self):
self._save_button.click()
def open_social_links_popup(self):
self._scroll_view.vertical_scroll_to(self._add_more_links_label)
self._add_more_links_label.click()
return SocialLinksPopup().wait_utill_appears()
def verify_display_name(self, display_name: str):
compare_text(display_name, self.display_name)
def verify_bio(self, bio: str):
compare_text(bio, self.bio)
def verify_social_links(self, table):
verify_equals(8, len(table)) # Expecting 8 as social media link fields to verify
twitter = table[0][0]
personal_site = table[1][0]
github = table[2][0]
youtube = table[3][0]
discord = table[4][0]
telegram = table[5][0]
custom_link_text = table[6][0]
custom_link = table[7][0]
links = self.social_links
compare_text(links['Twitter'], twitter)
compare_text(links['Personal Site'], personal_site)
compare_text(links['Github'], github)
compare_text(links['YouTube'], youtube)
compare_text(links['Discord'], discord)
compare_text(links['Telegram'], telegram)
compare_text(links[custom_link_text], custom_link)
def verify_social_no_links(self):
links = self.social_links
for value in links.values():
compare_text(value, '')
def open_change_password_popup(self):
self._scroll_view.vertical_scroll_to(self._change_password_button)
self._change_password_button.click()
return ChangePasswordPopup().wait_utill_appears()

View File

@ -1,7 +1,7 @@
#****************************************************************************** # ******************************************************************************
# Status.im # Status.im
#*****************************************************************************/ # *****************************************************************************/
#/** # /**
# * \file AccountsPopup.py # * \file AccountsPopup.py
# * # *
# * \date February 2022 # * \date February 2022
@ -13,27 +13,28 @@ from drivers.SquishDriver import *
from drivers.SquishDriverVerification import * from drivers.SquishDriverVerification import *
from utils.ObjectAccess import * from utils.ObjectAccess import *
# It defines the identifier for each Account View component: # It defines the identifier for each Account View component:
class SAccountsComponents(Enum): class SAccountsComponents(Enum):
ACCOUNTS_POPUP = "accountsView_accountListPanel" ACCOUNTS_POPUP = "accountsView_accountListPanel"
#It defines the status accounts popup behavior and properties.
class StatusAccountsScreen():
# It defines the status accounts popup behavior and properties.
class StatusAccountsScreen:
def __init__(self): def __init__(self):
verify_screen(SAccountsComponents.ACCOUNTS_POPUP.value) verify_screen(SAccountsComponents.ACCOUNTS_POPUP.value)
def find_account(self, account): def find_account(self, account):
[found, account_obj] = self.__find_account(account) [found, account_obj] = self.__find_account(account)
return found return found
def select_account(self, account): def select_account(self, account):
[found, account_obj] = self.__find_account(account) [found, account_obj] = self.__find_account(account)
if found: if found:
return click_obj(account_obj) return click_obj(account_obj)
return found return found
def __find_account(self, account): def __find_account(self, account):
found = False found = False
account_obj = None account_obj = None
@ -41,8 +42,8 @@ class StatusAccountsScreen():
if is_loaded: if is_loaded:
for index in range(accountsList.count): for index in range(accountsList.count):
a = accountsList.itemAt(index) a = accountsList.itemAt(index)
if(a.label == account): if (a.label == account):
account_obj = a account_obj = a
found = True found = True
break break
return found, account_obj return found, account_obj

View File

@ -11,11 +11,12 @@
import time import time
from enum import Enum from enum import Enum
from drivers.SDKeyboardCommands import *
from drivers.SquishDriver import * from drivers.SquishDriver import *
from drivers.SquishDriverVerification import * from drivers.SquishDriverVerification import *
from drivers.SDKeyboardCommands import *
from utils.ObjectAccess import * from utils.ObjectAccess import *
import time
class MainScreenComponents(Enum): class MainScreenComponents(Enum):
MAIN_WINDOW = "statusDesktop_mainWindow" MAIN_WINDOW = "statusDesktop_mainWindow"
@ -194,9 +195,8 @@ class StatusMainScreen:
def close_popup(self): def close_popup(self):
# Click in the corner of the overlay to close the popup # Click in the corner of the overlay to close the popup
click_obj_by_name_at_coordinates(MainScreenComponents.POPUP_OVERLAY.value, 1, 1) click_obj_by_name_at_coordinates(MainScreenComponents.POPUP_OVERLAY.value, 1, 1)
def is_secure_your_seed_phrase_banner_visible(self, value: bool): def is_secure_your_seed_phrase_banner_visible(self, value: bool):
verify(is_found(MainScreenComponents.SECURE_YOUR_SEED_PHRASE_BANNER.value) is value, verify(is_found(MainScreenComponents.SECURE_YOUR_SEED_PHRASE_BANNER.value) is value,
f'Secure your seed phrase banner visible: {value}' f'Secure your seed phrase banner visible: {value}'
) )

0
test/ui-test/src/screens/components/__init__.py Executable file → Normal file
View File

View File

@ -0,0 +1,19 @@
from drivers.SquishDriver import *
class ChangePasswordPopup(BaseElement):
def __init__(self):
super(ChangePasswordPopup, self).__init__('statusDesktop_mainWindow_overlay')
self._current_password_text_field = TextEdit('change_password_menu_current_password')
self._new_password_text_field = TextEdit('change_password_menu_new_password')
self._confirm_password_text_field = TextEdit('change_password_menu_new_password_confirm')
self._submit_button = Button('change_password_menu_submit_button')
self._quit_button = Button('change_password_success_menu_sign_out_quit_button')
def change_password(self, old_pwd: str, new_pwd: str):
self._current_password_text_field.text = old_pwd
self._new_password_text_field.text = new_pwd
self._confirm_password_text_field.text = new_pwd
self._submit_button.click()
self._quit_button.click()

View File

@ -0,0 +1,33 @@
import typing
from drivers.SquishDriver import *
class SocialLinksPopup(BaseElement):
def __init__(self):
super(SocialLinksPopup, self).__init__('statusDesktop_mainWindow_overlay')
self._add_social_link_list_item = BaseElement('socialLink_StatusListItem')
self._social_link_text_field = TextEdit('edit_TextEdit')
self._add_button = Button('add_StatusButton')
def _get_list_item(self, title: str) -> BaseElement:
self._add_social_link_list_item.object_name['title'] = title
return self._add_social_link_list_item
def _get_text_field(self, occurrence: int) -> BaseElement:
key = 'occurrence'
if occurrence:
self._social_link_text_field.object_name[key] = occurrence + 1
else:
if key in self._social_link_text_field.object_name:
del self._social_link_text_field.object_name[key]
return self._social_link_text_field
def add_link(self, network: str, links: typing.List[str]):
self._get_list_item(network).click()
time.sleep(0.5)
for occurrence, link in enumerate(links):
self._get_text_field(occurrence).text = link
self._add_button.click()
self.wait_utill_hidden()

View File

@ -1,5 +1,6 @@
import squish
import object import object
import squish
def get_children_of_type(parent, typename, depth=1000): def get_children_of_type(parent, typename, depth=1000):
children = [] children = []
@ -10,6 +11,7 @@ def get_children_of_type(parent, typename, depth=1000):
children.extend(get_children_of_type(child, typename, depth - 1)) children.extend(get_children_of_type(child, typename, depth - 1))
return children return children
def get_children_with_object_name(parent, objectName, depth=1000): def get_children_with_object_name(parent, objectName, depth=1000):
children = [] children = []
for child in object.children(parent): for child in object.children(parent):
@ -17,4 +19,11 @@ def get_children_with_object_name(parent, objectName, depth=1000):
children.append(child) children.append(child)
if depth: if depth:
children.extend(get_children_with_object_name(child, objectName, depth - 1)) children.extend(get_children_with_object_name(child, objectName, depth - 1))
return children return children
def walk_children(parent, depth: int = 1000):
for child in object.children(parent):
yield child
if depth:
yield from walk_children(child, depth - 1)

View File

@ -5,6 +5,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "../../../testSuites/glo
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/")) sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
from steps.commonInitSteps import context_init from steps.commonInitSteps import context_init
@OnScenarioStart @OnScenarioStart
def hook(context): def hook(context):

View File

@ -31,6 +31,8 @@ class SettingsSubsection(Enum):
navBarListView_Settings_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Settings-navbar", "type": "StatusNavBarTabButton", "visible": True} navBarListView_Settings_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Settings-navbar", "type": "StatusNavBarTabButton", "visible": True}
settingsSave_StatusButton = {"container": statusDesktop_mainWindow, "objectName": "settingsDirtyToastMessageSaveButton", "type": "StatusButton", "visible": True} settingsSave_StatusButton = {"container": statusDesktop_mainWindow, "objectName": "settingsDirtyToastMessageSaveButton", "type": "StatusButton", "visible": True}
settings_Sidebar_ENS_Item = {"container": mainWindow_ScrollView, "objectName": SettingsSubsection.ENS_USERNAMES.value, "type": "StatusNavigationListItem"} settings_Sidebar_ENS_Item = {"container": mainWindow_ScrollView, "objectName": SettingsSubsection.ENS_USERNAMES.value, "type": "StatusNavigationListItem"}
settingsContentBase_ScrollView = {"container": statusDesktop_mainWindow, "objectName": "settingsContentBaseScrollView", "type": "StatusScrollView", "visible": True}
settingsContentBaseScrollView_Item = {"container": settingsContentBase_ScrollView, "type": "Item", "unnamed": 1, "visible": True}
# ENS view; # ENS view;
settings_ENS_Start_Button = {"container": statusDesktop_mainWindow, "objectName": "ensStartButton", "type": "StatusButton"} settings_ENS_Start_Button = {"container": statusDesktop_mainWindow, "objectName": "ensStartButton", "type": "StatusButton"}
@ -53,6 +55,7 @@ messaging_StatusNavigationListItem = {"container": mainWindow_ScrollView, "objec
# Profile Settings: # Profile Settings:
mainWindow_MyProfileView = {"container": statusDesktop_mainWindow, "type": "MyProfileView", "unnamed": 1, "visible": True}
displayName_StatusInput = {"container": statusDesktop_mainWindow, "objectName": "displayNameInput", "type": "StatusInput", "visible": True} displayName_StatusInput = {"container": statusDesktop_mainWindow, "objectName": "displayNameInput", "type": "StatusInput", "visible": True}
displayName_TextEdit = {"container": displayName_StatusInput, "type": "TextEdit", "unnamed": 1, "visible": True} displayName_TextEdit = {"container": displayName_StatusInput, "type": "TextEdit", "unnamed": 1, "visible": True}
bio_StatusInput = {"container": statusDesktop_mainWindow, "objectName": "bioInput", "type": "StatusInput", "visible": True} bio_StatusInput = {"container": statusDesktop_mainWindow, "objectName": "bioInput", "type": "StatusInput", "visible": True}
@ -61,25 +64,27 @@ twitter_StaticSocialLinkInput = {"container": statusDesktop_mainWindow, "objectN
twitter_TextEdit = {"container": twitter_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True} twitter_TextEdit = {"container": twitter_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
personalSite_StaticSocialLinkInput = {"container": statusDesktop_mainWindow, "objectName": "__personal_site-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} personalSite_StaticSocialLinkInput = {"container": statusDesktop_mainWindow, "objectName": "__personal_site-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
personalSite_TextEdit = {"container": personalSite_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True} personalSite_TextEdit = {"container": personalSite_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
addMoreSocialLinks_StatusIconTextButton = {"container": statusDesktop_mainWindow, "objectName": "addMoreSocialLinksButton", "type": "StatusIconTextButton", "visible": True} addMoreSocialLinks = {"container": statusDesktop_mainWindow, "objectName": "addMoreSocialLinks", "type": "StatusLinkText", "visible": True}
twitter_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__twitter-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} twitter_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__twitter-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
twitter_popup_TextEdit = {"container": twitter_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
personalSite_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__personal_site-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} personalSite_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__personal_site-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
personalSite_popup_TextEdit = {"container": personalSite_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
github_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__github-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} github_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__github-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
github_popup_TextEdit = {"container": github_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
youtube_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__youtube-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} youtube_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__youtube-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
youtube_popup_TextEdit = {"container": youtube_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
discord_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__discord-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} discord_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__discord-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
discord_popup_TextEdit = {"container": discord_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
telegram_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__telegram-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True} telegram_popup_StaticSocialLinkInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "__telegram-socialLinkInput", "type": "StaticSocialLinkInput", "visible": True}
telegram_popup_TextEdit = {"container": telegram_popup_StaticSocialLinkInput, "type": "TextEdit", "unnamed": 1, "visible": True}
customLink_popup_StatusInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "hyperlinkInput", "type": "StatusInput", "visible": True} customLink_popup_StatusInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "hyperlinkInput", "type": "StatusInput", "visible": True}
customLink_popup_TextEdit = {"container": customLink_popup_StatusInput, "type": "TextEdit", "unnamed": 1, "visible": True}
customUrl_popup_StatusInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "urlInput", "type": "StatusInput", "visible": True} customUrl_popup_StatusInput = {"container": statusDesktop_mainWindow_overlay, "objectName": "urlInput", "type": "StatusInput", "visible": True}
customUrl_popup_TextEdit = {"container": customUrl_popup_StatusInput, "type": "TextEdit", "unnamed": 1, "visible": True} customUrl_popup_TextEdit = {"container": customUrl_popup_StatusInput, "type": "TextEdit", "unnamed": 1, "visible": True}
change_password_button = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "profileSettingsChangePasswordButton", "visible": True} change_password_button = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "profileSettingsChangePasswordButton", "visible": True}
# Social Links Popup
socialLink_StatusListItem = {"container": statusDesktop_mainWindow_overlay, "type": "StatusListItem", "title": "", "visible": True}
placeholder_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "id": "placeholder", "type": "StatusBaseText", "unnamed": 1, "visible": True}
o_StatusBackButton = {"container": statusDesktop_mainWindow_overlay, "type": "StatusBackButton", "unnamed": 1, "visible": True}
add_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "unnamed": 1, "visible": True}
linksView = {"container": statusDesktop_mainWindow, "id": "linksView", "type": "StatusListView", "unnamed": 1, "visible": True}
edit_TextEdit = {"container": statusDesktop_mainWindow_overlay, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
# Wallet Settings: # Wallet Settings:
settings_Wallet_MainView_GeneratedAccounts = {"container": statusDesktop_mainWindow, "objectName":'generatedAccounts', "type": 'ListView'} settings_Wallet_MainView_GeneratedAccounts = {"container": statusDesktop_mainWindow, "objectName":'generatedAccounts', "type": 'ListView'}
settings_Wallet_AccountView_DeleteAccount = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "deleteAccountButton"} settings_Wallet_AccountView_DeleteAccount = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "deleteAccountButton"}
@ -98,12 +103,12 @@ settings_Wallet_MainView_BackupSeedPhrase = {"container": mainWindow_ScrollView,
generatedAccounts_ListView = {"container": statusDesktop_mainWindow, "objectName": "generatedAccounts", "type": "ListView"} generatedAccounts_ListView = {"container": statusDesktop_mainWindow, "objectName": "generatedAccounts", "type": "ListView"}
# Messaging Settings: # Messaging Settings:
settingsContentBase_ScrollView = {"container": statusDesktop_mainWindow, "objectName": "settingsContentBaseScrollView", "type": "StatusScrollView", "visible": True}
displayMessageLinkPreviewItem = {"container": statusDesktop_mainWindow, "objectName": "displayMessageLinkPreviewsItem", "type": "StatusListItem"} displayMessageLinkPreviewItem = {"container": statusDesktop_mainWindow, "objectName": "displayMessageLinkPreviewsItem", "type": "StatusListItem"}
linkPreviewSwitch = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_showMessageLinksSwitch", "type": "StatusSwitch", "visible": True} linkPreviewSwitch = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_showMessageLinksSwitch", "type": "StatusSwitch", "visible": True}
imageUnfurlingItem = {"container": statusDesktop_mainWindow, "objectName": "imageUnfurlingItem", "type": "StatusListItem"} imageUnfurlingItem = {"container": statusDesktop_mainWindow, "objectName": "imageUnfurlingItem", "type": "StatusListItem"}
tenorGifsPreviewSwitchItem = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_sitesListView_StatusListItem_tenor_gifs_subdomain", "type": "StatusListItem"} tenorGifsPreviewSwitchItem = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_sitesListView_StatusListItem_tenor_gifs_subdomain", "type": "StatusListItem"}
contacts_listItem_btn = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_ContactsListItem_btn", "type": "StatusContactRequestsIndicatorListItem"} contacts_listItem_btn = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_ContactsListItem_btn", "type": "StatusContactRequestsIndicatorListItem"}
settingsContentBaseScrollView_StatusScrollBar = {"container": settingsContentBase_ScrollView, "occurrence": 3, "type": "StatusScrollBar", "unnamed": 1, "visible": True}
# Contacts View # Contacts View
contact_request_to_chat_key_btn = {"container": statusDesktop_mainWindow, "objectName": "ContactsView_ContactRequest_Button", "type": "StatusButton"} contact_request_to_chat_key_btn = {"container": statusDesktop_mainWindow, "objectName": "ContactsView_ContactRequest_Button", "type": "StatusButton"}

View File

@ -31,6 +31,7 @@ _feature_name = "feature_name"
def context_init(context, testSettings, screenshot_on_fail = True): def context_init(context, testSettings, screenshot_on_fail = True):
# With this property it is enabled that every test failure will cause Squish to take a screenshot of the desktop when the failure occurred # With this property it is enabled that every test failure will cause Squish to take a screenshot of the desktop when the failure occurred
testSettings.logScreenshotOnFail = screenshot_on_fail testSettings.logScreenshotOnFail = screenshot_on_fail
testSettings.waitForObjectTimeout = 5000
filesMngr.erase_directory(_status_qt_path) filesMngr.erase_directory(_status_qt_path)
context.userData = {} context.userData = {}

View File

@ -1,8 +1,7 @@
import steps.commonInitSteps as init_steps import steps.commonInitSteps as init_steps
from screens.StatusMainScreen import StatusMainScreen
from screens.SettingsScreen import SettingsScreen from screens.SettingsScreen import SettingsScreen
from screens.StatusLanguageScreen import StatusLanguageScreen from screens.StatusLanguageScreen import StatusLanguageScreen
from screens.StatusMainScreen import StatusMainScreen
_statusMain = StatusMainScreen() _statusMain = StatusMainScreen()
_settingsScreen = SettingsScreen() _settingsScreen = SettingsScreen()
@ -45,11 +44,11 @@ def step(context, display_name: str):
@Given("the user's bio is empty") @Given("the user's bio is empty")
def step(context): def step(context):
_settingsScreen.verify_bio("") _settingsScreen.profile_settings.verify_bio("")
@Given("the user's social links are empty") @Given("the user's social links are empty")
def step(context): def step(context):
_settingsScreen.verify_social_links(None) _settingsScreen.profile_settings.verify_social_no_links()
@Given("the user opens own profile popup") @Given("the user opens own profile popup")
def step(context: any): def step(context: any):
@ -153,19 +152,22 @@ def step(context: any):
@When("the user sets display name to \"|any|\"") @When("the user sets display name to \"|any|\"")
def step(context, display_name): def step(context, display_name):
_settingsScreen.set_display_name(display_name) _settingsScreen.profile_settings.display_name = display_name
@When("the user backs up the wallet seed phrase") @When("the user backs up the wallet seed phrase")
def step(context): def step(context):
_settingsScreen.check_backup_seed_phrase_workflow() _settingsScreen.check_backup_seed_phrase_workflow()
@When("the user sets social links to:") @When("the user sets social links to:")
def step(context): def step(context):
_settingsScreen.set_social_links(context.table) profile_settings = _settingsScreen.profile_settings
profile_settings.social_links = context.table
profile_settings.save_changes()
@When("the user sets bio to \"|any|\"") @When("the user sets bio to \"|any|\"")
def step(context, bio): def step(context, bio):
_settingsScreen.set_bio(bio) _settingsScreen.profile_settings.bio = bio
@When("the users switches state to offline") @When("the users switches state to offline")
def step(context: any): def step(context: any):
@ -181,7 +183,7 @@ def step(context: any):
@When("the user changes the password from |any| to |any|") @When("the user changes the password from |any| to |any|")
def step(context: any, oldPassword: str, newPassword: str): def step(context: any, oldPassword: str, newPassword: str):
_settingsScreen.change_user_password(oldPassword, newPassword) _settingsScreen.profile_settings.open_change_password_popup().change_password(oldPassword, newPassword)
@When("the user sends a contact request to the chat key \"|any|\" with the reason \"|any|\"") @When("the user sends a contact request to the chat key \"|any|\" with the reason \"|any|\"")
def step(context: any, chat_key: str, reason: str): def step(context: any, chat_key: str, reason: str):
@ -232,11 +234,11 @@ def step(context, display_name: str):
@Then("the user's bio is \"|any|\"") @Then("the user's bio is \"|any|\"")
def step(context, bio): def step(context, bio):
_settingsScreen.verify_bio(bio) _settingsScreen.profile_settings.verify_bio(bio)
@Then("the user's social links are:") @Then("the user's social links are:")
def step(context): def step(context):
_settingsScreen.verify_social_links(context.table) _settingsScreen.profile_settings.verify_social_links(context.table)
@Then("the application displays |any| as the selected language") @Then("the application displays |any| as the selected language")
def step(context, native): def step(context, native):
@ -293,10 +295,10 @@ def the_user_opens_the_wallet_settings():
_settingsScreen.open_wallet_settings() _settingsScreen.open_wallet_settings()
def the_user_opens_the_profile_settings(): def the_user_opens_the_profile_settings():
_settingsScreen.open_profile_settings() _settingsScreen.profile_settings
def the_user_display_name_is(display_name: str): def the_user_display_name_is(display_name: str):
_settingsScreen.verify_display_name(display_name) _settingsScreen.profile_settings.verify_display_name(display_name)
def the_user_display_name_in_profile_popup_is(display_name: str): def the_user_display_name_in_profile_popup_is(display_name: str):
_statusMain.verify_profile_popup_display_name(display_name) _statusMain.verify_profile_popup_display_name(display_name)

View File

@ -5,6 +5,4 @@ collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps
def main(): def main():
testSettings.throwOnFailure = True testSettings.throwOnFailure = True
testSettings.logScreenshotOnError = True
testSettings.logScreenshotOnFail = True
runFeatureFile('test.feature') runFeatureFile('test.feature')

View File

@ -9,7 +9,6 @@ Feature: User Identity
And the user signs up with username "tester123" and password "TesTEr16843/!@00" And the user signs up with username "tester123" and password "TesTEr16843/!@00"
And the user lands on the signed in app And the user lands on the signed in app
@mayfail
Scenario Outline: The user sets display name, bio and social links Scenario Outline: The user sets display name, bio and social links
Given the user opens app settings screen Given the user opens app settings screen
And the user opens the profile settings And the user opens the profile settings
@ -61,4 +60,4 @@ Feature: User Identity
Examples: Examples:
| user | | user |
| tester123_changed | | tester123_changed |

View File

@ -49,6 +49,7 @@ Control {
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }
StatusLinkText { StatusLinkText {
objectName: "addMoreSocialLinks"
text: qsTr(" Add more links") text: qsTr(" Add more links")
color: Theme.palette.primaryColor1 color: Theme.palette.primaryColor1
font.pixelSize: Theme.tertiaryTextFontSize font.pixelSize: Theme.tertiaryTextFontSize