2018-04-26 12:34:15 +00:00
|
|
|
import hmac
|
2023-06-08 02:57:38 +00:00
|
|
|
import json
|
2018-04-26 12:34:15 +00:00
|
|
|
import os
|
2022-06-14 14:02:48 +00:00
|
|
|
import re
|
2024-04-19 15:33:19 +00:00
|
|
|
import urllib
|
2023-06-08 02:57:38 +00:00
|
|
|
from hashlib import md5
|
|
|
|
|
2018-04-28 09:02:39 +00:00
|
|
|
from support.test_data import SingleTestData
|
2023-02-02 11:16:34 +00:00
|
|
|
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
class BaseTestReport:
|
|
|
|
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.sauce_username = os.environ.get('SAUCE_USERNAME')
|
|
|
|
self.sauce_access_key = os.environ.get('SAUCE_ACCESS_KEY')
|
2018-04-26 12:34:15 +00:00
|
|
|
self.init_report()
|
|
|
|
|
|
|
|
def init_report(self):
|
|
|
|
if not os.path.exists(self.TEST_REPORT_DIR):
|
|
|
|
os.makedirs(self.TEST_REPORT_DIR)
|
|
|
|
# delete all old files in report dir
|
|
|
|
file_list = [f for f in os.listdir(self.TEST_REPORT_DIR)]
|
|
|
|
for f in file_list:
|
|
|
|
os.remove(os.path.join(self.TEST_REPORT_DIR, f))
|
|
|
|
|
|
|
|
def get_test_report_file_path(self, test_name):
|
|
|
|
file_name = "%s.json" % test_name
|
|
|
|
return os.path.join(self.TEST_REPORT_DIR, file_name)
|
|
|
|
|
2024-09-17 19:31:34 +00:00
|
|
|
def save_logs(self, logs: dict):
|
|
|
|
logs_paths = {}
|
|
|
|
for log in logs.keys():
|
|
|
|
log_path = os.path.join(self.TEST_REPORT_DIR, log)
|
|
|
|
result = open(log_path, 'wb')
|
|
|
|
result.write(logs[log])
|
2021-11-11 11:40:31 +00:00
|
|
|
result.close()
|
2024-09-17 19:31:34 +00:00
|
|
|
logs_paths[log] = log_path
|
|
|
|
return logs_paths
|
2022-01-24 11:40:02 +00:00
|
|
|
|
2024-09-17 19:31:34 +00:00
|
|
|
def save_test(self, test, geth: dict = None, requests_log: dict = None):
|
|
|
|
for log in geth, requests_log:
|
|
|
|
if log:
|
|
|
|
logs_paths = self.save_logs(log)
|
2022-06-14 14:02:48 +00:00
|
|
|
else:
|
2024-09-17 19:31:34 +00:00
|
|
|
if hasattr(test, 'logs_paths'):
|
|
|
|
logs_paths = test.logs_paths
|
|
|
|
else:
|
|
|
|
logs_paths = ''
|
|
|
|
|
2022-01-24 11:40:02 +00:00
|
|
|
file_path = self.get_test_report_file_path(test.name)
|
2018-04-28 09:02:39 +00:00
|
|
|
test_dict = {
|
|
|
|
'testrail_case_id': test.testrail_case_id,
|
|
|
|
'name': test.name,
|
2024-09-17 19:31:34 +00:00
|
|
|
'logs_paths': logs_paths,
|
2022-04-14 12:59:14 +00:00
|
|
|
'testruns': list(),
|
2024-04-17 00:46:59 +00:00
|
|
|
'group_name': test.group_name,
|
|
|
|
'secured': test.secured
|
2018-04-28 09:02:39 +00:00
|
|
|
}
|
|
|
|
for testrun in test.testruns:
|
|
|
|
test_dict['testruns'].append(testrun.__dict__)
|
|
|
|
json.dump(test_dict, open(file_path, 'w'))
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
def get_all_tests(self):
|
|
|
|
tests = list()
|
2021-11-11 11:40:31 +00:00
|
|
|
file_list = [f for f in os.listdir(self.TEST_REPORT_DIR) if f.endswith('json')]
|
2018-04-26 12:34:15 +00:00
|
|
|
for file_name in file_list:
|
|
|
|
file_path = os.path.join(self.TEST_REPORT_DIR, file_name)
|
2018-04-28 09:02:39 +00:00
|
|
|
test_data = json.load(open(file_path))
|
|
|
|
testruns = list()
|
|
|
|
for testrun_data in test_data['testruns']:
|
|
|
|
testruns.append(SingleTestData.TestRunData(
|
2021-11-11 11:40:31 +00:00
|
|
|
steps=testrun_data['steps'],
|
|
|
|
jobs=testrun_data['jobs'],
|
2022-01-24 11:40:02 +00:00
|
|
|
error=testrun_data['error'],
|
2022-06-14 14:02:48 +00:00
|
|
|
first_commands=testrun_data['first_commands'],
|
|
|
|
xfail=testrun_data['xfail']))
|
2021-11-11 11:40:31 +00:00
|
|
|
tests.append(SingleTestData(name=test_data['name'],
|
2024-09-17 19:31:34 +00:00
|
|
|
logs_paths=test_data['logs_paths'],
|
2021-11-11 11:40:31 +00:00
|
|
|
testruns=testruns,
|
2022-04-14 12:59:14 +00:00
|
|
|
testrail_case_id=test_data['testrail_case_id'],
|
2024-04-17 00:46:59 +00:00
|
|
|
grop_name=test_data['group_name'],
|
|
|
|
secured=test_data['secured']))
|
2018-04-26 12:34:15 +00:00
|
|
|
return tests
|
|
|
|
|
2023-10-18 03:16:05 +00:00
|
|
|
def get_tests_by_status(self):
|
2018-04-26 12:34:15 +00:00
|
|
|
tests = self.get_all_tests()
|
2023-10-18 03:16:05 +00:00
|
|
|
passed, failed, xfailed = list(), list(), list()
|
2018-04-26 12:34:15 +00:00
|
|
|
for test in tests:
|
2018-04-28 09:02:39 +00:00
|
|
|
if self.is_test_successful(test):
|
2018-04-26 12:34:15 +00:00
|
|
|
passed.append(test)
|
2023-10-18 03:16:05 +00:00
|
|
|
else:
|
|
|
|
if test.testruns[-1].xfail:
|
|
|
|
xfailed.append(test)
|
|
|
|
else:
|
|
|
|
failed.append(test)
|
|
|
|
return passed, failed, xfailed
|
2018-04-26 12:34:15 +00:00
|
|
|
|
2018-08-15 12:51:52 +00:00
|
|
|
def get_sauce_token(self, job_id):
|
|
|
|
return hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'),
|
|
|
|
bytes(job_id, 'latin-1'), md5).hexdigest()
|
|
|
|
|
2022-01-24 11:40:02 +00:00
|
|
|
def get_sauce_job_url(self, job_id, first_command=0):
|
2018-08-15 12:51:52 +00:00
|
|
|
token = self.get_sauce_token(job_id)
|
2023-02-02 11:16:34 +00:00
|
|
|
from tests.conftest import apibase
|
2022-11-03 11:26:53 +00:00
|
|
|
url = 'https://%s/jobs/%s?auth=%s' % (apibase, job_id, token)
|
2022-01-24 11:40:02 +00:00
|
|
|
if first_command > 0:
|
|
|
|
url += "#%s" % first_command
|
|
|
|
return url
|
2018-08-15 12:51:52 +00:00
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
@staticmethod
|
2023-02-08 14:51:57 +00:00
|
|
|
def get_jenkins_link_to_rerun_e2e(branch_name="develop", pr_id="", tr_case_ids=""):
|
2024-04-19 15:33:19 +00:00
|
|
|
branch_name = urllib.parse.quote(branch_name)
|
2022-07-17 12:37:46 +00:00
|
|
|
return 'https://ci.status.im/job/status-mobile/job/e2e/job/status-app-prs-rerun/parambuild/' \
|
2024-04-19 15:33:19 +00:00
|
|
|
'?BRANCH_NAME=%s&PR_ID=%s&APK_NAME=%s.apk&TR_CASE_IDS=%s' % (branch_name, pr_id, pr_id, tr_case_ids)
|
2021-04-12 10:23:50 +00:00
|
|
|
|
2018-08-15 12:51:52 +00:00
|
|
|
def get_sauce_final_screenshot_url(self, job_id):
|
2023-02-02 11:16:34 +00:00
|
|
|
return 'https://media.giphy.com/media/9M5jK4GXmD5o1irGrF/giphy.gif'
|
|
|
|
# temp blocked, no sense with groups
|
|
|
|
# from tests.conftest import sauce, apibase
|
|
|
|
# token = self.get_sauce_token(job_id)
|
|
|
|
# username = sauce.accounts.account_user.get_active_user().username
|
|
|
|
# for _ in range(10):
|
|
|
|
# try:
|
|
|
|
# scr_number = sauce.jobs.get_job_assets(username=username, job_id=job_id)['screenshots'][-1]
|
|
|
|
# return 'https://assets.%s/jobs/%s/%s?auth=%s' % (apibase, job_id, scr_number, token)
|
|
|
|
# except SauceException:
|
|
|
|
# time.sleep(3)
|
2018-04-28 09:02:39 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def is_test_successful(test):
|
|
|
|
# Test passed if last testrun has passed
|
2022-06-14 14:02:48 +00:00
|
|
|
return test.testruns[-1].error is None
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def separate_xfail_error(error):
|
|
|
|
issue_id_list = re.findall(r'#\d+', error)
|
2022-06-21 22:44:42 +00:00
|
|
|
issue_id = issue_id_list[0] if issue_id_list else ''
|
|
|
|
|
|
|
|
xfail_error = re.findall(r'\[\[.*\]\]', error)
|
|
|
|
if xfail_error:
|
|
|
|
no_code_error_str = xfail_error[0]
|
|
|
|
main_error = error.replace(no_code_error_str, '')
|
|
|
|
else:
|
|
|
|
no_code_error_str = ''
|
|
|
|
main_error = error
|
|
|
|
|
|
|
|
return main_error, no_code_error_str, issue_id
|