e2e: Updated report

This commit is contained in:
Yevheniia Berdnyk 2023-06-08 05:57:38 +03:00
parent 0fcb8a33aa
commit 032c254d19
No known key found for this signature in database
GPG Key ID: 0642C73C66214825
6 changed files with 71 additions and 54 deletions

View File

@ -1,10 +1,9 @@
import time
import json
import hmac import hmac
import json
import os import os
from hashlib import md5
from sauceclient import SauceException
import re import re
from hashlib import md5
from support.test_data import SingleTestData from support.test_data import SingleTestData

View File

@ -18,10 +18,9 @@ from selenium.webdriver.support.wait import WebDriverWait
from urllib3.exceptions import MaxRetryError, ProtocolError from urllib3.exceptions import MaxRetryError, ProtocolError
from support.api.network_api import NetworkApi from support.api.network_api import NetworkApi
from support.github_report import GithubHtmlReport
from tests import test_suite_data, start_threads, appium_container, pytest_config_global from tests import test_suite_data, start_threads, appium_container, pytest_config_global
from tests import transl from tests import transl
from tests.conftest import sauce_username, sauce_access_key, apibase from tests.conftest import sauce_username, sauce_access_key, apibase, github_report
executor_sauce_lab = 'https://%s:%s@ondemand.%s:443/wd/hub' % (sauce_username, sauce_access_key, apibase) executor_sauce_lab = 'https://%s:%s@ondemand.%s:443/wd/hub' % (sauce_username, sauce_access_key, apibase)
@ -127,7 +126,6 @@ class AbstractTestCase:
return pytest_config_global['env'] return pytest_config_global['env']
network_api = NetworkApi() network_api = NetworkApi()
github_report = GithubHtmlReport()
@staticmethod @staticmethod
def get_alert_text(driver): def get_alert_text(driver):
@ -215,7 +213,7 @@ class SingleDeviceTestCase(AbstractTestCase):
except (WebDriverException, AttributeError): except (WebDriverException, AttributeError):
pass pass
finally: finally:
self.github_report.save_test(test_suite_data.current_test, github_report.save_test(test_suite_data.current_test,
{'%s_geth.log' % test_suite_data.current_test.name: geth_content}) {'%s_geth.log' % test_suite_data.current_test.name: geth_content})
@ -277,7 +275,7 @@ class SauceMultipleDeviceTestCase(AbstractTestCase):
except (WebDriverException, AttributeError): except (WebDriverException, AttributeError):
pass pass
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) github_report.save_test(test_suite_data.current_test, geth)
@classmethod @classmethod
def teardown_class(cls): def teardown_class(cls):
@ -377,7 +375,7 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
finally: finally:
try: try:
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))}
test_suite_data.current_test.geth_paths = self.github_report.save_geth(geth) test_suite_data.current_test.geth_paths = github_report.save_geth(geth)
except IndexError: except IndexError:
pass pass
@ -419,7 +417,7 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
if cls.loop: if cls.loop:
cls.loop.close() cls.loop.close()
for test in test_suite_data.tests: for test in test_suite_data.tests:
cls.github_report.save_test(test) github_report.save_test(test)
if pytest_config_global['env'] == 'local': if pytest_config_global['env'] == 'local':
@ -436,4 +434,4 @@ class NoDeviceTestCase(AbstractTestCase):
pass pass
def teardown_method(self, method): def teardown_method(self, method):
self.github_report.save_test(test_suite_data.current_test) github_report.save_test(test_suite_data.current_test)

View File

@ -1,15 +1,16 @@
import os
import re import re
import urllib.request
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from http.client import RemoteDisconnected from http.client import RemoteDisconnected
from os import environ from os import environ
from time import sleep from time import sleep
import os
import urllib.request
import pytest import pytest
from _pytest.runner import runtestprotocol from _pytest.runner import runtestprotocol
from requests.exceptions import ConnectionError as c_er from requests.exceptions import ConnectionError as c_er
import tests import tests
from support.device_stats_db import DeviceStatsDB from support.device_stats_db import DeviceStatsDB
from support.test_rerun import should_rerun_test from support.test_rerun import should_rerun_test
@ -20,7 +21,6 @@ sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
github_token = environ.get('GIT_HUB_TOKEN') github_token = environ.get('GIT_HUB_TOKEN')
def pytest_addoption(parser): def pytest_addoption(parser):
parser.addoption("--build", parser.addoption("--build",
action="store", action="store",
@ -158,6 +158,7 @@ def is_uploaded():
if stored_files[i].name == test_suite_data.apk_name: if stored_files[i].name == test_suite_data.apk_name:
return True return True
def pytest_configure(config): def pytest_configure(config):
global option global option
option = config.option option = config.option
@ -178,7 +179,7 @@ def pytest_configure(config):
else: else:
raise NotImplementedError("Unknown SauceLabs datacenter") raise NotImplementedError("Unknown SauceLabs datacenter")
global sauce global sauce
sauce = SauceLab('https://api.' + apibase +'/', sauce_username, sauce_access_key) sauce = SauceLab('https://api.' + apibase + '/', sauce_username, sauce_access_key)
if config.getoption('log_steps'): if config.getoption('log_steps'):
import logging import logging
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@ -208,7 +209,8 @@ def pytest_configure(config):
file_path = os.path.join(os.path.dirname(__file__), apk_name) file_path = os.path.join(os.path.dirname(__file__), apk_name)
for _ in range(3): for _ in range(3):
try: try:
urllib.request.urlretrieve(config.getoption('apk'), filename=file_path) # if url is not valid it raises an error urllib.request.urlretrieve(config.getoption('apk'),
filename=file_path) # if url is not valid it raises an error
sauce.storage.upload(file_path) sauce.storage.upload(file_path)
os.remove(file_path) os.remove(file_path)
break break
@ -263,7 +265,8 @@ def pytest_runtest_makereport(item, call):
is_group = "xdist_group" in item.keywords._markers or "xdist_group" in item.parent.keywords._markers is_group = "xdist_group" in item.keywords._markers or "xdist_group" in item.parent.keywords._markers
error_intro, error = 'Test setup failed:', '' error_intro, error = 'Test setup failed:', ''
final_error = '%s %s' % (error_intro, error) final_error = '%s %s' % (error_intro, error)
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))): 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))):
if '[NOTRUN]' in report.wasxfail: if '[NOTRUN]' in report.wasxfail:
test_suite_data.set_current_test(item.name, testrail_case_id=get_testrail_case_id(item)) test_suite_data.set_current_test(item.name, testrail_case_id=get_testrail_case_id(item))
test_suite_data.current_test.create_new_testrun() test_suite_data.current_test.create_new_testrun()
@ -287,15 +290,15 @@ def pytest_runtest_makereport(item, call):
report.passed) report.passed)
if error: if error:
test_suite_data.current_test.testruns[-1].error = final_error test_suite_data.current_test.testruns[-1].error = final_error
from support.github_report import GithubHtmlReport github_report.save_test(test_suite_data.current_test)
GithubHtmlReport().save_test(test_suite_data.current_test)
if report.when == 'call': if report.when == 'call':
current_test = test_suite_data.current_test current_test = test_suite_data.current_test
error = catch_error() error = catch_error()
if report.failed: if report.failed:
current_test.testruns[-1].error = error current_test.testruns[-1].error = error
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))): 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))):
current_test.testruns[-1].xfail = report.wasxfail current_test.testruns[-1].xfail = report.wasxfail
if error: if error:
current_test.testruns[-1].error = '%s [[%s]]' % (error, report.wasxfail) current_test.testruns[-1].error = '%s [[%s]]' % (error, report.wasxfail)

View File

@ -926,11 +926,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.home_2.just_fyi("Check 'Open in Status' option") self.home_2.just_fyi("Check 'Open in Status' option")
url_message = 'http://status.im' url_message = 'http://status.im'
self.chat_1.send_message(url_message) self.chat_1.send_message(url_message)
try:
self.chat_2.element_starts_with_text(url_message, 'button').wait_for_visibility_of_element(120) self.chat_2.element_starts_with_text(url_message, 'button').wait_for_visibility_of_element(120)
self.chat_2.element_starts_with_text(url_message, 'button').click_inside_element_by_coordinate(0.2, 0.5) self.chat_2.element_starts_with_text(url_message, 'button').click_inside_element_by_coordinate(0.2, 0.5)
web_view = self.chat_2.open_in_status_button.click() web_view = self.chat_2.open_in_status_button.click()
if not web_view.element_by_text('Private, Secure Communication').is_element_displayed(60): if not web_view.element_by_text('Private, Secure Communication').is_element_displayed(60):
self.errors.append('URL was not opened from 1-1 chat') self.errors.append('URL was not opened from 1-1 chat')
except TimeoutException:
self.errors.append("Message with URL was not received")
self.errors.verify_no_errors() self.errors.verify_no_errors()
@ -1124,6 +1127,8 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.errors.append("PN are keep staying after message was seen by user") self.errors.append("PN are keep staying after message was seen by user")
self.errors.verify_no_errors() self.errors.verify_no_errors()
@marks.xfail(
reason="Message is being in status 'Sending' for a long time: https://github.com/status-im/status-mobile/issues/15385")
@marks.testrail_id(702855) @marks.testrail_id(702855)
def test_1_1_chat_edit_message(self): def test_1_1_chat_edit_message(self):
[home.click_system_back_button_until_element_is_shown() for home in self.homes] [home.click_system_back_button_until_element_is_shown() for home in self.homes]
@ -1160,8 +1165,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.device_2.just_fyi("Delete message for me and check it is only deleted for the author") self.device_2.just_fyi("Delete message for me and check it is only deleted for the author")
self.chat_2.send_message(message_to_delete_for_me) self.chat_2.send_message(message_to_delete_for_me)
self.chat_2.chat_element_by_text(message_to_delete_for_me).wait_for_status_to_be("Delivered") try:
timeout = 60
self.chat_2.chat_element_by_text(message_to_delete_for_me).wait_for_status_to_be("Delivered", timeout)
self.chat_2.delete_message_in_chat(message_to_delete_for_me, everyone=False) self.chat_2.delete_message_in_chat(message_to_delete_for_me, everyone=False)
except TimeoutException:
self.errors.append(
"Message status was not changed to 'Delivered' after %s s, https://github.com/status-im/status-mobile/issues/15385" % timeout)
else:
if not self.chat_2.chat_element_by_text(message_to_delete_for_me).is_element_disappeared(20): if not self.chat_2.chat_element_by_text(message_to_delete_for_me).is_element_disappeared(20):
self.errors.append("Deleted for me message is shown in chat for the author of message") self.errors.append("Deleted for me message is shown in chat for the author of message")
if not self.chat_2.element_by_translation_id('message-deleted-for-you').is_element_displayed(20): if not self.chat_2.element_by_translation_id('message-deleted-for-you').is_element_displayed(20):

View File

@ -455,8 +455,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.verify_message_is_under_today_text(message, self.errors) self.channel_1.verify_message_is_under_today_text(message, self.errors)
new_message = "new message" new_message = "new message"
self.channel_1.send_message(message) self.channel_1.send_message(message)
self.channel_1.chat_element_by_text(message).wait_for_status_to_be('Delivered', timeout=120) self.channel_2.verify_message_is_under_today_text(new_message, self.errors, 60)
self.channel_2.verify_message_is_under_today_text(new_message, self.errors)
if self.channel_2.chat_element_by_text(message).username.text != self.username_1: if self.channel_2.chat_element_by_text(message).username.text != self.username_1:
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1) self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
self.errors.verify_no_errors() self.errors.verify_no_errors()
@ -502,9 +501,8 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.just_fyi('Send image in 1-1 chat from Gallery') self.home_1.just_fyi('Send image in 1-1 chat from Gallery')
image_description = 'description' image_description = 'description'
self.channel_1.send_images_with_description(image_description) self.channel_1.send_images_with_description(image_description)
self.channel_1.chat_element_by_text(image_description).wait_for_status_to_be('Delivered', timeout=120) # self.channel_1.chat_element_by_text(image_description).image_in_message.click()
self.channel_1.chat_element_by_text(image_description).image_in_message.click() # self.channel_1.click_system_back_button_until_element_is_shown(element='chat')
self.channel_1.click_system_back_button_until_element_is_shown(element='chat')
# TODO: options for image are still WIP; add case with edit description of image and after 15901 fix # TODO: options for image are still WIP; add case with edit description of image and after 15901 fix
self.home_2.just_fyi('check image, description and options for receiver') self.home_2.just_fyi('check image, description and options for receiver')
@ -533,6 +531,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
# #
# self.channel_2.chat_element_by_text(image_description).image_in_message.save_new_screenshot_of_element('images_test.png') # self.channel_2.chat_element_by_text(image_description).image_in_message.save_new_screenshot_of_element('images_test.png')
self.channel_2.chat_element_by_text(image_description).wait_for_visibility_of_element(60)
if not self.channel_2.chat_element_by_text( if not self.channel_2.chat_element_by_text(
image_description).image_in_message.is_element_image_similar_to_template('image_sent_in_community.png'): image_description).image_in_message.is_element_image_similar_to_template('image_sent_in_community.png'):
self.errors.append("Not expected image is shown to the receiver") self.errors.append("Not expected image is shown to the receiver")

View File

@ -220,11 +220,12 @@ class ChatElementByText(Text):
def wait_for_status_to_be(self, expected_status: str, timeout: int = 30): def wait_for_status_to_be(self, expected_status: str, timeout: int = 30):
self.driver.info("Waiting for message to be sent for %s sec" % timeout) self.driver.info("Waiting for message to be sent for %s sec" % timeout)
start_time = time.time() start_time = time.time()
current_status = self.status
while time.time() - start_time <= timeout: while time.time() - start_time <= timeout:
if self.status == expected_status: if current_status == expected_status:
return return
time.sleep(1) time.sleep(1)
raise TimeoutException("Message status was not changed to %s" % expected_status) raise TimeoutException("Message status was not changed to %s, it's %s" % (expected_status, current_status))
@property @property
def sent_status_checkmark(self) -> object: def sent_status_checkmark(self) -> object:
@ -285,7 +286,8 @@ class ChatElementByText(Text):
@property @property
def image_container_in_message(self): def image_container_in_message(self):
try: try:
self.driver.info("Trying to access images (image container) inside message with text '%s'" % self.message_text) self.driver.info(
"Trying to access images (image container) inside message with text '%s'" % self.message_text)
ChatElementByText(self.driver, self.message_text).wait_for_sent_state(60) ChatElementByText(self.driver, self.message_text).wait_for_sent_state(60)
return Button(self.driver, xpath='%s//*[@content-desc="image-container"]' % self.locator) return Button(self.driver, xpath='%s//*[@content-desc="image-container"]' % self.locator)
except NoSuchElementException: except NoSuchElementException:
@ -363,7 +365,8 @@ class CommunityView(HomeView):
self.invite_button = Button(self.driver, accessibility_id="community-invite-people") self.invite_button = Button(self.driver, accessibility_id="community-invite-people")
# Community info page # Community info page
self.community_membership_request_value = Text(self.driver, translation_id="members-label", self.community_membership_request_value = Text(
self.driver, translation_id="members-label",
suffix='/following-sibling::android.view.ViewGroup/android.widget.TextView') suffix='/following-sibling::android.view.ViewGroup/android.widget.TextView')
self.members_button = Button(self.driver, translation_id="members-label") self.members_button = Button(self.driver, translation_id="members-label")
self.community_info_picture = Button(self.driver, accessibility_id="chat-icon") self.community_info_picture = Button(self.driver, accessibility_id="chat-icon")
@ -393,7 +396,6 @@ class CommunityView(HomeView):
self.checkbox_button.scroll_and_click() self.checkbox_button.scroll_and_click()
self.join_community_button.scroll_and_click() self.join_community_button.scroll_and_click()
def get_channel(self, channel_name: str): def get_channel(self, channel_name: str):
self.driver.info("Getting %s channel element in community" % channel_name) self.driver.info("Getting %s channel element in community" % channel_name)
chat_element = self.get_chat(username=channel_name, community_channel=True, wait_time=30) chat_element = self.get_chat(username=channel_name, community_channel=True, wait_time=30)
@ -732,8 +734,10 @@ class ChatView(BaseView):
self.chat_message_input = ChatMessageInput(self.driver) self.chat_message_input = ChatMessageInput(self.driver)
self.cancel_reply_button = Button(self.driver, accessibility_id="reply-cancel-button") self.cancel_reply_button = Button(self.driver, accessibility_id="reply-cancel-button")
self.url_preview_composer = Button(self.driver, accessibility_id="url-preview") self.url_preview_composer = Button(self.driver, accessibility_id="url-preview")
self.url_preview_composer_text = Text(self.driver, xpath='//*[@content-desc="url-preview"]//*[@content-desc="title"]') self.url_preview_composer_text = Text(self.driver,
self.quote_username_in_message_input = EditBox(self.driver, xpath='//*[@content-desc="url-preview"]//*[@content-desc="title"]')
self.quote_username_in_message_input = EditBox(
self.driver,
xpath="//*[@content-desc='reply-cancel-button']/preceding::android.widget.TextView[3]") xpath="//*[@content-desc='reply-cancel-button']/preceding::android.widget.TextView[3]")
self.chat_item = Button(self.driver, xpath="(//*[@content-desc='chat-item'])[1]") self.chat_item = Button(self.driver, xpath="(//*[@content-desc='chat-item'])[1]")
self.chat_name_editbox = EditBox(self.driver, accessibility_id="chat-name-input") self.chat_name_editbox = EditBox(self.driver, accessibility_id="chat-name-input")
@ -938,10 +942,10 @@ class ChatView(BaseView):
self.driver.info("Looking for a message by text: %s" % chat_element.exclude_emoji(text)) self.driver.info("Looking for a message by text: %s" % chat_element.exclude_emoji(text))
return chat_element return chat_element
def verify_message_is_under_today_text(self, text, errors): def verify_message_is_under_today_text(self, text, errors, timeout=10):
self.driver.info("Verifying that '%s' is under today" % text) self.driver.info("Verifying that '%s' is under today" % text)
message_element = self.chat_element_by_text(text) message_element = self.chat_element_by_text(text)
message_element.wait_for_visibility_of_element() message_element.wait_for_visibility_of_element(timeout)
message_location = message_element.find_element().location['y'] message_location = message_element.find_element().location['y']
today_text_element = self.element_by_text('Today').find_element() today_text_element = self.element_by_text('Today').find_element()
today_location = today_text_element.location['y'] today_location = today_text_element.location['y']
@ -1043,8 +1047,10 @@ class ChatView(BaseView):
self.chat_message_input.click() self.chat_message_input.click()
self.show_stickers_button.click() self.show_stickers_button.click()
self.get_stickers.click() self.get_stickers.click()
element = Button(self.driver, element = Button(
xpath="//*[@content-desc='sticker-pack-name'][@text='%s']/..//*[@content-desc='sticker-pack-price']" % pack_name) self.driver,
xpath="//*[@content-desc='sticker-pack-name'][@text='%s']/..//*[@content-desc='sticker-pack-price']"
% pack_name)
element.scroll_to_element(depth=21) element.scroll_to_element(depth=21)
element.click() element.click()
element.wait_for_invisibility_of_element() element.wait_for_invisibility_of_element()
@ -1146,7 +1152,8 @@ class ChatView(BaseView):
self.chat_message_input.send_keys("@") self.chat_message_input.send_keys("@")
try: try:
self.mentions_list.wait_for_element() self.mentions_list.wait_for_element()
self.driver.find_element(MobileBy.XPATH, "//*[@content-desc='user-list']//*[@text='%s']" % user_name).click() self.driver.find_element(MobileBy.XPATH,
"//*[@content-desc='user-list']//*[@text='%s']" % user_name).click()
except TimeoutException: except TimeoutException:
self.driver.fail("Mentions list is not shown") self.driver.fail("Mentions list is not shown")