e2e: LambdaTest
|
@ -73,9 +73,9 @@ pipeline {
|
||||||
passwordVariable: 'TESTRAIL_PASS'
|
passwordVariable: 'TESTRAIL_PASS'
|
||||||
),
|
),
|
||||||
usernamePassword(
|
usernamePassword(
|
||||||
credentialsId: 'sauce-labs-api',
|
credentialsId: 'lambda-test-api',
|
||||||
usernameVariable: 'SAUCE_USERNAME',
|
usernameVariable: 'LAMBDA_TEST_USERNAME',
|
||||||
passwordVariable: 'SAUCE_ACCESS_KEY'
|
passwordVariable: 'LAMBDA_TEST_ACCESS_KEY'
|
||||||
),
|
),
|
||||||
string(
|
string(
|
||||||
credentialsId: 'etherscan-api-key',
|
credentialsId: 'etherscan-api-key',
|
||||||
|
@ -96,7 +96,6 @@ pipeline {
|
||||||
sh """
|
sh """
|
||||||
python3 -m pytest \
|
python3 -m pytest \
|
||||||
--numprocesses 8 \
|
--numprocesses 8 \
|
||||||
--rerun_count=2 \
|
|
||||||
--testrail_report=True \
|
--testrail_report=True \
|
||||||
-m testrail_id \
|
-m testrail_id \
|
||||||
-m \"nightly\" \
|
-m \"nightly\" \
|
||||||
|
@ -110,21 +109,6 @@ pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
always {
|
|
||||||
script {
|
|
||||||
sauce('sauce-labs-cred') {
|
|
||||||
saucePublisher()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
success {
|
|
||||||
script {
|
|
||||||
junit(
|
|
||||||
testDataPublishers: [[$class: 'SauceOnDemandReportPublisher', jobVisibility: 'public']],
|
|
||||||
testResults: 'test/appium/tests/*.xml'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cleanup {
|
cleanup {
|
||||||
sh 'make purge'
|
sh 'make purge'
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,11 +110,6 @@ pipeline {
|
||||||
usernameVariable: 'TESTRAIL_USER',
|
usernameVariable: 'TESTRAIL_USER',
|
||||||
passwordVariable: 'TESTRAIL_PASS'
|
passwordVariable: 'TESTRAIL_PASS'
|
||||||
),
|
),
|
||||||
usernamePassword(
|
|
||||||
credentialsId: 'sauce-labs-api',
|
|
||||||
usernameVariable: 'SAUCE_USERNAME',
|
|
||||||
passwordVariable: 'SAUCE_ACCESS_KEY'
|
|
||||||
),
|
|
||||||
usernamePassword(
|
usernamePassword(
|
||||||
credentialsId: 'lambda-test-api',
|
credentialsId: 'lambda-test-api',
|
||||||
usernameVariable: 'LAMBDA_TEST_USERNAME',
|
usernameVariable: 'LAMBDA_TEST_USERNAME',
|
||||||
|
@ -139,7 +134,6 @@ pipeline {
|
||||||
sh """
|
sh """
|
||||||
python3 -m pytest \
|
python3 -m pytest \
|
||||||
--numprocesses 8 \
|
--numprocesses 8 \
|
||||||
--rerun_count=2 \
|
|
||||||
--testrail_report=True \
|
--testrail_report=True \
|
||||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||||
--apk=${params.APK_URL ?: apk_path} \
|
--apk=${params.APK_URL ?: apk_path} \
|
||||||
|
|
|
@ -17,6 +17,7 @@ eth-account==0.7.0
|
||||||
eth-hash==0.3.2
|
eth-hash==0.3.2
|
||||||
eth-keys
|
eth-keys
|
||||||
execnet==1.7.1
|
execnet==1.7.1
|
||||||
|
filelock==3.16.1
|
||||||
flaky==3.7.0
|
flaky==3.7.0
|
||||||
future==0.18.2
|
future==0.18.2
|
||||||
hexbytes==0.2.2
|
hexbytes==0.2.2
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import hmac
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
from hashlib import md5
|
|
||||||
|
|
||||||
|
from support.lambda_test import get_session_info
|
||||||
from support.test_data import SingleTestData
|
from support.test_data import SingleTestData
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,8 +11,6 @@ class 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__))
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sauce_username = os.environ.get('SAUCE_USERNAME')
|
|
||||||
self.sauce_access_key = os.environ.get('SAUCE_ACCESS_KEY')
|
|
||||||
self.init_report()
|
self.init_report()
|
||||||
|
|
||||||
def init_report(self):
|
def init_report(self):
|
||||||
|
@ -97,17 +94,8 @@ class BaseTestReport:
|
||||||
failed.append(test)
|
failed.append(test)
|
||||||
return passed, failed, xfailed
|
return passed, failed, xfailed
|
||||||
|
|
||||||
def get_sauce_token(self, job_id):
|
def get_lambda_test_job_url(self, job_id, first_command=0):
|
||||||
return hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'),
|
return "https://appautomation.lambdatest.com/test?testID=" + get_session_info(job_id)['test_id']
|
||||||
bytes(job_id, 'latin-1'), md5).hexdigest()
|
|
||||||
|
|
||||||
def get_sauce_job_url(self, job_id, first_command=0):
|
|
||||||
token = self.get_sauce_token(job_id)
|
|
||||||
from tests.conftest import apibase
|
|
||||||
url = 'https://%s/jobs/%s?auth=%s' % (apibase, 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="", tr_case_ids=""):
|
def get_jenkins_link_to_rerun_e2e(branch_name="develop", pr_id="", tr_case_ids=""):
|
||||||
|
@ -115,19 +103,6 @@ class BaseTestReport:
|
||||||
return 'https://ci.status.im/job/status-mobile/job/e2e/job/status-app-prs-rerun/parambuild/' \
|
return 'https://ci.status.im/job/status-mobile/job/e2e/job/status-app-prs-rerun/parambuild/' \
|
||||||
'?BRANCH_NAME=%s&PR_ID=%s&APK_NAME=%s.apk&TR_CASE_IDS=%s' % (branch_name, pr_id, pr_id, tr_case_ids)
|
'?BRANCH_NAME=%s&PR_ID=%s&APK_NAME=%s.apk&TR_CASE_IDS=%s' % (branch_name, pr_id, pr_id, tr_case_ids)
|
||||||
|
|
||||||
def get_sauce_final_screenshot_url(self, job_id):
|
|
||||||
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)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_test_successful(test):
|
def is_test_successful(test):
|
||||||
# Test passed if last testrun has passed
|
# Test passed if last testrun has passed
|
||||||
|
|
|
@ -166,7 +166,7 @@ class GithubHtmlReport(BaseTestReport):
|
||||||
first_command = 0
|
first_command = 0
|
||||||
else:
|
else:
|
||||||
first_command = 0
|
first_command = 0
|
||||||
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_sauce_job_url(job_id, first_command)
|
html += "<li><a href=\"%s\">Steps, video, logs</a></li>" % self.get_lambda_test_job_url(job_id, first_command)
|
||||||
# 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>"
|
||||||
|
|
|
@ -9,7 +9,6 @@ session.auth = (lambda_test_username, lambda_test_access_key)
|
||||||
|
|
||||||
def upload_apk(apk_file_path):
|
def upload_apk(apk_file_path):
|
||||||
resp = session.post(
|
resp = session.post(
|
||||||
# url="https://manual-api.lambdatest.com/app/upload/realDevice",
|
|
||||||
url="https://manual-api.lambdatest.com/app/upload/virtualDevice",
|
url="https://manual-api.lambdatest.com/app/upload/virtualDevice",
|
||||||
files={'appFile': open(apk_file_path, 'rb')},
|
files={'appFile': open(apk_file_path, 'rb')},
|
||||||
data={'name': test_suite_data.apk_name}
|
data={'name': test_suite_data.apk_name}
|
||||||
|
@ -22,7 +21,18 @@ def update_session(session_id, session_name, status):
|
||||||
resp = session.get(
|
resp = session.get(
|
||||||
url="https://mobile-api.lambdatest.com/mobile-automation/api/v1/sessions/%s" % session_id,
|
url="https://mobile-api.lambdatest.com/mobile-automation/api/v1/sessions/%s" % session_id,
|
||||||
data={
|
data={
|
||||||
"name": session_name #, "status_ind": status
|
"name": session_name # , "status_ind": status
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def get_session_info(session_id):
|
||||||
|
resp = session.get(url="https://mobile-api.lambdatest.com/mobile-automation/api/v1/sessions/%s" % session_id)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
return resp.json()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def upload_image():
|
||||||
|
'curl -u "yevheniia:fZaXHEAFEWOVCZLnSVrwHY11eJGsWAknibtG572PiZsvT1h57V" -X POST https://mobile-mgm.lambdatest.com/mfs/v1.0/media/upload -F media_file=@/Users/yberdnyk/Downloads/aaa.png -F type=image -F custom_id=SampleImage'
|
||||||
|
pass
|
||||||
|
|
|
@ -167,10 +167,10 @@ class TestrailReport(BaseTestReport):
|
||||||
else:
|
else:
|
||||||
first_command = 0
|
first_command = 0
|
||||||
try:
|
try:
|
||||||
devices += "# [Device %d](%s) \n" % (i + 1, self.get_sauce_job_url(job_id=device,
|
devices += "# [Device %d](%s) \n" % (i + 1, self.get_lambda_test_job_url(job_id=device,
|
||||||
first_command=first_command))
|
first_command=first_command))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
devices += "# Device %s: SauceLabs session was not found \n" % (i + 1)
|
devices += "# Device %s: LambdaTest session was not found \n" % (i + 1)
|
||||||
comment = str()
|
comment = str()
|
||||||
if test.group_name:
|
if test.group_name:
|
||||||
comment += "# Class: %s \n" % test.group_name
|
comment += "# Class: %s \n" % test.group_name
|
||||||
|
@ -274,9 +274,8 @@ class TestrailReport(BaseTestReport):
|
||||||
first_command = 0
|
first_command = 0
|
||||||
else:
|
else:
|
||||||
first_command = 0
|
first_command = 0
|
||||||
job_url = self.get_sauce_job_url(job_id=job_id, first_command=first_command)
|
job_url = self.get_lambda_test_job_url(job_id=job_id, first_command=first_command)
|
||||||
case_info = "Logs for device %d: [steps](%s), [failure screenshot](%s)" \
|
case_info = "Logs for device %d: [steps](%s)" % (f, job_url)
|
||||||
% (f, job_url, self.get_sauce_final_screenshot_url(job_id))
|
|
||||||
|
|
||||||
if test.group_name:
|
if test.group_name:
|
||||||
group_blocks[test.group_name] += case_title + error + case_info
|
group_blocks[test.group_name] += case_title + error + case_info
|
||||||
|
|
|
@ -12,17 +12,14 @@ import requests
|
||||||
from appium import webdriver
|
from appium import webdriver
|
||||||
from appium.options.common import AppiumOptions
|
from appium.options.common import AppiumOptions
|
||||||
from appium.webdriver.common.mobileby import MobileBy
|
from appium.webdriver.common.mobileby import MobileBy
|
||||||
from sauceclient import SauceException
|
from appium.webdriver.connectiontype import ConnectionType
|
||||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException, WebDriverException
|
from selenium.common.exceptions import NoSuchElementException, WebDriverException
|
||||||
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 tests import test_suite_data, start_threads, appium_container, pytest_config_global, transl
|
from tests import test_suite_data, start_threads, appium_container, pytest_config_global, transl
|
||||||
from tests.conftest import sauce_username, sauce_access_key, apibase, github_report, run_name, option, \
|
from tests.conftest import github_report, run_name, lambda_test_username, lambda_test_access_key
|
||||||
lambda_test_username, lambda_test_access_key
|
|
||||||
|
|
||||||
executor_sauce_lab = 'https://%s:%s@ondemand.%s:443/wd/hub' % (sauce_username, sauce_access_key, apibase)
|
|
||||||
executor_lambda_test = 'https://%s:%s@mobile-hub.lambdatest.com/wd/hub' % (lambda_test_username, lambda_test_access_key)
|
executor_lambda_test = 'https://%s:%s@mobile-hub.lambdatest.com/wd/hub' % (lambda_test_username, lambda_test_access_key)
|
||||||
|
|
||||||
executor_local = 'http://localhost:4723/wd/hub'
|
executor_local = 'http://localhost:4723/wd/hub'
|
||||||
|
@ -62,41 +59,6 @@ def add_local_devices_to_capabilities():
|
||||||
return updated_capabilities
|
return updated_capabilities
|
||||||
|
|
||||||
|
|
||||||
def get_capabilities_sauce_lab():
|
|
||||||
caps = dict()
|
|
||||||
caps['platformName'] = 'Android'
|
|
||||||
caps['idleTimeout'] = 1000
|
|
||||||
caps['appium:app'] = 'storage:filename=' + test_suite_data.apk_name
|
|
||||||
caps['appium:deviceName'] = 'Android GoogleAPI Emulator'
|
|
||||||
caps['appium:deviceOrientation'] = 'portrait'
|
|
||||||
caps['appium:platformVersion'] = '14.0'
|
|
||||||
caps['appium:automationName'] = 'UiAutomator2'
|
|
||||||
caps['appium:newCommandTimeout'] = 600
|
|
||||||
caps['appium:idleTimeout'] = 1000
|
|
||||||
caps['appium:hideKeyboard'] = True
|
|
||||||
caps['appium:automationName'] = 'UiAutomator2'
|
|
||||||
caps['appium:setWebContentDebuggingEnabled'] = True
|
|
||||||
caps['appium:ignoreUnimportantViews'] = False
|
|
||||||
caps['ignoreUnimportantViews'] = False
|
|
||||||
caps['appium:enableNotificationListener'] = True
|
|
||||||
caps['enableNotificationListener'] = True
|
|
||||||
caps['appium:enforceXPath1'] = True
|
|
||||||
caps['enforceXPath1'] = True
|
|
||||||
caps['sauce:options'] = dict()
|
|
||||||
caps['sauce:options']['appiumVersion'] = '2.11.0'
|
|
||||||
caps['sauce:options']['username'] = sauce_username
|
|
||||||
caps['sauce:options']['accessKey'] = sauce_access_key
|
|
||||||
caps['sauce:options']['build'] = run_name
|
|
||||||
caps['sauce:options']['name'] = test_suite_data.current_test.name
|
|
||||||
caps['sauce:options']['maxDuration'] = 3600
|
|
||||||
caps['sauce:options']['idleTimeout'] = 1000
|
|
||||||
|
|
||||||
options = AppiumOptions()
|
|
||||||
options.load_capabilities(caps)
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
|
|
||||||
def get_lambda_test_capabilities_real_device():
|
def get_lambda_test_capabilities_real_device():
|
||||||
capabilities = {
|
capabilities = {
|
||||||
"lt:options": {
|
"lt:options": {
|
||||||
|
@ -104,10 +66,9 @@ def get_lambda_test_capabilities_real_device():
|
||||||
"platformName": "android",
|
"platformName": "android",
|
||||||
"deviceName": "Pixel 8",
|
"deviceName": "Pixel 8",
|
||||||
"platformVersion": "14",
|
"platformVersion": "14",
|
||||||
"app": "lt://APP10160471311729636675434695", # lambda_test_apk_url,
|
"app": pytest_config_global['lt_apk_url'],
|
||||||
"devicelog": True,
|
"devicelog": True,
|
||||||
"visual": True,
|
"visual": True,
|
||||||
# "network": True,
|
|
||||||
"video": True,
|
"video": True,
|
||||||
"build": run_name,
|
"build": run_name,
|
||||||
"name": test_suite_data.current_test.group_name,
|
"name": test_suite_data.current_test.group_name,
|
||||||
|
@ -126,16 +87,21 @@ def get_lambda_test_capabilities_emulator():
|
||||||
"w3c": True,
|
"w3c": True,
|
||||||
"platformName": "android",
|
"platformName": "android",
|
||||||
"deviceName": "Pixel 6",
|
"deviceName": "Pixel 6",
|
||||||
"appiumVersion": "2.11.0",
|
"appiumVersion": "2.1.3",
|
||||||
"platformVersion": "14",
|
"platformVersion": "14",
|
||||||
"app": "lt://APP10160522181729681886587724", #option.lambda_test_apk_url,
|
"app": pytest_config_global['lt_apk_url'],
|
||||||
"devicelog": True,
|
"devicelog": True,
|
||||||
"visual": True,
|
"visual": True,
|
||||||
# "network": True,
|
|
||||||
"video": True,
|
"video": True,
|
||||||
"build": run_name,
|
"build": run_name,
|
||||||
"name": test_suite_data.current_test.group_name,
|
"name": test_suite_data.current_test.group_name,
|
||||||
"idleTimeout": 1000
|
"idleTimeout": 1000,
|
||||||
|
# "enableImageInjection": True,
|
||||||
|
# "uploadMedia": ["lt://MEDIA2b3e34e2b0ee4928b9fc38c603f98191",], # "lt://MEDIAcfc1b4f1af0740759254404186bbe4f1"]
|
||||||
|
},
|
||||||
|
"appium:options": {
|
||||||
|
"automationName": "UiAutomator2",
|
||||||
|
"hideKeyboard": True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options = AppiumOptions()
|
options = AppiumOptions()
|
||||||
|
@ -165,9 +131,9 @@ def pull_requests_log(driver):
|
||||||
class AbstractTestCase:
|
class AbstractTestCase:
|
||||||
__metaclass__ = ABCMeta
|
__metaclass__ = ABCMeta
|
||||||
|
|
||||||
def print_sauce_lab_info(self, driver):
|
def print_lt_session_info(self, driver):
|
||||||
sys.stdout = sys.stderr
|
sys.stdout = sys.stderr
|
||||||
print("SauceOnDemandSessionID=%s job-name=%s" % (driver.session_id, run_name))
|
print("LambdaTestSessionID=%s job-name=%s" % (driver.session_id, run_name))
|
||||||
|
|
||||||
def get_translation_by_key(self, key):
|
def get_translation_by_key(self, key):
|
||||||
return transl[key]
|
return transl[key]
|
||||||
|
@ -220,6 +186,16 @@ class Driver(webdriver.Remote):
|
||||||
def fail(self, text: str):
|
def fail(self, text: str):
|
||||||
pytest.fail('Device %s: %s' % (self.number, text))
|
pytest.fail('Device %s: %s' % (self.number, text))
|
||||||
|
|
||||||
|
def update_lt_session_status(self, index, status):
|
||||||
|
data = {
|
||||||
|
"action": "setTestStatus",
|
||||||
|
"arguments": {
|
||||||
|
"status": status,
|
||||||
|
"remark": "Device %s" % index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.execute_script("lambda-hook: %s" % str(data).replace("'", "\""))
|
||||||
|
|
||||||
|
|
||||||
class Errors(object):
|
class Errors(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -240,11 +216,11 @@ class SingleDeviceTestCase(AbstractTestCase):
|
||||||
appium_container.start_appium_container(pytest_config_global['docker_shared_volume'])
|
appium_container.start_appium_container(pytest_config_global['docker_shared_volume'])
|
||||||
appium_container.connect_device(pytest_config_global['device_ip'])
|
appium_container.connect_device(pytest_config_global['device_ip'])
|
||||||
|
|
||||||
(executor, capabilities) = (executor_sauce_lab, get_capabilities_sauce_lab()) if \
|
# (executor, capabilities) = (executor_sauce_lab, get_capabilities_sauce_lab()) if \
|
||||||
self.environment == 'sauce' else (executor_local, get_capabilities_local())
|
# self.environment == 'sauce' else (executor_local, get_capabilities_local())
|
||||||
for key, value in kwargs.items():
|
# for key, value in kwargs.items():
|
||||||
capabilities[key] = value
|
# capabilities[key] = value
|
||||||
self.driver = Driver(executor, capabilities)
|
# self.driver = Driver(executor, capabilities)
|
||||||
test_suite_data.current_test.testruns[-1].jobs[self.driver.session_id] = 1
|
test_suite_data.current_test.testruns[-1].jobs[self.driver.session_id] = 1
|
||||||
self.driver.implicitly_wait(implicit_wait)
|
self.driver.implicitly_wait(implicit_wait)
|
||||||
self.errors = Errors()
|
self.errors = Errors()
|
||||||
|
@ -254,7 +230,7 @@ class SingleDeviceTestCase(AbstractTestCase):
|
||||||
|
|
||||||
def teardown_method(self, method):
|
def teardown_method(self, method):
|
||||||
if self.environment == 'sauce':
|
if self.environment == 'sauce':
|
||||||
self.print_sauce_lab_info(self.driver)
|
self.print_lt_session_info(self.driver)
|
||||||
try:
|
try:
|
||||||
self.add_alert_text_to_report(self.driver)
|
self.add_alert_text_to_report(self.driver)
|
||||||
geth_content = pull_geth(self.driver)
|
geth_content = pull_geth(self.driver)
|
||||||
|
@ -290,48 +266,6 @@ class LocalMultipleDeviceTestCase(AbstractTestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SauceMultipleDeviceTestCase(AbstractTestCase):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setup_class(cls):
|
|
||||||
cls.loop = asyncio.new_event_loop()
|
|
||||||
asyncio.set_event_loop(cls.loop)
|
|
||||||
|
|
||||||
def setup_method(self, method):
|
|
||||||
self.drivers = dict()
|
|
||||||
self.errors = Errors()
|
|
||||||
|
|
||||||
def create_drivers(self, quantity=2, max_duration=1800, custom_implicitly_wait=None):
|
|
||||||
self.drivers = self.loop.run_until_complete(start_threads(quantity,
|
|
||||||
Driver,
|
|
||||||
self.drivers,
|
|
||||||
executor_sauce_lab,
|
|
||||||
get_capabilities_sauce_lab()))
|
|
||||||
for driver in range(quantity):
|
|
||||||
test_suite_data.current_test.testruns[-1].jobs[self.drivers[driver].session_id] = driver + 1
|
|
||||||
self.drivers[driver].implicitly_wait(
|
|
||||||
custom_implicitly_wait if custom_implicitly_wait else implicit_wait)
|
|
||||||
|
|
||||||
def teardown_method(self, method):
|
|
||||||
geth_names, geth_contents = [], []
|
|
||||||
for driver in self.drivers:
|
|
||||||
try:
|
|
||||||
self.print_sauce_lab_info(self.drivers[driver])
|
|
||||||
self.add_alert_text_to_report(self.drivers[driver])
|
|
||||||
geth_names.append(
|
|
||||||
'%s_geth%s.log' % (test_suite_data.current_test.name, str(self.drivers[driver].number)))
|
|
||||||
geth_contents.append(pull_geth(self.drivers[driver]))
|
|
||||||
self.drivers[driver].quit()
|
|
||||||
except (WebDriverException, AttributeError):
|
|
||||||
pass
|
|
||||||
geth = {geth_names[i]: geth_contents[i] for i in range(len(geth_names))}
|
|
||||||
github_report.save_test(test_suite_data.current_test, geth)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def teardown_class(cls):
|
|
||||||
cls.loop.close()
|
|
||||||
|
|
||||||
|
|
||||||
def create_shared_drivers(quantity):
|
def create_shared_drivers(quantity):
|
||||||
drivers = dict()
|
drivers = dict()
|
||||||
if pytest_config_global['env'] == 'local':
|
if pytest_config_global['env'] == 'local':
|
||||||
|
@ -354,18 +288,20 @@ def create_shared_drivers(quantity):
|
||||||
drivers,
|
drivers,
|
||||||
command_executor=executor_lambda_test,
|
command_executor=executor_lambda_test,
|
||||||
options=get_lambda_test_capabilities_emulator()))
|
options=get_lambda_test_capabilities_emulator()))
|
||||||
# options=get_lambda_test_capabilities_real_device()))
|
|
||||||
if len(drivers) < quantity:
|
if len(drivers) < quantity:
|
||||||
test_suite_data.current_test.testruns[-1].error = "Not all %s drivers are created" % quantity
|
test_suite_data.current_test.testruns[-1].error = "Not all %s drivers are created" % quantity
|
||||||
|
|
||||||
for i in range(quantity):
|
for i in range(quantity):
|
||||||
test_suite_data.current_test.testruns[-1].jobs[drivers[i].session_id] = i + 1
|
test_suite_data.current_test.testruns[-1].jobs[drivers[i].session_id] = i + 1
|
||||||
drivers[i].implicitly_wait(implicit_wait)
|
drivers[i].implicitly_wait(implicit_wait)
|
||||||
|
drivers[i].update_settings({"enforceXPath1": True})
|
||||||
|
drivers[i].set_network_connection(ConnectionType.WIFI_ONLY)
|
||||||
return drivers, loop
|
return drivers, loop
|
||||||
except (MaxRetryError, AttributeError) as e:
|
except (MaxRetryError, AttributeError) as e:
|
||||||
test_suite_data.current_test.testruns[-1].error = str(e)
|
test_suite_data.current_test.testruns[-1].error = str(e)
|
||||||
for _, driver in drivers.items():
|
for i, driver in drivers.items():
|
||||||
try:
|
try:
|
||||||
|
driver.update_lt_session_status(i + 1, "failed")
|
||||||
driver.quit()
|
driver.quit()
|
||||||
except (WebDriverException, AttributeError):
|
except (WebDriverException, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
@ -405,13 +341,14 @@ class LocalSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
class LambdaTestSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
|
|
||||||
def setup_method(self, method):
|
def setup_method(self, method):
|
||||||
if not self.drivers:
|
if not self.drivers:
|
||||||
pytest.fail(test_suite_data.current_test.testruns[-1].error)
|
pytest.fail(test_suite_data.current_test.testruns[-1].error)
|
||||||
# for _, driver in self.drivers.items():
|
for _, driver in self.drivers.items():
|
||||||
# driver.execute_script("sauce:context=Started %s" % method.__name__)
|
driver.execute_script("lambda-testCase-start=%s" % method.__name__)
|
||||||
|
driver.log_event("appium", "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():
|
||||||
|
@ -423,7 +360,7 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
log_names, log_contents = [], []
|
log_names, log_contents = [], []
|
||||||
for driver in self.drivers:
|
for driver in self.drivers:
|
||||||
try:
|
try:
|
||||||
self.print_sauce_lab_info(self.drivers[driver])
|
self.print_lt_session_info(self.drivers[driver])
|
||||||
self.add_alert_text_to_report(self.drivers[driver])
|
self.add_alert_text_to_report(self.drivers[driver])
|
||||||
log_names.append(
|
log_names.append(
|
||||||
'%s_geth%s.log' % (test_suite_data.current_test.name, str(self.drivers[driver].number)))
|
'%s_geth%s.log' % (test_suite_data.current_test.name, str(self.drivers[driver].number)))
|
||||||
|
@ -451,7 +388,6 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def teardown_class(cls):
|
def teardown_class(cls):
|
||||||
from tests.conftest import sauce
|
|
||||||
requests_session = requests.Session()
|
requests_session = requests.Session()
|
||||||
requests_session.auth = (lambda_test_username, lambda_test_access_key)
|
requests_session.auth = (lambda_test_username, lambda_test_access_key)
|
||||||
if test_suite_data.tests[0].testruns[-1].error and 'setup failed' in test_suite_data.tests[0].testruns[
|
if test_suite_data.tests[0].testruns[-1].error and 'setup failed' in test_suite_data.tests[0].testruns[
|
||||||
|
@ -467,20 +403,13 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
log_names.append('%s_geth%s.log' % (cls.__name__, i))
|
log_names.append('%s_geth%s.log' % (cls.__name__, i))
|
||||||
log_contents.append(pull_requests_log(driver=driver))
|
log_contents.append(pull_requests_log(driver=driver))
|
||||||
log_names.append('%s_requests%s.log' % (cls.__name__, i))
|
log_names.append('%s_requests%s.log' % (cls.__name__, i))
|
||||||
session_id = driver.session_id
|
lt_session_status = "failed"
|
||||||
from support.lambda_test import update_session
|
else:
|
||||||
try:
|
lt_session_status = "passed"
|
||||||
# sauce.jobs.update_job(username=sauce_username, job_id=session_id, name=cls.__name__)
|
|
||||||
update_session(
|
|
||||||
session_id=session_id,
|
|
||||||
session_name=cls.__name__,
|
|
||||||
status="failed" if group_setup_failed else "passed"
|
|
||||||
)
|
|
||||||
except (RemoteDisconnected, SauceException, requests.exceptions.ConnectionError):
|
|
||||||
pass
|
|
||||||
try:
|
try:
|
||||||
|
driver.update_lt_session_status(i + 1, lt_session_status)
|
||||||
driver.quit()
|
driver.quit()
|
||||||
except WebDriverException:
|
except (WebDriverException, RemoteDisconnected):
|
||||||
pass
|
pass
|
||||||
# url = 'https://api.%s/rest/v1/%s/jobs/%s/assets/%s' % (apibase, sauce_username, session_id, "log.json")
|
# url = 'https://api.%s/rest/v1/%s/jobs/%s/assets/%s' % (apibase, sauce_username, session_id, "log.json")
|
||||||
# try:
|
# try:
|
||||||
|
@ -514,11 +443,9 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
|
||||||
|
|
||||||
|
|
||||||
if pytest_config_global['env'] == 'local':
|
if pytest_config_global['env'] == 'local':
|
||||||
MultipleDeviceTestCase = LocalMultipleDeviceTestCase
|
|
||||||
MultipleSharedDeviceTestCase = LocalSharedMultipleDeviceTestCase
|
MultipleSharedDeviceTestCase = LocalSharedMultipleDeviceTestCase
|
||||||
else:
|
else:
|
||||||
MultipleDeviceTestCase = SauceMultipleDeviceTestCase
|
MultipleSharedDeviceTestCase = LambdaTestSharedMultipleDeviceTestCase
|
||||||
MultipleSharedDeviceTestCase = SauceSharedMultipleDeviceTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class NoDeviceTestCase(AbstractTestCase):
|
class NoDeviceTestCase(AbstractTestCase):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
|
@ -11,6 +12,7 @@ from os import environ
|
||||||
import pytest
|
import pytest
|
||||||
import requests
|
import requests
|
||||||
from _pytest.runner import runtestprotocol
|
from _pytest.runner import runtestprotocol
|
||||||
|
from filelock import FileLock
|
||||||
from requests.exceptions import ConnectionError as c_er
|
from requests.exceptions import ConnectionError as c_er
|
||||||
|
|
||||||
import tests
|
import tests
|
||||||
|
@ -18,9 +20,6 @@ from support.device_stats_db import DeviceStatsDB
|
||||||
from support.test_rerun import should_rerun_test
|
from support.test_rerun import should_rerun_test
|
||||||
from tests import test_suite_data, appium_container
|
from tests import test_suite_data, appium_container
|
||||||
|
|
||||||
sauce_username = environ.get('SAUCE_USERNAME')
|
|
||||||
sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
|
|
||||||
|
|
||||||
lambda_test_username = environ.get('LAMBDA_TEST_USERNAME')
|
lambda_test_username = environ.get('LAMBDA_TEST_USERNAME')
|
||||||
lambda_test_access_key = environ.get('LAMBDA_TEST_ACCESS_KEY')
|
lambda_test_access_key = environ.get('LAMBDA_TEST_ACCESS_KEY')
|
||||||
|
|
||||||
|
@ -38,12 +37,8 @@ def pytest_addoption(parser):
|
||||||
help='Url or local path to apk')
|
help='Url or local path to apk')
|
||||||
parser.addoption('--env',
|
parser.addoption('--env',
|
||||||
action='store',
|
action='store',
|
||||||
default='sauce',
|
default='lt',
|
||||||
help='Specify environment: local/sauce/api')
|
help='Specify environment: local/lt/api')
|
||||||
parser.addoption('--datacenter',
|
|
||||||
action='store',
|
|
||||||
default='eu-central-1',
|
|
||||||
help='For sauce only: us-west-1, eu-central-1')
|
|
||||||
parser.addoption('--platform_version',
|
parser.addoption('--platform_version',
|
||||||
action='store',
|
action='store',
|
||||||
default='8.0',
|
default='8.0',
|
||||||
|
@ -60,10 +55,6 @@ def pytest_addoption(parser):
|
||||||
action='store',
|
action='store',
|
||||||
default=False,
|
default=False,
|
||||||
help='boolean; For creating testrail report per run')
|
help='boolean; For creating testrail report per run')
|
||||||
parser.addoption('--network',
|
|
||||||
action='store',
|
|
||||||
default='ropsten',
|
|
||||||
help='string; ropsten or rinkeby')
|
|
||||||
parser.addoption('--rerun_count',
|
parser.addoption('--rerun_count',
|
||||||
action='store',
|
action='store',
|
||||||
default=0,
|
default=0,
|
||||||
|
@ -145,32 +136,18 @@ def pytest_addoption(parser):
|
||||||
@dataclass
|
@dataclass
|
||||||
class Option:
|
class Option:
|
||||||
datacenter: str = None
|
datacenter: str = None
|
||||||
lambda_test_apk_url: str = None
|
|
||||||
|
|
||||||
|
|
||||||
option = Option()
|
option = Option()
|
||||||
testrail_report = None
|
testrail_report = None
|
||||||
github_report = None
|
github_report = None
|
||||||
apibase = None
|
|
||||||
sauce = None
|
|
||||||
run_name = None
|
run_name = None
|
||||||
|
|
||||||
|
|
||||||
# lambda_test_apk_url = None
|
|
||||||
|
|
||||||
|
|
||||||
def is_master(config):
|
def is_master(config):
|
||||||
return not hasattr(config, 'workerinput')
|
return not hasattr(config, 'workerinput')
|
||||||
|
|
||||||
|
|
||||||
def is_uploaded():
|
|
||||||
return False # ToDo: add verification
|
|
||||||
# stored_files = sauce.storage.files()
|
|
||||||
# for i in range(len(stored_files)):
|
|
||||||
# if stored_files[i].name == test_suite_data.apk_name:
|
|
||||||
# return True
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def _upload_time_limit(seconds):
|
def _upload_time_limit(seconds):
|
||||||
def signal_handler(signum, frame):
|
def signal_handler(signum, frame):
|
||||||
|
@ -193,20 +170,13 @@ class UploadApkException(Exception):
|
||||||
def _upload_and_check_response(apk_file_path):
|
def _upload_and_check_response(apk_file_path):
|
||||||
from support.lambda_test import upload_apk
|
from support.lambda_test import upload_apk
|
||||||
with _upload_time_limit(1000):
|
with _upload_time_limit(1000):
|
||||||
# # resp = sauce.storage.upload(apk_file_path)
|
|
||||||
return upload_apk(apk_file_path)
|
return upload_apk(apk_file_path)
|
||||||
# try:
|
|
||||||
# if resp.name != test_suite_data.apk_name:
|
|
||||||
# raise UploadApkException("Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp)
|
|
||||||
# except AttributeError:
|
|
||||||
# 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):
|
def _upload_and_check_response_with_retries(apk_file_path, retries=3):
|
||||||
for _ in range(retries):
|
for _ in range(retries):
|
||||||
try:
|
try:
|
||||||
return _upload_and_check_response(apk_file_path)
|
return _upload_and_check_response(apk_file_path)
|
||||||
# break
|
|
||||||
except (ConnectionError, RemoteDisconnected, c_er):
|
except (ConnectionError, RemoteDisconnected, c_er):
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
|
@ -252,20 +222,10 @@ def pytest_configure(config):
|
||||||
testrail_report = TestrailReport()
|
testrail_report = TestrailReport()
|
||||||
from support.github_report import GithubHtmlReport
|
from support.github_report import GithubHtmlReport
|
||||||
global github_report
|
global github_report
|
||||||
from saucelab_api_client.saucelab_api_client import SauceLab
|
|
||||||
github_report = GithubHtmlReport()
|
github_report = GithubHtmlReport()
|
||||||
tests.pytest_config_global = vars(config.option)
|
tests.pytest_config_global = vars(config.option)
|
||||||
config.addinivalue_line("markers", "testrail_id(name): empty")
|
config.addinivalue_line("markers", "testrail_id(name): empty")
|
||||||
global apibase
|
|
||||||
if config.getoption('datacenter') == 'us-west-1':
|
|
||||||
apibase = 'us-west-1.saucelabs.com'
|
|
||||||
elif config.getoption('datacenter') == 'eu-central-1':
|
|
||||||
apibase = 'eu-central-1.saucelabs.com'
|
|
||||||
else:
|
|
||||||
raise NotImplementedError("Unknown SauceLabs datacenter")
|
|
||||||
|
|
||||||
# global sauce
|
|
||||||
# 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)
|
||||||
|
@ -281,18 +241,6 @@ def pytest_configure(config):
|
||||||
else:
|
else:
|
||||||
run_name = get_run_name(config, new_one=False)
|
run_name = get_run_name(config, new_one=False)
|
||||||
|
|
||||||
if is_master(config):
|
|
||||||
apk_src = config.getoption('apk')
|
|
||||||
if apk_src.startswith('http'):
|
|
||||||
apk_path = _download_apk(apk_src)
|
|
||||||
else:
|
|
||||||
apk_path = apk_src
|
|
||||||
|
|
||||||
# global lambda_test_apk_url
|
|
||||||
option.lambda_test_apk_url = _upload_and_check_response(apk_path)
|
|
||||||
if apk_src.startswith('http'):
|
|
||||||
os.remove(apk_path)
|
|
||||||
|
|
||||||
if not is_master(config):
|
if not is_master(config):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -308,8 +256,23 @@ def pytest_configure(config):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure_node(node):
|
@pytest.fixture(scope='session', autouse=True)
|
||||||
node.workerinput['lambda_test_apk_url'] = node.config.option.lambda_test_apk_url
|
def upload_apk(tmp_path_factory):
|
||||||
|
fn = tmp_path_factory.getbasetemp().parent / "lt_apk.json"
|
||||||
|
with FileLock(str(fn) + ".lock"):
|
||||||
|
if fn.is_file():
|
||||||
|
data = json.loads(fn.read_text())
|
||||||
|
tests.pytest_config_global['lt_apk_url'] = data['lambda_test_apk_url']
|
||||||
|
else:
|
||||||
|
apk_src = tests.pytest_config_global['apk']
|
||||||
|
if apk_src.startswith('http'):
|
||||||
|
apk_path = _download_apk(apk_src)
|
||||||
|
else:
|
||||||
|
apk_path = apk_src
|
||||||
|
tests.pytest_config_global['lt_apk_url'] = _upload_and_check_response(apk_path)
|
||||||
|
fn.write_text(json.dumps({'lambda_test_apk_url': tests.pytest_config_global['lt_apk_url']}))
|
||||||
|
if apk_src.startswith('http'):
|
||||||
|
os.remove(apk_path)
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config):
|
def pytest_unconfigure(config):
|
||||||
|
@ -342,7 +305,6 @@ def pytest_runtest_makereport(item, call):
|
||||||
outcome = yield
|
outcome = yield
|
||||||
report = outcome.get_result()
|
report = outcome.get_result()
|
||||||
|
|
||||||
is_sauce_env = item.config.getoption('env') == 'sauce'
|
|
||||||
case_ids_set = item.config.getoption("run_testrail_ids")
|
case_ids_set = item.config.getoption("run_testrail_ids")
|
||||||
|
|
||||||
def catch_error():
|
def catch_error():
|
||||||
|
@ -381,10 +343,6 @@ def pytest_runtest_makereport(item, call):
|
||||||
test_suite_data.current_test.group_name = item.instance.__class__.__name__
|
test_suite_data.current_test.group_name = item.instance.__class__.__name__
|
||||||
error = catch_error()
|
error = catch_error()
|
||||||
final_error = '%s %s' % (error_intro, error)
|
final_error = '%s %s' % (error_intro, error)
|
||||||
# if is_sauce_env:
|
|
||||||
# update_sauce_jobs(test_suite_data.current_test.group_name,
|
|
||||||
# test_suite_data.current_test.testruns[-1].jobs,
|
|
||||||
# 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
|
||||||
github_report.save_test(test_suite_data.current_test)
|
github_report.save_test(test_suite_data.current_test)
|
||||||
|
@ -401,8 +359,6 @@ def pytest_runtest_makereport(item, call):
|
||||||
current_test.testruns[-1].run = False
|
current_test.testruns[-1].run = False
|
||||||
if error:
|
if error:
|
||||||
current_test.testruns[-1].error = '%s [[%s]]' % (error, report.wasxfail)
|
current_test.testruns[-1].error = '%s [[%s]]' % (error, report.wasxfail)
|
||||||
# if is_sauce_env:
|
|
||||||
# update_sauce_jobs(current_test.name, current_test.testruns[-1].jobs, report.passed)
|
|
||||||
if item.config.getoption('docker'):
|
if item.config.getoption('docker'):
|
||||||
device_stats = appium_container.get_device_stats()
|
device_stats = appium_container.get_device_stats()
|
||||||
if item.config.getoption('bugreport'):
|
if item.config.getoption('bugreport'):
|
||||||
|
@ -426,15 +382,6 @@ def pytest_runtest_makereport(item, call):
|
||||||
device_stats_db.save_stats(build_name, item.name, test_group, not report.failed, device_stats)
|
device_stats_db.save_stats(build_name, item.name, test_group, not report.failed, device_stats)
|
||||||
|
|
||||||
|
|
||||||
def update_sauce_jobs(test_name, job_ids, passed):
|
|
||||||
from sauceclient import SauceException
|
|
||||||
for job_id in job_ids.keys():
|
|
||||||
try:
|
|
||||||
sauce.jobs.update_job(username=sauce_username, job_id=job_id, name=test_name, passed=passed)
|
|
||||||
except (RemoteDisconnected, SauceException, c_er):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def get_testrail_case_id(item):
|
def get_testrail_case_id(item):
|
||||||
testrail_id = item.get_closest_marker('testrail_id')
|
testrail_id = item.get_closest_marker('testrail_id')
|
||||||
if testrail_id:
|
if testrail_id:
|
||||||
|
|
|
@ -14,7 +14,6 @@ from views.sign_in_view import SignInView
|
||||||
|
|
||||||
@pytest.mark.xdist_group(name="new_one_2")
|
@pytest.mark.xdist_group(name="new_one_2")
|
||||||
@marks.nightly
|
@marks.nightly
|
||||||
@marks.lt
|
|
||||||
class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
|
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
|
@ -61,13 +60,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
"Receiver also sets 'thumbs-up' emoji and verifies counter on received message in 1-1 chat")
|
"Receiver also sets 'thumbs-up' emoji and verifies counter on received message in 1-1 chat")
|
||||||
message_receiver = self.chat_2.chat_element_by_text(message_from_sender)
|
message_receiver = self.chat_2.chat_element_by_text(message_from_sender)
|
||||||
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1, 90)
|
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1, 90)
|
||||||
self.chat_2.add_remove_same_reaction(message_from_sender)
|
self.chat_2.add_remove_same_reaction()
|
||||||
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(2)
|
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(2)
|
||||||
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(2, 90)
|
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(2, 90)
|
||||||
|
|
||||||
self.device_2.just_fyi(
|
self.device_2.just_fyi(
|
||||||
"Receiver removes 'thumbs-up' emoji and verify that counter will decrease for both users")
|
"Receiver removes 'thumbs-up' emoji and verify that counter will decrease for both users")
|
||||||
self.chat_2.add_remove_same_reaction(message_from_sender)
|
self.chat_2.add_remove_same_reaction()
|
||||||
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
||||||
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1, 90)
|
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1, 90)
|
||||||
|
|
||||||
|
@ -79,21 +78,20 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
message_sender.emojis_below_message(emoji="love").wait_for_element_text(1, 90)
|
message_sender.emojis_below_message(emoji="love").wait_for_element_text(1, 90)
|
||||||
|
|
||||||
self.device_1.just_fyi("Sender votes for 'love' reaction. Check reactions counters")
|
self.device_1.just_fyi("Sender votes for 'love' reaction. Check reactions counters")
|
||||||
self.chat_1.add_remove_same_reaction(message_from_sender, emoji="love")
|
self.chat_1.add_remove_same_reaction(emoji="love")
|
||||||
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
message_receiver.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
||||||
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
message_sender.emojis_below_message(emoji="thumbs-up").wait_for_element_text(1)
|
||||||
message_receiver.emojis_below_message(emoji="love").wait_for_element_text(2, 90)
|
message_receiver.emojis_below_message(emoji="love").wait_for_element_text(2, 90)
|
||||||
message_sender.emojis_below_message(emoji="love").wait_for_element_text(2)
|
message_sender.emojis_below_message(emoji="love").wait_for_element_text(2)
|
||||||
|
|
||||||
self.device_1.just_fyi("Check emojis info")
|
self.device_1.just_fyi("Check emojis info")
|
||||||
message_sender.emojis_below_message(emoji="love").long_press_until_element_is_shown(
|
message_sender.emojis_below_message(emoji="love").long_press_without_release()
|
||||||
self.chat_1.authors_for_reaction(emoji="love"))
|
|
||||||
if not self.chat_1.user_list_element_by_name(
|
if not self.chat_1.user_list_element_by_name(
|
||||||
self.username_1).is_element_displayed() or not self.chat_1.user_list_element_by_name(
|
self.username_1).is_element_displayed() or not self.chat_1.user_list_element_by_name(
|
||||||
self.username_2).is_element_displayed():
|
self.username_2).is_element_displayed():
|
||||||
self.errors.append("Incorrect users are shown for 'love' reaction.")
|
self.errors.append("Incorrect users are shown for 'love' reaction.")
|
||||||
|
|
||||||
self.chat_1.authors_for_reaction(emoji="thumbs-up").click()
|
self.chat_1.authors_for_reaction(emoji="thumbs-up").double_click()
|
||||||
if not self.chat_1.user_list_element_by_name(
|
if not self.chat_1.user_list_element_by_name(
|
||||||
self.username_1).is_element_displayed() or self.chat_1.user_list_element_by_name(
|
self.username_1).is_element_displayed() or self.chat_1.user_list_element_by_name(
|
||||||
self.username_2).is_element_displayed():
|
self.username_2).is_element_displayed():
|
||||||
|
@ -232,8 +230,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
self.errors.append("Can pin more than 3 messages in chat")
|
self.errors.append("Can pin more than 3 messages in chat")
|
||||||
else:
|
else:
|
||||||
unpin_element = self.chat_1.element_by_translation_id('unpin-from-chat')
|
unpin_element = self.chat_1.element_by_translation_id('unpin-from-chat')
|
||||||
self.chat_1.pinned_messages_list.message_element_by_text(self.message_2).long_press_element(
|
self.chat_1.pinned_messages_list.message_element_by_text(self.message_2).long_press_without_release()
|
||||||
element_to_release_on=unpin_element)
|
|
||||||
self.home_1.just_fyi("Unpin one message so that another could be pinned")
|
self.home_1.just_fyi("Unpin one message so that another could be pinned")
|
||||||
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
|
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
|
||||||
self.chat_1.pin_message(self.message_4, 'pin-to-chat')
|
self.chat_1.pin_message(self.message_4, 'pin-to-chat')
|
||||||
|
@ -254,7 +251,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
pinned_message = self.chat_1.pinned_messages_list.message_element_by_text(self.message_4)
|
pinned_message = self.chat_1.pinned_messages_list.message_element_by_text(self.message_4)
|
||||||
|
|
||||||
unpin_element = self.chat_1.element_by_translation_id("unpin-from-chat")
|
unpin_element = self.chat_1.element_by_translation_id("unpin-from-chat")
|
||||||
pinned_message.long_press_element(element_to_release_on=unpin_element)
|
pinned_message.long_press_without_release()
|
||||||
unpin_element.click_until_absense_of_element(unpin_element)
|
unpin_element.click_until_absense_of_element(unpin_element)
|
||||||
# try:
|
# try:
|
||||||
# self.chat_2.chat_element_by_text(self.message_4).pinned_by_label.wait_for_invisibility_of_element()
|
# self.chat_2.chat_element_by_text(self.message_4).pinned_by_label.wait_for_invisibility_of_element()
|
||||||
|
@ -276,7 +273,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
def test_1_1_chat_non_latin_messages_stack_update_profile_photo(self):
|
def test_1_1_chat_non_latin_messages_stack_update_profile_photo(self):
|
||||||
self.home_1.navigate_back_to_home_view()
|
self.home_1.navigate_back_to_home_view()
|
||||||
self.home_1.profile_button.click()
|
self.home_1.profile_button.click()
|
||||||
self.profile_1.edit_profile_picture(image_index=2)
|
self.profile_1.edit_profile_picture(image_index=0)
|
||||||
|
|
||||||
self.chat_2.just_fyi("Send messages with non-latin symbols")
|
self.chat_2.just_fyi("Send messages with non-latin symbols")
|
||||||
self.home_1.click_system_back_button()
|
self.home_1.click_system_back_button()
|
||||||
|
@ -315,8 +312,8 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
self.chat_1.just_fyi("Go back to chat view and checking that profile photo is updated")
|
self.chat_1.just_fyi("Go back to chat view and checking that profile photo is updated")
|
||||||
if not self.chat_2.chat_message_input.is_element_displayed():
|
if not self.chat_2.chat_message_input.is_element_displayed():
|
||||||
self.home_2.get_chat(self.username_1).click()
|
self.home_2.get_chat(self.username_1).click()
|
||||||
if self.chat_2.chat_element_by_text(message).member_photo.is_element_differs_from_template("member3.png",
|
if self.chat_2.chat_element_by_text(message).member_photo.is_element_differs_from_template(
|
||||||
diff=7):
|
"profile_image_in_1_1_chat.png", diff=7):
|
||||||
self.errors.append("Image of user in 1-1 chat is too different from template!")
|
self.errors.append("Image of user in 1-1 chat is too different from template!")
|
||||||
self.errors.verify_no_errors()
|
self.errors.verify_no_errors()
|
||||||
|
|
||||||
|
@ -415,14 +412,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
|
|
||||||
self.chat_1.just_fyi("Device 1 sends an image")
|
self.chat_1.just_fyi("Device 1 sends an image")
|
||||||
image_description = "test image"
|
image_description = "test image"
|
||||||
self.chat_1.send_images_with_description(description=image_description, indexes=[2])
|
self.chat_1.send_images_with_description(description=image_description, indexes=[0])
|
||||||
|
|
||||||
self.chat_2.just_fyi("Device 2 checks image message")
|
self.chat_2.just_fyi("Device 2 checks image message")
|
||||||
if not self.chat_2.chat_element_by_text(image_description).is_element_displayed(30):
|
if not self.chat_2.chat_element_by_text(image_description).is_element_displayed(30):
|
||||||
self.chat_2.hide_keyboard_if_shown()
|
self.chat_2.hide_keyboard_if_shown()
|
||||||
self.chat_2.chat_element_by_text(image_description).wait_for_visibility_of_element(30)
|
self.chat_2.chat_element_by_text(image_description).wait_for_visibility_of_element(30)
|
||||||
if not self.chat_2.chat_element_by_text(
|
if not self.chat_2.chat_element_by_text(
|
||||||
image_description).image_in_message.is_element_image_similar_to_template('saucelabs_sauce_chat.png'):
|
image_description).image_in_message.is_element_image_similar_to_template('image_1_chat_view.png'):
|
||||||
self.errors.append("Not expected image is shown to the receiver.")
|
self.errors.append("Not expected image is shown to the receiver.")
|
||||||
|
|
||||||
for chat in self.chat_1, self.chat_2:
|
for chat in self.chat_1, self.chat_2:
|
||||||
|
@ -460,7 +457,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
chat.just_fyi("Check that image is saved in gallery")
|
chat.just_fyi("Check that image is saved in gallery")
|
||||||
chat.show_images_button.click()
|
chat.show_images_button.click()
|
||||||
chat.allow_all_button.click_if_shown()
|
chat.allow_all_button.click_if_shown()
|
||||||
if not chat.get_image_by_index(0).is_element_image_similar_to_template("saucelabs_sauce_gallery.png"):
|
if not chat.get_image_by_index(0).is_element_image_similar_to_template("image_1_gallery_view.png"):
|
||||||
self.errors.append(
|
self.errors.append(
|
||||||
"Image is not saved to gallery for %s." % ("sender" if chat is self.chat_1 else "receiver"))
|
"Image is not saved to gallery for %s." % ("sender" if chat is self.chat_1 else "receiver"))
|
||||||
chat.click_system_back_button()
|
chat.click_system_back_button()
|
||||||
|
@ -485,7 +482,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
self.chat_2.send_message(message_after_edit_1_1)
|
self.chat_2.send_message(message_after_edit_1_1)
|
||||||
self.chat_2.chat_element_by_text(message_after_edit_1_1).wait_for_status_to_be("Delivered")
|
self.chat_2.chat_element_by_text(message_after_edit_1_1).wait_for_status_to_be("Delivered")
|
||||||
chat_1_element = self.chat_1.chat_element_by_text(message_after_edit_1_1)
|
chat_1_element = self.chat_1.chat_element_by_text(message_after_edit_1_1)
|
||||||
chat_1_element.long_press_element()
|
chat_1_element.long_press_without_release()
|
||||||
for action in ("edit", "delete-for-everyone"):
|
for action in ("edit", "delete-for-everyone"):
|
||||||
if self.chat_1.element_by_translation_id(action).is_element_displayed():
|
if self.chat_1.element_by_translation_id(action).is_element_displayed():
|
||||||
self.errors.append('Option to %s someone else message available!' % action)
|
self.errors.append('Option to %s someone else message available!' % action)
|
||||||
|
@ -643,13 +640,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
|
||||||
|
|
||||||
self.chat_1.just_fyi("Unmute chat")
|
self.chat_1.just_fyi("Unmute chat")
|
||||||
self.chat_1.navigate_back_to_home_view()
|
self.chat_1.navigate_back_to_home_view()
|
||||||
chat.long_press_element()
|
chat.long_press_without_release()
|
||||||
if self.home_1.mute_chat_button.text != transl["unmute-chat"]:
|
if self.home_1.mute_chat_button.text != transl["unmute-chat"]:
|
||||||
self.errors.append("Chat is not muted")
|
self.errors.append("Chat is not muted")
|
||||||
expected_text = "Muted until you turn it back on"
|
expected_text = "Muted until you turn it back on"
|
||||||
if not self.home_1.element_by_text(expected_text).is_element_displayed():
|
if not self.home_1.element_by_text(expected_text).is_element_displayed():
|
||||||
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
|
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
|
||||||
self.home_1.mute_chat_button.click()
|
self.home_1.mute_chat_button.double_click()
|
||||||
|
|
||||||
unmuted_message = "after unmute"
|
unmuted_message = "after unmute"
|
||||||
self.chat_2.send_message(unmuted_message)
|
self.chat_2.send_message(unmuted_message)
|
||||||
|
|
|
@ -13,7 +13,6 @@ from views.sign_in_view import SignInView
|
||||||
|
|
||||||
@pytest.mark.xdist_group(name="new_one_3")
|
@pytest.mark.xdist_group(name="new_one_3")
|
||||||
@marks.nightly
|
@marks.nightly
|
||||||
@marks.lt
|
|
||||||
class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
|
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
|
@ -119,7 +118,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.chats[1].set_reaction(message=message, emoji="love")
|
self.chats[1].set_reaction(message=message, emoji="love")
|
||||||
|
|
||||||
self.chats[2].just_fyi("Member_2 sets 2 reactions on the message: 'thumbs-up' and 'laugh'")
|
self.chats[2].just_fyi("Member_2 sets 2 reactions on the message: 'thumbs-up' and 'laugh'")
|
||||||
self.chats[2].add_remove_same_reaction(message=message, emoji="thumbs-up")
|
self.chats[2].add_remove_same_reaction(emoji="thumbs-up")
|
||||||
self.chats[2].set_reaction(message=message, emoji="laugh")
|
self.chats[2].set_reaction(message=message, emoji="laugh")
|
||||||
|
|
||||||
def _check_reactions_count(chat_view_index):
|
def _check_reactions_count(chat_view_index):
|
||||||
|
@ -136,14 +135,13 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
)))
|
)))
|
||||||
|
|
||||||
self.chats[0].just_fyi("Admin checks info about voted users")
|
self.chats[0].just_fyi("Admin checks info about voted users")
|
||||||
self.chats[0].chat_element_by_text(message).emojis_below_message(
|
self.chats[0].chat_element_by_text(message).emojis_below_message(emoji="thumbs-up").long_press_without_release()
|
||||||
emoji="thumbs-up").long_press_until_element_is_shown(self.chats[0].authors_for_reaction(emoji="thumbs-up"))
|
|
||||||
if not self.chats[0].user_list_element_by_name(
|
if not self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
|
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[2]).is_element_displayed():
|
self.usernames[2]).is_element_displayed():
|
||||||
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction.")
|
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction.")
|
||||||
|
|
||||||
self.chats[0].authors_for_reaction(emoji="love").click()
|
self.chats[0].authors_for_reaction(emoji="love").double_click()
|
||||||
if not self.chats[0].user_list_element_by_name(
|
if not self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
|
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[2]).is_element_displayed():
|
self.usernames[2]).is_element_displayed():
|
||||||
|
@ -169,12 +167,12 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.chats[0].navigate_back_to_chat_view()
|
self.chats[0].navigate_back_to_chat_view()
|
||||||
|
|
||||||
self.chats[1].just_fyi("Member_1 removes 'thumbs-up' reaction and adds 'sad' one")
|
self.chats[1].just_fyi("Member_1 removes 'thumbs-up' reaction and adds 'sad' one")
|
||||||
self.chats[1].add_remove_same_reaction(message=message, emoji="thumbs-up")
|
self.chats[1].add_remove_same_reaction(emoji="thumbs-up")
|
||||||
self.chats[1].set_reaction(message=message, emoji="sad")
|
self.chats[1].set_reaction(message=message, emoji="sad")
|
||||||
|
|
||||||
self.chats[2].just_fyi("Member_2 removes 'laugh' reaction and adds 'sad' one")
|
self.chats[2].just_fyi("Member_2 removes 'laugh' reaction and adds 'sad' one")
|
||||||
self.chats[2].add_remove_same_reaction(message=message, emoji="laugh")
|
self.chats[2].add_remove_same_reaction(emoji="laugh")
|
||||||
self.chats[2].add_remove_same_reaction(message=message, emoji="sad")
|
self.chats[2].add_remove_same_reaction(emoji="sad")
|
||||||
|
|
||||||
def _check_reactions_count_after_change(chat_view_index):
|
def _check_reactions_count_after_change(chat_view_index):
|
||||||
self.chats[chat_view_index].just_fyi(
|
self.chats[chat_view_index].just_fyi(
|
||||||
|
@ -212,14 +210,13 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
chat.navigate_back_to_home_view()
|
chat.navigate_back_to_home_view()
|
||||||
|
|
||||||
self.chats[0].just_fyi("Admin checks info about voted users after relogin")
|
self.chats[0].just_fyi("Admin checks info about voted users after relogin")
|
||||||
message_element.emojis_below_message(
|
message_element.emojis_below_message(emoji="thumbs-up").long_press_without_release()
|
||||||
emoji="thumbs-up").long_press_until_element_is_shown(self.chats[0].authors_for_reaction(emoji="thumbs-up"))
|
|
||||||
if self.chats[0].user_list_element_by_name(
|
if self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
|
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[2]).is_element_displayed():
|
self.usernames[2]).is_element_displayed():
|
||||||
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction after relogin.")
|
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction after relogin.")
|
||||||
|
|
||||||
self.chats[0].authors_for_reaction(emoji="love").click()
|
self.chats[0].authors_for_reaction(emoji="love").double_click()
|
||||||
if not self.chats[0].user_list_element_by_name(
|
if not self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
|
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
|
||||||
self.usernames[2]).is_element_displayed():
|
self.usernames[2]).is_element_displayed():
|
||||||
|
@ -241,18 +238,18 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
|
|
||||||
self.chats[1].just_fyi("Member_1 sends an image")
|
self.chats[1].just_fyi("Member_1 sends an image")
|
||||||
image_description = "test image"
|
image_description = "test image"
|
||||||
self.chats[1].send_images_with_description(description=image_description, indexes=[2])
|
self.chats[1].send_images_with_description(description=image_description, indexes=[1])
|
||||||
|
|
||||||
self.chats[0].just_fyi("Admin checks image message")
|
self.chats[0].just_fyi("Admin checks image message")
|
||||||
chat_element = self.chats[0].chat_element_by_text(image_description)
|
chat_element = self.chats[0].chat_element_by_text(image_description)
|
||||||
chat_element.wait_for_visibility_of_element(60)
|
chat_element.wait_for_visibility_of_element(60)
|
||||||
if not chat_element.image_in_message.is_element_image_similar_to_template('saucelabs_sauce_group_chat.png'):
|
if not chat_element.image_in_message.is_element_image_similar_to_template('image_2_chat_view.png'):
|
||||||
self.errors.append("Not expected image is shown to the admin.")
|
self.errors.append("Not expected image is shown to the admin.")
|
||||||
|
|
||||||
self.chats[2].just_fyi("Member_2 checks image message")
|
self.chats[2].just_fyi("Member_2 checks image message")
|
||||||
chat_element = self.chats[2].chat_element_by_text(image_description)
|
chat_element = self.chats[2].chat_element_by_text(image_description)
|
||||||
chat_element.wait_for_visibility_of_element(60)
|
chat_element.wait_for_visibility_of_element(60)
|
||||||
if not chat_element.image_in_message.is_element_image_similar_to_template('saucelabs_sauce_group_chat.png'):
|
if not chat_element.image_in_message.is_element_image_similar_to_template('image_2_chat_view.png'):
|
||||||
self.errors.append("Not expected image is shown to the member_2.")
|
self.errors.append("Not expected image is shown to the member_2.")
|
||||||
|
|
||||||
self.chats[0].just_fyi("Admin opens the image and shares it")
|
self.chats[0].just_fyi("Admin opens the image and shares it")
|
||||||
|
@ -293,7 +290,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.chats[2].just_fyi("Member_2 checks that image was saved in gallery")
|
self.chats[2].just_fyi("Member_2 checks that image was saved in gallery")
|
||||||
self.chats[2].show_images_button.click()
|
self.chats[2].show_images_button.click()
|
||||||
self.chats[2].allow_all_button.click_if_shown()
|
self.chats[2].allow_all_button.click_if_shown()
|
||||||
if not self.chats[2].get_image_by_index(0).is_element_image_similar_to_template("saucelabs_sauce_gallery.png"):
|
if not self.chats[2].get_image_by_index(0).is_element_image_similar_to_template("image_2_gallery_view.png"):
|
||||||
self.errors.append("Image is not saved to gallery for member_2.")
|
self.errors.append("Image is not saved to gallery for member_2.")
|
||||||
self.chats[2].navigate_back_to_home_view()
|
self.chats[2].navigate_back_to_home_view()
|
||||||
|
|
||||||
|
@ -374,10 +371,11 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.errors.append("Message 1 is not pinned in group chat!")
|
self.errors.append("Message 1 is not pinned in group chat!")
|
||||||
|
|
||||||
self.chats[0].just_fyi("Check that non admin user can not unpin messages")
|
self.chats[0].just_fyi("Check that non admin user can not unpin messages")
|
||||||
self.chats[1].chat_element_by_text(self.message_1).long_press_element()
|
self.chats[1].chat_element_by_text(self.message_1).long_press_without_release()
|
||||||
if self.chats[1].element_by_translation_id("unpin-from-chat").is_element_displayed():
|
if self.chats[1].element_by_translation_id("unpin-from-chat").is_element_displayed():
|
||||||
self.errors.append("Unpin option is available for non-admin user")
|
self.errors.append("Unpin option is available for non-admin user")
|
||||||
self.chats[1].tap_by_coordinates(500, 100)
|
self.chats[1].tap_by_coordinates(500, 100)
|
||||||
|
self.chats[1].tap_by_coordinates(500, 100)
|
||||||
|
|
||||||
# not implemented yet :
|
# not implemented yet :
|
||||||
|
|
||||||
|
@ -406,8 +404,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.chats[0].pin_message(self.message_4, 'pin-to-chat')
|
self.chats[0].pin_message(self.message_4, 'pin-to-chat')
|
||||||
self.chats[0].view_pinned_messages_button.click_until_presence_of_element(self.chats[0].pinned_messages_list)
|
self.chats[0].view_pinned_messages_button.click_until_presence_of_element(self.chats[0].pinned_messages_list)
|
||||||
unpin_element = self.chats[0].element_by_translation_id('unpin-from-chat')
|
unpin_element = self.chats[0].element_by_translation_id('unpin-from-chat')
|
||||||
self.chats[0].pinned_messages_list.message_element_by_text(self.message_2).long_press_element(
|
self.chats[0].pinned_messages_list.message_element_by_text(self.message_2).long_press_without_release()
|
||||||
element_to_release_on=unpin_element)
|
|
||||||
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
|
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
|
||||||
self.chats[0].chat_element_by_text(self.message_4).click()
|
self.chats[0].chat_element_by_text(self.message_4).click()
|
||||||
self.chats[0].pin_message(self.message_4, 'pin-to-chat')
|
self.chats[0].pin_message(self.message_4, 'pin-to-chat')
|
||||||
|
@ -457,7 +454,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
"Muted until %s %s" % (exp_time.strftime('%H:%M'), "today" if current_time.hour < 16 else "tomorrow") for
|
"Muted until %s %s" % (exp_time.strftime('%H:%M'), "today" if current_time.hour < 16 else "tomorrow") for
|
||||||
exp_time in expected_times]
|
exp_time in expected_times]
|
||||||
chat = self.homes[1].get_chat(self.chat_name)
|
chat = self.homes[1].get_chat(self.chat_name)
|
||||||
chat.long_press_element()
|
chat.long_press_without_release()
|
||||||
if self.homes[1].mute_chat_button.text != transl["unmute-chat"]:
|
if self.homes[1].mute_chat_button.text != transl["unmute-chat"]:
|
||||||
pytest.fail("Chat is not muted")
|
pytest.fail("Chat is not muted")
|
||||||
current_text = self.homes[1].mute_chat_button.unmute_caption_text
|
current_text = self.homes[1].mute_chat_button.unmute_caption_text
|
||||||
|
@ -487,15 +484,16 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[0], muted_message[:25])):
|
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[0], muted_message[:25])):
|
||||||
self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message)
|
self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message)
|
||||||
chat.click()
|
chat.click()
|
||||||
|
chat.click()
|
||||||
if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30):
|
if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30):
|
||||||
self.errors.append(
|
self.errors.append(
|
||||||
"Message '%s' is not shown in chat for %s after mute" % (muted_message, self.usernames[1]))
|
"Message '%s' is not shown in chat for %s (Member 1) after mute" % (muted_message, self.usernames[1]))
|
||||||
self.chats[1].navigate_back_to_home_view()
|
self.chats[1].navigate_back_to_home_view()
|
||||||
|
|
||||||
self.chats[1].just_fyi("Member 1 unmutes the chat")
|
self.chats[1].just_fyi("Member 1 unmutes the chat")
|
||||||
chat.long_press_element()
|
chat.long_press_without_release()
|
||||||
self.homes[1].mute_chat_button.click()
|
self.homes[1].mute_chat_button.double_click()
|
||||||
chat.long_press_element()
|
chat.long_press_without_release()
|
||||||
if self.homes[1].element_starts_with_text("Muted until").is_element_displayed():
|
if self.homes[1].element_starts_with_text("Muted until").is_element_displayed():
|
||||||
self.errors.append("Chat is still muted after being unmuted")
|
self.errors.append("Chat is still muted after being unmuted")
|
||||||
self.errors.verify_no_errors()
|
self.errors.verify_no_errors()
|
||||||
|
@ -523,8 +521,10 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[2], unmuted_message)):
|
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[2], unmuted_message)):
|
||||||
self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
|
self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
|
||||||
chat.click()
|
chat.click()
|
||||||
|
chat.click()
|
||||||
if not self.chats[1].chat_element_by_text(unmuted_message).is_element_displayed(30):
|
if not self.chats[1].chat_element_by_text(unmuted_message).is_element_displayed(30):
|
||||||
self.errors.append(
|
self.errors.append(
|
||||||
"Message '%s' is not shown in chat for %s after unmute" % (self.usernames[1], unmuted_message))
|
"Message '%s' is not shown in chat for %s (Member 1) after unmute" % (
|
||||||
|
unmuted_message, self.usernames[1]))
|
||||||
|
|
||||||
self.errors.verify_no_errors()
|
self.errors.verify_no_errors()
|
||||||
|
|
|
@ -281,11 +281,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
# if community_name == 'Status':
|
# if community_name == 'Status':
|
||||||
self.home.just_fyi("Check Status community screen")
|
self.home.just_fyi("Check Status community screen")
|
||||||
card.click()
|
card.click()
|
||||||
self.community_view.join_button.save_new_screenshot_of_element('status_community_join_button_aaa.png')
|
|
||||||
if self.community_view.join_button.is_element_differs_from_template(
|
if self.community_view.join_button.is_element_differs_from_template(
|
||||||
'status_community_join_button.png'):
|
'status_community_join_button.png'):
|
||||||
self.errors.append("Status community Join button is different from expected template.")
|
self.errors.append("Status community Join button is different from expected template.")
|
||||||
self.community_view.community_logo.save_new_screenshot_of_element('status_community_logo_aaa.png')
|
|
||||||
if self.community_view.community_logo.is_element_differs_from_template('status_community_logo.png'):
|
if self.community_view.community_logo.is_element_differs_from_template('status_community_logo.png'):
|
||||||
self.errors.append("Status community logo is different from expected template.")
|
self.errors.append("Status community logo is different from expected template.")
|
||||||
|
|
||||||
|
@ -412,7 +410,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
@marks.testrail_id(703194)
|
@marks.testrail_id(703194)
|
||||||
def test_community_several_images_send_reply(self):
|
def test_community_several_images_send_reply(self):
|
||||||
self.home_1.just_fyi('Send several images in 1-1 chat from Gallery')
|
self.home_1.just_fyi('Send several images in 1-1 chat from Gallery')
|
||||||
image_description, file_name = 'gallery', 'gallery_1.png'
|
image_description = 'gallery'
|
||||||
self.channel_1.send_images_with_description(image_description, [0, 1])
|
self.channel_1.send_images_with_description(image_description, [0, 1])
|
||||||
|
|
||||||
self.channel_2.just_fyi("Check gallery on second device")
|
self.channel_2.just_fyi("Check gallery on second device")
|
||||||
|
@ -423,7 +421,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
try:
|
try:
|
||||||
chat_element.wait_for_visibility_of_element(120)
|
chat_element.wait_for_visibility_of_element(120)
|
||||||
received = True
|
received = True
|
||||||
if chat_element.image_container_in_message.is_element_differs_from_template(file_name, 5):
|
if chat_element.image_container_in_message.is_element_differs_from_template("images_gallery.png", 5):
|
||||||
self.errors.append("Gallery message do not match the template!")
|
self.errors.append("Gallery message do not match the template!")
|
||||||
except TimeoutException:
|
except TimeoutException:
|
||||||
self.errors.append("Gallery message was not received")
|
self.errors.append("Gallery message was not received")
|
||||||
|
@ -465,7 +463,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
self.channel_2.hide_keyboard_if_shown()
|
self.channel_2.hide_keyboard_if_shown()
|
||||||
self.channel_2.chat_element_by_text(image_description).wait_for_visibility_of_element(10)
|
self.channel_2.chat_element_by_text(image_description).wait_for_visibility_of_element(10)
|
||||||
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_1_chat_view.png'):
|
||||||
self.errors.append("Not expected image is shown to the receiver")
|
self.errors.append("Not expected image is shown to the receiver")
|
||||||
|
|
||||||
if not self.channel_1.chat_element_by_text(image_description).is_element_displayed(60):
|
if not self.channel_1.chat_element_by_text(image_description).is_element_displayed(60):
|
||||||
|
@ -489,7 +487,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
self.channel_1.show_images_button.click()
|
self.channel_1.show_images_button.click()
|
||||||
self.channel_1.allow_all_button.click_if_shown()
|
self.channel_1.allow_all_button.click_if_shown()
|
||||||
if not self.channel_1.get_image_by_index(0).is_element_image_similar_to_template(
|
if not self.channel_1.get_image_by_index(0).is_element_image_similar_to_template(
|
||||||
"sauce_dark_image_gallery.png"):
|
"image_1_gallery_view.png"):
|
||||||
self.errors.append('Saved image is not shown in Recent')
|
self.errors.append('Saved image is not shown in Recent')
|
||||||
self.channel_1.click_system_back_button()
|
self.channel_1.click_system_back_button()
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
|
||||||
self.sign_in_2.continue_button.click()
|
self.sign_in_2.continue_button.click()
|
||||||
if not self.sign_in_2.password_input.is_element_displayed():
|
if not self.sign_in_2.password_input.is_element_displayed():
|
||||||
self.errors.append("Can't recover an access with a valid passphrase")
|
self.errors.append("Can't recover an access with a valid passphrase")
|
||||||
self.sign_in_2.click_system_back_button()
|
self.sign_in_2.click_system_back_button(times=2)
|
||||||
|
|
||||||
self.sign_in_2.just_fyi("Device 2: try recovering an account which is already synced")
|
self.sign_in_2.just_fyi("Device 2: try recovering an account which is already synced")
|
||||||
self.sign_in_2.passphrase_edit_box.clear()
|
self.sign_in_2.passphrase_edit_box.clear()
|
||||||
|
|
|
@ -13,5 +13,3 @@ upgrade = pytest.mark.upgrade
|
||||||
skip = pytest.mark.skip
|
skip = pytest.mark.skip
|
||||||
xfail = pytest.mark.xfail
|
xfail = pytest.mark.xfail
|
||||||
secured = pytest.mark.secured
|
secured = pytest.mark.secured
|
||||||
|
|
||||||
lt = pytest.mark.lt # temp
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from tests import marks, pytest_config_global, test_dapp_name
|
from tests import marks, pytest_config_global, test_dapp_name
|
||||||
from tests.base_test_case import SingleDeviceTestCase, MultipleDeviceTestCase
|
from tests.base_test_case import SingleDeviceTestCase, MultipleSharedDeviceTestCase
|
||||||
from tests.users import upgrade_users, transaction_recipients, basic_user, ens_user, transaction_senders
|
from tests.users import upgrade_users, transaction_recipients, basic_user, ens_user, transaction_senders
|
||||||
from views.sign_in_view import SignInView
|
from views.sign_in_view import SignInView
|
||||||
import views.dbs.chats.data as chat_data
|
import views.dbs.chats.data as chat_data
|
||||||
|
@ -245,7 +245,7 @@ class TestUpgradeApplication(SingleDeviceTestCase):
|
||||||
|
|
||||||
|
|
||||||
@marks.upgrade
|
@marks.upgrade
|
||||||
class TestUpgradeMultipleApplication(MultipleDeviceTestCase):
|
class TestUpgradeMultipleApplication(MultipleSharedDeviceTestCase):
|
||||||
|
|
||||||
@marks.testrail_id(695783)
|
@marks.testrail_id(695783)
|
||||||
def test_commands_audio_backward_compatibility_upgrade(self):
|
def test_commands_audio_backward_compatibility_upgrade(self):
|
||||||
|
|
|
@ -10,6 +10,9 @@ from PIL import Image, ImageChops, ImageStat
|
||||||
from appium.webdriver.common.mobileby import MobileBy
|
from appium.webdriver.common.mobileby import MobileBy
|
||||||
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException, TimeoutException
|
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException, TimeoutException
|
||||||
from selenium.webdriver import ActionChains
|
from selenium.webdriver import ActionChains
|
||||||
|
from selenium.webdriver.common.actions import interaction
|
||||||
|
from selenium.webdriver.common.actions.action_builder import ActionBuilder
|
||||||
|
from selenium.webdriver.common.actions.pointer_input import PointerInput
|
||||||
from selenium.webdriver.support import expected_conditions
|
from selenium.webdriver.support import expected_conditions
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
|
|
||||||
|
@ -324,9 +327,21 @@ class BaseElement(object):
|
||||||
action.click_and_hold(element).perform()
|
action.click_and_hold(element).perform()
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
if element_to_release_on:
|
if element_to_release_on:
|
||||||
action.release(element_to_release_on.find_element()).perform()
|
action.release(element_to_release_on.find_element())
|
||||||
|
action.perform()
|
||||||
else:
|
else:
|
||||||
action.release(element).perform()
|
action.release(element)
|
||||||
|
action.perform()
|
||||||
|
|
||||||
|
# actions = ActionChains(self.driver)
|
||||||
|
# actions.w3c_actions = ActionBuilder(self, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
|
||||||
|
# actions.w3c_actions.pointer_action.click_and_hold(element)
|
||||||
|
# actions.w3c_actions.pointer_action.release()
|
||||||
|
# actions.perform()
|
||||||
|
|
||||||
|
def long_press_without_release(self):
|
||||||
|
action = ActionChains(self.driver)
|
||||||
|
action.click_and_hold(self.find_element()).perform()
|
||||||
|
|
||||||
def long_press_until_element_is_shown(self, expected_element):
|
def long_press_until_element_is_shown(self, expected_element):
|
||||||
element = self.find_element()
|
element = self.find_element()
|
||||||
|
|
|
@ -411,6 +411,7 @@ class BaseView(object):
|
||||||
def just_fyi(self, some_str):
|
def just_fyi(self, some_str):
|
||||||
self.driver.info('# STEP: %s' % some_str, device=False)
|
self.driver.info('# STEP: %s' % some_str, device=False)
|
||||||
# self.driver.execute_script("sauce:context=STEP: %s" % some_str)
|
# self.driver.execute_script("sauce:context=STEP: %s" % some_str)
|
||||||
|
self.driver.log_event("appium", "STEP: %s" % some_str)
|
||||||
|
|
||||||
def hide_keyboard_if_shown(self):
|
def hide_keyboard_if_shown(self):
|
||||||
if self.driver.is_keyboard_shown():
|
if self.driver.is_keyboard_shown():
|
||||||
|
|
|
@ -4,6 +4,8 @@ from datetime import datetime, timedelta
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
import pytest
|
||||||
|
from appium.webdriver.common.appiumby import AppiumBy
|
||||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException, \
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException, \
|
||||||
InvalidElementStateException
|
InvalidElementStateException
|
||||||
from selenium.webdriver import ActionChains
|
from selenium.webdriver import ActionChains
|
||||||
|
@ -232,11 +234,14 @@ class ChatElementByText(Text):
|
||||||
def replied_message_text(self):
|
def replied_message_text(self):
|
||||||
class RepliedMessageText(Text):
|
class RepliedMessageText(Text):
|
||||||
def __init__(self, driver, parent_locator: str):
|
def __init__(self, driver, parent_locator: str):
|
||||||
super().__init__(driver, prefix=parent_locator,
|
super().__init__(driver,
|
||||||
xpath="/preceding::android.widget.TextView[@content-desc='quoted-message']")
|
# prefix=parent_locator,
|
||||||
|
# xpath="/preceding::android.widget.TextView[@content-desc='quoted-message']"
|
||||||
|
accessibility_id='quoted-message')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return RepliedMessageText(self.driver, self.message_locator).text
|
# return RepliedMessageText(self.driver, self.message_locator).text
|
||||||
|
return self.find_element().find_element(by=AppiumBy.ACCESSIBILITY_ID, value='quoted-message').text
|
||||||
except NoSuchElementException:
|
except NoSuchElementException:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@ -1011,13 +1016,13 @@ class ChatView(BaseView):
|
||||||
def pin_message(self, message, action="pin"):
|
def pin_message(self, message, action="pin"):
|
||||||
self.driver.info("Looking for message '%s' pin" % message)
|
self.driver.info("Looking for message '%s' pin" % message)
|
||||||
element = self.element_by_translation_id(action)
|
element = self.element_by_translation_id(action)
|
||||||
self.chat_element_by_text(message).long_press_until_element_is_shown(element)
|
self.chat_element_by_text(message).long_press_without_release()
|
||||||
element.click_until_absense_of_element(element)
|
element.click_until_absense_of_element(element)
|
||||||
|
|
||||||
def edit_message_in_chat(self, message_to_edit, message_to_update):
|
def edit_message_in_chat(self, message_to_edit, message_to_update):
|
||||||
self.driver.info("Looking for message '%s' to edit it" % message_to_edit)
|
self.driver.info("Looking for message '%s' to edit it" % message_to_edit)
|
||||||
self.chat_element_by_text(message_to_edit).message_body.long_press_element()
|
self.chat_element_by_text(message_to_edit).message_body.long_press_without_release()
|
||||||
self.element_by_translation_id("edit-message").click()
|
self.element_by_translation_id("edit-message").double_click()
|
||||||
self.chat_message_input.clear()
|
self.chat_message_input.clear()
|
||||||
self.chat_message_input.send_keys(message_to_update)
|
self.chat_message_input.send_keys(message_to_update)
|
||||||
self.send_message_button.click()
|
self.send_message_button.click()
|
||||||
|
@ -1028,40 +1033,34 @@ class ChatView(BaseView):
|
||||||
delete_button = self.element_by_translation_id("delete-for-everyone")
|
delete_button = self.element_by_translation_id("delete-for-everyone")
|
||||||
else:
|
else:
|
||||||
delete_button = self.element_by_translation_id("delete-for-me")
|
delete_button = self.element_by_translation_id("delete-for-me")
|
||||||
self.chat_element_by_text(message).message_body.long_press_element()
|
self.chat_element_by_text(message).message_body.long_press_without_release()
|
||||||
delete_button.click()
|
delete_button.double_click()
|
||||||
|
|
||||||
def copy_message_text(self, message_text):
|
def copy_message_text(self, message_text):
|
||||||
self.driver.info("Copying '%s' message via long press" % message_text)
|
self.driver.info("Copying '%s' message via long press" % message_text)
|
||||||
self.chat_element_by_text(message_text).wait_for_visibility_of_element()
|
self.chat_element_by_text(message_text).wait_for_visibility_of_element()
|
||||||
self.chat_element_by_text(message_text).long_press_element()
|
self.chat_element_by_text(message_text).long_press_without_release()
|
||||||
self.element_by_translation_id("copy-text").click()
|
self.element_by_translation_id("copy-text").double_click()
|
||||||
|
|
||||||
def quote_message(self, message: str):
|
def quote_message(self, message: str):
|
||||||
self.driver.info("Quoting '%s' message" % message)
|
self.driver.info("Quoting '%s' message" % message)
|
||||||
element = self.chat_element_by_text(message)
|
element = self.chat_element_by_text(message)
|
||||||
element.wait_for_sent_state()
|
element.wait_for_sent_state()
|
||||||
element.long_press_until_element_is_shown(self.reply_message_button)
|
element.long_press_without_release()
|
||||||
self.reply_message_button.click()
|
self.reply_message_button.double_click()
|
||||||
|
|
||||||
def set_reaction(self, message: str, emoji: str = 'thumbs-up', emoji_message=False):
|
def set_reaction(self, message: str, emoji: str = 'thumbs-up', emoji_message=False):
|
||||||
self.driver.info("Setting '%s' reaction" % emoji)
|
self.driver.info("Setting '%s' reaction" % emoji)
|
||||||
# Audio message is obvious should be tapped not on audio-scroll-line
|
|
||||||
# so we tap on its below element as exception here (not the case for link/tag message!)
|
|
||||||
element = Button(self.driver, accessibility_id='reaction-%s' % emoji)
|
element = Button(self.driver, accessibility_id='reaction-%s' % emoji)
|
||||||
if message == 'audio':
|
if emoji_message:
|
||||||
self.audio_message_in_chat_timer.long_press_element()
|
self.element_by_text_part(message).long_press_without_release()
|
||||||
else:
|
else:
|
||||||
if not emoji_message:
|
self.chat_element_by_text(message).long_press_without_release()
|
||||||
self.chat_element_by_text(message).long_press_until_element_is_shown(element)
|
element.wait_for_element()
|
||||||
else:
|
element.double_click()
|
||||||
self.element_by_text_part(message).long_press_until_element_is_shown(element)
|
|
||||||
# old UI
|
|
||||||
# element = Button(self.driver, accessibility_id='pick-emoji-%s' % key)
|
|
||||||
element.click()
|
|
||||||
element.wait_for_invisibility_of_element()
|
element.wait_for_invisibility_of_element()
|
||||||
|
|
||||||
def add_remove_same_reaction(self, message: str, emoji: str = 'thumbs-up'):
|
def add_remove_same_reaction(self, emoji: str = 'thumbs-up'):
|
||||||
self.driver.info("Adding one more '%s' reaction or removing an added one" % emoji)
|
self.driver.info("Adding one more '%s' reaction or removing an added one" % emoji)
|
||||||
key = emojis[emoji]
|
key = emojis[emoji]
|
||||||
element = Button(self.driver, accessibility_id='emoji-reaction-%s' % key)
|
element = Button(self.driver, accessibility_id='emoji-reaction-%s' % key)
|
||||||
|
@ -1212,7 +1211,11 @@ class ChatView(BaseView):
|
||||||
self.show_images_button.click()
|
self.show_images_button.click()
|
||||||
self.allow_button.click_if_shown()
|
self.allow_button.click_if_shown()
|
||||||
self.allow_all_button.click_if_shown()
|
self.allow_all_button.click_if_shown()
|
||||||
[self.get_image_by_index(i).click() for i in indexes]
|
try:
|
||||||
|
[self.get_image_by_index(i).click() for i in indexes]
|
||||||
|
except NoSuchElementException:
|
||||||
|
self.click_system_back_button()
|
||||||
|
pytest.fail("Can't send image(s) with index(es) %s" % indexes)
|
||||||
self.images_confirm_selection_button.click()
|
self.images_confirm_selection_button.click()
|
||||||
self.chat_message_input.send_keys(description)
|
self.chat_message_input.send_keys(description)
|
||||||
self.send_message_button.click()
|
self.send_message_button.click()
|
||||||
|
|
Before Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 322 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 173 KiB |
After Width: | Height: | Size: 496 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 250 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 250 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 122 KiB |
|
@ -545,8 +545,8 @@ class HomeView(BaseView):
|
||||||
|
|
||||||
def delete_chat_long_press(self, username):
|
def delete_chat_long_press(self, username):
|
||||||
self.driver.info("Deleting chat '%s' by long press" % username)
|
self.driver.info("Deleting chat '%s' by long press" % username)
|
||||||
self.get_chat(username).long_press_element()
|
self.get_chat(username).long_press_without_release()
|
||||||
self.close_chat_button.click()
|
self.close_chat_button.double_click()
|
||||||
self.confirm_closing_chat_button.click()
|
self.confirm_closing_chat_button.click()
|
||||||
|
|
||||||
def leave_chat_long_press(self, username):
|
def leave_chat_long_press(self, username):
|
||||||
|
@ -565,13 +565,15 @@ class HomeView(BaseView):
|
||||||
|
|
||||||
def mute_chat_long_press(self, chat_name, mute_period="mute-till-unmute", community=False, community_channel=False):
|
def mute_chat_long_press(self, chat_name, mute_period="mute-till-unmute", community=False, community_channel=False):
|
||||||
self.driver.info("Muting chat with %s" % chat_name)
|
self.driver.info("Muting chat with %s" % chat_name)
|
||||||
self.get_chat(username=chat_name, community=community, community_channel=community_channel).long_press_element()
|
self.get_chat(username=chat_name, community=community,
|
||||||
|
community_channel=community_channel).long_press_without_release()
|
||||||
if community:
|
if community:
|
||||||
self.mute_community_button.click()
|
element = self.mute_community_button
|
||||||
elif community_channel:
|
elif community_channel:
|
||||||
self.mute_channel_button.click()
|
element = self.mute_channel_button
|
||||||
else:
|
else:
|
||||||
self.mute_chat_button.click()
|
element = self.mute_chat_button
|
||||||
|
element.double_click()
|
||||||
self.element_by_translation_id(mute_period).click()
|
self.element_by_translation_id(mute_period).click()
|
||||||
|
|
||||||
def get_pn(self, pn_text: str):
|
def get_pn(self, pn_text: str):
|
||||||
|
@ -587,7 +589,14 @@ class HomeView(BaseView):
|
||||||
|
|
||||||
def get_link_to_profile(self):
|
def get_link_to_profile(self):
|
||||||
self.show_qr_code_button.click()
|
self.show_qr_code_button.click()
|
||||||
|
try:
|
||||||
|
element = self.link_to_profile_button.find_element()
|
||||||
|
except NoSuchElementException:
|
||||||
|
element = None
|
||||||
|
pass
|
||||||
self.share_profile_tab_button.click()
|
self.share_profile_tab_button.click()
|
||||||
|
if element:
|
||||||
|
self.wait_for_staleness_of_element(element)
|
||||||
self.link_to_profile_button.click()
|
self.link_to_profile_button.click()
|
||||||
link_to_profile = self.sharing_text_native.text
|
link_to_profile = self.sharing_text_native.text
|
||||||
self.click_system_back_button()
|
self.click_system_back_button()
|
||||||
|
|
|
@ -438,7 +438,7 @@ class ProfileView(BaseView):
|
||||||
|
|
||||||
def edit_profile_picture(self, image_index: int, update_by="Gallery"):
|
def edit_profile_picture(self, image_index: int, update_by="Gallery"):
|
||||||
self.driver.info("## Setting custom profile image", device=False)
|
self.driver.info("## Setting custom profile image", device=False)
|
||||||
if not AbstractTestCase().environment == 'sauce':
|
if not AbstractTestCase().environment == 'lt':
|
||||||
raise NotImplementedError('Test case is implemented to run on SauceLabs only')
|
raise NotImplementedError('Test case is implemented to run on SauceLabs only')
|
||||||
self.edit_profile_button.click()
|
self.edit_profile_button.click()
|
||||||
self.change_profile_photo_button.click()
|
self.change_profile_photo_button.click()
|
||||||
|
@ -473,6 +473,7 @@ class ProfileView(BaseView):
|
||||||
try:
|
try:
|
||||||
image_element.find_elements()[image_index].click()
|
image_element.find_elements()[image_index].click()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
self.click_system_back_button(times=2)
|
||||||
raise NoSuchElementException("Image with index %s was not found" % image_index) from None
|
raise NoSuchElementException("Image with index %s was not found" % image_index) from None
|
||||||
|
|
||||||
def logout(self):
|
def logout(self):
|
||||||
|
|
|
@ -163,8 +163,8 @@ class WalletView(BaseView):
|
||||||
|
|
||||||
def send_asset_from_drawer(self, address: str, asset_name: str, amount: float):
|
def send_asset_from_drawer(self, address: str, asset_name: str, amount: float):
|
||||||
asset_element = self.get_asset(asset_name)
|
asset_element = self.get_asset(asset_name)
|
||||||
asset_element.long_press_element()
|
asset_element.long_press_without_release()
|
||||||
self.send_from_drawer_button.click()
|
self.send_from_drawer_button.double_click()
|
||||||
self.address_text_input.send_keys(address)
|
self.address_text_input.send_keys(address)
|
||||||
self.continue_button.click()
|
self.continue_button.click()
|
||||||
self.set_amount(amount)
|
self.set_amount(amount)
|
||||||
|
@ -218,6 +218,7 @@ class WalletView(BaseView):
|
||||||
self.element_by_translation_id("reveal-phrase").click()
|
self.element_by_translation_id("reveal-phrase").click()
|
||||||
# ToDo: can't be done in current small size emulators, add when moved to LambdaTest
|
# ToDo: can't be done in current small size emulators, add when moved to LambdaTest
|
||||||
self.slide_and_confirm_with_password()
|
self.slide_and_confirm_with_password()
|
||||||
|
self.add_account_derivation_path_text.wait_for_element()
|
||||||
derivation_path = self.add_account_derivation_path_text.text
|
derivation_path = self.add_account_derivation_path_text.text
|
||||||
return derivation_path.replace(' ', '')
|
return derivation_path.replace(' ', '')
|
||||||
|
|
||||||
|
|