2023-06-08 02:57:38 +00:00
|
|
|
import os
|
2022-11-03 11:26:53 +00:00
|
|
|
import re
|
2023-07-06 14:47:35 +00:00
|
|
|
import signal
|
2023-06-08 02:57:38 +00:00
|
|
|
import urllib.request
|
2023-07-06 14:47:35 +00:00
|
|
|
from contextlib import contextmanager
|
2022-11-03 11:26:53 +00:00
|
|
|
from dataclasses import dataclass
|
|
|
|
from datetime import datetime
|
|
|
|
from http.client import RemoteDisconnected
|
|
|
|
from os import environ
|
2023-02-02 11:16:34 +00:00
|
|
|
from time import sleep
|
2022-06-20 15:28:23 +00:00
|
|
|
|
2018-08-10 10:09:19 +00:00
|
|
|
import pytest
|
2018-04-28 09:02:39 +00:00
|
|
|
from _pytest.runner import runtestprotocol
|
2023-02-17 00:32:28 +00:00
|
|
|
from requests.exceptions import ConnectionError as c_er
|
2023-06-08 02:57:38 +00:00
|
|
|
|
2022-11-03 11:26:53 +00:00
|
|
|
import tests
|
2018-11-07 12:26:32 +00:00
|
|
|
from support.device_stats_db import DeviceStatsDB
|
2018-04-28 09:02:39 +00:00
|
|
|
from support.test_rerun import should_rerun_test
|
2018-11-07 12:26:32 +00:00
|
|
|
from tests import test_suite_data, appium_container
|
2017-08-31 13:39:41 +00:00
|
|
|
|
2021-01-13 10:14:32 +00:00
|
|
|
sauce_username = environ.get('SAUCE_USERNAME')
|
|
|
|
sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
|
2018-01-26 11:07:09 +00:00
|
|
|
github_token = environ.get('GIT_HUB_TOKEN')
|
|
|
|
|
2017-08-31 13:39:41 +00:00
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
def pytest_addoption(parser):
|
2017-08-31 13:39:41 +00:00
|
|
|
parser.addoption("--build",
|
|
|
|
action="store",
|
2018-04-25 17:02:03 +00:00
|
|
|
default=datetime.now().strftime('%Y-%m-%d-%H-%M'),
|
2017-08-28 10:02:20 +00:00
|
|
|
help="Specify build name")
|
2017-08-31 13:39:41 +00:00
|
|
|
parser.addoption('--apk',
|
|
|
|
action='store',
|
2018-04-30 09:58:20 +00:00
|
|
|
default=None,
|
2017-11-13 10:49:45 +00:00
|
|
|
help='Url or local path to apk')
|
2017-10-05 19:41:17 +00:00
|
|
|
parser.addoption('--env',
|
|
|
|
action='store',
|
|
|
|
default='sauce',
|
2018-06-07 15:13:37 +00:00
|
|
|
help='Specify environment: local/sauce/api')
|
2022-11-03 11:26:53 +00:00
|
|
|
parser.addoption('--datacenter',
|
|
|
|
action='store',
|
|
|
|
default='eu-central-1',
|
|
|
|
help='For sauce only: us-west-1, eu-central-1')
|
2018-11-07 12:26:32 +00:00
|
|
|
parser.addoption('--platform_version',
|
|
|
|
action='store',
|
2018-12-19 10:50:39 +00:00
|
|
|
default='8.0',
|
2018-11-07 12:26:32 +00:00
|
|
|
help='Android device platform version')
|
2019-05-23 09:04:41 +00:00
|
|
|
parser.addoption('--log_steps',
|
2017-11-13 10:49:45 +00:00
|
|
|
action='store',
|
|
|
|
default=False,
|
|
|
|
help='Display each test step in terminal as plain text: True/False')
|
2018-01-26 11:07:09 +00:00
|
|
|
parser.addoption('--pr_number',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Pull Request number')
|
2018-05-23 13:02:45 +00:00
|
|
|
parser.addoption('--testrail_report',
|
2018-04-26 12:34:15 +00:00
|
|
|
action='store',
|
|
|
|
default=False,
|
2018-05-23 13:02:45 +00:00
|
|
|
help='boolean; For creating testrail report per run')
|
2018-08-07 09:08:54 +00:00
|
|
|
parser.addoption('--network',
|
|
|
|
action='store',
|
|
|
|
default='ropsten',
|
|
|
|
help='string; ropsten or rinkeby')
|
2018-04-28 09:02:39 +00:00
|
|
|
parser.addoption('--rerun_count',
|
|
|
|
action='store',
|
|
|
|
default=0,
|
|
|
|
help='How many times tests should be re-run if failed')
|
2018-12-19 10:50:39 +00:00
|
|
|
parser.addoption("--run_testrail_ids",
|
|
|
|
action="store",
|
|
|
|
metavar="NAME",
|
|
|
|
default=None,
|
|
|
|
help="only run tests matching the environment NAME.")
|
2020-04-21 08:39:45 +00:00
|
|
|
parser.addoption("--apk_upgrade",
|
|
|
|
action="store",
|
|
|
|
metavar="NAME",
|
|
|
|
default=None,
|
|
|
|
help='Url or local path to apk for upgrade')
|
2018-11-30 11:42:48 +00:00
|
|
|
|
2018-12-19 10:50:39 +00:00
|
|
|
# chat bot
|
2018-11-30 11:42:48 +00:00
|
|
|
|
2018-03-31 20:05:11 +00:00
|
|
|
parser.addoption('--messages_number',
|
|
|
|
action='store',
|
|
|
|
default=20,
|
|
|
|
help='Messages number')
|
2018-09-03 21:18:18 +00:00
|
|
|
parser.addoption('--public_keys',
|
|
|
|
action='store',
|
2018-09-28 12:31:02 +00:00
|
|
|
default='',
|
2018-09-03 21:18:18 +00:00
|
|
|
help='List of public keys for one-to-one chats')
|
|
|
|
parser.addoption('--running_time',
|
|
|
|
action='store',
|
2018-09-14 13:35:37 +00:00
|
|
|
default=600,
|
2018-09-03 21:18:18 +00:00
|
|
|
help='Running time in seconds')
|
2019-06-03 12:02:39 +00:00
|
|
|
parser.addoption('--chat_name',
|
|
|
|
action='store',
|
|
|
|
default='test_chat',
|
|
|
|
help='Public chat name')
|
|
|
|
parser.addoption('--device_number',
|
|
|
|
action='store',
|
|
|
|
default=2,
|
|
|
|
help='Public chat name')
|
2018-09-03 21:18:18 +00:00
|
|
|
|
2018-11-07 12:26:32 +00:00
|
|
|
# running tests using appium docker instance
|
|
|
|
|
|
|
|
parser.addoption('--docker',
|
|
|
|
action='store',
|
|
|
|
default=False,
|
|
|
|
help='Are you using the appium docker container to run the tests?')
|
|
|
|
parser.addoption('--docker_shared_volume',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Path to a directory with .apk that will be shared with docker instance. Test reports will be also saved there')
|
|
|
|
parser.addoption('--device_ip',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Android device IP address used for battery tests')
|
|
|
|
parser.addoption('--bugreport',
|
|
|
|
action='store',
|
|
|
|
default=False,
|
|
|
|
help='Should generate bugreport for each test?')
|
|
|
|
parser.addoption('--stats_db_host',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Host address for device stats database')
|
|
|
|
parser.addoption('--stats_db_port',
|
|
|
|
action='store',
|
|
|
|
default=8086,
|
|
|
|
help='Port for device stats db')
|
|
|
|
parser.addoption('--stats_db_username',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Username for device stats db')
|
|
|
|
parser.addoption('--stats_db_password',
|
|
|
|
action='store',
|
|
|
|
default=None,
|
|
|
|
help='Password for device stats db')
|
|
|
|
parser.addoption('--stats_db_database',
|
|
|
|
action='store',
|
|
|
|
default='example9',
|
|
|
|
help='Database name for device stats db')
|
|
|
|
|
2018-04-28 09:02:39 +00:00
|
|
|
|
2022-11-03 11:26:53 +00:00
|
|
|
@dataclass
|
|
|
|
class Option:
|
|
|
|
datacenter: str = None
|
|
|
|
|
|
|
|
|
|
|
|
option = Option()
|
|
|
|
testrail_report = None
|
|
|
|
github_report = None
|
2023-02-02 11:16:34 +00:00
|
|
|
apibase = None
|
|
|
|
sauce = None
|
2022-11-03 11:26:53 +00:00
|
|
|
|
|
|
|
|
2017-08-31 13:39:41 +00:00
|
|
|
def is_master(config):
|
2021-01-19 15:23:33 +00:00
|
|
|
return not hasattr(config, 'workerinput')
|
2017-08-31 13:39:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def is_uploaded():
|
2023-02-02 11:16:34 +00:00
|
|
|
stored_files = sauce.storage.files()
|
|
|
|
for i in range(len(stored_files)):
|
|
|
|
if stored_files[i].name == test_suite_data.apk_name:
|
2017-08-31 13:39:41 +00:00
|
|
|
return True
|
|
|
|
|
2023-06-08 02:57:38 +00:00
|
|
|
|
2023-11-15 12:42:03 +00:00
|
|
|
@contextmanager
|
|
|
|
def _upload_time_limit(seconds):
|
|
|
|
def signal_handler(signum, frame):
|
|
|
|
raise TimeoutError("Apk upload took more than %s seconds" % seconds)
|
|
|
|
|
|
|
|
signal.signal(signal.SIGALRM, signal_handler)
|
|
|
|
signal.alarm(seconds)
|
|
|
|
try:
|
|
|
|
yield
|
|
|
|
finally:
|
|
|
|
signal.alarm(0)
|
|
|
|
|
|
|
|
class UploadApkException(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _upload_and_check_response(apk_file_path):
|
|
|
|
with _upload_time_limit(600):
|
|
|
|
with open(apk_file_path, 'rb') as f:
|
|
|
|
resp = sauce.storage._session.request('post', '/v1/storage/upload', files={'payload': f})
|
|
|
|
|
|
|
|
try:
|
|
|
|
if resp['item']['name'] != test_suite_data.apk_name:
|
|
|
|
raise UploadApkException("Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp)
|
|
|
|
except KeyError:
|
|
|
|
raise UploadApkException("Error when uploading apk to Sauce storage, response:\n%s" % resp)
|
|
|
|
|
|
|
|
def _upload_and_check_response_with_retries(apk_file_path, retries=3):
|
|
|
|
for _ in range(retries):
|
|
|
|
try:
|
|
|
|
_upload_and_check_response(apk_file_path)
|
|
|
|
break
|
|
|
|
except (ConnectionError, RemoteDisconnected):
|
|
|
|
sleep(10)
|
|
|
|
|
2017-08-31 13:39:41 +00:00
|
|
|
def pytest_configure(config):
|
2022-11-03 11:26:53 +00:00
|
|
|
global option
|
|
|
|
option = config.option
|
|
|
|
from support.testrail_report import TestrailReport
|
|
|
|
global testrail_report
|
|
|
|
testrail_report = TestrailReport()
|
|
|
|
from support.github_report import GithubHtmlReport
|
|
|
|
global github_report
|
2023-02-02 11:16:34 +00:00
|
|
|
from saucelab_api_client.saucelab_api_client import SauceLab
|
2022-11-03 11:26:53 +00:00
|
|
|
github_report = GithubHtmlReport()
|
2019-11-29 11:48:07 +00:00
|
|
|
tests.pytest_config_global = vars(config.option)
|
2018-12-19 10:50:39 +00:00
|
|
|
config.addinivalue_line("markers", "testrail_id(name): empty")
|
2023-02-02 11:16:34 +00:00
|
|
|
global apibase
|
|
|
|
if config.getoption('datacenter') == 'us-west-1':
|
2023-02-24 19:05:30 +00:00
|
|
|
apibase = 'us-west-1.saucelabs.com'
|
2023-02-02 11:16:34 +00:00
|
|
|
elif config.getoption('datacenter') == 'eu-central-1':
|
|
|
|
apibase = 'eu-central-1.saucelabs.com'
|
|
|
|
else:
|
|
|
|
raise NotImplementedError("Unknown SauceLabs datacenter")
|
2023-11-15 12:42:03 +00:00
|
|
|
|
2023-02-02 11:16:34 +00:00
|
|
|
global sauce
|
2023-06-08 02:57:38 +00:00
|
|
|
sauce = SauceLab('https://api.' + apibase + '/', sauce_username, sauce_access_key)
|
2019-05-23 09:04:41 +00:00
|
|
|
if config.getoption('log_steps'):
|
2017-11-13 10:49:45 +00:00
|
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
2023-11-15 12:42:03 +00:00
|
|
|
if config.getoption('env') == 'api':
|
|
|
|
return
|
|
|
|
|
|
|
|
test_suite_data.apk_name = ([i for i in [i for i in config.getoption('apk').split('/')
|
|
|
|
if '.apk' in i]])[0]
|
|
|
|
if not is_master(config):
|
|
|
|
return
|
|
|
|
|
|
|
|
pr_number = config.getoption('pr_number')
|
|
|
|
if config.getoption('testrail_report'):
|
|
|
|
if pr_number:
|
|
|
|
run_number = len(testrail_report.get_runs(pr_number)) + 1
|
|
|
|
run_name = 'PR-%s run #%s' % (pr_number, run_number)
|
|
|
|
else:
|
|
|
|
run_name = test_suite_data.apk_name
|
|
|
|
testrail_report.add_run(run_name)
|
|
|
|
|
|
|
|
if pr_number:
|
|
|
|
from github import Github
|
|
|
|
repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
|
|
|
|
pull = repo.get_pull(int(pr_number))
|
|
|
|
pull.get_commits()[0].create_status(
|
|
|
|
state='pending',
|
|
|
|
context='Mobile e2e tests',
|
|
|
|
description='e2e tests are running'
|
|
|
|
)
|
|
|
|
|
|
|
|
if config.getoption('env') == 'sauce' and not is_uploaded():
|
|
|
|
apk_src = config.getoption('apk')
|
|
|
|
if apk_src.startsWith('http'):
|
|
|
|
# Absolute path adde to handle CI runs.
|
|
|
|
apk_path = os.path.join(os.path.dirname(__file__), test_suite_data.apk_name)
|
|
|
|
urllib.request.urlretrieve(apk_src, filename=apk_path)
|
|
|
|
else:
|
|
|
|
apk_path = apk_src
|
|
|
|
|
|
|
|
_upload_and_check_response_with_retries(apk_path)
|
|
|
|
if apk_src.startsWith('http'):
|
|
|
|
os.remove(apk_path)
|
2018-01-26 11:07:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pytest_unconfigure(config):
|
2018-04-26 12:34:15 +00:00
|
|
|
if is_master(config):
|
2018-10-26 13:32:05 +00:00
|
|
|
if config.getoption('testrail_report'):
|
|
|
|
testrail_report.add_results()
|
2018-04-26 12:34:15 +00:00
|
|
|
if config.getoption('pr_number'):
|
|
|
|
from github import Github
|
2022-07-17 12:37:46 +00:00
|
|
|
repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
|
2018-04-26 12:34:15 +00:00
|
|
|
pull = repo.get_pull(int(config.getoption('pr_number')))
|
2018-11-24 16:18:31 +00:00
|
|
|
comment = pull.create_issue_comment(github_report.build_html_report(testrail_report.run_id))
|
|
|
|
if not testrail_report.is_run_successful():
|
|
|
|
pull.get_commits()[0].create_status(state='failure', context='Mobile e2e tests',
|
|
|
|
description='Failure - e2e tests are failed',
|
|
|
|
target_url=comment.html_url)
|
|
|
|
else:
|
|
|
|
pull.get_commits()[0].create_status(state='success', context='Mobile e2e tests',
|
|
|
|
description='Success - e2e tests are passed',
|
|
|
|
target_url=comment.html_url)
|
2018-01-26 11:07:09 +00:00
|
|
|
|
|
|
|
|
2018-11-28 09:57:18 +00:00
|
|
|
def should_save_device_stats(config):
|
|
|
|
db_args = [config.getoption(option) for option in
|
|
|
|
('stats_db_host', 'stats_db_port', 'stats_db_username', 'stats_db_password', 'stats_db_database')]
|
|
|
|
return all(db_args)
|
|
|
|
|
|
|
|
|
2023-09-06 03:07:12 +00:00
|
|
|
@pytest.hookimpl(hookwrapper=True)
|
2018-01-26 11:07:09 +00:00
|
|
|
def pytest_runtest_makereport(item, call):
|
|
|
|
outcome = yield
|
|
|
|
report = outcome.get_result()
|
2022-06-14 14:02:48 +00:00
|
|
|
|
2022-06-17 00:57:19 +00:00
|
|
|
is_sauce_env = item.config.getoption('env') == 'sauce'
|
2022-12-30 14:34:19 +00:00
|
|
|
case_ids_set = item.config.getoption("run_testrail_ids")
|
2022-06-17 00:57:19 +00:00
|
|
|
|
2022-06-14 14:02:48 +00:00
|
|
|
def catch_error():
|
2022-05-05 22:00:06 +00:00
|
|
|
error = report.longreprtext
|
2022-06-14 14:02:48 +00:00
|
|
|
failure_pattern = 'E.*Message:|E.*Error:|E.*Failed:'
|
|
|
|
exception = re.findall(failure_pattern, error)
|
2022-05-05 22:00:06 +00:00
|
|
|
if exception:
|
2022-06-14 14:02:48 +00:00
|
|
|
error = error.replace(re.findall(failure_pattern, report.longreprtext)[0], '')
|
|
|
|
return error
|
|
|
|
|
|
|
|
if report.when == 'setup':
|
2022-06-17 00:57:19 +00:00
|
|
|
is_group = "xdist_group" in item.keywords._markers or "xdist_group" in item.parent.keywords._markers
|
2022-06-14 14:02:48 +00:00
|
|
|
error_intro, error = 'Test setup failed:', ''
|
|
|
|
final_error = '%s %s' % (error_intro, error)
|
2023-06-08 02:57:38 +00:00
|
|
|
if (hasattr(report, 'wasxfail') and not case_ids_set) or (hasattr(report, 'wasxfail') and (
|
|
|
|
str([mark.args[0] for mark in item.iter_markers(name='testrail_id')][0]) in str(case_ids_set))):
|
2022-06-14 14:02:48 +00:00
|
|
|
if '[NOTRUN]' in report.wasxfail:
|
|
|
|
test_suite_data.set_current_test(item.name, testrail_case_id=get_testrail_case_id(item))
|
|
|
|
test_suite_data.current_test.create_new_testrun()
|
2022-06-17 00:57:19 +00:00
|
|
|
if is_group:
|
2022-06-14 14:02:48 +00:00
|
|
|
test_suite_data.current_test.group_name = item.instance.__class__.__name__
|
2023-10-18 03:16:05 +00:00
|
|
|
test_suite_data.current_test.testruns[-1].xfail = report.wasxfail
|
2022-06-14 14:02:48 +00:00
|
|
|
error_intro, error = 'Test is not run, e2e blocker ', report.wasxfail
|
|
|
|
final_error = "%s [[%s]]" % (error_intro, error)
|
|
|
|
else:
|
2022-06-17 00:57:19 +00:00
|
|
|
if is_group:
|
2022-06-14 14:02:48 +00:00
|
|
|
test_suite_data.current_test.group_name = item.instance.__class__.__name__
|
|
|
|
error = catch_error()
|
|
|
|
final_error = '%s %s [[%s]]' % (error_intro, error, report.wasxfail)
|
|
|
|
else:
|
2022-06-17 00:57:19 +00:00
|
|
|
if is_group and report.failed:
|
2022-06-14 14:02:48 +00:00
|
|
|
test_suite_data.current_test.group_name = item.instance.__class__.__name__
|
|
|
|
error = catch_error()
|
|
|
|
final_error = '%s %s' % (error_intro, error)
|
2022-06-17 00:57:19 +00:00
|
|
|
if is_sauce_env:
|
|
|
|
update_sauce_jobs(test_suite_data.current_test.group_name,
|
|
|
|
test_suite_data.current_test.testruns[-1].jobs,
|
|
|
|
report.passed)
|
2022-06-14 14:02:48 +00:00
|
|
|
if error:
|
|
|
|
test_suite_data.current_test.testruns[-1].error = final_error
|
2023-06-08 02:57:38 +00:00
|
|
|
github_report.save_test(test_suite_data.current_test)
|
2022-06-14 14:02:48 +00:00
|
|
|
|
2018-02-26 23:38:56 +00:00
|
|
|
if report.when == 'call':
|
2018-04-28 09:02:39 +00:00
|
|
|
current_test = test_suite_data.current_test
|
2022-06-14 14:02:48 +00:00
|
|
|
error = catch_error()
|
2018-02-26 23:38:56 +00:00
|
|
|
if report.failed:
|
2018-08-10 10:09:19 +00:00
|
|
|
current_test.testruns[-1].error = error
|
2023-06-08 02:57:38 +00:00
|
|
|
if (hasattr(report, 'wasxfail') and not case_ids_set) or (hasattr(report, 'wasxfail') and (
|
|
|
|
str([mark.args[0] for mark in item.iter_markers(name='testrail_id')][0]) in str(case_ids_set))):
|
2022-06-14 14:02:48 +00:00
|
|
|
current_test.testruns[-1].xfail = report.wasxfail
|
|
|
|
if error:
|
|
|
|
current_test.testruns[-1].error = '%s [[%s]]' % (error, report.wasxfail)
|
2018-02-26 23:38:56 +00:00
|
|
|
if is_sauce_env:
|
2018-04-28 09:02:39 +00:00
|
|
|
update_sauce_jobs(current_test.name, current_test.testruns[-1].jobs, report.passed)
|
2019-11-29 11:48:07 +00:00
|
|
|
if item.config.getoption('docker'):
|
2018-11-07 12:26:32 +00:00
|
|
|
device_stats = appium_container.get_device_stats()
|
2019-11-29 11:48:07 +00:00
|
|
|
if item.config.getoption('bugreport'):
|
2018-11-07 12:26:32 +00:00
|
|
|
appium_container.generate_bugreport(item.name)
|
|
|
|
|
2019-11-29 11:48:07 +00:00
|
|
|
build_name = item.config.getoption('apk')
|
2018-11-07 12:26:32 +00:00
|
|
|
# Find type of tests that are run on the device
|
|
|
|
if 'battery_consumption' in item.keywords._markers:
|
|
|
|
test_group = 'battery_consumption'
|
|
|
|
else:
|
|
|
|
test_group = None
|
|
|
|
|
2018-11-28 09:57:18 +00:00
|
|
|
if should_save_device_stats(item.config):
|
|
|
|
device_stats_db = DeviceStatsDB(
|
|
|
|
item.config.getoption('stats_db_host'),
|
|
|
|
item.config.getoption('stats_db_port'),
|
|
|
|
item.config.getoption('stats_db_username'),
|
|
|
|
item.config.getoption('stats_db_password'),
|
|
|
|
item.config.getoption('stats_db_database'),
|
|
|
|
)
|
|
|
|
device_stats_db.save_stats(build_name, item.name, test_group, not report.failed, device_stats)
|
2018-02-26 23:38:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def update_sauce_jobs(test_name, job_ids, passed):
|
2023-02-02 11:16:34 +00:00
|
|
|
from sauceclient import SauceException
|
2018-08-15 12:51:52 +00:00
|
|
|
for job_id in job_ids.keys():
|
2018-11-29 18:16:26 +00:00
|
|
|
try:
|
2023-02-02 11:16:34 +00:00
|
|
|
sauce.jobs.update_job(username=sauce_username, job_id=job_id, name=test_name, passed=passed)
|
2023-02-17 00:32:28 +00:00
|
|
|
except (RemoteDisconnected, SauceException, c_er):
|
2018-11-29 18:16:26 +00:00
|
|
|
pass
|
2017-11-13 10:49:45 +00:00
|
|
|
|
|
|
|
|
2018-12-19 10:50:39 +00:00
|
|
|
def get_testrail_case_id(item):
|
|
|
|
testrail_id = item.get_closest_marker('testrail_id')
|
2018-10-15 07:06:21 +00:00
|
|
|
if testrail_id:
|
|
|
|
return testrail_id.args[0]
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
|
2017-11-13 10:49:45 +00:00
|
|
|
def pytest_runtest_setup(item):
|
2019-06-03 12:02:39 +00:00
|
|
|
try:
|
|
|
|
testrail_id = [mark.args[0] for mark in item.iter_markers(name='testrail_id')][0]
|
|
|
|
except IndexError:
|
|
|
|
pass
|
2018-12-19 10:50:39 +00:00
|
|
|
run_testrail_ids = item.config.getoption("run_testrail_ids")
|
|
|
|
if run_testrail_ids:
|
2021-05-07 09:19:05 +00:00
|
|
|
if str(testrail_id) not in list(run_testrail_ids.split(",")):
|
2018-12-19 10:50:39 +00:00
|
|
|
pytest.skip("test requires testrail case id %s" % testrail_id)
|
2018-04-28 09:02:39 +00:00
|
|
|
test_suite_data.set_current_test(item.name, testrail_case_id=get_testrail_case_id(item))
|
|
|
|
test_suite_data.current_test.create_new_testrun()
|
|
|
|
|
|
|
|
|
|
|
|
def pytest_runtest_protocol(item, nextitem):
|
2018-10-15 15:38:42 +00:00
|
|
|
rerun_count = int(item.config.getoption('rerun_count'))
|
2018-10-15 07:06:21 +00:00
|
|
|
for i in range(rerun_count):
|
2018-04-28 09:02:39 +00:00
|
|
|
reports = runtestprotocol(item, nextitem=nextitem)
|
|
|
|
for report in reports:
|
2021-12-15 19:14:16 +00:00
|
|
|
is_in_group = [i for i in item.iter_markers(name='xdist_group')]
|
|
|
|
if report.failed and should_rerun_test(report.longreprtext) and not is_in_group:
|
2018-04-28 09:02:39 +00:00
|
|
|
break # rerun
|
|
|
|
else:
|
|
|
|
return True # no need to rerun
|
2018-03-31 20:05:11 +00:00
|
|
|
|
|
|
|
|
2022-09-08 14:27:38 +00:00
|
|
|
# @pytest.fixture(scope="session", autouse=False)
|
|
|
|
# def faucet_for_senders():
|
|
|
|
# network_api = NetworkApi()
|
|
|
|
# for user in transaction_senders.values():
|
|
|
|
# network_api.faucet(address=user['address'])
|
2018-09-17 08:50:01 +00:00
|
|
|
|
|
|
|
|
2018-03-31 20:05:11 +00:00
|
|
|
@pytest.fixture
|
2018-10-15 07:06:21 +00:00
|
|
|
def messages_number(request):
|
|
|
|
return int(request.config.getoption('messages_number'))
|
2018-03-31 20:05:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2018-10-15 07:06:21 +00:00
|
|
|
def message_wait_time(request):
|
|
|
|
return int(request.config.getoption('message_wait_time'))
|
2018-03-31 20:05:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2018-10-15 07:06:21 +00:00
|
|
|
def participants_number(request):
|
|
|
|
return int(request.config.getoption('participants_number'))
|
2018-06-05 15:12:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2018-10-15 07:06:21 +00:00
|
|
|
def chat_name(request):
|
|
|
|
return request.config.getoption('chat_name')
|
2018-06-05 15:12:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2018-10-15 07:06:21 +00:00
|
|
|
def user_public_key(request):
|
|
|
|
return request.config.getoption('user_public_key')
|