Added screenshots for failed tests and device number to errors

Signed-off-by: yevh-berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
yevh-berdnyk 2018-08-15 15:51:52 +03:00
parent 4ddb9d582a
commit a22d13fd80
No known key found for this signature in database
GPG Key ID: E9B425FDFC4DEA9C
23 changed files with 177 additions and 159 deletions

View File

@ -1,7 +1,7 @@
import logging
import pytest import pytest
import requests import requests
import time import time
from tests import info
class NetworkApi: class NetworkApi:
@ -39,7 +39,7 @@ class NetworkApi:
transactions = self.get_transactions(address=address) transactions = self.get_transactions(address=address)
for transaction in transactions: for transaction in transactions:
if transaction['hash'] == transaction_hash: if transaction['hash'] == transaction_hash:
info('Transaction is found in Ropsten network') logging.info('Transaction is found in Ropsten network')
return return
pytest.fail('Transaction is not found in Ropsten network') pytest.fail('Transaction is not found in Ropsten network')
@ -57,11 +57,12 @@ class NetworkApi:
transactions = self.get_token_transaction(address=address) transactions = self.get_token_transaction(address=address)
else: else:
transactions = self.get_transactions(address=address) transactions = self.get_transactions(address=address)
info('Looking for a transaction with unique amount %s in list of transactions, address is %s' % logging.info('Looking for a transaction with unique amount %s in list of transactions, address is %s' %
(amount, address)) (amount, address))
for transaction in transactions: for transaction in transactions:
if float(int(transaction['value']) / 10 ** decimals) == float(amount): if float(int(transaction['value']) / 10 ** decimals) == float(amount):
info('Transaction with unique amount %s is found in list of transactions, address is %s' % logging.info(
'Transaction with unique amount %s is found in list of transactions, address is %s' %
(amount, address)) (amount, address))
return transaction return transaction
@ -82,9 +83,9 @@ class NetworkApi:
elif initial_balance == self.get_balance(recipient_address): elif initial_balance == self.get_balance(recipient_address):
counter += 10 counter += 10
time.sleep(10) time.sleep(10)
info('Waiting %s seconds for funds' % counter) logging.info('Waiting %s seconds for funds' % counter)
else: else:
info('Transaction is received') logging.info('Transaction is received')
return return
def verify_balance_is(self, expected_balance: int, recipient_address: str, errors: list): def verify_balance_is(self, expected_balance: int, recipient_address: str, errors: list):
@ -106,9 +107,9 @@ class NetworkApi:
elif self.get_balance(address) == initial_balance: elif self.get_balance(address) == initial_balance:
counter += 10 counter += 10
time.sleep(10) time.sleep(10)
info('Waiting %s seconds for donation' % counter) logging.info('Waiting %s seconds for donation' % counter)
else: else:
info('Got %s for %s' % (response["amount_eth"], address)) logging.info('Got %s for %s' % (response["amount_eth"], address))
return return
def start_chat_bot(self, chat_name: str, messages_number: int, interval: int = 1) -> list: def start_chat_bot(self, chat_name: str, messages_number: int, interval: int = 1) -> list:

View File

@ -1,12 +1,14 @@
import time
import json import json
import hmac import hmac
import os import os
from hashlib import md5 from hashlib import md5
from sauceclient import SauceException
from support.test_data import SingleTestData from support.test_data import SingleTestData
class BaseTestReport: class BaseTestReport:
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__)) TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
def __init__(self, sauce_username, sauce_access_key): def __init__(self, sauce_username, sauce_access_key):
@ -67,10 +69,23 @@ class BaseTestReport:
passed.append(test) passed.append(test)
return passed return passed
def get_sauce_job_url(self, job_id): def get_sauce_token(self, job_id):
token = hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'), return hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'),
bytes(job_id, 'latin-1'), md5).hexdigest() bytes(job_id, 'latin-1'), md5).hexdigest()
return "https://saucelabs.com/jobs/%s?auth=%s" % (job_id, token)
def get_sauce_job_url(self, job_id):
token = self.get_sauce_token(job_id)
return 'https://saucelabs.com/jobs/%s?auth=%s' % (job_id, token)
def get_sauce_final_screenshot_url(self, job_id):
token = self.get_sauce_token(job_id)
from tests.conftest import sauce
for _ in range(10):
try:
scr_number = sauce.jobs.get_job_assets(job_id)['screenshots'][-1]
return 'https://assets.saucelabs.com/jobs/%s/%s?auth=%s' % (job_id, scr_number, token)
except SauceException:
time.sleep(3)
@staticmethod @staticmethod
def is_test_successful(test): def is_test_successful(test):

View File

@ -1,10 +1,9 @@
import logging
from selenium.common.exceptions import WebDriverException from selenium.common.exceptions import WebDriverException
from tests import info
def start_web_browser(driver): def start_web_browser(driver):
info('Start web browser') logging.info('Start web browser')
try: try:
driver.start_activity('org.chromium.webview_shell', 'WebViewBrowserActivity') driver.start_activity('org.chromium.webview_shell', 'WebViewBrowserActivity')
except WebDriverException: except WebDriverException:

View File

@ -3,7 +3,6 @@ from support.base_test_report import BaseTestReport
class GithubHtmlReport(BaseTestReport): class GithubHtmlReport(BaseTestReport):
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__)) TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
def __init__(self, sauce_username, sauce_access_key): def __init__(self, sauce_username, sauce_access_key):
@ -53,7 +52,7 @@ class GithubHtmlReport(BaseTestReport):
return html return html
def build_test_row_html(self, index, test): def build_test_row_html(self, index, test):
html = "<tr><td><b>%d. %s</b></td></tr>" % (index+1, test.name) html = "<tr><td><b>%d. %s</b></td></tr>" % (index + 1, test.name)
html += "<tr><td>" html += "<tr><td>"
test_steps_html = list() test_steps_html = list()
last_testrun = test.testruns[-1] last_testrun = test.testruns[-1]
@ -70,15 +69,18 @@ class GithubHtmlReport(BaseTestReport):
html += "<code>%s</code>" % last_testrun.error html += "<code>%s</code>" % last_testrun.error
html += "<br/><br/>" html += "<br/><br/>"
if last_testrun.jobs: if last_testrun.jobs:
html += self.build_device_sessions_html(last_testrun.jobs) html += self.build_device_sessions_html(last_testrun.jobs, last_testrun)
html += "</td></tr>" html += "</td></tr>"
return html return html
def build_device_sessions_html(self, jobs): def build_device_sessions_html(self, jobs, test_run):
html = "<ins>Device sessions:</ins>" html = "<ins>Device sessions</ins>"
html += "<p><ul>" html += "<p><ul>"
for i, job_id in enumerate(jobs): for job_id, i in jobs.items():
html += "<li><a href=\"%s\">Device %d</a></li>" % (self.get_sauce_job_url(job_id), i+1) html += "Device %d:" % i
html += "<p><ul>"
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id)
if test_run.error:
html += "<li><a href=\"%s\">Failure screenshot</a></li>" % self.get_sauce_final_screenshot_url(job_id)
html += "</ul></p>" html += "</ul></p>"
return html return html

View File

@ -13,7 +13,7 @@ class SingleTestData(object):
self.error = error self.error = error
def create_new_testrun(self): def create_new_testrun(self):
self.testruns.append(SingleTestData.TestRunData(list(), list(), None)) self.testruns.append(SingleTestData.TestRunData(list(), dict(), None))
class TestSuiteData(object): class TestSuiteData(object):

View File

@ -19,12 +19,6 @@ def get_current_time():
return datetime.now().strftime('%-m%-d%-H%-M%-S') return datetime.now().strftime('%-m%-d%-H%-M%-S')
def info(text: str):
if "Base" not in text:
logging.info(text)
test_suite_data.current_test.testruns[-1].steps.append(text)
def debug(text: str): def debug(text: str):
logging.debug(text) logging.debug(text)

View File

@ -56,14 +56,13 @@ class TestSignInOffline(MultipleDeviceTestCase):
@marks.testrail_id(1432) @marks.testrail_id(1432)
def test_offline_login(self): def test_offline_login(self):
self.create_drivers(1, offline_mode=True) self.create_drivers(1, offline_mode=True)
driver = self.drivers[0] sign_in = SignInView(self.drivers[0])
sign_in = SignInView(driver)
sign_in.create_user() sign_in.create_user()
driver.close_app() sign_in.driver.close_app()
driver.set_network_connection(1) # airplane mode sign_in.driver.set_network_connection(1) # airplane mode
driver.launch_app() sign_in.driver.launch_app()
sign_in.accept_agreements() sign_in.accept_agreements()
home = sign_in.sign_in() home = sign_in.sign_in()
home.home_button.wait_for_visibility_of_element() home.home_button.wait_for_visibility_of_element()

View File

@ -162,7 +162,7 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
chat_2.chat_message_input.send_keys(message) chat_2.chat_message_input.send_keys(message)
chat_2.send_message_button.click() chat_2.send_message_button.click()
self.drivers[1].quit() chat_2.driver.quit()
chat_element = chat_1.chat_element_by_text(message) chat_element = chat_1.chat_element_by_text(message)
chat_element.find_element() chat_element.find_element()

View File

@ -328,7 +328,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
chat_2 = home_2.get_chat_with_user(sender['username']).click() chat_2 = home_2.get_chat_with_user(sender['username']).click()
self.network_api.wait_for_confirmation_of_transaction(recipient['address'], amount) self.network_api.wait_for_confirmation_of_transaction(recipient['address'], amount)
if not chat_2.chat_element_by_text(amount).contains_text('Confirmed', 60): if not chat_2.chat_element_by_text(amount).contains_text('Confirmed', 60):
pytest.fail('Transaction state is not updated on the recipient side') chat_2.driver.fail('Transaction state is not updated on the recipient side')
@marks.chat @marks.chat

View File

@ -35,22 +35,21 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
@marks.smoke_1 @marks.smoke_1
def test_offline_messaging_1_1_chat(self): def test_offline_messaging_1_1_chat(self):
self.create_drivers(2, offline_mode=True) self.create_drivers(2, offline_mode=True)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_2 = 'user_2' username_2 = 'user_2'
home_1, home_2 = sign_in_1.create_user(), sign_in_2.create_user(username=username_2) home_1, home_2 = sign_in_1.create_user(), sign_in_2.create_user(username=username_2)
public_key_1 = home_1.get_public_key() public_key_1 = home_1.get_public_key()
home_1.home_button.click() home_1.home_button.click()
device_1.set_network_connection(1) # airplane mode on primary device home_1.driver.set_network_connection(1) # airplane mode on primary device
chat_2 = home_2.add_contact(public_key_1) chat_2 = home_2.add_contact(public_key_1)
message_1 = 'test message' message_1 = 'test message'
chat_2.chat_message_input.send_keys(message_1) chat_2.chat_message_input.send_keys(message_1)
chat_2.send_message_button.click() chat_2.send_message_button.click()
device_2.set_network_connection(1) # airplane mode on secondary device chat_2.driver.set_network_connection(1) # airplane mode on secondary device
device_1.set_network_connection(2) # turning on WiFi connection on primary device home_1.driver.set_network_connection(2) # turning on WiFi connection on primary device
home_1.connection_status.wait_for_invisibility_of_element(20) home_1.connection_status.wait_for_invisibility_of_element(20)
chat_element = home_1.get_chat_with_user(username_2) chat_element = home_1.get_chat_with_user(username_2)
@ -58,15 +57,15 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
chat_1 = chat_element.click() chat_1 = chat_element.click()
chat_1.chat_element_by_text(message_1).wait_for_visibility_of_element(2) chat_1.chat_element_by_text(message_1).wait_for_visibility_of_element(2)
device_2.set_network_connection(2) # turning on WiFi connection on secondary device chat_2.driver.set_network_connection(2) # turning on WiFi connection on secondary device
device_1.set_network_connection(1) # airplane mode on primary device home_1.driver.set_network_connection(1) # airplane mode on primary device
chat_2.element_by_text('Connecting to peers...').wait_for_invisibility_of_element(60) chat_2.element_by_text('Connecting to peers...').wait_for_invisibility_of_element(60)
message_2 = 'one more message' message_2 = 'one more message'
chat_2.chat_message_input.send_keys(message_2) chat_2.chat_message_input.send_keys(message_2)
chat_2.send_message_button.click() chat_2.send_message_button.click()
device_1.set_network_connection(2) # turning on WiFi connection on primary device home_1.driver.set_network_connection(2) # turning on WiFi connection on primary device
chat_1 = chat_element.click() chat_1 = chat_element.click()
chat_1.chat_element_by_text(message_2).wait_for_visibility_of_element(180) chat_1.chat_element_by_text(message_2).wait_for_visibility_of_element(180)
@ -75,14 +74,13 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
@marks.testrail_id(3701) @marks.testrail_id(3701)
def test_resend_message_offline(self): def test_resend_message_offline(self):
self.create_drivers(2, offline_mode=True) self.create_drivers(2, offline_mode=True)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_1 = 'user_%s' % get_current_time() username_1 = 'user_%s' % get_current_time()
home_1, home_2 = sign_in_1.create_user(username_1), sign_in_2.create_user() home_1, home_2 = sign_in_1.create_user(username_1), sign_in_2.create_user()
public_key_2 = home_2.get_public_key() public_key_2 = home_2.get_public_key()
home_2.home_button.click() home_2.home_button.click()
device_1.set_network_connection(1) # airplane mode on primary device home_1.driver.set_network_connection(1) # airplane mode on primary device
chat_1 = home_1.add_contact(public_key_2) chat_1 = home_1.add_contact(public_key_2)
message = 'test message' message = 'test message'
@ -92,7 +90,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
if not 5 < progress_time < 30: if not 5 < progress_time < 30:
self.errors.append('Progress indicator is shown during %s seconds' % progress_time) self.errors.append('Progress indicator is shown during %s seconds' % progress_time)
device_1.set_network_connection(2) # turning on WiFi connection home_1.driver.set_network_connection(2) # turning on WiFi connection
chat_1.element_by_text('Connecting to peers...').wait_for_invisibility_of_element(30) chat_1.element_by_text('Connecting to peers...').wait_for_invisibility_of_element(30)
chat_1.element_by_text('Not sent. Tap for options').click() chat_1.element_by_text('Not sent. Tap for options').click()
if not chat_1.element_by_text('Delete message').is_element_displayed(): if not chat_1.element_by_text('Delete message').is_element_displayed():
@ -114,12 +112,9 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
@marks.smoke_1 @marks.smoke_1
def test_messaging_in_different_networks(self): def test_messaging_in_different_networks(self):
self.create_drivers(2) self.create_drivers(2)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_1 = 'user_%s' % get_current_time() username_1 = 'user_%s' % get_current_time()
sign_in_1.create_user(username_1) home_1, home_2 = sign_in_1.create_user(username_1), sign_in_2.create_user()
sign_in_2.create_user()
home_1, home_2 = sign_in_1.get_home_view(), sign_in_2.get_home_view()
public_key_2 = home_2.get_public_key() public_key_2 = home_2.get_public_key()
profile_2 = home_2.get_profile_view() profile_2 = home_2.get_profile_view()
profile_2.switch_network('Mainnet with upstream RPC') profile_2.switch_network('Mainnet with upstream RPC')
@ -266,8 +261,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
@marks.smoke_1 @marks.smoke_1
def test_offline_status(self): def test_offline_status(self):
self.create_drivers(1, offline_mode=True) self.create_drivers(1, offline_mode=True)
driver = self.drivers[0] sign_in = SignInView(self.drivers[0])
sign_in = SignInView(driver)
home_view = sign_in.create_user() home_view = sign_in.create_user()
# Dismiss "Welcome to Status" placeholder. # Dismiss "Welcome to Status" placeholder.
@ -275,7 +269,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
wallet_view = home_view.wallet_button.click() wallet_view = home_view.wallet_button.click()
wallet_view.home_button.click() wallet_view.home_button.click()
driver.set_network_connection(1) # airplane mode sign_in.driver.set_network_connection(1) # airplane mode
if home_view.connection_status.text != 'Offline': if home_view.connection_status.text != 'Offline':
self.errors.append('Offline status is not shown in home screen') self.errors.append('Offline status is not shown in home screen')
@ -405,8 +399,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
@marks.testrail_id(2781) @marks.testrail_id(2781)
def test_timestamp_in_chats(self): def test_timestamp_in_chats(self):
self.create_drivers(2) self.create_drivers(2)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_1 = 'user_%s' % get_current_time() username_1 = 'user_%s' % get_current_time()
device_1_home, device_2_home = sign_in_1.create_user(username=username_1), sign_in_2.create_user() device_1_home, device_2_home = sign_in_1.create_user(username=username_1), sign_in_2.create_user()
device_2_public_key = device_2_home.get_public_key() device_2_public_key = device_2_home.get_public_key()
@ -417,7 +410,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
message = 'test text' message = 'test text'
device_1_chat.chat_message_input.send_keys(message) device_1_chat.chat_message_input.send_keys(message)
device_1_chat.send_message_button.click() device_1_chat.send_message_button.click()
sent_time = datetime.strptime(device_1.device_time, '%a %b %d %H:%M:%S GMT %Y').strftime("%I:%M %p") sent_time = datetime.strptime(device_1_chat.driver.device_time, '%a %b %d %H:%M:%S GMT %Y').strftime("%I:%M %p")
if not device_1_chat.chat_element_by_text(message).contains_text(sent_time): if not device_1_chat.chat_element_by_text(message).contains_text(sent_time):
self.errors.append('Timestamp is not displayed in 1-1 chat for the sender') self.errors.append('Timestamp is not displayed in 1-1 chat for the sender')
if device_1_chat.chat_element_by_text(message).member_photo.is_element_displayed(): if device_1_chat.chat_element_by_text(message).member_photo.is_element_displayed():
@ -437,7 +430,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
device_2_chat.chat_message_input.send_keys(message) device_2_chat.chat_message_input.send_keys(message)
device_2_chat.send_message_button.click() device_2_chat.send_message_button.click()
sent_time = datetime.strptime(device_2.device_time, '%a %b %d %H:%M:%S GMT %Y').strftime("%I:%M %p") sent_time = datetime.strptime(device_2_chat.driver.device_time, '%a %b %d %H:%M:%S GMT %Y').strftime("%I:%M %p")
if not device_2_chat.chat_element_by_text(message).contains_text(sent_time): if not device_2_chat.chat_element_by_text(message).contains_text(sent_time):
self.errors.append('Timestamp is not displayed in public chat for the sender') self.errors.append('Timestamp is not displayed in public chat for the sender')
if device_2_chat.chat_element_by_text(message).member_photo.is_element_displayed(): if device_2_chat.chat_element_by_text(message).member_photo.is_element_displayed():

View File

@ -61,13 +61,14 @@ class TestPublicChatMultipleDevice(MultipleDeviceTestCase):
chat_1.element_by_text(message_3).is_element_present() chat_1.element_by_text(message_3).is_element_present()
for message in message_1, message_2: for message in message_1, message_2:
if chat_1.element_starts_with_text(message).is_element_present(): if chat_1.element_starts_with_text(message).is_element_present():
pytest.fail("Message '%s' is shown, but public chat history has been cleared" % message) chat_1.driver.fail("Message '%s' is shown, but public chat history has been cleared" % message)
home_1 = chat_1.get_back_to_home_view() home_1 = chat_1.get_back_to_home_view()
home_1.relogin() home_1.relogin()
home_1.element_by_text('#' + chat_name).click() home_1.element_by_text('#' + chat_name).click()
for message in message_1, message_2: for message in message_1, message_2:
if chat_1.element_starts_with_text(message).is_element_present(): if chat_1.element_starts_with_text(message).is_element_present():
pytest.fail("Message '%s' is shown after re-login, but public chat history has been cleared" % message) chat_1.driver.fail(
"Message '%s' is shown after re-login, but public chat history has been cleared" % message)
@marks.testrail_id(3729) @marks.testrail_id(3729)
def test_unread_messages_counter_public_chat(self): def test_unread_messages_counter_public_chat(self):

View File

@ -1,3 +1,4 @@
import logging
import pytest import pytest
import sys import sys
import re import re
@ -10,7 +11,7 @@ from os import environ
from appium import webdriver from appium import webdriver
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from selenium.common.exceptions import WebDriverException from selenium.common.exceptions import WebDriverException
from tests import test_suite_data, start_threads, marks from tests import test_suite_data, start_threads
from appium.webdriver.common.mobileby import MobileBy from appium.webdriver.common.mobileby import MobileBy
from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoSuchElementException
from support.github_report import GithubHtmlReport from support.github_report import GithubHtmlReport
@ -132,6 +133,22 @@ class AbstractTestCase:
% self.get_alert_text(driver) % self.get_alert_text(driver)
class Driver(webdriver.Remote):
@property
def number(self):
return test_suite_data.current_test.testruns[-1].jobs[self.session_id]
def info(self, text: str):
if "Base" not in text:
text = 'Device %s: %s' % (self.number, text)
logging.info(text)
test_suite_data.current_test.testruns[-1].steps.append(text)
def fail(self, text: str):
pytest.fail('Device %s: %s' % (self.number, text))
class SingleDeviceTestCase(AbstractTestCase): class SingleDeviceTestCase(AbstractTestCase):
def setup_method(self, method): def setup_method(self, method):
@ -140,10 +157,10 @@ class SingleDeviceTestCase(AbstractTestCase):
'sauce': {'executor': self.executor_sauce_lab, 'sauce': {'executor': self.executor_sauce_lab,
'capabilities': self.capabilities_sauce_lab}} 'capabilities': self.capabilities_sauce_lab}}
self.driver = webdriver.Remote(capabilities[self.environment]['executor'], self.driver = Driver(capabilities[self.environment]['executor'],
capabilities[self.environment]['capabilities']) capabilities[self.environment]['capabilities'])
test_suite_data.current_test.testruns[-1].jobs[self.driver.session_id] = 1
self.driver.implicitly_wait(self.implicitly_wait) self.driver.implicitly_wait(self.implicitly_wait)
test_suite_data.current_test.testruns[-1].jobs.append(self.driver.session_id)
def teardown_method(self, method): def teardown_method(self, method):
if self.environment == 'sauce': if self.environment == 'sauce':
@ -165,9 +182,9 @@ class LocalMultipleDeviceTestCase(AbstractTestCase):
def create_drivers(self, quantity): def create_drivers(self, quantity):
capabilities = self.add_local_devices_to_capabilities() capabilities = self.add_local_devices_to_capabilities()
for driver in range(quantity): for driver in range(quantity):
self.drivers[driver] = webdriver.Remote(self.executor_local, capabilities[driver]) self.drivers[driver] = Driver(self.executor_local, capabilities[driver])
test_suite_data.current_test.testruns[-1].jobs[self.drivers[driver].session_id] = driver + 1
self.drivers[driver].implicitly_wait(self.implicitly_wait) self.drivers[driver].implicitly_wait(self.implicitly_wait)
test_suite_data.current_test.testruns[-1].jobs.append(self.drivers[driver].session_id)
def teardown_method(self, method): def teardown_method(self, method):
for driver in self.drivers: for driver in self.drivers:
@ -193,14 +210,14 @@ class SauceMultipleDeviceTestCase(AbstractTestCase):
if offline_mode: if offline_mode:
capabilities['platformVersion'] = '6.0' capabilities['platformVersion'] = '6.0'
self.drivers = self.loop.run_until_complete(start_threads(quantity, self.drivers = self.loop.run_until_complete(start_threads(quantity,
webdriver.Remote, Driver,
self.drivers, self.drivers,
self.executor_sauce_lab, self.executor_sauce_lab,
self.update_capabilities_sauce_lab(capabilities))) self.update_capabilities_sauce_lab(capabilities)))
for driver in range(quantity): for driver in range(quantity):
test_suite_data.current_test.testruns[-1].jobs[self.drivers[driver].session_id] = driver + 1
self.drivers[driver].implicitly_wait( self.drivers[driver].implicitly_wait(
custom_implicitly_wait if custom_implicitly_wait else self.implicitly_wait) custom_implicitly_wait if custom_implicitly_wait else self.implicitly_wait)
test_suite_data.current_test.testruns[-1].jobs.append(self.drivers[driver].session_id)
def teardown_method(self, method): def teardown_method(self, method):
for driver in self.drivers: for driver in self.drivers:

View File

@ -1,3 +1,4 @@
import time
import requests import requests
import pytest import pytest
import re import re
@ -146,14 +147,14 @@ def pytest_runtest_makereport(item, call):
error = report.longreprtext error = report.longreprtext
exception = re.findall('E.*:', error) exception = re.findall('E.*:', error)
if exception: if exception:
error = error.replace(re.findall('E.*:', report.longreprtext)[0], '') error = error.replace(re.findall('E.*Message:|E.*Error:|E.*Failed:', report.longreprtext)[0], '')
current_test.testruns[-1].error = error current_test.testruns[-1].error = error
if is_sauce_env: if is_sauce_env:
update_sauce_jobs(current_test.name, current_test.testruns[-1].jobs, report.passed) update_sauce_jobs(current_test.name, current_test.testruns[-1].jobs, report.passed)
def update_sauce_jobs(test_name, job_ids, passed): def update_sauce_jobs(test_name, job_ids, passed):
for job_id in job_ids: for job_id in job_ids.keys():
sauce.jobs.update_job(job_id, name=test_name, passed=passed) sauce.jobs.update_job(job_id, name=test_name, passed=passed)

View File

@ -10,7 +10,7 @@ from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.wait import WebDriverWait
from tests import info, marks from tests import marks
from tests.base_test_case import MessageReliabilityTestCase from tests.base_test_case import MessageReliabilityTestCase
from views.base_element import BaseButton from views.base_element import BaseButton
from views.sign_in_view import SignInView from views.sign_in_view import SignInView
@ -61,7 +61,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
user_b_message_time[duration_time] = user_b_receive_time user_b_message_time[duration_time] = user_b_receive_time
user_b_received_messages += 1 user_b_received_messages += 1
except TimeoutException: except TimeoutException:
info("Message with text '%s' was not received by user_b" % message_1) device_2_chat.driver.info("Message with text '%s' was not received by user_b" % message_1)
message_2 = ''.join(random.sample(string.ascii_lowercase, k=10)) message_2 = ''.join(random.sample(string.ascii_lowercase, k=10))
device_2_chat.chat_message_input.send_keys(message_2) device_2_chat.chat_message_input.send_keys(message_2)
device_2_chat.send_message_button.click() device_2_chat.send_message_button.click()
@ -74,7 +74,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
user_a_message_time[duration_time] = user_a_receive_time user_a_message_time[duration_time] = user_a_receive_time
user_a_received_messages += 1 user_a_received_messages += 1
except TimeoutException: except TimeoutException:
info("Message with text '%s' was not received by user_a" % message_2) device_1_chat.driver.info("Message with text '%s' was not received by user_a" % message_2)
finally: finally:
self.one_to_one_chat_data['user_a'] = {'sent_messages': user_a_sent_messages, self.one_to_one_chat_data['user_a'] = {'sent_messages': user_a_sent_messages,
'message_time': user_a_message_time} 'message_time': user_a_message_time}
@ -132,8 +132,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
self.public_chat_data['message_time'] = dict() self.public_chat_data['message_time'] = dict()
self.create_drivers(1, max_duration=10800, custom_implicitly_wait=2, offline_mode=True) self.create_drivers(1, max_duration=10800, custom_implicitly_wait=2, offline_mode=True)
driver = self.drivers[0] sign_in_view = SignInView(self.drivers[0])
sign_in_view = SignInView(driver)
home_view = sign_in_view.create_user() home_view = sign_in_view.create_user()
chat_name = chat_name if chat_name else home_view.get_public_chat_name() chat_name = chat_name if chat_name else home_view.get_public_chat_name()
home_view.join_public_chat(chat_name) home_view.join_public_chat(chat_name)
@ -142,12 +141,12 @@ class TestMessageReliability(MessageReliabilityTestCase):
iterations = int(messages_number / 10 if messages_number > 10 else messages_number) iterations = int(messages_number / 10 if messages_number > 10 else messages_number)
for _ in range(iterations): for _ in range(iterations):
home_view.get_back_to_home_view() home_view.get_back_to_home_view()
driver.set_network_connection(1) # airplane mode home_view.driver.set_network_connection(1) # airplane mode
sent_messages_texts = self.network_api.start_chat_bot(chat_name=chat_name, messages_number=10) sent_messages_texts = self.network_api.start_chat_bot(chat_name=chat_name, messages_number=10)
self.public_chat_data['sent_messages'] += 10 self.public_chat_data['sent_messages'] += 10
driver.set_network_connection(2) # turning on WiFi connection home_view.driver.set_network_connection(2) # turning on WiFi connection
home_view.get_chat_with_user('#' + chat_name).click() home_view.get_chat_with_user('#' + chat_name).click()
chat_view = home_view.get_chat_view() chat_view = home_view.get_chat_view()
@ -170,8 +169,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
user_b_message_time = dict() user_b_message_time = dict()
try: try:
self.create_drivers(2, max_duration=10800, custom_implicitly_wait=2, offline_mode=True) self.create_drivers(2, max_duration=10800, custom_implicitly_wait=2, offline_mode=True)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
sign_in_1.create_user(username='user_a') sign_in_1.create_user(username='user_a')
sign_in_2.create_user(username='user_b') sign_in_2.create_user(username='user_b')
device_1_home, device_2_home = sign_in_1.get_home_view(), sign_in_2.get_home_view() device_1_home, device_2_home = sign_in_1.get_home_view(), sign_in_2.get_home_view()
@ -188,7 +186,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
iterations = int((messages_number / 10 if messages_number > 10 else messages_number) / 2) iterations = int((messages_number / 10 if messages_number > 10 else messages_number) / 2)
start_time = time.time() start_time = time.time()
for i in range(iterations): for i in range(iterations):
device_2.set_network_connection(1) # airplane mode device_2_home.driver.set_network_connection(1) # airplane mode
messages_1 = list() messages_1 = list()
for _ in range(10): for _ in range(10):
@ -199,7 +197,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
messages_1.append(messages_1) messages_1.append(messages_1)
user_a_sent_messages += 1 user_a_sent_messages += 1
device_2.set_network_connection(2) # turning on WiFi connection device_2_home.driver.set_network_connection(2) # turning on WiFi connection
for message in messages_1: for message in messages_1:
try: try:
@ -210,7 +208,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
user_b_message_time[duration_time] = user_b_receive_time user_b_message_time[duration_time] = user_b_receive_time
user_b_received_messages += 1 user_b_received_messages += 1
except TimeoutException: except TimeoutException:
info("Message with text '%s' was not received by user_b" % message) device_2_home.driver.info("Message with text '%s' was not received by user_b" % message)
messages_2 = list() messages_2 = list()
for _ in range(10): for _ in range(10):
@ -229,7 +227,7 @@ class TestMessageReliability(MessageReliabilityTestCase):
user_a_message_time[duration_time] = user_a_receive_time user_a_message_time[duration_time] = user_a_receive_time
user_a_received_messages += 1 user_a_received_messages += 1
except TimeoutException: except TimeoutException:
info("Message with text '%s' was not received by user_a" % message) device_1_home.driver.info("Message with text '%s' was not received by user_a" % message)
finally: finally:
self.one_to_one_chat_data['user_a'] = {'sent_messages': user_a_sent_messages, self.one_to_one_chat_data['user_a'] = {'sent_messages': user_a_sent_messages,
'message_time': user_a_message_time} 'message_time': user_a_message_time}
@ -238,27 +236,26 @@ class TestMessageReliability(MessageReliabilityTestCase):
def test_message_reliability_push_notifications(self, message_wait_time): def test_message_reliability_push_notifications(self, message_wait_time):
self.create_drivers(2, max_duration=10800, custom_implicitly_wait=2) self.create_drivers(2, max_duration=10800, custom_implicitly_wait=2)
device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
sign_in_1.create_user(username='user_a') sign_in_1.create_user(username='user_a')
sign_in_2.create_user(username='user_b') sign_in_2.create_user(username='user_b')
device_1_home, device_2_home = sign_in_1.get_home_view(), sign_in_2.get_home_view() device_1_home, device_2_home = sign_in_1.get_home_view(), sign_in_2.get_home_view()
device_2_public_key = device_2_home.get_public_key() device_2_public_key = device_2_home.get_public_key()
device_2_home.home_button.click() device_2_home.home_button.click()
device_2.close_app() device_2_home.driver.close_app()
device_1_home.add_contact(device_2_public_key) device_1_home.add_contact(device_2_public_key)
device_1_chat = device_1_home.get_chat_view() device_1_chat = device_1_home.get_chat_view()
device_1_chat.chat_message_input.send_keys('hello') device_1_chat.chat_message_input.send_keys('hello')
device_1_chat.send_message_button.click() device_1_chat.send_message_button.click()
device_2.open_notifications() device_2_home.driver.open_notifications()
try: try:
WebDriverWait(device_2, message_wait_time) \ WebDriverWait(device_2_home.driver, message_wait_time) \
.until( .until(
expected_conditions.presence_of_element_located((MobileBy.XPATH, '//*[contains(@text, "Status")]'))) expected_conditions.presence_of_element_located((MobileBy.XPATH, '//*[contains(@text, "Status")]')))
element = BaseButton(device_2) element = BaseButton(device_2_home.driver)
element.locator = element.Locator.xpath_selector("//*[contains(@text,'Status')]") element.locator = element.Locator.xpath_selector("//*[contains(@text,'Status')]")
element.click() element.click()
except TimeoutException as exception: except TimeoutException as exception:

View File

@ -12,7 +12,6 @@ from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions from selenium.webdriver.support import expected_conditions
from tests import info
class BaseElement(object): class BaseElement(object):
@ -61,7 +60,8 @@ class BaseElement(object):
try: try:
return self.driver.find_element(self.locator.by, self.locator.value) return self.driver.find_element(self.locator.by, self.locator.value)
except NoSuchElementException: except NoSuchElementException:
raise NoSuchElementException("'%s' is not found on the screen" % self.name) from None raise NoSuchElementException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
except Exception as exception: except Exception as exception:
if 'Internal Server Error' in str(exception): if 'Internal Server Error' in str(exception):
continue continue
@ -71,47 +71,50 @@ class BaseElement(object):
def click(self): def click(self):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
def wait_for_element(self, seconds=10): def wait_for_element(self, seconds=10):
try: try:
return WebDriverWait(self.driver, seconds) \ return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.presence_of_element_located((self.locator.by, self.locator.value))) .until(expected_conditions.presence_of_element_located((self.locator.by, self.locator.value)))
except TimeoutException: except TimeoutException:
raise TimeoutException("'%s' is not found on the screen" % self.name) from None raise TimeoutException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
def wait_for_visibility_of_element(self, seconds=10, ignored_exceptions=None): def wait_for_visibility_of_element(self, seconds=10, ignored_exceptions=None):
try: try:
return WebDriverWait(self.driver, seconds, ignored_exceptions=ignored_exceptions) \ return WebDriverWait(self.driver, seconds, ignored_exceptions=ignored_exceptions) \
.until(expected_conditions.visibility_of_element_located((self.locator.by, self.locator.value))) .until(expected_conditions.visibility_of_element_located((self.locator.by, self.locator.value)))
except TimeoutException: except TimeoutException:
raise TimeoutException("'%s' is not found on the screen" % self.name) from None raise TimeoutException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
def wait_for_invisibility_of_element(self, seconds=10): def wait_for_invisibility_of_element(self, seconds=10):
try: try:
return WebDriverWait(self.driver, seconds) \ return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.invisibility_of_element_located((self.locator.by, self.locator.value))) .until(expected_conditions.invisibility_of_element_located((self.locator.by, self.locator.value)))
except TimeoutException: except TimeoutException:
raise TimeoutException("'%s' is not found on the screen" % self.name) from None raise TimeoutException("Device %s: '%s' is still visible on the screen after %s seconds" % (
self.driver.number, self.name, seconds)) from None
def scroll_to_element(self): def scroll_to_element(self):
for _ in range(9): for _ in range(9):
try: try:
return self.find_element() return self.find_element()
except NoSuchElementException: except NoSuchElementException:
info('Scrolling down to %s' % self.name) self.driver.info('Scrolling down to %s' % self.name)
self.driver.swipe(500, 1000, 500, 500) self.driver.swipe(500, 1000, 500, 500)
def is_element_present(self, sec=5): def is_element_present(self, sec=5):
try: try:
info('Wait for %s' % self.name) self.driver.info('Wait for %s' % self.name)
return self.wait_for_element(sec) return self.wait_for_element(sec)
except TimeoutException: except TimeoutException:
return False return False
def is_element_displayed(self, sec=5, ignored_exceptions=None): def is_element_displayed(self, sec=5, ignored_exceptions=None):
try: try:
info('Wait for %s' % self.name) self.driver.info('Wait for %s' % self.name)
return self.wait_for_visibility_of_element(sec, ignored_exceptions=ignored_exceptions) return self.wait_for_visibility_of_element(sec, ignored_exceptions=ignored_exceptions)
except TimeoutException: except TimeoutException:
return False return False
@ -149,7 +152,7 @@ class BaseElement(object):
def long_press_element(self): def long_press_element(self):
element = self.find_element() element = self.find_element()
info('Long press %s' % self.name) self.driver.info('Long press %s' % self.name)
action = TouchAction(self.driver) action = TouchAction(self.driver)
action.long_press(element).release().perform() action.long_press(element).release().perform()
@ -173,25 +176,25 @@ class BaseEditBox(BaseElement):
def send_keys(self, value): def send_keys(self, value):
self.find_element().send_keys(value) self.find_element().send_keys(value)
info("Type '%s' to %s" % (value, self.name)) self.driver.info("Type '%s' to %s" % (value, self.name))
def set_value(self, value): def set_value(self, value):
self.find_element().set_value(value) self.find_element().set_value(value)
info("Type '%s' to %s" % (value, self.name)) self.driver.info("Type '%s' to %s" % (value, self.name))
def clear(self): def clear(self):
self.find_element().clear() self.find_element().clear()
info('Clear text in %s' % self.name) self.driver.info('Clear text in %s' % self.name)
def delete_last_symbols(self, number_of_symbols_to_delete: int): def delete_last_symbols(self, number_of_symbols_to_delete: int):
info('Delete last %s symbols from %s' % (number_of_symbols_to_delete, self.name)) self.driver.info('Delete last %s symbols from %s' % (number_of_symbols_to_delete, self.name))
self.click() self.click()
for _ in range(number_of_symbols_to_delete): for _ in range(number_of_symbols_to_delete):
time.sleep(1) time.sleep(1)
self.driver.press_keycode(67) self.driver.press_keycode(67)
def paste_text_from_clipboard(self): def paste_text_from_clipboard(self):
info('Paste text from clipboard into %s' % self.name) self.driver.info('Paste text from clipboard into %s' % self.name)
self.long_press_element() self.long_press_element()
time.sleep(2) time.sleep(2)
action = TouchAction(self.driver) action = TouchAction(self.driver)
@ -200,7 +203,7 @@ class BaseEditBox(BaseElement):
action.press(x=x + 100, y=y - 50).release().perform() action.press(x=x + 100, y=y - 50).release().perform()
def cut_text(self): def cut_text(self):
info('Cut text in %s' % self.name) self.driver.info('Cut text in %s' % self.name)
location = self.find_element().location location = self.find_element().location
x, y = location['x'], location['y'] x, y = location['x'], location['y']
action = TouchAction(self.driver) action = TouchAction(self.driver)
@ -217,7 +220,7 @@ class BaseText(BaseElement):
@property @property
def text(self): def text(self):
text = self.find_element().text text = self.find_element().text
info('%s is %s' % (self.name, text)) self.driver.info('%s is %s' % (self.name, text))
return text return text
@ -228,16 +231,16 @@ class BaseButton(BaseElement):
def click(self): def click(self):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
return self.navigate() return self.navigate()
def click_until_presence_of_element(self, desired_element, attempts=3): def click_until_presence_of_element(self, desired_element, attempts=3):
counter = 0 counter = 0
while not desired_element.is_element_present(1) and counter <= attempts: while not desired_element.is_element_present(1) and counter <= attempts:
try: try:
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
self.find_element().click() self.find_element().click()
info('Wait for %s' % desired_element.name) self.driver.info('Wait for %s' % desired_element.name)
desired_element.wait_for_element(5) desired_element.wait_for_element(5)
return self.navigate() return self.navigate()
except (NoSuchElementException, TimeoutException): except (NoSuchElementException, TimeoutException):

View File

@ -5,7 +5,7 @@ import base64
import pytest import pytest
import re import re
import zbarlight import zbarlight
from tests import info, common_password, test_fairy_warning_text from tests import common_password, test_fairy_warning_text
from eth_keys import datatypes from eth_keys import datatypes
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException
from PIL import Image from PIL import Image
@ -22,7 +22,7 @@ class BackButton(BaseButton):
def click(self, times_to_click: int = 1): def click(self, times_to_click: int = 1):
for _ in range(times_to_click): for _ in range(times_to_click):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
return self.navigate() return self.navigate()
@ -35,7 +35,7 @@ class AllowButton(BaseButton):
try: try:
for _ in range(3): for _ in range(3):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
except NoSuchElementException: except NoSuchElementException:
pass pass
@ -114,7 +114,7 @@ class WalletButton(TabButton):
return WalletView(self.driver) return WalletView(self.driver)
def click(self): def click(self):
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
from views.wallet_view import SetUpButton, SendTransactionButton from views.wallet_view import SetUpButton, SendTransactionButton
for _ in range(3): for _ in range(3):
self.find_element().click() self.find_element().click()
@ -179,7 +179,7 @@ class SendMessageButton(BaseButton):
def click(self): def click(self):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
class ConnectionStatusText(BaseText): class ConnectionStatusText(BaseText):
@ -299,7 +299,7 @@ class BaseView(object):
raise TimeoutError('Logcat is empty') raise TimeoutError('Logcat is empty')
def confirm(self): def confirm(self):
info("Tap 'Confirm' on native keyboard") self.driver.info("Tap 'Confirm' on native keyboard")
self.driver.press_keycode(66) self.driver.press_keycode(66)
def confirm_until_presence_of_element(self, desired_element, attempts=3): def confirm_until_presence_of_element(self, desired_element, attempts=3):
@ -307,26 +307,26 @@ class BaseView(object):
while not desired_element.is_element_present(1) and counter <= attempts: while not desired_element.is_element_present(1) and counter <= attempts:
try: try:
self.confirm() self.confirm()
info('Wait for %s' % desired_element.name) self.driver.info('Wait for %s' % desired_element.name)
desired_element.wait_for_element(5) desired_element.wait_for_element(5)
return return
except TimeoutException: except TimeoutException:
counter += 1 counter += 1
def click_system_back_button(self): def click_system_back_button(self):
info('Click system back button') self.driver.info('Click system back button')
self.driver.press_keycode(4) self.driver.press_keycode(4)
def cut_text(self): def cut_text(self):
info('Cut text') self.driver.info('Cut text')
self.driver.press_keycode(277) self.driver.press_keycode(277)
def copy_text(self): def copy_text(self):
info('Copy text') self.driver.info('Copy text')
self.driver.press_keycode(278) self.driver.press_keycode(278)
def paste_text(self): def paste_text(self):
info('Paste text') self.driver.info('Paste text')
self.driver.press_keycode(279) self.driver.press_keycode(279)
def send_as_keyevent(self, string): def send_as_keyevent(self, string):
@ -339,7 +339,7 @@ class BaseView(object):
'k': 39, 'l': 40, 'm': 41, 'n': 42, 'o': 43, 'p': 44, 'q': 45, 'r': 46, 's': 47, 't': 48, 'k': 39, 'l': 40, 'm': 41, 'n': 42, 'o': 43, 'p': 44, 'q': 45, 'r': 46, 's': 47, 't': 48,
'u': 49, 'v': 50, 'w': 51, 'x': 52, 'y': 53, 'z': 54} 'u': 49, 'v': 50, 'w': 51, 'x': 52, 'y': 53, 'z': 54}
time.sleep(3) time.sleep(3)
info("Enter '%s' using native keyboard" % string) self.driver.info("Enter '%s' using native keyboard" % string)
for i in string: for i in string:
if type(keys[i]) is list: if type(keys[i]) is list:
keycode, metastate = keys[i][0], keys[i][1] keycode, metastate = keys[i][0], keys[i][1]
@ -348,49 +348,49 @@ class BaseView(object):
self.driver.press_keycode(keycode=keycode, metastate=metastate) self.driver.press_keycode(keycode=keycode, metastate=metastate)
def find_full_text(self, text, wait_time=60): def find_full_text(self, text, wait_time=60):
info("Looking for full text: '%s'" % text) self.driver.info("Looking for full text: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.text_selector(text) element.locator = element.Locator.text_selector(text)
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def find_text_part(self, text, wait_time=60): def find_text_part(self, text, wait_time=60):
info("Looking for a text part: '%s'" % text) self.driver.info("Looking for a text part: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.text_part_selector(text) element.locator = element.Locator.text_part_selector(text)
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def element_by_text(self, text, element_type='button'): def element_by_text(self, text, element_type='button'):
info("Looking for an element by text: '%s'" % text) self.driver.info("Looking for an element by text: '%s'" % text)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.text_selector(text) element.locator = element.Locator.text_selector(text)
return element return element
def element_by_text_part(self, text, element_type='button'): def element_by_text_part(self, text, element_type='button'):
info("Looking for an element by text part: '%s'" % text) self.driver.info("Looking for an element by text part: '%s'" % text)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.text_part_selector(text) element.locator = element.Locator.text_part_selector(text)
return element return element
def element_starts_with_text(self, text, element_type='base'): def element_starts_with_text(self, text, element_type='base'):
info("Looking for full text: '%s'" % text) self.driver.info("Looking for full text: '%s'" % text)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text) element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
return element return element
def wait_for_element_starts_with_text(self, text, wait_time=60): def wait_for_element_starts_with_text(self, text, wait_time=60):
info("Looking for full text: '%s'" % text) self.driver.info("Looking for full text: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text) element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def element_by_accessibility_id(self, accessibility_id, element_type='button'): def element_by_accessibility_id(self, accessibility_id, element_type='button'):
info("Looking for an element by accessibility id: '%s'" % accessibility_id) self.driver.info("Looking for an element by accessibility id: '%s'" % accessibility_id)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.accessibility_id(accessibility_id) element.locator = element.Locator.accessibility_id(accessibility_id)
return element return element
def element_by_xpath(self, xpath, element_type='button'): def element_by_xpath(self, xpath, element_type='button'):
info("Looking for an element by xpath: '%s'" % xpath) self.driver.info("Looking for an element by xpath: '%s'" % xpath)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.xpath_selector(xpath) element.locator = element.Locator.xpath_selector(xpath)
return element return element
@ -492,7 +492,7 @@ class BaseView(object):
connect_status.wait_for_invisibility_of_element() connect_status.wait_for_invisibility_of_element()
except TimeoutException as e: except TimeoutException as e:
if i == 2: if i == 2:
e.msg = "Can't reconnect to mail server after 3 attempts" e.msg = "Device %s: Can't reconnect to mail server after 3 attempts" % self.driver.number
raise e raise e
def check_no_values_in_logcat(self, **kwargs): def check_no_values_in_logcat(self, **kwargs):

View File

@ -1,8 +1,6 @@
import time import time
import pytest
from selenium.common.exceptions import TimeoutException, NoSuchElementException from selenium.common.exceptions import TimeoutException, NoSuchElementException
from tests import info
from views.base_element import BaseButton, BaseEditBox, BaseText from views.base_element import BaseButton, BaseEditBox, BaseText
from views.base_view import BaseView, ProgressBar from views.base_view import BaseView, ProgressBar
from views.profile_view import ProfilePictureElement, PublicKeyText from views.profile_view import ProfilePictureElement, PublicKeyText
@ -178,7 +176,7 @@ class ChatElementByText(BaseText):
"//*[starts-with(@text,'%s')]/ancestor::android.view.ViewGroup[@content-desc='chat-item']" % text) "//*[starts-with(@text,'%s')]/ancestor::android.view.ViewGroup[@content-desc='chat-item']" % text)
def find_element(self): def find_element(self):
info("Looking for message with text '%s'" % self.message_text) self.driver.info("Looking for message with text '%s'" % self.message_text)
for _ in range(2): for _ in range(2):
try: try:
return super(ChatElementByText, self).find_element() return super(ChatElementByText, self).find_element()
@ -272,11 +270,11 @@ class ChatView(BaseView):
self.public_key_text = PublicKeyText(self.driver) self.public_key_text = PublicKeyText(self.driver)
def wait_for_syncing_complete(self): def wait_for_syncing_complete(self):
info('Waiting for syncing complete:') self.driver.info('Waiting for syncing complete:')
while True: while True:
try: try:
sync = self.find_text_part('Syncing', 10) sync = self.find_text_part('Syncing', 10)
info(sync.text) self.driver.info(sync.text)
except TimeoutException: except TimeoutException:
break break
@ -345,7 +343,7 @@ class ChatView(BaseView):
chat_elem.wait_for_visibility_of_element() chat_elem.wait_for_visibility_of_element()
chat_elem.progress_bar.wait_for_invisibility_of_element(20) chat_elem.progress_bar.wait_for_invisibility_of_element(20)
if chat_elem.status.text not in ('Sent', 'Delivered', 'Seen'): if chat_elem.status.text not in ('Sent', 'Delivered', 'Seen'):
pytest.fail('Sent transaction message was not sent') self.driver.fail('Sent transaction message was not sent')
def send_transaction_in_group_chat(self, amount, password, recipient): def send_transaction_in_group_chat(self, amount, password, recipient):
self.commands_button.click() self.commands_button.click()
@ -368,7 +366,7 @@ class ChatView(BaseView):
self.send_message_button.click() self.send_message_button.click()
def chat_element_by_text(self, text): def chat_element_by_text(self, text):
info("Looking for a message by text: '%s'" % text) self.driver.info("Looking for a message by text: '%s'" % text)
return ChatElementByText(self.driver, text) return ChatElementByText(self.driver, text)
def verify_message_is_under_today_text(self, text, errors): def verify_message_is_under_today_text(self, text, errors):

View File

@ -1,4 +1,3 @@
from tests import info
import time import time
from selenium.common.exceptions import TimeoutException, NoSuchElementException from selenium.common.exceptions import TimeoutException, NoSuchElementException
from views.base_element import BaseButton, BaseText, BaseElement from views.base_element import BaseButton, BaseText, BaseElement
@ -45,7 +44,7 @@ class ChatElement(BaseButton):
return self.navigate() return self.navigate()
def find_element(self): def find_element(self):
info('Looking for %s' % self.name) self.driver.info('Looking for %s' % self.name)
for i in range(2): for i in range(2):
try: try:
return super(ChatElement, self).find_element() return super(ChatElement, self).find_element()
@ -53,7 +52,7 @@ class ChatElement(BaseButton):
if i == 0: if i == 0:
HomeView(self.driver).reconnect() HomeView(self.driver).reconnect()
else: else:
e.msg = 'Unable to find chat with user %s' % self.username e.msg = 'Device %s: Unable to find chat with user %s' % (self.driver.number, self.username)
raise e raise e
@property @property
@ -108,11 +107,11 @@ class HomeView(BaseView):
self.chat_url_text = ChatUrlText(self.driver) self.chat_url_text = ChatUrlText(self.driver)
def wait_for_syncing_complete(self): def wait_for_syncing_complete(self):
info('Waiting for syncing complete:') self.driver.info('Waiting for syncing complete:')
while True: while True:
try: try:
sync = self.find_text_part('Syncing', 10) sync = self.find_text_part('Syncing', 10)
info(sync.text) self.driver.info(sync.text)
except TimeoutException: except TimeoutException:
break break

View File

@ -1,5 +1,4 @@
import time import time
from tests import info
from tests.base_test_case import AbstractTestCase from tests.base_test_case import AbstractTestCase
from views.base_element import BaseText, BaseButton, BaseEditBox, BaseElement from views.base_element import BaseText, BaseButton, BaseEditBox, BaseElement
from views.base_view import BaseView from views.base_view import BaseView
@ -14,7 +13,7 @@ class PublicKeyText(BaseText):
@property @property
def text(self): def text(self):
text = self.scroll_to_element().text text = self.scroll_to_element().text
info('%s is %s' % (self.name, text)) self.driver.info('%s is %s' % (self.name, text))
return text return text
@ -166,7 +165,7 @@ class AdvancedButton(BaseButton):
def click(self): def click(self):
self.scroll_to_element().click() self.scroll_to_element().click()
info('Tap on %s' % self.name) self.driver.info('Tap on %s' % self.name)
return self.navigate() return self.navigate()

View File

@ -149,4 +149,5 @@ class SignInView(BaseView):
try: try:
self.account_button.find_elements()[position].click() self.account_button.find_elements()[position].click()
except IndexError: except IndexError:
raise NoSuchElementException('Unable to find account by position %s' % position) from None raise NoSuchElementException(
'Device %s: Unable to find account by position %s' % (self.driver.number, position)) from None

View File

@ -93,7 +93,7 @@ class TransactionTable(BaseElement):
except NoSuchElementException: except NoSuchElementException:
time.sleep(5) time.sleep(5)
self.refresh_transactions() self.refresh_transactions()
pytest.fail('Transaction was not found on Wallet/Transaction screen') self.driver.fail('Transaction was not found on Wallet/Transaction screen')
def refresh_transactions(self): def refresh_transactions(self):
self.driver.swipe(500, 500, 500, 1000) self.driver.swipe(500, 500, 500, 1000)

View File

@ -1,4 +1,3 @@
from tests import info
import time import time
from views.base_view import BaseView from views.base_view import BaseView
from views.base_element import BaseButton, BaseText from views.base_element import BaseButton, BaseText
@ -152,7 +151,7 @@ class AssetCheckBox(BaseButton):
def click(self): def click(self):
self.scroll_to_element().click() self.scroll_to_element().click()
info('Click %s asset checkbox' % self.asset_name) self.driver.info('Click %s asset checkbox' % self.asset_name)
class TotalAmountText(BaseText): class TotalAmountText(BaseText):
@ -228,21 +227,21 @@ class WalletView(BaseView):
if percentage_diff > 2: if percentage_diff > 2:
errors.append('Difference between current (%s) and expected (%s) USD balance > 2%%!!' % (usd, expected_usd)) errors.append('Difference between current (%s) and expected (%s) USD balance > 2%%!!' % (usd, expected_usd))
else: else:
info('Current USD balance %s is ok' % usd) self.driver.info('Current USD balance %s is ok' % usd)
def wait_balance_changed_on_wallet_screen(self, expected_balance=0.1, wait_time=300): def wait_balance_changed_on_wallet_screen(self, expected_balance=0.1, wait_time=300):
counter = 0 counter = 0
while True: while True:
if counter >= wait_time: if counter >= wait_time:
info('Balance is not changed during %s seconds!' % wait_time) self.driver.info('Balance is not changed during %s seconds!' % wait_time)
return return
elif self.get_eth_value() != expected_balance: elif self.get_eth_value() != expected_balance:
counter += 10 counter += 10
time.sleep(10) time.sleep(10)
self.swipe_down() self.swipe_down()
info('Waiting %s seconds for ETH update' % counter) self.driver.info('Waiting %s seconds for ETH update' % counter)
else: else:
info('Transaction received, balance updated!') self.driver.info('Transaction received, balance updated!')
return return
def get_sign_in_phrase(self): def get_sign_in_phrase(self):

View File

@ -87,7 +87,7 @@ class BaseWebView(BaseView):
time.sleep(1) time.sleep(1)
counter += 1 counter += 1
if counter > wait_time: if counter > wait_time:
pytest.fail("Page is not loaded during %s seconds" % wait_time) self.driver.fail("Page is not loaded during %s seconds" % wait_time)
def open_in_webview(self): def open_in_webview(self):
self.web_view_browser.click() self.web_view_browser.click()