test(Onboarding) Test on Import: 12 word seed phrase added

#86
This commit is contained in:
Vladimir Druzhinin 2023-08-10 13:43:17 +02:00 committed by Anastasiya Semenkevich
parent 768b05ac1b
commit bfa7866cee
13 changed files with 184 additions and 38 deletions

View File

@ -1,4 +1,8 @@
import logging
import os import os
LOCAL_RUN = False LOG_LEVEL = logging.DEBUG
LOCAL_RUN = True
DEV_BUILD = False
APP_DIR = os.getenv('APP_DIR') APP_DIR = os.getenv('APP_DIR')

View File

@ -1,2 +1,7 @@
import logging
LOG_LEVEL = logging.DEBUG
LOCAL_RUN = True LOCAL_RUN = True
DEV_BUILD = False
APP_DIR = None APP_DIR = None

View File

@ -1,7 +1,6 @@
import os import os
from datetime import datetime
import typing import typing
from datetime import datetime
from scripts.utils.system_path import SystemPath from scripts.utils.system_path import SystemPath
@ -19,6 +18,7 @@ RESULTS: SystemPath = TEMP / 'results'
RUN: SystemPath = RESULTS / RUN_ID RUN: SystemPath = RESULTS / RUN_ID
VP: SystemPath = ROOT / 'ext' / 'vp' VP: SystemPath = ROOT / 'ext' / 'vp'
TEST_FILES: SystemPath = ROOT / 'ext' / 'test_files' TEST_FILES: SystemPath = ROOT / 'ext' / 'test_files'
TEST_USER_DATA: SystemPath = ROOT / 'ext' / 'user_data'
# Driver Directories # Driver Directories
SQUISH_DIR = SystemPath(os.getenv('SQUISH_DIR')) SQUISH_DIR = SystemPath(os.getenv('SQUISH_DIR'))

View File

@ -32,9 +32,11 @@ def setup_session_scope(
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def setup_function_scope( def setup_function_scope(
caplog,
generate_test_data, generate_test_data,
check_result check_result
): ):
caplog.set_level(configs.LOG_LEVEL)
yield yield

View File

@ -1,7 +1,9 @@
from collections import namedtuple from collections import namedtuple
UserAccount = namedtuple('User', ['name', 'password']) UserAccount = namedtuple('User', ['name', 'password', 'seed_phrase'])
user_account = UserAccount('squisher', '*P@ssw0rd*') user_account = UserAccount('squisher', '*P@ssw0rd*', [
user_account_one = UserAccount('tester123', 'TesTEr16843/!@00') 'rail', 'witness', 'era', 'asthma', 'empty', 'cheap', 'shed', 'pond', 'skate', 'amount', 'invite', 'year'
user_account_two = UserAccount('Athletic', 'TesTEr16843/!@00') ])
user_account_three = UserAccount('Nervous', 'TesTEr16843/!@00') user_account_one = UserAccount('tester123', 'TesTEr16843/!@00', [])
user_account_two = UserAccount('Athletic', 'TesTEr16843/!@00', [])
user_account_three = UserAccount('Nervous', 'TesTEr16843/!@00', [])

View File

@ -21,6 +21,7 @@ class AUT:
self.host = host self.host = host
self.port = int(port) self.port = int(port)
self.ctx = None self.ctx = None
self.pid = None
self.aut_id = self.path.name if IS_LIN else self.path.stem self.aut_id = self.path.name if IS_LIN else self.path.stem
self.process_name = 'Status' if IS_WIN else 'nim_status_client' self.process_name = 'Status' if IS_WIN else 'nim_status_client'
driver.testSettings.setWrappersForApplication(self.aut_id, ['Qt']) driver.testSettings.setWrappersForApplication(self.aut_id, ['Qt'])
@ -51,7 +52,7 @@ class AUT:
@allure.step('Close application by process name') @allure.step('Close application by process name')
def stop(self): def stop(self):
if configs.LOCAL_RUN: if configs.LOCAL_RUN:
local_system.kill_process_by_port(self.port) local_system.kill_process_by_pid(self.pid)
else: else:
local_system.kill_process_by_name(self.process_name) local_system.kill_process_by_name(self.process_name)
@ -77,5 +78,6 @@ class AUT:
' '.join(command), configs.timeouts.PROCESS_TIMEOUT_SEC) ' '.join(command), configs.timeouts.PROCESS_TIMEOUT_SEC)
self.attach() self.attach()
self.pid = self.ctx.pid
assert squish.waitFor(lambda: self.ctx.isRunning, configs.timeouts.PROCESS_TIMEOUT_SEC) assert squish.waitFor(lambda: self.ctx.isRunning, configs.timeouts.PROCESS_TIMEOUT_SEC)
return self return self

View File

@ -1,5 +1,4 @@
import logging import logging
import time
import typing import typing
import configs.testpath import configs.testpath
@ -36,17 +35,12 @@ class SquishServer:
_logger.info(err) _logger.info(err)
local_system.execute(cmd, check=True) local_system.execute(cmd, check=True)
def stop(self, attempt: int = 2): def stop(self):
local_system.run([self.path, '--stop']) local_system.kill_process_by_name(_PROCESS_NAME, verify=False)
try: try:
local_system.wait_for_close(_PROCESS_NAME, 2) local_system.wait_for_close(_PROCESS_NAME, 2)
except AssertionError as err: except AssertionError as err:
_logger.debug(err) _logger.debug(err)
if attempt:
time.sleep(1)
self.stop(attempt-1)
else:
raise err
# https://doc-snapshots.qt.io/squish/cli-squishserver.html # https://doc-snapshots.qt.io/squish/cli-squishserver.html
def configuring(self, action: str, options: typing.Union[int, str, list]): def configuring(self, action: str, options: typing.Union[int, str, list]):

View File

@ -14,6 +14,36 @@ mainWindow_I_already_use_Status_StatusBaseText = {"container": mainWindow_Welcom
# Get Keys View # Get Keys View
mainWindow_KeysMainView = {"container": statusDesktop_mainWindow, "type": "KeysMainView", "unnamed": 1, "visible": True} mainWindow_KeysMainView = {"container": statusDesktop_mainWindow, "type": "KeysMainView", "unnamed": 1, "visible": True}
mainWindow_Generate_new_keys_StatusButton = {"checkable": False, "container": mainWindow_KeysMainView, "objectName": "keysMainViewPrimaryActionButton", "type": "StatusButton", "visible": True} mainWindow_Generate_new_keys_StatusButton = {"checkable": False, "container": mainWindow_KeysMainView, "objectName": "keysMainViewPrimaryActionButton", "type": "StatusButton", "visible": True}
mainWindow_Generate_keys_for_new_Keycard_StatusBaseText = {"container": mainWindow_KeysMainView, "id": "button2",
"type": "StatusBaseText", "unnamed": 1, "visible": True}
mainWindow_Import_seed_phrase = {"container": mainWindow_KeysMainView, "id": "button3", "type": "Row", "unnamed": 1,
"visible": True}
# Import Seed Phrase View
keysMainView_PrimaryAction_Button = {"container": statusDesktop_mainWindow,
"objectName": "keysMainViewPrimaryActionButton", "type": "StatusButton"}
# Seed Phrase Input View
mainWindow_SeedPhraseInputView = {"container": statusDesktop_mainWindow, "type": "SeedPhraseInputView", "unnamed": 1,
"visible": True}
switchTabBar_12_words_Button = {"container": mainWindow_SeedPhraseInputView, "objectName": "12SeedButton",
"type": "StatusSwitchTabButton"}
switchTabBar_18_words_Button = {"container": mainWindow_SeedPhraseInputView, "objectName": "18SeedButton",
"type": "StatusSwitchTabButton"}
switchTabBar_24_words_Button = {"container": mainWindow_SeedPhraseInputView, "objectName": "24SeedButton",
"type": "StatusSwitchTabButton"}
mainWindow_statusSeedPhraseInputField_TextEdit = {"container": mainWindow_SeedPhraseInputView,
"objectName": "statusSeedPhraseInputField", "type": "TextEdit",
"visible": True}
mainWindow_Import_StatusButton = {"checkable": False, "container": mainWindow_SeedPhraseInputView,
"objectName": "seedPhraseViewSubmitButton", "text": "Import", "type": "StatusButton",
"visible": True}
# Keycard Init View
mainWindow_KeycardInitView = {"container": statusDesktop_mainWindow, "type": "KeycardInitView", "unnamed": 1,
"visible": True}
mainWindow_Plug_in_Keycard_reader_StatusBaseText = {"container": mainWindow_KeycardInitView, "type": "StatusBaseText",
"unnamed": 1, "visible": True}
# Your Profile View # Your Profile View
mainWindow_InsertDetailsView = {"container": statusDesktop_mainWindow, "type": "InsertDetailsView", "unnamed": 1, "visible": True} mainWindow_InsertDetailsView = {"container": statusDesktop_mainWindow, "type": "InsertDetailsView", "unnamed": 1, "visible": True}

View File

@ -1,11 +1,10 @@
import logging import logging
import time import time
import typing
from abc import abstractmethod from abc import abstractmethod
import allure import allure
import cv2
import configs.testpath
import constants.tesseract import constants.tesseract
import driver import driver
from gui.components.os.open_file_dialogs import OpenFileDialog from gui.components.os.open_file_dialogs import OpenFileDialog
@ -62,18 +61,94 @@ class KeysView(OnboardingScreen):
def __init__(self): def __init__(self):
super(KeysView, self).__init__('mainWindow_KeysMainView') super(KeysView, self).__init__('mainWindow_KeysMainView')
self._generate_key_button = Button('mainWindow_Generate_new_keys_StatusButton') self._generate_key_button = Button('mainWindow_Generate_new_keys_StatusButton')
self._generate_key_for_new_keycard_button = Button('mainWindow_Generate_keys_for_new_Keycard_StatusBaseText')
self._import_seed_phrase_button = Button('mainWindow_Import_seed_phrase')
@allure.step('Open Profile view') @allure.step('Open Profile view')
def generate_new_keys(self) -> 'YourProfileView': def generate_new_keys(self) -> 'YourProfileView':
self._generate_key_button.click() self._generate_key_button.click()
return YourProfileView().wait_until_appears() return YourProfileView().wait_until_appears()
@allure.step('Open Keycard Init view')
def generate_key_for_new_keycard(self) -> 'KeycardInitView':
self._generate_key_for_new_keycard_button.click()
return KeycardInitView().wait_until_appears()
@allure.step('Open Import Seed Phrase view')
def open_import_seed_phrase_view(self) -> 'ImportSeedPhraseView':
self._import_seed_phrase_button.click()
return ImportSeedPhraseView().wait_until_appears()
@allure.step('Go back') @allure.step('Go back')
def back(self) -> WelcomeScreen: def back(self) -> WelcomeScreen:
self._back_button.click() self._back_button.click()
return WelcomeScreen().wait_until_appears() return WelcomeScreen().wait_until_appears()
class ImportSeedPhraseView(OnboardingScreen):
def __init__(self):
super(ImportSeedPhraseView, self).__init__('mainWindow_KeysMainView')
self._import_seed_phrase_button = Button('keysMainView_PrimaryAction_Button')
@allure.step('Open seed phrase input view')
def open_seed_phrase_input_view(self):
self._import_seed_phrase_button.click()
return SeedPhraseInputView().wait_until_appears()
@allure.step('Go back')
def back(self) -> KeysView:
self._back_button.click()
return KeysView().wait_until_appears()
class SeedPhraseInputView(OnboardingScreen):
def __init__(self):
super(SeedPhraseInputView, self).__init__('mainWindow_SeedPhraseInputView')
self._12_words_tab_button = Button('switchTabBar_12_words_Button')
self._18_words_tab_button = Button('switchTabBar_18_words_Button')
self._24_words_tab_button = Button('switchTabBar_24_words_Button')
self._seed_phrase_input_text_edit = TextEdit('mainWindow_statusSeedPhraseInputField_TextEdit')
self._import_button = Button('mainWindow_Import_StatusButton')
@allure.step('Input seed phrase')
def input_seed_phrase(self, seed_phrase: typing.List[str]):
if len(seed_phrase) == 12:
if not self._12_words_tab_button.is_checked:
self._12_words_tab_button.click()
elif len(seed_phrase) == 18:
if not self._18_words_tab_button.is_checked:
self._18_words_tab_button.click()
elif len(seed_phrase) == 24:
if not self._24_words_tab_button.is_checked:
self._24_words_tab_button.click()
else:
raise RuntimeError("Wrong amount of seed words", len(seed_phrase))
for index, word in enumerate(seed_phrase, start=1):
self._seed_phrase_input_text_edit.real_name['objectName'] = f'statusSeedPhraseInputField{index}'
self._seed_phrase_input_text_edit.text = word
self._import_button.click()
return YourProfileView().wait_until_appears()
class KeycardInitView(OnboardingScreen):
def __init__(self):
super(KeycardInitView, self).__init__('mainWindow_KeycardInitView')
self._message = TextLabel('mainWindow_Plug_in_Keycard_reader_StatusBaseText')
@property
def message(self) -> str:
return self._message.text
def back(self) -> KeysView:
self._back_button.click()
return KeysView().wait_until_appears()
class YourProfileView(OnboardingScreen): class YourProfileView(OnboardingScreen):
def __init__(self): def __init__(self):
@ -177,16 +252,16 @@ class EmojiAndIconView(OnboardingScreen):
@allure.step('Verify: User image contains text') @allure.step('Verify: User image contains text')
def is_user_image_contains(self, text: str): def is_user_image_contains(self, text: str):
crop = driver.UiTypes.ScreenRectangle( crop = driver.UiTypes.ScreenRectangle(
20, 20, self._profile_image.image.width - 40, self._profile_image.image.height - 40 20, 20, self._profile_image.image.width - 40, self._profile_image.image.height - 40
) )
return self.profile_image.has_text(text, constants.tesseract.text_on_profile_image, crop=crop) return self.profile_image.has_text(text, constants.tesseract.text_on_profile_image, crop=crop)
@allure.step @allure.step
@allure.step('Verify: User image background color') @allure.step('Verify: User image background color')
def is_user_image_background_white(self): def is_user_image_background_white(self):
crop = driver.UiTypes.ScreenRectangle( crop = driver.UiTypes.ScreenRectangle(
20, 20, self._profile_image.image.width - 40, self._profile_image.image.height - 40 20, 20, self._profile_image.image.width - 40, self._profile_image.image.height - 40
) )
return self.profile_image.has_color(constants.Color.WHITE, crop=crop) return self.profile_image.has_color(constants.Color.WHITE, crop=crop)

View File

@ -1,7 +1,6 @@
[pytest] [pytest]
log_format = %(asctime)s.%(msecs)03d %(levelname)7s %(name)s %(message).5000s log_format = %(asctime)s.%(msecs)03d %(levelname)7s %(name)s %(message).5000s
log_cli = true log_cli = true
log_cli_level = INFO
addopts = --disable-warnings addopts = --disable-warnings

View File

@ -117,7 +117,7 @@ def wait_for_close(process_name: str = None, timeout_sec: int = configs.timeouts
else: else:
raise RuntimeError('Set process name or PID to find process') raise RuntimeError('Set process name or PID to find process')
time.sleep(1) time.sleep(1)
assert time.monotonic() - started_at < timeout_sec, f'Close process error: {process_name}' assert time.monotonic() - started_at < timeout_sec, f'Close process error: {process_name or pid}'
_logger.info(f'Process closed: {process_name}') _logger.info(f'Process closed: {process_name}')

View File

@ -1,6 +1,5 @@
from datetime import datetime from datetime import datetime
import allure
import pytest import pytest
import configs import configs
@ -21,7 +20,11 @@ def aut() -> AUT:
def user_data(request) -> system_path.SystemPath: def user_data(request) -> system_path.SystemPath:
user_data = configs.testpath.STATUS_DATA / f'app_{datetime.now():%H%M%S_%f}' / 'data' user_data = configs.testpath.STATUS_DATA / f'app_{datetime.now():%H%M%S_%f}' / 'data'
if hasattr(request, 'param'): if hasattr(request, 'param'):
system_path.SystemPath(request.param).copy_to(user_data) 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 yield user_data

View File

@ -5,18 +5,29 @@ import pytest
from allure import step from allure import step
import configs.timeouts import configs.timeouts
import constants
import driver import driver
from gui.components.before_started_popup import BeforeStartedPopUp from gui.components.before_started_popup import BeforeStartedPopUp
from gui.components.profile_picture_popup import shift_image from gui.components.profile_picture_popup import shift_image
from gui.components.splash_screen import SplashScreen from gui.components.splash_screen import SplashScreen
from gui.components.welcome_status_popup import WelcomeStatusPopup from gui.components.welcome_status_popup import WelcomeStatusPopup
from gui.screens.onboarding import AllowNotificationsView, WelcomeScreen, TouchIDAuthView from gui.screens.onboarding import AllowNotificationsView, WelcomeScreen, TouchIDAuthView, KeysView
from scripts.tools import image from scripts.tools import image
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
pytestmark = allure.suite("Onboarding") pytestmark = allure.suite("Onboarding")
@pytest.fixture
def keys_screen(main_window) -> KeysView:
with step('Open Generate new keys view'):
if configs.system.IS_MAC:
AllowNotificationsView().wait_until_appears().allow()
BeforeStartedPopUp().get_started()
wellcome_screen = WelcomeScreen().wait_until_appears()
return wellcome_screen.get_keys()
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703421', 'Generate new keys') @allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703421', 'Generate new keys')
@pytest.mark.case(703421) @pytest.mark.case(703421)
@pytest.mark.parametrize('user_name, password, user_image, zoom, shift', [ @pytest.mark.parametrize('user_name, password, user_image, zoom, shift', [
@ -25,15 +36,7 @@ pytestmark = allure.suite("Onboarding")
pytest.param('_1Test-User', '*P@ssw0rd*', 'tv_signal.jpeg', 5, shift_image(0, 1000, 1000, 0), pytest.param('_1Test-User', '*P@ssw0rd*', 'tv_signal.jpeg', 5, shift_image(0, 1000, 1000, 0),
marks=pytest.mark.smoke), marks=pytest.mark.smoke),
]) ])
def test_generate_new_keys(main_window, user_name, password, user_image: str, zoom, shift): def test_generate_new_keys(main_window, keys_screen, user_name: str, password, user_image: str, zoom: int, shift):
with step('Open Generate new keys view'):
if configs.system.IS_MAC:
AllowNotificationsView().wait_until_appears().allow()
BeforeStartedPopUp().get_started()
wellcome_screen = WelcomeScreen().wait_until_appears()
keys_screen = wellcome_screen.get_keys()
with step(f'Setup profile with name: {user_name} and image: {user_image}'): with step(f'Setup profile with name: {user_name} and image: {user_image}'):
profile_view = keys_screen.generate_new_keys() profile_view = keys_screen.generate_new_keys()
@ -71,7 +74,8 @@ def test_generate_new_keys(main_window, user_name, password, user_image: str, zo
if configs.system.IS_MAC: if configs.system.IS_MAC:
TouchIDAuthView().wait_until_appears().prefer_password() TouchIDAuthView().wait_until_appears().prefer_password()
SplashScreen().wait_until_appears().wait_until_hidden() SplashScreen().wait_until_appears().wait_until_hidden()
WelcomeStatusPopup().confirm() if not configs.DEV_BUILD:
WelcomeStatusPopup().confirm()
with step('Open User Canvas and verify user info'): with step('Open User Canvas and verify user info'):
@ -100,3 +104,29 @@ def test_generate_new_keys(main_window, user_name, password, user_image: str, zo
f'{user_image.split(".")[1]}_profile.png', f'{user_image.split(".")[1]}_profile.png',
threshold=0.9 threshold=0.9
) )
@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])
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()
profile_view = input_view.input_seed_phrase(user_account.seed_phrase)
profile_view.set_display_name(user_account.name)
with step('Finalize onboarding and open main screen'):
details_view = profile_view.next()
create_password_view = details_view.next()
confirm_password_view = create_password_view.create_password(user_account.password)
confirm_password_view.confirm_password(user_account.password)
if configs.system.IS_MAC:
TouchIDAuthView().wait_until_appears().prefer_password()
SplashScreen().wait_until_appears().wait_until_hidden()
if not configs.DEV_BUILD:
WelcomeStatusPopup().confirm()
with step('Verify that the user logged in via seed phrase correctly'):
user_canvas = main_window.left_panel.open_user_canvas()
profile_popup = user_canvas.open_profile_popup()
assert profile_popup.user_name == user_account.name