Desktop automation PoC

Signed-off-by: yevh-berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
yevh-berdnyk 2018-09-15 20:18:29 +03:00
parent d823bfd71c
commit 55d72b534a
No known key found for this signature in database
GPG Key ID: E9B425FDFC4DEA9C
17 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,2 @@
[pytest]
addopts = -s -v --junitxml=result.xml --tb=line

View File

@ -0,0 +1,16 @@
atomicwrites==1.2.1
attrs==18.2.0
certifi==2018.8.24
chardet==3.0.4
funcsigs==1.0.2
idna==2.7
jip==0.9.13
more-itertools==4.3.0
pathlib2==2.3.2
pluggy==0.7.1
py==1.6.0
pytest==2.7.2
requests==2.19.1
scandir==1.9.0
six==1.11.0
urllib3==1.23

View File

View File

@ -0,0 +1,52 @@
import org.sikuli.script.SikulixForJython
import pytest
from sikuli import *
from subprocess import check_output
def mac_os_setup():
check_output(['hdiutil', 'attach', 'nightly.dmg'])
check_output(['cp', '-rf', '/Volumes/Status/Status.app', '/Applications/'])
check_output(['hdiutil', 'detach', '/Volumes/Status/'])
import time
time.sleep(10)
openApp('Status.app')
def mac_os_teardown():
closeApp('Status.app')
for dir in '/Applications/Status.app', '/Library/Application\ Support/StatusIm', \
'/Users/yberdnyk/Library/Caches/StatusIm':
check_output(['rm', '-rf', dir])
def linux_setup():
check_output(['chmod', '+x', './nightly.AppImage'])
check_output(['./nightly.AppImage', '--appimage-extract'])
check_output(['chmod', '+x', '/src/squashfs-root/AppRun'])
openApp('/src/squashfs-root/AppRun')
def linux_teardown():
pass
# check_output(['killall', 'ubuntu-server'])
# check_output(['rm', '-rf', '~/.local/share/StatusIm/'])
# check_output(['rm', '-rf', '~/.cache/StatusIm/'])
class BaseTestCase:
Settings.ActionLogs = 0
Settings.OcrTextSearch = True
Settings.OcrTextRead = True
def setup_method(self, method):
if pytest.config.getoption('os') == 'linux':
linux_setup()
else:
mac_os_setup()
def teardown_method(self, method):
if pytest.config.getoption('os') == 'linux':
linux_teardown()
else:
mac_os_teardown()

View File

@ -0,0 +1,56 @@
import org.sikuli.script.SikulixForJython
from sikuli import *
import pytest
import requests
import re
from urllib import urlretrieve
from subprocess import check_output
from tests.report import save_test_result, TEST_REPORT_DIR
def pytest_addoption(parser):
parser.addoption('--os',
action='store',
default='linux')
parser.addoption("--nightly",
action="store",
default=True)
parser.addoption('--dmg',
action='store',
default=None,
help='Url or local path to dmg')
def pytest_configure(config):
if config.getoption('nightly'):
raw_data = requests.request('GET', 'https://status-im.github.io/nightly/').text
if config.getoption('os') == 'linux':
app_url = re.findall('href="(.*AppImage)', raw_data)[0]
urlretrieve(app_url, 'nightly.AppImage')
else:
dmg_url = re.findall('href="(.*dmg)', raw_data)[0]
urlretrieve(dmg_url, 'nightly.dmg')
@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
import logging
# logging.basicConfig(filename='%s/%s.log' % (TEST_REPORT_DIR, item.name), filemode='w', level=logging.INFO)
outcome = yield
report = outcome.get_result()
if report.when == 'call':
pass
# save_test_result(item, report)
def after_all():
if pytest.config.getoption('os') == 'linux':
check_output(['rm', '-rf', 'nightly.AppImage'])
else:
check_output(['rm', '-rf', 'nightly.dmg'])
@pytest.fixture(scope="session", autouse=True)
def before_all(request):
request.addfinalizer(finalizer=after_all)

View File

@ -0,0 +1,33 @@
import json
import os
from subprocess import check_output
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
def get_test_report_file_path(test_name):
file_name = "%s.json" % test_name
if not os.path.exists(TEST_REPORT_DIR):
os.makedirs(TEST_REPORT_DIR)
return os.path.join(TEST_REPORT_DIR, file_name)
def get_testrail_case_id(obj):
if 'testrail_id' in obj.keywords._markers:
return obj.keywords._markers['testrail_id'].args[0]
def save_test_result(test, report):
test_name = test.name
file_path = get_test_report_file_path(test_name)
if report.failed:
check_output(['screencapture', '%s/%s.png' % (TEST_REPORT_DIR, test_name)])
with open('%s/%s.log' % (TEST_REPORT_DIR, test_name), 'r') as log:
steps = [i for i in log]
test_dict = {
'testrail_case_id': get_testrail_case_id(test),
'name': test_name,
'steps': steps,
'error': str(report.longrepr.reprcrash.message),
'screenshot': test_name + '.png'}
json.dump(test_dict, open(file_path, 'w'))

View File

@ -0,0 +1,16 @@
from tests.base_test_case import BaseTestCase
from views.sign_in_view import SignInView
class TestCreateAccount(BaseTestCase):
def test_create_account(self):
sign_in = SignInView()
sign_in.create_account_button.click()
sign_in.password_input.input_value('123456')
sign_in.next_button.click()
sign_in.confirm_password_input.input_value('123456')
sign_in.next_button.click()
sign_in.username_input.input_value('test')
sign_in.next_button.click()
sign_in.home_button.find_element()

View File

View File

@ -0,0 +1,27 @@
import logging
import org.sikuli.script.SikulixForJython
import pytest
from sikuli import *
class BaseElement(object):
def __init__(self, screenshot):
self.screenshot = screenshot
def find_element(self):
try:
wait(self.screenshot, 10)
except FindFailed:
pytest.fail('%s was not found' % self.__class__.__name__)
def click(self):
logging.info('Click %s' % self.__class__.__name__)
self.find_element()
click(self.screenshot)
class InputField(BaseElement):
def input_value(self, value):
self.click()
type(value)

View File

@ -0,0 +1,17 @@
import os
from views.base_element import BaseElement
IMAGES_PATH = os.path.join(os.path.dirname(__file__), 'images/base_view')
class HomeButton(BaseElement):
def __init__(self):
super(HomeButton, self).__init__(IMAGES_PATH + '/home_button.png')
class BaseView(object):
def __init__(self):
super(BaseView, self).__init__()
self.home_button = HomeButton()

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,41 @@
import os
from views.base_element import BaseElement, InputField
from views.base_view import BaseView
IMAGES_PATH = os.path.join(os.path.dirname(__file__), 'images/sign_in_view')
class CreateAccountButton(BaseElement):
def __init__(self):
super(CreateAccountButton, self).__init__(IMAGES_PATH + '/create_account.png')
class PasswordInput(InputField):
def __init__(self):
super(PasswordInput, self).__init__(IMAGES_PATH + '/password_input.png')
class ConfirmPasswordInput(InputField):
def __init__(self):
super(ConfirmPasswordInput, self).__init__(IMAGES_PATH + '/confirm_password_input.png')
class UserNameInput(InputField):
def __init__(self):
super(UserNameInput, self).__init__(IMAGES_PATH + '/username_input.png')
class NextButton(InputField):
def __init__(self):
super(NextButton, self).__init__(IMAGES_PATH + '/next_button.png')
class SignInView(BaseView):
def __init__(self):
super(SignInView, self).__init__()
self.create_account_button = CreateAccountButton()
self.password_input = PasswordInput()
self.confirm_password_input = ConfirmPasswordInput()
self.username_input = UserNameInput()
self.next_button = NextButton()