mirror of
https://github.com/status-im/status-react.git
synced 2025-02-04 07:06:18 +00:00
e2e: shared steps for session
This commit is contained in:
parent
012b3e396e
commit
7bbb882ffa
@ -28,8 +28,7 @@ class BaseTestReport:
|
|||||||
file_name = "%s.json" % test_name
|
file_name = "%s.json" % test_name
|
||||||
return os.path.join(self.TEST_REPORT_DIR, file_name)
|
return os.path.join(self.TEST_REPORT_DIR, file_name)
|
||||||
|
|
||||||
def save_test(self, test, geth: dict):
|
def save_geth(self, geth: dict):
|
||||||
file_path = self.get_test_report_file_path(test.name)
|
|
||||||
geth_paths = {}
|
geth_paths = {}
|
||||||
for log in geth.keys():
|
for log in geth.keys():
|
||||||
geth_path = os.path.join(self.TEST_REPORT_DIR, log)
|
geth_path = os.path.join(self.TEST_REPORT_DIR, log)
|
||||||
@ -37,6 +36,14 @@ class BaseTestReport:
|
|||||||
result.write(geth[log])
|
result.write(geth[log])
|
||||||
result.close()
|
result.close()
|
||||||
geth_paths[log] = geth_path
|
geth_paths[log] = geth_path
|
||||||
|
return geth_paths
|
||||||
|
|
||||||
|
def save_test(self, test, geth: dict = None):
|
||||||
|
if geth:
|
||||||
|
geth_paths = self.save_geth(geth)
|
||||||
|
else:
|
||||||
|
geth_paths = test.geth_paths
|
||||||
|
file_path = self.get_test_report_file_path(test.name)
|
||||||
test_dict = {
|
test_dict = {
|
||||||
'testrail_case_id': test.testrail_case_id,
|
'testrail_case_id': test.testrail_case_id,
|
||||||
'name': test.name,
|
'name': test.name,
|
||||||
@ -58,7 +65,8 @@ class BaseTestReport:
|
|||||||
testruns.append(SingleTestData.TestRunData(
|
testruns.append(SingleTestData.TestRunData(
|
||||||
steps=testrun_data['steps'],
|
steps=testrun_data['steps'],
|
||||||
jobs=testrun_data['jobs'],
|
jobs=testrun_data['jobs'],
|
||||||
error=testrun_data['error']))
|
error=testrun_data['error'],
|
||||||
|
first_commands=testrun_data['first_commands']))
|
||||||
tests.append(SingleTestData(name=test_data['name'],
|
tests.append(SingleTestData(name=test_data['name'],
|
||||||
geth_paths=test_data['geth_paths'],
|
geth_paths=test_data['geth_paths'],
|
||||||
testruns=testruns,
|
testruns=testruns,
|
||||||
@ -85,9 +93,12 @@ class BaseTestReport:
|
|||||||
return 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()
|
||||||
|
|
||||||
def get_sauce_job_url(self, job_id):
|
def get_sauce_job_url(self, job_id, first_command=0):
|
||||||
token = self.get_sauce_token(job_id)
|
token = self.get_sauce_token(job_id)
|
||||||
return 'https://saucelabs.com/jobs/%s?auth=%s' % (job_id, token)
|
url = 'https://saucelabs.com/jobs/%s?auth=%s' % (job_id, token)
|
||||||
|
if first_command > 0:
|
||||||
|
url += "#%s" % first_command
|
||||||
|
return url
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_jenkins_link_to_rerun_e2e(branch_name="develop", pr_id="", apk_name="", tr_case_ids=""):
|
def get_jenkins_link_to_rerun_e2e(branch_name="develop", pr_id="", apk_name="", tr_case_ids=""):
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
from support.base_test_report import BaseTestReport
|
from support.base_test_report import BaseTestReport
|
||||||
from support.testrail_report import TestrailReport
|
from support.testrail_report import TestrailReport
|
||||||
|
|
||||||
|
|
||||||
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__))
|
||||||
|
|
||||||
@ -52,7 +53,9 @@ class GithubHtmlReport(BaseTestReport):
|
|||||||
pr_id = pytest_config_global['pr_number']
|
pr_id = pytest_config_global['pr_number']
|
||||||
apk_name = pytest_config_global['apk']
|
apk_name = pytest_config_global['apk']
|
||||||
tr_case_ids = self.list_of_failed_testrail_ids(self.get_failed_tests())
|
tr_case_ids = self.list_of_failed_testrail_ids(self.get_failed_tests())
|
||||||
html += "<li><a href=\"%s\">Rerun tests</a></li>" % self.get_jenkins_link_to_rerun_e2e(pr_id=pr_id, apk_name=apk_name, tr_case_ids=tr_case_ids)
|
html += "<li><a href=\"%s\">Rerun tests</a></li>" % self.get_jenkins_link_to_rerun_e2e(pr_id=pr_id,
|
||||||
|
apk_name=apk_name,
|
||||||
|
tr_case_ids=tr_case_ids)
|
||||||
|
|
||||||
html += "<br/>"
|
html += "<br/>"
|
||||||
html += "<table style=\"width: 100%\">"
|
html += "<table style=\"width: 100%\">"
|
||||||
@ -73,7 +76,8 @@ class GithubHtmlReport(BaseTestReport):
|
|||||||
def build_test_row_html(self, index, test, run_id):
|
def build_test_row_html(self, index, test, run_id):
|
||||||
test_rail_link = TestrailReport().get_test_result_link(run_id, test.testrail_case_id)
|
test_rail_link = TestrailReport().get_test_result_link(run_id, test.testrail_case_id)
|
||||||
if test_rail_link:
|
if test_rail_link:
|
||||||
html = "<tr><td><b>%s. <a href=\"%s\">%s</a>, id: %s </b></td></tr>" % (index + 1, test_rail_link, test.name, test.testrail_case_id)
|
html = "<tr><td><b>%s. <a href=\"%s\">%s</a>, id: %s </b></td></tr>" % (
|
||||||
|
index + 1, test_rail_link, test.name, test.testrail_case_id)
|
||||||
else:
|
else:
|
||||||
html = "<tr><td><b>%d. %s</b> (TestRail link is not found)</td></tr>" % (index + 1, test.name)
|
html = "<tr><td><b>%d. %s</b> (TestRail link is not found)</td></tr>" % (index + 1, test.name)
|
||||||
html += "<tr><td>"
|
html += "<tr><td>"
|
||||||
@ -92,18 +96,23 @@ class GithubHtmlReport(BaseTestReport):
|
|||||||
html += "<code>%s</code>" % last_testrun.error[:255]
|
html += "<code>%s</code>" % last_testrun.error[:255]
|
||||||
html += "<br/><br/>"
|
html += "<br/><br/>"
|
||||||
if last_testrun.jobs:
|
if last_testrun.jobs:
|
||||||
html += self.build_device_sessions_html(last_testrun.jobs, last_testrun)
|
html += self.build_device_sessions_html(last_testrun)
|
||||||
html += "</td></tr>"
|
html += "</td></tr>"
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def build_device_sessions_html(self, jobs, test_run):
|
def build_device_sessions_html(self, test_run):
|
||||||
html = "<ins>Device sessions</ins>"
|
html = "<ins>Device sessions</ins>"
|
||||||
html += "<p><ul>"
|
html += "<p><ul>"
|
||||||
for job_id, i in jobs.items():
|
for job_id, i in test_run.jobs.items():
|
||||||
html += "<p>"
|
html += "<p>"
|
||||||
html += "Device %d:" % i
|
html += "Device %d:" % i
|
||||||
html += "<ul>"
|
html += "<ul>"
|
||||||
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id)
|
if test_run.first_commands:
|
||||||
|
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id,
|
||||||
|
test_run.first_commands[
|
||||||
|
job_id])
|
||||||
|
else:
|
||||||
|
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id)
|
||||||
if test_run.error:
|
if test_run.error:
|
||||||
html += "<li><a href=\"%s\">Failure screenshot</a></li>" % self.get_sauce_final_screenshot_url(job_id)
|
html += "<li><a href=\"%s\">Failure screenshot</a></li>" % self.get_sauce_final_screenshot_url(job_id)
|
||||||
html += "</ul></p>"
|
html += "</ul></p>"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
|
||||||
class SingleTestData(object):
|
class SingleTestData(object):
|
||||||
@ -8,13 +9,14 @@ class SingleTestData(object):
|
|||||||
self.geth_paths = geth_paths
|
self.geth_paths = geth_paths
|
||||||
|
|
||||||
class TestRunData(object):
|
class TestRunData(object):
|
||||||
def __init__(self, steps, jobs, error):
|
def __init__(self, steps, jobs, error, first_commands: Dict[str, int]):
|
||||||
self.steps = steps
|
self.steps = steps
|
||||||
self.jobs = jobs
|
self.jobs = jobs
|
||||||
self.error = error
|
self.error = error
|
||||||
|
self.first_commands = first_commands
|
||||||
|
|
||||||
def create_new_testrun(self):
|
def create_new_testrun(self):
|
||||||
self.testruns.append(SingleTestData.TestRunData(list(), dict(), None))
|
self.testruns.append(SingleTestData.TestRunData(list(), dict(), None, dict()))
|
||||||
|
|
||||||
|
|
||||||
class TestSuiteData(object):
|
class TestSuiteData(object):
|
||||||
|
@ -130,7 +130,11 @@ class TestrailReport(BaseTestReport):
|
|||||||
for step in last_testrun.steps:
|
for step in last_testrun.steps:
|
||||||
test_steps += step + "\n"
|
test_steps += step + "\n"
|
||||||
for i, device in enumerate(last_testrun.jobs):
|
for i, device in enumerate(last_testrun.jobs):
|
||||||
devices += "# [Device %d](%s) \n" % (i + 1, self.get_sauce_job_url(device))
|
if last_testrun.first_commands:
|
||||||
|
devices += "# [Device %d](%s) \n" % (
|
||||||
|
i + 1, self.get_sauce_job_url(job_id=device, first_command=last_testrun.first_commands[device]))
|
||||||
|
else:
|
||||||
|
devices += "# [Device %d](%s) \n" % (i + 1, self.get_sauce_job_url(job_id=device))
|
||||||
data = {'status_id': self.outcomes['undefined_fail'] if last_testrun.error else self.outcomes['passed'],
|
data = {'status_id': self.outcomes['undefined_fail'] if last_testrun.error else self.outcomes['passed'],
|
||||||
'comment': '%s' % ('# Error: \n %s \n' % emoji.demojize(
|
'comment': '%s' % ('# Error: \n %s \n' % emoji.demojize(
|
||||||
last_testrun.error)) + devices + test_steps if last_testrun.error
|
last_testrun.error)) + devices + test_steps if last_testrun.error
|
||||||
@ -166,13 +170,17 @@ class TestrailReport(BaseTestReport):
|
|||||||
ids_failed_test.append(test.testrail_case_id)
|
ids_failed_test.append(test.testrail_case_id)
|
||||||
case_title = '\n'
|
case_title = '\n'
|
||||||
case_title += '-------\n'
|
case_title += '-------\n'
|
||||||
case_title += "## %s) ID %s: [%s](%s) \n" % (i + 1, test.testrail_case_id, test.name, test_rail_link)
|
case_title += "## %s) ID %s: [%s](%s) \n" % (
|
||||||
|
i + 1, test.testrail_case_id, test.name, test_rail_link)
|
||||||
error = "```%s```\n" % last_testrun.error[:255]
|
error = "```%s```\n" % last_testrun.error[:255]
|
||||||
for job_id, f in last_testrun.jobs.items():
|
for job_id, f in last_testrun.jobs.items():
|
||||||
|
if last_testrun.first_commands:
|
||||||
|
job_url = self.get_sauce_job_url(job_id=job_id,
|
||||||
|
first_command=last_testrun.first_commands[job_id])
|
||||||
|
else:
|
||||||
|
job_url = self.get_sauce_job_url(job_id=job_id)
|
||||||
case_info = "Logs for device %d: [steps](%s), [failure screenshot](%s)" \
|
case_info = "Logs for device %d: [steps](%s), [failure screenshot](%s)" \
|
||||||
% (f,
|
% (f, job_url, self.get_sauce_final_screenshot_url(job_id))
|
||||||
self.get_sauce_job_url(job_id),
|
|
||||||
self.get_sauce_final_screenshot_url(job_id))
|
|
||||||
|
|
||||||
description += case_title + error + case_info
|
description += case_title + error + case_info
|
||||||
description_title += '## Failed tests: %s \n' % ','.join(map(str, ids_failed_test))
|
description_title += '## Failed tests: %s \n' % ','.join(map(str, ids_failed_test))
|
||||||
|
@ -4,13 +4,18 @@ import re
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
from http.client import RemoteDisconnected
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import requests
|
||||||
from appium import webdriver
|
from appium import webdriver
|
||||||
from appium.webdriver.common.mobileby import MobileBy
|
from appium.webdriver.common.mobileby import MobileBy
|
||||||
|
from sauceclient import SauceException
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from selenium.common.exceptions import WebDriverException
|
from selenium.common.exceptions import WebDriverException
|
||||||
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
|
|
||||||
from tests import transl
|
from tests import transl
|
||||||
|
|
||||||
from support.api.network_api import NetworkApi
|
from support.api.network_api import NetworkApi
|
||||||
@ -19,8 +24,9 @@ from tests import test_suite_data, start_threads, appium_container, pytest_confi
|
|||||||
import base64
|
import base64
|
||||||
from re import findall
|
from re import findall
|
||||||
|
|
||||||
sauce_username = environ.get('SAUCE_USERNAME')
|
from tests.conftest import sauce
|
||||||
|
|
||||||
|
sauce_username = environ.get('SAUCE_USERNAME')
|
||||||
|
|
||||||
sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
|
sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
|
||||||
|
|
||||||
@ -334,6 +340,8 @@ class LocalSharedMultipleDeviceTestCase(AbstractTestCase):
|
|||||||
class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
|
|
||||||
def setup_method(self, method):
|
def setup_method(self, method):
|
||||||
|
for _, driver in self.drivers.items():
|
||||||
|
driver.execute_script("sauce:context=Started %s" % method.__name__)
|
||||||
jobs = test_suite_data.current_test.testruns[-1].jobs
|
jobs = test_suite_data.current_test.testruns[-1].jobs
|
||||||
if not jobs:
|
if not jobs:
|
||||||
for index, driver in self.drivers.items():
|
for index, driver in self.drivers.items():
|
||||||
@ -354,16 +362,36 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
|||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
geth = {geth_names[i]: geth_contents[i] for i in range(len(geth_names))}
|
geth = {geth_names[i]: geth_contents[i] for i in range(len(geth_names))}
|
||||||
self.github_report.save_test(test_suite_data.current_test, geth)
|
test_suite_data.current_test.geth_paths = self.github_report.save_geth(geth)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def teardown_class(cls):
|
def teardown_class(cls):
|
||||||
for driver in cls.drivers:
|
requests_session = requests.Session()
|
||||||
|
requests_session.auth = (sauce_username, sauce_access_key)
|
||||||
|
for _, driver in cls.drivers.items():
|
||||||
|
session_id = driver.session_id
|
||||||
try:
|
try:
|
||||||
cls.drivers[driver].quit()
|
sauce.jobs.update_job(job_id=session_id, name=cls.__name__)
|
||||||
|
except (RemoteDisconnected, SauceException):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
driver.quit()
|
||||||
except WebDriverException:
|
except WebDriverException:
|
||||||
pass
|
pass
|
||||||
|
url = sauce.jobs.get_job_asset_url(job_id=session_id, filename="log.json")
|
||||||
|
WebDriverWait(driver, 60, 2).until(lambda _: requests_session.get(url).status_code == 200)
|
||||||
|
commands = requests_session.get(url).json()
|
||||||
|
for command in commands:
|
||||||
|
try:
|
||||||
|
if command['message'].startswith("Started "):
|
||||||
|
for test in test_suite_data.tests:
|
||||||
|
if command['message'] == "Started %s" % test.name:
|
||||||
|
test.testruns[-1].first_commands[session_id] = commands.index(command) + 1
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
cls.loop.close()
|
cls.loop.close()
|
||||||
|
for test in test_suite_data.tests:
|
||||||
|
cls.github_report.save_test(test)
|
||||||
|
|
||||||
|
|
||||||
if pytest_config_global['env'] == 'local':
|
if pytest_config_global['env'] == 'local':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user