mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-13 10:16:01 +00:00
added group chat test and auto retrieving of latest apk
This commit is contained in:
parent
d2530517c4
commit
fb53417295
2
test/appium/Jenkinsfile
vendored
2
test/appium/Jenkinsfile
vendored
@ -1,5 +1,5 @@
|
||||
node {sauce('6269510b-13f3-4019-b156-c2c835f3a408') {
|
||||
try {sh '/usr/local/bin/python3 -m pytest -m sanity -n5 --apk apkUrl --build ${JOB_NAME}__${BUILD_NUMBER}'
|
||||
try {sh '/usr/local/bin/python3 -m pytest -m sanity -v --dist=loadscope -n3 --build ${JOB_NAME}__${BUILD_NUMBER}'
|
||||
}
|
||||
finally {
|
||||
saucePublisher()
|
||||
|
@ -1,3 +1,3 @@
|
||||
[pytest]
|
||||
norecursedirs = .git views
|
||||
addopts = -s -v --junitxml=result.xml --tb=short
|
||||
addopts = -s --junitxml=result.xml --tb=short
|
||||
|
@ -1,12 +1,63 @@
|
||||
from tests import tests_data
|
||||
import time
|
||||
import requests
|
||||
import re
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
from os import environ
|
||||
from io import BytesIO
|
||||
from sauceclient import SauceClient
|
||||
|
||||
storage = 'http://artifacts.status.im:8081/artifactory/nightlies-local/'
|
||||
|
||||
sauce_username = environ.get('SAUCE_USERNAME')
|
||||
sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
|
||||
|
||||
|
||||
def get_latest_apk():
|
||||
raw_data = requests.request('GET', storage).text
|
||||
dates = re.findall("\d{2}-[a-zA-Z]{3}-\d{4} \d{2}:\d{2}", raw_data)
|
||||
dates.sort(key=lambda date: datetime.strptime(date, "%d-%b-%Y %H:%M"), reverse=True)
|
||||
return re.findall('>(.*k)</a>\s*%s' % dates[0], raw_data)[0]
|
||||
|
||||
latest_apk = get_latest_apk()
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--build", action="store", default='build_' + time.strftime('%Y_%m_%d_%H_%M'),
|
||||
parser.addoption("--build",
|
||||
action="store",
|
||||
default='build_' + time.strftime('%Y_%m_%d_%H_%M'),
|
||||
help="Specify build name")
|
||||
parser.addoption('--apk', action='store', default=None, help='Please provide url or local path to apk')
|
||||
parser.addoption('--apk',
|
||||
action='store',
|
||||
default='sauce-storage:' + latest_apk,
|
||||
help='Please provide url or local path to apk')
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
tests_data.name = item.name
|
||||
tests_data.name = item.name + '_' + latest_apk
|
||||
|
||||
|
||||
def is_master(config):
|
||||
return not hasattr(config, 'slaveinput')
|
||||
|
||||
|
||||
def is_uploaded():
|
||||
stored_files = SauceClient(sauce_username, sauce_access_key).storage.get_stored_files()
|
||||
for i in range(len(stored_files['files'])):
|
||||
if stored_files['files'][i]['name'] == latest_apk:
|
||||
return True
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
if is_master(config):
|
||||
if not is_uploaded():
|
||||
response = requests.get(storage + latest_apk, stream=True)
|
||||
response.raise_for_status()
|
||||
file = BytesIO(response.content)
|
||||
del response
|
||||
requests.post('http://saucelabs.com/rest/v1/storage/'
|
||||
+ sauce_username + '/' + latest_apk + '?overwrite=true',
|
||||
auth=(sauce_username, sauce_access_key),
|
||||
data=file,
|
||||
headers={'Content-Type': 'application/octet-stream'})
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
def set_chat_for_users_from_scratch(*args):
|
||||
def set_password_as_new_user(*args):
|
||||
for view in args:
|
||||
view.request_password_icon.click()
|
||||
view.type_message_edit_box.send_keys("qwerty1234")
|
||||
|
@ -1,22 +1,22 @@
|
||||
import pytest
|
||||
from tests.basetestcase import MultiplyDeviceTestCase
|
||||
from tests.preconditions import set_chat_for_users_from_scratch
|
||||
from tests.preconditions import set_password_as_new_user
|
||||
from views.home import HomeView
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
class TestMultiplyDevices(MultiplyDeviceTestCase):
|
||||
class TestChats(MultiplyDeviceTestCase):
|
||||
|
||||
def test_private_chat(self):
|
||||
|
||||
device_1, device_2 = HomeView(self.driver_1), HomeView(self.driver_2)
|
||||
set_chat_for_users_from_scratch(device_1, device_2)
|
||||
set_password_as_new_user(device_1, device_2)
|
||||
|
||||
device_1.back_button.click()
|
||||
chats_d1 = device_1.get_chats()
|
||||
chats_d1.profile_button.click()
|
||||
profile_d1 = chats_d1.profile_icon.click()
|
||||
key = profile_d1.public_key_text.get_key()
|
||||
key = profile_d1.public_key_text.text
|
||||
|
||||
device_2.back_button.click()
|
||||
chats_d2 = device_2.get_chats()
|
||||
|
49
test/appium/tests/test_group_chats.py
Normal file
49
test/appium/tests/test_group_chats.py
Normal file
@ -0,0 +1,49 @@
|
||||
import pytest
|
||||
from tests.basetestcase import MultiplyDeviceTestCase
|
||||
from tests.preconditions import set_password_as_new_user
|
||||
from views.home import HomeView
|
||||
from views.chats import UserNameText
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
class TestDev(MultiplyDeviceTestCase):
|
||||
|
||||
def test_group_chat(self):
|
||||
device_1, device_2 = HomeView(self.driver_1), \
|
||||
HomeView(self.driver_2)
|
||||
|
||||
set_password_as_new_user(device_2, device_1)
|
||||
|
||||
device_1.back_button.click()
|
||||
chats_d1 = device_1.get_chats()
|
||||
chats_d1.profile_button.click()
|
||||
profile_d1 = chats_d1.profile_icon.click()
|
||||
key = profile_d1.public_key_text.text
|
||||
|
||||
device_2.back_button.click()
|
||||
chats_d2 = device_2.get_chats()
|
||||
chats_d2.plus_button.click()
|
||||
chats_d2.add_new_contact.click()
|
||||
chats_d2.public_key_edit_box.send_keys(key)
|
||||
chats_d2.confirm()
|
||||
chats_d2.confirm_public_key_button.click()
|
||||
|
||||
user_d1_name = chats_d2.user_name_text.text
|
||||
|
||||
device_2.back_button.click()
|
||||
chats_d2.new_group_chat_button.click()
|
||||
|
||||
profile_d1.back_button.click()
|
||||
|
||||
user_contact = UserNameText.UserContactByName(self.driver_2, user_d1_name)
|
||||
user_contact.scroll_to_element()
|
||||
user_contact.click()
|
||||
|
||||
chats_d2.next_button.click()
|
||||
chats_d2.name_edit_box.send_keys('new_chat')
|
||||
chats_d2.save_button.click()
|
||||
|
||||
chats_d2.chat_message_input.send_keys('SOMETHING')
|
||||
chats_d2.send_message_button.click()
|
||||
|
||||
profile_d1.find_text('SOMETHING')
|
@ -2,6 +2,7 @@ from selenium.webdriver.common.by import By
|
||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
||||
from selenium.webdriver.support.wait import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions
|
||||
from appium.webdriver.common.touch_action import TouchAction
|
||||
import pytest
|
||||
|
||||
|
||||
@ -32,16 +33,22 @@ class BaseElement(object):
|
||||
return None
|
||||
|
||||
def find_element(self):
|
||||
try:
|
||||
return self.wait_for_element()
|
||||
except (NoSuchElementException, TimeoutException):
|
||||
pytest.fail("'%s' not found by %s '%s'" % (
|
||||
self.name, self.locator.by, self.locator.value), pytrace=False)
|
||||
return self.driver.find_element(self.locator.by, self.locator.value)
|
||||
|
||||
def wait_for_element(self, seconds=30):
|
||||
def wait_for_element(self, seconds=10):
|
||||
return WebDriverWait(self.driver, seconds)\
|
||||
.until(expected_conditions.presence_of_element_located((self.locator.by, self.locator.value)))
|
||||
|
||||
def scroll_to_element(self):
|
||||
for x in range(10):
|
||||
action = TouchAction(self.driver)
|
||||
action.press(x=0, y=1000).move_to(x=200, y=-1000).release().perform()
|
||||
try:
|
||||
self.find_element()
|
||||
break
|
||||
except NoSuchElementException:
|
||||
pass
|
||||
|
||||
|
||||
class BaseEditBox(BaseElement):
|
||||
|
||||
|
@ -18,9 +18,9 @@ class BaseViewObject(object):
|
||||
self.driver.keyevent(66)
|
||||
|
||||
def find_text(self, text):
|
||||
element = BaseElement(self.driver)
|
||||
element = BaseButton(self.driver)
|
||||
element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]')
|
||||
return element.wait_for_element(30)
|
||||
return element.wait_for_element(100)
|
||||
|
||||
def get_chats(self):
|
||||
from views.chats import ChatsViewObject
|
||||
|
@ -7,7 +7,8 @@ class ProfileButton(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(ProfileButton, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.support.v4.view.ViewPager//android.view.ViewGroup[1]/android.widget.ImageView")
|
||||
"//android.support.v4.view.ViewPager//android.view.ViewGroup[2]/android.view.ViewGroup[1]/android.view.View"
|
||||
)
|
||||
|
||||
|
||||
class ProfileIcon(BaseButton):
|
||||
@ -38,6 +39,44 @@ class AddNewContactButton(BaseButton):
|
||||
"//android.widget.TextView[@text='Add new contact']")
|
||||
|
||||
|
||||
class NewGroupChatButton(BaseButton):
|
||||
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.widget.TextView[@text='New group chat']")
|
||||
|
||||
class AugurContact(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton.AugurContact, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.widget.TextView[@text='Augur']")
|
||||
|
||||
class JarradContact(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton.JarradContact, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.widget.TextView[@text='Jarrad']")
|
||||
|
||||
class NextButton(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton.NextButton, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.widget.TextView[@text='NEXT']")
|
||||
|
||||
class NameEditBox(BaseEditBox):
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton.NameEditBox, self).__init__(driver)
|
||||
self.locator = \
|
||||
self.Locator.xpath_selector("//android.widget.EditText[@NAF='true']")
|
||||
|
||||
class SaveButton(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(NewGroupChatButton.SaveButton, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
"//android.widget.TextView[@text='SAVE']")
|
||||
|
||||
|
||||
class PublicKeyEditBox(BaseEditBox):
|
||||
|
||||
def __init__(self, driver):
|
||||
@ -73,6 +112,20 @@ class SendMessageButton(BaseButton):
|
||||
"android.view.ViewGroup[2]//android.widget.ImageView")
|
||||
|
||||
|
||||
class UserNameText(BaseText):
|
||||
|
||||
def __init__(self, driver):
|
||||
super(UserNameText, self).__init__(driver)
|
||||
self.locator = \
|
||||
self.Locator.xpath_selector("//android.widget.ScrollView//android.widget.TextView")
|
||||
|
||||
class UserContactByName(BaseButton):
|
||||
|
||||
def __init__(self, driver, user_name):
|
||||
super(UserNameText.UserContactByName, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector('//*[@text="' + user_name + '"]')
|
||||
|
||||
|
||||
class ChatsViewObject(BaseViewObject):
|
||||
|
||||
def __init__(self, driver):
|
||||
@ -83,7 +136,17 @@ class ChatsViewObject(BaseViewObject):
|
||||
self.profile_icon = ProfileIcon(self.driver)
|
||||
self.plus_button = PlusButton(self.driver)
|
||||
self.add_new_contact = AddNewContactButton(self.driver)
|
||||
|
||||
self.public_key_edit_box = PublicKeyEditBox(self.driver)
|
||||
self.confirm_public_key_button = ConfirmPublicKeyButton(self.driver)
|
||||
|
||||
self.chat_message_input = ChatMessageInput(self.driver)
|
||||
self.send_message_button = SendMessageButton(self.driver)
|
||||
self.user_name_text = UserNameText(self.driver)
|
||||
|
||||
self.new_group_chat_button = NewGroupChatButton(self.driver)
|
||||
self.augur_contact = NewGroupChatButton.AugurContact(self.driver)
|
||||
self.jarrad_contact = NewGroupChatButton.JarradContact(self.driver)
|
||||
self.next_button = NewGroupChatButton.NextButton(self.driver)
|
||||
self.name_edit_box = NewGroupChatButton.NameEditBox(self.driver)
|
||||
self.save_button = NewGroupChatButton.SaveButton(self.driver)
|
||||
|
@ -9,6 +9,13 @@ class ContinueButton(BaseButton):
|
||||
self.locator = self.Locator.xpath_selector("//*[@text='Continue']")
|
||||
|
||||
|
||||
class OkButton(BaseButton):
|
||||
|
||||
def __init__(self, driver):
|
||||
super(OkButton, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector("//*[@text='OK']")
|
||||
|
||||
|
||||
class TypeMessageEditBox(BaseEditBox):
|
||||
|
||||
def __init__(self, driver):
|
||||
@ -29,11 +36,13 @@ class HomeView(BaseViewObject):
|
||||
def __init__(self, driver):
|
||||
super(HomeView, self).__init__(driver)
|
||||
self.continue_button = ContinueButton(driver)
|
||||
self.ok_button = OkButton(driver)
|
||||
|
||||
try:
|
||||
self.continue_button.click()
|
||||
except Exception:
|
||||
pass
|
||||
for i in self.ok_button, self.continue_button:
|
||||
try:
|
||||
i.click()
|
||||
except (NoSuchElementException, TimeoutException):
|
||||
pass
|
||||
|
||||
self.type_message_edit_box = TypeMessageEditBox(driver)
|
||||
self.request_password_icon = RequestPasswordIcon(driver)
|
||||
|
@ -6,14 +6,7 @@ class PublicKeyText(BaseText):
|
||||
|
||||
def __init__(self, driver):
|
||||
super(PublicKeyText, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector("//android.widget.TextView")
|
||||
|
||||
def get_key(self):
|
||||
texts = self.driver.find_elements(self.locator.by, self.locator.value)
|
||||
for i in texts:
|
||||
if i.text.startswith('0x04'):
|
||||
return i.text
|
||||
pytest.fail("Public key wasn't found!")
|
||||
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@instance='7']")
|
||||
|
||||
|
||||
class ProfileViewObject(BaseViewObject):
|
||||
|
Loading…
x
Reference in New Issue
Block a user