Added new desktop e2e tests

Signed-off-by: yevh-berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
yevh-berdnyk 2018-11-16 10:53:05 +01:00
parent 8f0bfde759
commit d299713037
No known key found for this signature in database
GPG Key ID: E9B425FDFC4DEA9C
20 changed files with 206 additions and 22 deletions

View File

@ -2,6 +2,8 @@ import docker
import pytest
import argparse
import os
import re
import requests
from datetime import datetime
from urllib.request import urlretrieve
from tests.report import TEST_REPORT_DIR_CONTAINER
@ -12,10 +14,12 @@ def main(**kwargs):
if not os.path.exists(kwargs['test_results_path']):
os.makedirs(kwargs['test_results_path'])
app_version = None
if kwargs['linux_app_url']:
app_version = ([i for i in [i for i in kwargs['linux_app_url'].split('/') if '.AppImage' in i]])[0]
urlretrieve(kwargs['linux_app_url'], 'nightly.AppImage')
linux_app_url = kwargs['linux_app_url']
else:
linux_app_url = re.findall('https\S*AppImage', requests.get('https://status.im/nightly/').text)[0]
app_version = ([i for i in [i for i in linux_app_url.split('/') if '.AppImage' in i]])[0]
urlretrieve(linux_app_url, 'nightly.AppImage')
client = docker.from_env()
client.images.build(tag='status_desktop', path='.')
pytest.main(['--collect-only', '-m %s' % kwargs['mark']])
@ -55,7 +59,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--test_results_path',
action='store',
default='/Users/adan/Desktop/desktop_e2e_results')
default=os.path.dirname(os.path.abspath(__file__)))
parser.add_argument('--linux_app_url',
action='store',
default=None)

View File

@ -1,3 +1,5 @@
import pytest
try:
import org.sikuli.script.SikulixForJython
from sikuli import *
@ -6,6 +8,7 @@ except Exception:
class BaseTestCase:
errors = list()
try:
Settings.ActionLogs = 0
@ -18,3 +21,7 @@ class BaseTestCase:
def teardown_method(self, method):
pass
def verify_no_errors(self):
if self.errors:
pytest.fail('. '.join([self.errors.pop(0) for _ in range(len(self.errors))]))

View File

@ -64,3 +64,11 @@ class TestCreateAccount(BaseTestCase):
sign_in.press_enter()
sign_in.profile_button.click()
profile.find_text('user_2')
@pytest.mark.testrail_id(5650)
def test_status_log(self):
sign_in = SignInView()
sign_in.create_account()
with open('/root/.local/share/Status/Status.log') as f:
if 'mnemonic' in f.read():
pytest.fail("'mnemonic' is in Status.log!")

View File

@ -6,13 +6,15 @@ import pytest
class TestProfile(BaseTestCase):
@pytest.mark.testrail_id(5590)
def test_copy_contact_code(self):
sign_in = SignInView()
sign_in.recover_access(base_user['passphrase'])
profile = sign_in.profile_button.click()
profile.share_my_code_button.click()
profile.copy_code_button.click()
assert profile.get_clipboard() == base_user['public_key']
if profile.get_clipboard() != base_user['public_key']:
pytest.fail('Contact code was not copied to clipboard')
@pytest.mark.skip('Test cases is not ready yet')
def test_change_mail_server(self):
@ -23,3 +25,33 @@ class TestProfile(BaseTestCase):
s_names = profile.get_mail_servers_list()
profile.get_mail_server(s_names[0]).is_active()
@pytest.mark.testrail_id(5593)
def test_log_out(self):
sign_in = SignInView()
username = 'test_log_out'
sign_in.create_account(username=username)
profile = sign_in.profile_button.click()
profile.log_out_button.click()
sign_in.password_input.find_element()
for text in username, 'Sign in to Status', 'Other accounts':
if not sign_in.element_by_text(text).is_visible():
pytest.fail("Text '%s' is not shown" % text)
@pytest.mark.skip
# @pytest.mark.testrail_id(5648)
def test_back_up_recovery_phrase(self):
sign_in = SignInView()
sign_in.create_account()
profile = sign_in.profile_button.click()
profile.back_up_recovery_phrase_button.click()
profile.ok_continue_button.click()
recovery_phrase = profile.get_recovery_phrase()
profile.next_button.click()
word_number = profile.get_recovery_phrase_word_number()
profile.recovery_phrase_word_input.input_value(recovery_phrase[word_number])
profile.next_button.click()
word_number_1 = profile.get_recovery_phrase_word_number()
profile.recovery_phrase_word_input.input_value(recovery_phrase[word_number_1])
profile.done_button.click()
profile.yes_button.click()
profile.find_text("You're all set!")

View File

@ -1,3 +1,6 @@
import pytest
from utilities import passpharse_with_spaces
from tests import base_user
from tests.base_test_case import BaseTestCase
from views.sign_in_view import SignInView
@ -16,6 +19,7 @@ class TestRecoverAccess(BaseTestCase):
profile.share_my_code_button.click()
profile.find_text(base_user['public_key'])
@pytest.mark.testrail_id(5571)
def test_recover_access_proceed_with_enter(self):
sign_in = SignInView()
sign_in.i_have_account_button.click()
@ -26,9 +30,55 @@ class TestRecoverAccess(BaseTestCase):
sign_in.press_enter()
sign_in.home_button.find_element()
@pytest.mark.testrail_id(5569)
def test_recover_access_go_back(self):
sign_in = SignInView()
sign_in.i_have_account_button.click()
sign_in.recovery_phrase_input.find_element()
sign_in.back_button.click()
sign_in.create_account_button.find_element()
@pytest.mark.testrail_id(5649)
def test_recovery_phrase_for_recovered_account(self):
sign_in = SignInView()
sign_in.recover_access(base_user['passphrase'])
profile = sign_in.profile_button.click()
if profile.share_my_code_button.is_visible():
profile.element_by_text('Backup').verify_element_is_not_present()
else:
pytest.fail('Profile view was not opened')
@pytest.mark.testrail_id(5652)
def test_recover_account_error_messages(self):
errors = {'': 'Required field',
' '.join(base_user['passphrase'].split()[::-1]): 'Some words might be misspelled',
' '.join(base_user['passphrase'].split()[:-1]) + ' aaa': 'Some words might be misspelled',
'robot seed robot seed robot seed robot seed robot seed robot seed.': 'Recovery phrase is invalid',
'robot': 'Recovery phrase is invalid',
'seed seed seed seed seed seed seed seed seed seed seed': 'Recovery phrase is invalid',
'seed seed seed seed seed seed seed seed seed seed seed seed seed': 'Recovery phrase is invalid'
}
sign_in = SignInView()
for i in errors:
sign_in.i_have_account_button.click()
sign_in.recovery_phrase_input.send_keys(i)
sign_in.recover_password_input.click()
error_message = errors[i]
if not sign_in.element_by_text(error_message).is_visible():
self.errors.append("Error message '%s' is not shown for passphrase '%s'" % (error_message, i))
sign_in.back_button.click()
sign_in.i_have_account_button.click()
sign_in.recovery_phrase_input.send_keys(base_user['passphrase'])
sign_in.recover_password_input.click()
sign_in.sign_in_button.click()
if not sign_in.element_by_text('Required field').is_visible():
self.errors.append("Error message 'Required field' is not shown for empty password input")
self.verify_no_errors()
@pytest.mark.testrail_id(5651)
def test_recover_account_with_spaces(self):
sign_in = SignInView()
passphrase = passpharse_with_spaces(base_user['passphrase'])
sign_in.recover_access(passphrase)
profile = sign_in.profile_button.click()
profile.find_text(base_user['username'])

View File

@ -0,0 +1,6 @@
import itertools
def passpharse_with_spaces(passphrase):
phrase_list = passphrase.split()
return ''.join(list(itertools.chain.from_iterable(zip(phrase_list, [' ' * i for i in range(1, 13)]))))

View File

@ -2,6 +2,7 @@ import logging
import time
import pytest
import re
try:
import org.sikuli.script.SikulixForJython
from sikuli import *
@ -10,15 +11,16 @@ except Exception:
class BaseElement(object):
def __init__(self, screenshot):
def __init__(self, screenshot, x=0, y=0, w=1024, h=768):
self.screenshot = screenshot
self.name = re.findall('([^\/]+)(?=.png)', self.screenshot)[0].replace('_', ' ').title()
self.region = Region(x, y, w, h)
def find_element(self, log=True):
if log:
logging.info('Find %s' % self.name)
try:
wait(self.screenshot, 10)
self.region.wait(self.screenshot, 10)
except FindFailed:
pytest.fail('%s was not found' % self.name)
@ -26,16 +28,27 @@ class BaseElement(object):
if log:
logging.info('Click %s' % self.name)
self.find_element(log=False)
click(self.screenshot)
self.region.click(self.screenshot)
def is_visible(self):
try:
self.region.wait(self.screenshot, 10)
return True
except FindFailed:
return False
def verify_element_is_not_present(self):
logging.info('Verify: %s is not present' % self.name)
try:
wait(self.screenshot, 10)
self.region.wait(self.screenshot, 10)
pytest.fail('%s is displayed but not expected' % self.name)
except FindFailed:
pass
def get_target(self):
self.find_element(log=False)
return self.region.find(self.screenshot).getTarget()
class InputField(BaseElement):
@ -53,7 +66,7 @@ class InputField(BaseElement):
def is_focused(self):
self.find_element(log=False)
return find(self.screenshot).getTarget() == Env.getMouseLocation()
return self.get_target() == Env.getMouseLocation()
def verify_is_focused(self):
logging.info('Verify %s is focused' % self.name)
@ -63,14 +76,36 @@ class InputField(BaseElement):
class TextElement(object):
def __init__(self, text):
self.text = text
self.element_line = None
def find_element(self):
for _ in range(3):
lines = collectLines()
for line in lines:
if text in line.getText().encode('ascii', 'ignore'):
if self.text in line.getText().encode('ascii', 'ignore'):
self.element_line = line
return
time.sleep(3)
pytest.fail("Element with text '%s' was not found" % self.text)
def click(self):
logging.info("Click %s button" % self.text)
self.find_element()
self.element_line.click()
def get_whole_text(self):
self.find_element()
return self.element_line.getText().encode('ascii', 'ignore')
def is_visible(self):
from _pytest.runner import Failed
try:
self.find_element()
return True
except Failed:
return False
def verify_element_is_not_present(self):
if self.is_visible():
pytest.fail("'%s text is displayed but not expected'" % self.text)

View File

@ -1,4 +1,5 @@
import logging
try:
import org.sikuli.script.SikulixForJython
from sikuli import *
@ -28,7 +29,11 @@ class BaseView(object):
super(BaseView, self).__init__()
self.home_button = BaseElement(IMAGES_PATH + '/home_button.png')
self.profile_button = ProfileButton()
self.back_button = BaseElement(IMAGES_PATH + '/back_button.png')
self.back_button = BaseElement(IMAGES_PATH + '/back_button.png', x=10, y=20, w=50, h=50)
self.ok_button = BaseElement(IMAGES_PATH + '/ok_button.png')
self.next_button = BaseElement(IMAGES_PATH + '/next_button.png')
self.done_button = BaseElement(IMAGES_PATH + '/done_button.png')
self.yes_button = BaseElement(IMAGES_PATH + '/yes_button.png')
def find_text(self, expected_text):
logging.info("Find text '%s'" % expected_text)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,4 +1,8 @@
import os
# import pytesseract
import re
# from PIL import Image
from subprocess import check_output
try:
import org.sikuli.script.SikulixForJython
@ -6,7 +10,7 @@ try:
except Exception:
pass
from views.base_element import BaseElement, TextElement
from views.base_element import BaseElement, TextElement, InputField
from views.base_view import BaseView
IMAGES_PATH = os.path.join(os.path.dirname(__file__), 'images/profile_view')
@ -27,9 +31,12 @@ class MailServerElement(TextElement):
class ProfileView(BaseView):
def __init__(self):
super(ProfileView, self).__init__()
self.share_my_code_button = BaseElement(IMAGES_PATH + '/share_my_code_button.png')
self.share_my_code_button = TextElement('Share my contact code')
self.copy_code_button = BaseElement(IMAGES_PATH + '/copy_code_button.png')
self.log_out_button = BaseElement(IMAGES_PATH + '/log_out_button.png')
self.back_up_recovery_phrase_button = TextElement('Backup your recovery')
self.ok_continue_button = BaseElement(IMAGES_PATH + '/ok_continue_button.png')
self.recovery_phrase_word_input = InputField(IMAGES_PATH + '/recovery_phrase_word_input.png')
def get_mail_servers_list(self):
server_names = []
@ -40,3 +47,21 @@ class ProfileView(BaseView):
def get_mail_server(self, name):
return MailServerElement(name)
def get_recovery_phrase(self):
self.share_my_code_button.find_element()
reg = Region(370, 130, 600, 240)
current_text = reg.text().encode('ascii', 'ignore')
phrase_list = re.findall(r"[\w']+", current_text.replace('1O', '10'))
phrase_dict = dict()
for i in range(len(phrase_list) - 1):
if phrase_list[i].isdigit():
phrase_dict[phrase_list[i]] = phrase_list[i + 1]
return phrase_dict
def get_recovery_phrase_word_number(self):
image_name = 'recovery.png'
# check_output(['import', '-window', 'root', image_name])
# text = pytesseract.image_to_string(Image.open(image_name))
# os.remove(image_name)
# return re.findall('#(.*)\n', text)[0]

View File

@ -4,8 +4,8 @@ try:
except Exception:
pass
import os
import pytest
from views.base_element import BaseElement, InputField
import logging
from views.base_element import BaseElement, InputField, TextElement
from views.base_view import BaseView
from views.home_view import HomeView
@ -25,17 +25,27 @@ class CreateAccountButton(BaseElement):
super(CreateAccountButton, self).find_element(log=log)
class UserNameInput(InputField):
def __init__(self):
super(UserNameInput, self).__init__(IMAGES_PATH + '/username_input.png')
def input_value(self, value):
logging.info("%s field: set value '%s'" % (self.name, value))
import time
time.sleep(10)
type(value)
class SignInView(BaseView):
def __init__(self):
super(SignInView, self).__init__()
self.create_account_button = CreateAccountButton()
self.i_have_account_button = BaseElement(IMAGES_PATH + '/i_have_account.png')
self.i_have_account_button = TextElement('I already have an account')
self.other_accounts_button = BaseElement(IMAGES_PATH + '/other_accounts.png')
self.privacy_policy_button = BaseElement(IMAGES_PATH + 'privacy_policy_button.png')
self.privacy_policy_button = TextElement('Privacy Policy')
self.create_password_input = InputField(IMAGES_PATH + '/create_password_input.png')
self.confirm_password_input = InputField(IMAGES_PATH + '/confirm_password_input.png')
self.username_input = InputField(IMAGES_PATH + '/username_input.png')
self.next_button = BaseElement(IMAGES_PATH + '/next_button.png')
self.username_input = UserNameInput()
self.recovery_phrase_input = InputField(IMAGES_PATH + '/recovery_phrase_input.png')
self.recover_password_input = InputField(IMAGES_PATH + '/recover_password_input.png')
self.sign_in_button = BaseElement(IMAGES_PATH + '/sign_in_button.png')
@ -50,12 +60,14 @@ class SignInView(BaseView):
self.username_input.input_value(username)
self.next_button.click()
self.home_button.find_element()
self.ok_button.click()
return HomeView()
def recover_access(self, passphrase):
def recover_access(self, passphrase, password='qwerty'):
self.i_have_account_button.click()
self.recovery_phrase_input.send_keys(passphrase)
self.recover_password_input.send_keys('123456')
self.recover_password_input.send_keys(password)
self.sign_in_button.click()
self.home_button.find_element()
self.ok_button.click()
return HomeView()