2018-02-26 23:38:56 +00:00
|
|
|
import os
|
2023-10-18 03:16:05 +00:00
|
|
|
|
2018-04-26 12:34:15 +00:00
|
|
|
from support.base_test_report import BaseTestReport
|
2018-10-26 13:32:05 +00:00
|
|
|
from support.testrail_report import TestrailReport
|
2018-02-26 23:38:56 +00:00
|
|
|
|
2022-01-24 11:40:02 +00:00
|
|
|
|
2018-04-26 12:34:15 +00:00
|
|
|
class GithubHtmlReport(BaseTestReport):
|
2018-02-26 23:38:56 +00:00
|
|
|
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def __init__(self):
|
|
|
|
super(GithubHtmlReport, self).__init__()
|
2018-02-26 23:38:56 +00:00
|
|
|
|
2021-04-12 10:23:50 +00:00
|
|
|
def list_of_failed_testrail_ids(self, tests_data):
|
|
|
|
ids_failed_test = []
|
|
|
|
for i, test in enumerate(tests_data):
|
|
|
|
if test.testrail_case_id:
|
|
|
|
ids_failed_test.append(test.testrail_case_id)
|
|
|
|
return ','.join(map(str, ids_failed_test))
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def build_html_report(self, run_id):
|
2018-02-26 23:38:56 +00:00
|
|
|
tests = self.get_all_tests()
|
2023-10-18 03:16:05 +00:00
|
|
|
passed, failed, xfailed = self.get_tests_by_status()
|
2022-04-14 12:59:14 +00:00
|
|
|
not_executed_tests = TestrailReport().get_not_executed_tests(run_id)
|
2018-02-26 23:38:56 +00:00
|
|
|
|
|
|
|
if len(tests) > 0:
|
2023-10-18 03:16:05 +00:00
|
|
|
title_html = "## %.0f%% of end-end tests have passed\n" % (len(passed) / len(tests) * 100)
|
2018-02-26 23:38:56 +00:00
|
|
|
summary_html = "```\n"
|
|
|
|
summary_html += "Total executed tests: %d\n" % len(tests)
|
2023-10-18 03:16:05 +00:00
|
|
|
summary_html += "Failed tests: %d\n" % len(failed)
|
|
|
|
summary_html += "Expected to fail tests: %d\n" % len(xfailed)
|
|
|
|
summary_html += "Passed tests: %d\n" % len(passed)
|
2022-04-14 12:59:14 +00:00
|
|
|
if not_executed_tests:
|
|
|
|
summary_html += "Not executed tests: %d\n" % len(not_executed_tests)
|
2018-02-26 23:38:56 +00:00
|
|
|
summary_html += "```\n"
|
2023-01-13 11:09:33 +00:00
|
|
|
not_executed_tests_html = str()
|
|
|
|
failed_tests_html = str()
|
2023-10-18 03:16:05 +00:00
|
|
|
xfailed_tests_html = str()
|
2023-01-13 11:09:33 +00:00
|
|
|
passed_tests_html = str()
|
2022-04-14 12:59:14 +00:00
|
|
|
if not_executed_tests:
|
|
|
|
not_executed_tests_html = self.build_tests_table_html(not_executed_tests, run_id,
|
|
|
|
not_executed_tests=True)
|
|
|
|
summary_html += "```\n"
|
|
|
|
summary_html += 'IDs of not executed tests: %s \n' % ','.join([str(i) for i in not_executed_tests])
|
|
|
|
summary_html += "```\n"
|
2023-10-18 03:16:05 +00:00
|
|
|
if failed:
|
|
|
|
failed_tests_html = self.build_tests_table_html(failed, run_id, failed_tests=True)
|
|
|
|
summary_html += "```\n"
|
|
|
|
summary_html += 'IDs of failed tests: %s \n' % self.list_of_failed_testrail_ids(failed)
|
|
|
|
summary_html += "```\n"
|
|
|
|
if xfailed:
|
|
|
|
xfailed_tests_html = self.build_tests_table_html(xfailed, run_id, xfailed_tests=True)
|
2020-09-02 15:57:19 +00:00
|
|
|
summary_html += "```\n"
|
2023-10-18 03:16:05 +00:00
|
|
|
summary_html += 'IDs of expected to fail tests: %s \n' % self.list_of_failed_testrail_ids(xfailed)
|
2020-09-02 15:57:19 +00:00
|
|
|
summary_html += "```\n"
|
2023-10-18 03:16:05 +00:00
|
|
|
if passed:
|
|
|
|
passed_tests_html = self.build_tests_table_html(passed, run_id, failed_tests=False)
|
|
|
|
return title_html + summary_html + not_executed_tests_html + failed_tests_html + xfailed_tests_html \
|
|
|
|
+ passed_tests_html
|
2018-02-26 23:38:56 +00:00
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2023-10-18 03:16:05 +00:00
|
|
|
def build_tests_table_html(self, tests, run_id, failed_tests=False, xfailed_tests=False, not_executed_tests=False):
|
2022-04-14 12:59:14 +00:00
|
|
|
if failed_tests:
|
2023-01-13 11:09:33 +00:00
|
|
|
tests_type = "Failed tests"
|
2022-04-14 12:59:14 +00:00
|
|
|
elif not_executed_tests:
|
|
|
|
tests_type = "Not executed tests"
|
2023-10-18 03:16:05 +00:00
|
|
|
elif xfailed_tests:
|
|
|
|
tests_type = "Expected to fail tests"
|
2022-04-14 12:59:14 +00:00
|
|
|
else:
|
|
|
|
tests_type = "Passed tests"
|
2018-02-26 23:38:56 +00:00
|
|
|
html = "<h3>%s (%d)</h3>" % (tests_type, len(tests))
|
|
|
|
html += "<details>"
|
|
|
|
html += "<summary>Click to expand</summary>"
|
|
|
|
html += "<br/>"
|
2021-04-12 10:23:50 +00:00
|
|
|
|
2022-04-14 12:59:14 +00:00
|
|
|
from tests import pytest_config_global
|
|
|
|
pr_id = pytest_config_global['pr_number']
|
|
|
|
|
2024-04-17 00:46:59 +00:00
|
|
|
from github import Github
|
|
|
|
from conftest import github_token
|
|
|
|
branch_name = Github(github_token).get_user('status-im').get_repo('status-mobile').get_pull(int(pr_id)).head.ref
|
|
|
|
|
2022-04-14 12:59:14 +00:00
|
|
|
if not_executed_tests:
|
|
|
|
html += "<li><a href=\"%s\">Rerun not executed tests</a></li>" % self.get_jenkins_link_to_rerun_e2e(
|
2024-04-17 00:46:59 +00:00
|
|
|
branch_name=branch_name,
|
2022-04-14 12:59:14 +00:00
|
|
|
pr_id=pr_id,
|
|
|
|
tr_case_ids=','.join([str(i) for i in tests]))
|
|
|
|
|
2021-04-12 10:23:50 +00:00
|
|
|
if failed_tests:
|
2022-04-14 12:59:14 +00:00
|
|
|
html += "<li><a href=\"%s\">Rerun failed tests</a></li>" % self.get_jenkins_link_to_rerun_e2e(
|
2024-04-17 00:46:59 +00:00
|
|
|
branch_name=branch_name,
|
2022-04-14 12:59:14 +00:00
|
|
|
pr_id=pr_id,
|
2022-04-23 22:41:11 +00:00
|
|
|
tr_case_ids=','.join([str(test.testrail_case_id) for test in tests]))
|
2021-04-12 10:23:50 +00:00
|
|
|
|
2022-04-14 12:59:14 +00:00
|
|
|
if not not_executed_tests:
|
2022-07-21 04:07:38 +00:00
|
|
|
groups = {i: list() for i in set([test.group_name for test in tests])}
|
|
|
|
for i in tests:
|
|
|
|
groups[i.group_name].append(i)
|
|
|
|
|
2022-04-14 12:59:14 +00:00
|
|
|
html += "<br/>"
|
2022-07-21 04:07:38 +00:00
|
|
|
|
|
|
|
for class_name, tests_list in groups.items():
|
|
|
|
if class_name:
|
|
|
|
html += "<h4>Class %s:</h4>" % class_name
|
|
|
|
else:
|
|
|
|
html += "<h4>Single device tests:</h4>"
|
|
|
|
html += "<table style=\"width: 100%\">"
|
|
|
|
html += "<colgroup>"
|
|
|
|
html += "<col span=\"1\" style=\"width: 20%;\">"
|
|
|
|
html += "<col span=\"1\" style=\"width: 80%;\">"
|
|
|
|
html += "</colgroup>"
|
|
|
|
html += "<tbody>"
|
|
|
|
html += "<tr>"
|
|
|
|
html += "</tr>"
|
|
|
|
for i, test in enumerate(tests_list):
|
|
|
|
html += self.build_test_row_html(i, test, run_id)
|
|
|
|
html += "</tbody>"
|
|
|
|
html += "</table>"
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "</details>"
|
|
|
|
return html
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def build_test_row_html(self, index, test, run_id):
|
|
|
|
test_rail_link = TestrailReport().get_test_result_link(run_id, test.testrail_case_id)
|
|
|
|
if test_rail_link:
|
2022-01-24 11:40:02 +00:00
|
|
|
html = "<tr><td><b>%s. <a href=\"%s\">%s</a>, id: %s </b></td></tr>" % (
|
2022-04-14 12:59:14 +00:00
|
|
|
index + 1, test_rail_link, test.name, test.testrail_case_id)
|
2018-10-26 13:32:05 +00:00
|
|
|
else:
|
|
|
|
html = "<tr><td><b>%d. %s</b> (TestRail link is not found)</td></tr>" % (index + 1, test.name)
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "<tr><td>"
|
|
|
|
test_steps_html = list()
|
2018-04-28 09:02:39 +00:00
|
|
|
last_testrun = test.testruns[-1]
|
|
|
|
for step in last_testrun.steps:
|
2018-02-26 23:38:56 +00:00
|
|
|
test_steps_html.append("<div>%s</div>" % step)
|
2018-04-28 09:02:39 +00:00
|
|
|
if last_testrun.error:
|
2022-08-23 15:14:56 +00:00
|
|
|
error = last_testrun.error
|
2018-02-26 23:38:56 +00:00
|
|
|
if test_steps_html:
|
|
|
|
html += "<p>"
|
|
|
|
html += "<blockquote>"
|
|
|
|
# last 2 steps as summary
|
|
|
|
html += "%s" % ''.join(test_steps_html[-2:])
|
|
|
|
html += "</blockquote>"
|
|
|
|
html += "</p>"
|
2022-06-21 22:44:42 +00:00
|
|
|
code_error, no_code_error_str, _ = self.separate_xfail_error(error)
|
2022-06-14 14:02:48 +00:00
|
|
|
if no_code_error_str:
|
2022-08-23 15:14:56 +00:00
|
|
|
html += "\n\n```\n%s\n```\n\n" % code_error
|
2022-06-21 22:44:42 +00:00
|
|
|
html += "<b>%s</b>" % no_code_error_str
|
2022-06-14 14:02:48 +00:00
|
|
|
else:
|
2022-08-23 15:14:56 +00:00
|
|
|
html += "\n\n```\n%s\n```\n\n" % error.replace("[[", "<b>[[").replace("]]", "]]</b>")
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "<br/><br/>"
|
2024-04-17 00:46:59 +00:00
|
|
|
if last_testrun.jobs and not test.secured:
|
2022-01-24 11:40:02 +00:00
|
|
|
html += self.build_device_sessions_html(last_testrun)
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "</td></tr>"
|
|
|
|
return html
|
|
|
|
|
2022-01-24 11:40:02 +00:00
|
|
|
def build_device_sessions_html(self, test_run):
|
2018-08-15 12:51:52 +00:00
|
|
|
html = "<ins>Device sessions</ins>"
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "<p><ul>"
|
2022-01-24 11:40:02 +00:00
|
|
|
for job_id, i in test_run.jobs.items():
|
2018-08-29 12:01:44 +00:00
|
|
|
html += "<p>"
|
2018-08-15 12:51:52 +00:00
|
|
|
html += "Device %d:" % i
|
2018-08-29 12:01:44 +00:00
|
|
|
html += "<ul>"
|
2022-01-24 11:40:02 +00:00
|
|
|
if test_run.first_commands:
|
2024-06-25 16:06:19 +00:00
|
|
|
try:
|
|
|
|
first_command = test_run.first_commands[job_id]
|
|
|
|
except KeyError:
|
|
|
|
first_command = 0
|
2022-01-24 11:40:02 +00:00
|
|
|
else:
|
2024-06-25 16:06:19 +00:00
|
|
|
first_command = 0
|
|
|
|
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id, first_command)
|
2024-04-17 00:46:59 +00:00
|
|
|
# if test_run.error:
|
|
|
|
# html += "<li><a href=\"%s\">Failure screenshot</a></li>" % self.get_sauce_final_screenshot_url(job_id)
|
2018-08-29 12:01:44 +00:00
|
|
|
html += "</ul></p>"
|
2018-02-26 23:38:56 +00:00
|
|
|
html += "</ul></p>"
|
2022-04-14 12:59:14 +00:00
|
|
|
return html
|