Added tests for messaging, chats deleting and wallet set up

Signed-off-by: Anton Danchenko <ant.danchenko@gmail.com>
This commit is contained in:
yevh-berdnyk 2018-05-16 21:59:36 +02:00 committed by Anton Danchenko
parent 26c819cc9c
commit 3d33f3feac
No known key found for this signature in database
GPG Key ID: C2D4819B698627E4
15 changed files with 439 additions and 95 deletions

View File

@ -68,6 +68,11 @@ class AbstractTestCase:
desired_caps['ignoreUnimportantViews'] = False desired_caps['ignoreUnimportantViews'] = False
return desired_caps return desired_caps
def update_capabilities_sauce_lab(self, key, value):
caps = self.capabilities_sauce_lab.copy()
caps[key] = value
return caps
@property @property
def capabilities_local(self): def capabilities_local(self):
desired_caps = dict() desired_caps = dict()
@ -167,10 +172,14 @@ class SauceMultipleDeviceTestCase(AbstractTestCase):
self.drivers = dict() self.drivers = dict()
def create_drivers(self, quantity=2): def create_drivers(self, quantity=2):
if self.__class__.__name__ == 'TestOfflineMessages':
capabilities = self.update_capabilities_sauce_lab('platformVersion', '6.0')
else:
capabilities = self.capabilities_sauce_lab
self.drivers = self.loop.run_until_complete(start_threads(quantity, webdriver.Remote, self.drivers = self.loop.run_until_complete(start_threads(quantity, webdriver.Remote,
self.drivers, self.drivers,
self.executor_sauce_lab, self.executor_sauce_lab,
self.capabilities_sauce_lab)) capabilities))
for driver in range(quantity): for driver in range(quantity):
self.drivers[driver].implicitly_wait(self.implicitly_wait) self.drivers[driver].implicitly_wait(self.implicitly_wait)
BaseView(self.drivers[driver]).accept_agreements() BaseView(self.drivers[driver]).accept_agreements()

View File

@ -2,6 +2,9 @@ import pytest
pr = pytest.mark.pr pr = pytest.mark.pr
testrail_case_id = pytest.mark.testrail_case_id testrail_case_id = pytest.mark.testrail_case_id
chat = pytest.mark.chat
all = pytest.mark.all all = pytest.mark.all
chat = pytest.mark.chat
chat_management = pytest.mark.chat_management
transaction = pytest.mark.transaction transaction = pytest.mark.transaction
wallet = pytest.mark.wallet

View File

@ -1,17 +1,15 @@
import time import time
import pytest from tests import transaction_users, marks, group_chat_users, get_current_time
from tests.base_test_case import MultipleDeviceTestCase, SingleDeviceTestCase
from tests import transaction_users
from tests.base_test_case import MultipleDeviceTestCase
from views.sign_in_view import SignInView from views.sign_in_view import SignInView
@pytest.mark.all @marks.all
@pytest.mark.chat_management @marks.chat_management
class TestChatManagement(MultipleDeviceTestCase): class TestChatManagementMultiple(MultipleDeviceTestCase):
@pytest.mark.testrail_case_id(3412) @marks.testrail_case_id(3412)
def test_delete_1_1_chat(self): def test_delete_1_1_chat(self):
self.senders['g_user'] = transaction_users['G_USER'] self.senders['g_user'] = transaction_users['G_USER']
self.senders['h_user'] = transaction_users['H_USER'] self.senders['h_user'] = transaction_users['H_USER']
@ -73,3 +71,41 @@ class TestChatManagement(MultipleDeviceTestCase):
assert device_1_chat_view.no_messages_in_chat.is_element_present() assert device_1_chat_view.no_messages_in_chat.is_element_present()
self.verify_no_errors() self.verify_no_errors()
@marks.all
@marks.chat_management
class TestChatManagement(SingleDeviceTestCase):
@marks.testrail_case_id(3413)
def test_swipe_and_delete_1_1_chat(self):
recipient = transaction_users['A_USER']
sign_in_view = SignInView(self.driver)
sign_in_view.create_user()
home_view = sign_in_view.get_home_view()
home_view.add_contact(recipient['public_key'])
chat_view = home_view.get_chat_view()
chat_view.chat_message_input.send_keys('test message')
chat_view.send_message_button.click()
chat_view.get_back_to_home_view()
home_view.swipe_and_delete_chat(recipient['username'][:20])
home_view.relogin()
assert not home_view.get_chat_with_user(recipient['username']).is_element_present(20)
@marks.testrail_case_id(3418)
def test_swipe_and_delete_group_chat(self):
recipient = group_chat_users['A_USER']
sign_in_view = SignInView(self.driver)
sign_in_view.create_user()
home_view = sign_in_view.get_home_view()
home_view.add_contact(recipient['public_key'])
home_view.get_back_to_home_view()
chat_name = 'a_chat_%s' % get_current_time()
home_view.create_group_chat([recipient['username']], chat_name)
chat_view = home_view.get_chat_view()
chat_view.chat_message_input.send_keys('This is text message!')
chat_view.send_message_button.click()
chat_view.get_back_to_home_view()
home_view.swipe_and_delete_chat(chat_name)
home_view.relogin()
assert not home_view.get_chat_with_user(chat_name).is_element_displayed()

View File

@ -1,8 +1,7 @@
import random import random
import string import string
import pytest
import emoji import emoji
import time
from tests.base_test_case import MultipleDeviceTestCase from tests.base_test_case import MultipleDeviceTestCase
from tests import group_chat_users, get_current_time, marks from tests import group_chat_users, get_current_time, marks
from views.sign_in_view import SignInView from views.sign_in_view import SignInView
@ -149,30 +148,197 @@ class TestMessages(MultipleDeviceTestCase):
users = [] users = []
chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7))
for sign_in in device_1, device_2: for sign_in in device_1, device_2:
sign_in.create_user() users.append(sign_in.create_user())
home = sign_in.get_home_view() home = sign_in.get_home_view()
profile = home.profile_button.click()
users.append(profile.username_text.text)
profile.home_button.click()
home.join_public_chat(chat_name) home.join_public_chat(chat_name)
chat_1, chat_2 = device_1.get_chat_view(), device_2.get_chat_view() chat_1, chat_2 = device_1.get_chat_view(), device_2.get_chat_view()
messages_to_send_1 = ['/command', '%s %s' % (unicode_text_message, unicode_chinese), 'This is text message.'] chat_1.chat_message_input.send_keys('/command')
for message in messages_to_send_1: chat_1.send_message_button.click()
chat_1.chat_message_input.send_keys(message)
chat_1.send_message_button.click()
chat_2.wait_for_messages(users[0], messages_to_send_1, self.errors)
message_with_emoji = 'message with emoji' message_with_emoji = 'message with emoji'
messages_to_send_2 = [emoji.emojize(emoji_name), emoji.emojize('%s %s' % (message_with_emoji, emoji_name_1))]
messages_to_receive_2 = [emoji_unicode, '%s %s' % (message_with_emoji, emoji_unicode_1), message_with_new_line] chat_2.chat_message_input.send_keys(emoji.emojize(emoji_name))
for message in messages_to_send_2: chat_2.send_message_button.click()
chat_2.chat_message_input.send_keys(message)
chat_2.send_message_button.click() chat_1.chat_message_input.send_keys('%s %s' % (unicode_text_message, unicode_chinese))
chat_1.send_message_button.click()
chat_2.chat_message_input.send_keys('%s %s' % (message_with_emoji, emoji_unicode_1))
chat_2.send_message_button.click()
chat_1.chat_message_input.send_keys('This is text message.')
chat_1.send_message_button.click()
chat_2.chat_message_input.click() chat_2.chat_message_input.click()
chat_2.send_as_keyevent(message_with_new_line) chat_2.send_as_keyevent(message_with_new_line)
chat_2.send_message_button.click() chat_2.send_message_button.click()
chat_1.wait_for_messages(users[1], messages_to_receive_2, self.errors)
messages_from_user_2 = [emoji_unicode, '%s %s' % (message_with_emoji, emoji_unicode_1), message_with_new_line]
chat_1.wait_for_messages(users[1], messages_from_user_2, self.errors)
chat_1.verify_username_is_shown_per_message(users[1], messages_from_user_2, self.errors)
messages_from_user_1 = ['/command', '%s %s' % (unicode_text_message, unicode_chinese), 'This is text message.']
chat_2.wait_for_messages(users[0], messages_from_user_1, self.errors)
chat_2.verify_username_is_shown_per_message(users[0], messages_from_user_1, self.errors)
for chat in chat_1, chat_2: for chat in chat_1, chat_2:
chat.delete_chat(chat_name, self.errors) chat.delete_chat(chat_name, self.errors)
self.verify_no_errors() self.verify_no_errors()
@marks.testrail_case_id(3423)
def test_username_and_profile_picture_in_chats(self):
self.create_drivers(2)
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
username_1, username_2 = device_1.create_user(), device_2.create_user()
home_1, home_2 = device_1.get_home_view(), device_2.get_home_view()
device_2_public_key = home_2.get_public_key()
profile_2 = home_2.get_profile_view()
file_name = 'sauce_logo.png'
profile_2.edit_profile_picture(file_name)
home_1.add_contact(device_2_public_key)
profile_2.home_button.click()
chat_2 = home_2.get_chat_with_user(username_1).click()
chat_2.add_to_contacts.click()
chat_1 = home_1.get_chat_view()
time.sleep(3)
if chat_1.user_name_text.text != username_2:
self.errors.append("Real username '%s' is not shown in one-to-one chat" % username_2)
chat_1.chat_options.click()
chat_1.view_profile_button.click()
if not chat_1.contact_profile_picture.is_element_image_equals_template(file_name):
self.errors.append("Updated profile picture is not shown in one-to-one chat")
home_1.get_back_to_home_view()
chat_name = 'a_chat_%s' % get_current_time()
home_1.create_group_chat([username_2], chat_name)
group_chat_1 = home_1.get_chat_view()
home_2.get_back_to_home_view()
group_chat_2 = home_2.get_chat_with_user(chat_name).click()
message_text = 'test message'
group_chat_2.chat_message_input.send_keys(message_text)
group_chat_2.send_message_button.click()
group_chat_1.wait_for_messages(username_2, message_text, self.errors)
group_chat_1.verify_username_is_shown_per_message(username_2, message_text, self.errors)
self.verify_no_errors()
@marks.testrail_case_id(3429)
def test_copy_and_paste_messages(self):
self.create_drivers(1)
sign_in = SignInView(self.drivers[0])
sign_in.create_user()
home = sign_in.get_home_view()
home.join_public_chat(''.join(random.choice(string.ascii_lowercase) for _ in range(7)))
chat = sign_in.get_chat_view()
message_text = 'test'
message_input = chat.chat_message_input
message_input.send_keys(message_text)
chat.send_message_button.click()
# copy text message
chat.chat_element_by_text(message_text).long_press_element()
chat.element_by_text('Copy to clipboard').click()
# paste text into the input field
message_input.paste_text_from_clipboard()
assert message_input.text == message_text
# delete part of the message
message_input.delete_last_symbols(2)
assert message_input.text == message_text[:-2]
# cut message text
message_input.cut_text()
# paste selected text
message_input.paste_text_from_clipboard()
chat.send_message_button.click()
# verify correct text is sent
chat.chat_element_by_text(message_text[:-2] + ' ')
@marks.all
@marks.chat
class TestOfflineMessages(MultipleDeviceTestCase):
@marks.testrail_case_id(3420)
def test_offline_messaging_1_1_chat(self):
self.create_drivers(2)
device_1, device_2 = self.drivers[0], self.drivers[1]
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_1 = sign_in_1.create_user()
sign_in_2.create_user()
home_1, home_2 = sign_in_1.get_home_view(), sign_in_2.get_home_view()
device_2_public_key = home_2.get_public_key()
home_1.add_contact(device_2_public_key)
chat_1 = home_1.get_chat_view()
profile_2 = home_2.get_profile_view()
profile_2.logout()
device_2.set_network_connection(1) # airplane mode
message_text = 'test message'
chat_1.chat_message_input.send_keys(message_text)
chat_1.send_message_button.click()
sign_in_2.click_account_by_position(0)
sign_in_2.sign_in('qwerty1234')
sign_in_2.home_button.wait_for_visibility_of_element()
if not home_2.offline_label.is_element_displayed():
self.errors.append('Offline label is not shown on Home view while being offline')
chat_2 = home_2.get_chat_with_user(username_1).click()
if not chat_2.offline_label.is_element_displayed():
self.errors.append('Offline label is not shown on Chat view while being offline')
device_2.set_network_connection(2) # turning on WiFi connection
chat_2.wait_for_message_in_one_to_one_chat(message_text, self.errors, wait_time=120)
self.verify_no_errors()
@marks.testrail_case_id(3430)
def test_offline_messaging_group_chat(self):
self.create_drivers(2)
device_1, device_2 = self.drivers[0], self.drivers[1]
sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2)
username_1 = sign_in_1.create_user()
username_2 = sign_in_2.create_user()
home_1, home_2 = sign_in_1.get_home_view(), sign_in_2.get_home_view()
device_2_public_key = home_2.get_public_key()
home_1.add_contact(device_2_public_key)
home_1.get_back_to_home_view()
home_2.home_button.click()
chat_view_2 = home_2.get_chat_with_user(username_1).click()
chat_view_2.add_to_contacts.click()
chat_view_2.get_back_to_home_view()
chat_name = 'a_chat_%s' % get_current_time()
home_1.create_group_chat([username_2], chat_name)
chat_1 = home_1.get_chat_view()
chat_element_2 = home_2.get_chat_with_user(chat_name)
chat_element_2.wait_for_visibility_of_element()
device_2.set_network_connection(1) # airplane mode
if not home_2.offline_label.is_element_displayed():
self.errors.append('Offline label is not shown on Home view while being offline')
chat_2 = chat_element_2.click()
if not chat_2.offline_label.is_element_displayed():
self.errors.append('Offline label is not shown on Chat view while being offline')
message_text = 'test message'
chat_1.chat_message_input.send_keys(message_text)
chat_1.send_message_button.click()
chat_1.get_back_to_home_view()
profile_1 = home_1.profile_button.click()
profile_1.logout()
device_2.set_network_connection(2) # turning on WiFi connection
chat_2.wait_for_messages(username_1, message_text, self.errors, wait_time=120)
self.verify_no_errors()

View File

@ -34,7 +34,7 @@ class TestProfileView(SingleDeviceTestCase):
self.verify_no_errors() self.verify_no_errors()
@marks.pr @marks.pr
@pytest.mark.testrail_case_id(3396) @marks.testrail_case_id(3396)
def test_contact_profile_view(self): def test_contact_profile_view(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
sign_in_view.create_user() sign_in_view.create_user()
@ -69,7 +69,7 @@ class TestProfileView(SingleDeviceTestCase):
desired_network.scroll_to_element() desired_network.scroll_to_element()
assert desired_network.is_element_displayed() assert desired_network.is_element_displayed()
@pytest.mark.testrail_case_id(3398) @marks.testrail_case_id(3398)
def test_profile_picture(self): def test_profile_picture(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
sign_in_view.create_user() sign_in_view.create_user()
@ -80,7 +80,7 @@ class TestProfileView(SingleDeviceTestCase):
if not profile_view.profile_picture.is_element_image_equals_template(): if not profile_view.profile_picture.is_element_image_equals_template():
pytest.fail('Profile picture was not updated') pytest.fail('Profile picture was not updated')
@pytest.mark.testrail_case_id(3399) @marks.testrail_case_id(3399)
def test_backup_seed_phrase_and_recover_account(self): def test_backup_seed_phrase_and_recover_account(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
sign_in_view.create_user(password='qwerty1234') sign_in_view.create_user(password='qwerty1234')
@ -109,7 +109,7 @@ class TestProfileView(SingleDeviceTestCase):
public_key_1 = home_view.get_public_key() public_key_1 = home_view.get_public_key()
assert public_key == public_key_1 assert public_key == public_key_1
@pytest.mark.testrail_case_id(3411) @marks.testrail_case_id(3411)
def test_faucet_console_command(self): def test_faucet_console_command(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
sign_in_view.create_user() sign_in_view.create_user()
@ -130,8 +130,7 @@ class TestProfileView(SingleDeviceTestCase):
wallet_view.set_up_wallet() wallet_view.set_up_wallet()
wallet_view.wait_balance_changed_on_wallet_screen() wallet_view.wait_balance_changed_on_wallet_screen()
@marks.testrail_case_id(3421)
@pytest.mark.testrail_case_id(3421)
def test_switch_users(self): def test_switch_users(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
for _ in range(3): for _ in range(3):
@ -145,7 +144,7 @@ class TestProfileView(SingleDeviceTestCase):
sign_in_view.sign_in_button.click() sign_in_view.sign_in_button.click()
sign_in_view.home_button.wait_for_visibility_of_element() sign_in_view.home_button.wait_for_visibility_of_element()
@pytest.mark.testrail_case_id(3424) @marks.testrail_case_id(3424)
def test_incorrect_password(self): def test_incorrect_password(self):
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
sign_in_view.create_account_button.click() sign_in_view.create_account_button.click()

View File

@ -1,3 +1,5 @@
import pytest
from tests.base_test_case import SingleDeviceTestCase, MultipleDeviceTestCase from tests.base_test_case import SingleDeviceTestCase, MultipleDeviceTestCase
from tests import transaction_users, api_requests, get_current_time, transaction_users_wallet, marks from tests import transaction_users, api_requests, get_current_time, transaction_users_wallet, marks
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException
@ -177,6 +179,35 @@ class TestTransaction(SingleDeviceTestCase):
send_transaction.enter_password_input.send_keys(sender['password']) send_transaction.enter_password_input.send_keys(sender['password'])
send_transaction.sign_transaction_button.click() send_transaction.sign_transaction_button.click()
send_transaction.got_it_button.click() send_transaction.got_it_button.click()
if sender['password'] in str(home_view.logcat):
pytest.fail('Password in logcat!!!', pytrace=False)
@marks.testrail_case_id(3452)
def test_sign_transaction_twice(self):
recipient = transaction_users['F_USER']
sender = transaction_users['E_USER']
sign_in_view = SignInView(self.driver)
sign_in_view.recover_access(sender['passphrase'], sender['password'])
home_view = sign_in_view.get_home_view()
home_view.add_contact(recipient['public_key'])
home_view.get_back_to_home_view()
wallet_view = home_view.wallet_button.click()
send_transaction = wallet_view.send_button.click()
send_transaction.amount_edit_box.click()
send_transaction.amount_edit_box.set_value(send_transaction.get_unique_amount())
send_transaction.confirm()
send_transaction.chose_recipient_button.click()
send_transaction.recent_recipients_button.click()
recent_recipient = send_transaction.element_by_text(recipient['username'])
send_transaction.recent_recipients_button.click_until_presence_of_element(recent_recipient)
recent_recipient.click()
send_transaction.sign_transaction_button.click()
send_transaction.enter_password_input.send_keys(sender['password'])
send_transaction.cancel_button.click()
send_transaction.sign_transaction_button.click()
send_transaction.enter_password_input.wait_for_visibility_of_element()
send_transaction.sign_transaction_button.click()
send_transaction.enter_password_input.wait_for_visibility_of_element()
@marks.all @marks.all

View File

@ -1,15 +1,14 @@
import pytest from tests import api_requests, transaction_users_wallet, marks
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException
from tests import api_requests, transaction_users_wallet
from tests.base_test_case import SingleDeviceTestCase from tests.base_test_case import SingleDeviceTestCase
from views.sign_in_view import SignInView from views.sign_in_view import SignInView
@pytest.mark.all @marks.all
@marks.wallet
class TestWallet(SingleDeviceTestCase): class TestWallet(SingleDeviceTestCase):
@pytest.mark.wallet @marks.testrail_case_id(3425)
@pytest.mark.testrail_case_id(3425)
def test_wallet_error_messages(self): def test_wallet_error_messages(self):
sender = transaction_users_wallet['A_USER'] sender = transaction_users_wallet['A_USER']
recipient = transaction_users_wallet['B_USER'] recipient = transaction_users_wallet['B_USER']
@ -66,7 +65,6 @@ class TestWallet(SingleDeviceTestCase):
self.verify_no_errors() self.verify_no_errors()
@pytest.mark.wallet
def test_eth_and_currency_balance(self): def test_eth_and_currency_balance(self):
errors = list() errors = list()
sign_in_view = SignInView(self.driver) sign_in_view = SignInView(self.driver)
@ -81,3 +79,26 @@ class TestWallet(SingleDeviceTestCase):
errors.append('Balance %s is not equal to the expected %s' % (wallet_balance, balance)) errors.append('Balance %s is not equal to the expected %s' % (wallet_balance, balance))
wallet.verify_currency_balance(eth_rate, errors) wallet.verify_currency_balance(eth_rate, errors)
assert not errors, 'errors occurred:\n{}'.format('\n'.join(errors)) assert not errors, 'errors occurred:\n{}'.format('\n'.join(errors))
@marks.testrail_case_id(3453)
def test_set_up_wallet(self):
sign_in_view = SignInView(self.driver)
sign_in_view.create_user()
home_view = sign_in_view.get_home_view()
sender_public_key = home_view.get_public_key()
sender_address = home_view.public_key_to_address(sender_public_key)
api_requests.get_donate(sender_address)
wallet_view = sign_in_view.wallet_button.click()
sign_in_phrase = wallet_view.set_up_wallet()
send_transaction = wallet_view.send_button.click()
send_transaction.chose_recipient_button.click()
send_transaction.enter_recipient_address_button.click()
recipient_address = transaction_users_wallet['A_USER']['address']
send_transaction.enter_recipient_address_input.set_value(recipient_address)
send_transaction.done_button.click()
send_transaction.amount_edit_box.click()
send_transaction.amount_edit_box.set_value(send_transaction.get_unique_amount())
send_transaction.confirm()
send_transaction.sign_transaction_button.click()
assert send_transaction.sign_in_phrase_text.text == sign_in_phrase

View File

@ -1,8 +1,11 @@
import base64 import base64
from io import BytesIO from io import BytesIO
import os import os
import time
from PIL import Image, ImageChops from PIL import Image, ImageChops
from appium.webdriver.common.mobileby import MobileBy from appium.webdriver.common.mobileby import MobileBy
from appium.webdriver.common.touch_action import TouchAction
from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.wait import WebDriverWait
@ -33,7 +36,6 @@ class BaseElement(object):
def text_part_selector(locator, text): def text_part_selector(locator, text):
return BaseElement.Locator.xpath_selector('//*[contains(@text, "' + text + '")]') return BaseElement.Locator.xpath_selector('//*[contains(@text, "' + text + '")]')
def __str__(self, *args, **kwargs): def __str__(self, *args, **kwargs):
return "%s:%s" % (self.by, self.value) return "%s:%s" % (self.by, self.value)
@ -119,9 +121,24 @@ class BaseElement(object):
def image(self): def image(self):
return Image.open(BytesIO(base64.b64decode(self.find_element().screenshot_as_base64))) return Image.open(BytesIO(base64.b64decode(self.find_element().screenshot_as_base64)))
def is_element_image_equals_template(self): def is_element_image_equals_template(self, file_name: str = ''):
if file_name:
self.template = file_name
return not ImageChops.difference(self.image, self.template).getbbox() return not ImageChops.difference(self.image, self.template).getbbox()
def swipe_element(self):
element = self.find_element()
location, size = element.location, element.size
x, y = location['x'], location['y']
width, height = size['width'], size['height']
self.driver.swipe(start_x=x + width / 2, start_y=y + height / 2, end_x=x, end_y=y + height / 2)
def long_press_element(self):
element = self.find_element()
info('Long press %s' % self.name)
action = TouchAction(self.driver)
action.long_press(element).release().perform()
class BaseEditBox(BaseElement): class BaseEditBox(BaseElement):
@ -144,6 +161,31 @@ class BaseEditBox(BaseElement):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) info('Tap on %s' % self.name)
def delete_last_symbols(self, number_of_symbols_to_delete: int):
info('Delete last %s symbols from %s' % (number_of_symbols_to_delete, self.name))
self.click()
for _ in range(number_of_symbols_to_delete):
time.sleep(1)
self.driver.press_keycode(67)
def paste_text_from_clipboard(self):
info('Paste text from clipboard into %s' % self.name)
self.long_press_element()
time.sleep(2)
action = TouchAction(self.driver)
location = self.find_element().location
x, y = location['x'], location['y']
action.press(x=x+100, y=y-50).release().perform()
def cut_text(self):
info('Cut text in %s' % self.name)
location = self.find_element().location
x, y = location['x'], location['y']
action = TouchAction(self.driver)
action.long_press(x=x, y=y).release().perform()
time.sleep(2)
action.press(x=x+50, y=y-50).release().perform()
class BaseText(BaseElement): class BaseText(BaseElement):

View File

@ -69,7 +69,7 @@ class OkButton(BaseButton):
class ContinueButton(BaseButton): class ContinueButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(ContinueButton, self).__init__(driver) super(ContinueButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='CONTINUE']") self.locator = self.Locator.xpath_selector("//*[@text='CONTINUE' or @text='Continue']")
class HomeButton(BaseButton): class HomeButton(BaseButton):
@ -87,11 +87,6 @@ class WalletButton(BaseButton):
super(WalletButton, self).__init__(driver) super(WalletButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('wallet-tab-button') self.locator = self.Locator.accessibility_id('wallet-tab-button')
def click(self):
from views.wallet_view import TransactionsButton
self.click_until_presence_of_element(desired_element=TransactionsButton(self.driver), attempts=3)
return self.navigate()
def navigate(self): def navigate(self):
from views.wallet_view import WalletView from views.wallet_view import WalletView
return WalletView(self.driver) return WalletView(self.driver)
@ -151,6 +146,12 @@ class SendMessageButton(BaseButton):
info('Tap on %s' % self.name) info('Tap on %s' % self.name)
class OfflineLabelText(BaseText):
def __init__(self, driver):
super(OfflineLabelText, self).__init__(driver)
self.locator = self.Locator.text_selector('Offline')
class BaseView(object): class BaseView(object):
def __init__(self, driver): def __init__(self, driver):
self.driver = driver self.driver = driver
@ -171,6 +172,7 @@ class BaseView(object):
self.save_button = SaveButton(self.driver) self.save_button = SaveButton(self.driver)
self.done_button = DoneButton(self.driver) self.done_button = DoneButton(self.driver)
self.delete_button = DeleteButton(self.driver) self.delete_button = DeleteButton(self.driver)
self.offline_label = OfflineLabelText(self.driver)
self.apps_button = AppsButton(self.driver) self.apps_button = AppsButton(self.driver)
self.status_app_icon = StatusAppIcon(self.driver) self.status_app_icon = StatusAppIcon(self.driver)
@ -219,13 +221,13 @@ class BaseView(object):
def find_full_text(self, text, wait_time=60): def find_full_text(self, text, wait_time=60):
info("Looking for full text: '%s'" % text) info("Looking for full text: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]') element.locator = element.Locator.text_selector(text)
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def find_text_part(self, text, wait_time=60): def find_text_part(self, text, wait_time=60):
info("Looking for a text part: '%s'" % text) info("Looking for a text part: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]') element.locator = element.Locator.text_part_selector(text)
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def element_by_text(self, text, element_type='button'): def element_by_text(self, text, element_type='button'):

View File

@ -1,8 +1,9 @@
import time import time
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException, NoSuchElementException
from tests import info from tests import info
from views.base_element import BaseButton, BaseEditBox, BaseText, BaseElement from views.base_element import BaseButton, BaseEditBox, BaseText
from views.base_view import BaseView from views.base_view import BaseView
from views.profile_view import ProfilePictureElement
class ChatMessageInput(BaseEditBox): class ChatMessageInput(BaseEditBox):
@ -99,11 +100,11 @@ class FirstRecipient(BaseButton):
self.locator = self.Locator.accessibility_id('contact-item') self.locator = self.Locator.accessibility_id('contact-item')
class MessageByUsername(BaseText): class UsernameByMessage(BaseText):
def __init__(self, driver, username): def __init__(self, driver, message):
super(MessageByUsername, self).__init__(driver) super(UsernameByMessage, self).__init__(driver)
self.locator = self.Locator.xpath_selector( self.locator = self.Locator.xpath_selector(
'//*[@text="%s"]/following-sibling::android.widget.TextView' % username) "//*[@content-desc='chat-item']//*[contains(@text, '%s')]/../../android.widget.TextView" % message)
class MoreUsersButton(BaseButton): class MoreUsersButton(BaseButton):
@ -167,7 +168,6 @@ class ChatView(BaseView):
self.faucet_command = FaucetCommand(self.driver) self.faucet_command = FaucetCommand(self.driver)
self.faucet_send_command = FaucetSendCommand(self.driver) self.faucet_send_command = FaucetSendCommand(self.driver)
self.chat_options = ChatMenuButton(self.driver) self.chat_options = ChatMenuButton(self.driver)
self.members_button = MembersButton(self.driver) self.members_button = MembersButton(self.driver)
self.delete_chat_button = DeleteChatButton(self.driver) self.delete_chat_button = DeleteChatButton(self.driver)
@ -183,6 +183,7 @@ class ChatView(BaseView):
self.open_in_browser_button = OpenInBrowserButton(self.driver) self.open_in_browser_button = OpenInBrowserButton(self.driver)
# Contact's profile # Contact's profile
self.contact_profile_picture = ProfilePictureElement(self.driver)
self.profile_send_message = ProfileSendMessageButton(self.driver) self.profile_send_message = ProfileSendMessageButton(self.driver)
self.profile_send_transaction = ProfileSendTransactionButton(self.driver) self.profile_send_transaction = ProfileSendTransactionButton(self.driver)
@ -195,25 +196,12 @@ class ChatView(BaseView):
except TimeoutException: except TimeoutException:
break break
def wait_for_message_in_one_to_one_chat(self, expected_message: str, errors: list): def wait_for_message_in_one_to_one_chat(self, expected_message: str, errors: list, wait_time: int = 20):
try: try:
self.wait_for_element_starts_with_text(expected_message, wait_time=20) self.wait_for_element_starts_with_text(expected_message, wait_time=wait_time)
except TimeoutException: except TimeoutException:
errors.append('Message with text "%s" was not received' % expected_message) errors.append('Message with text "%s" was not received' % expected_message)
def wait_for_messages_by_user(self, username: str, expected_messages: list, errors: list, wait_time: int = 30):
expected_messages = expected_messages if type(expected_messages) == list else [expected_messages]
repeat = 0
while repeat <= wait_time:
received_messages = [element.text for element in MessageByUsername(self.driver, username).find_elements()]
if not set(expected_messages) - set(received_messages):
break
time.sleep(3)
repeat += 3
if set(expected_messages) - set(received_messages):
errors.append('Not received messages from user %s: "%s"' % (username, ', '.join(
[i for i in list(set(expected_messages) - set(received_messages))])))
def wait_for_messages(self, username: str, expected_messages: list, errors: list, wait_time: int = 30): def wait_for_messages(self, username: str, expected_messages: list, errors: list, wait_time: int = 30):
expected_messages = expected_messages if type(expected_messages) == list else [expected_messages] expected_messages = expected_messages if type(expected_messages) == list else [expected_messages]
repeat = 0 repeat = 0
@ -230,6 +218,15 @@ class ChatView(BaseView):
errors.append('Not received messages from user %s: "%s"' % (username, ', '.join( errors.append('Not received messages from user %s: "%s"' % (username, ', '.join(
[i for i in list(set(expected_messages) - set(received_messages))]))) [i for i in list(set(expected_messages) - set(received_messages))])))
def verify_username_is_shown_per_message(self, username: str, messages: str, errors: list):
messages = messages if type(messages) == list else [messages]
for message in messages:
elements = UsernameByMessage(self.driver, message).find_elements()
for element in elements:
if not element.text == username:
errors.append("Message '%s' was received but username is '%s' instead of %s" %
(message, element.text, username))
def send_eth_to_request(self, request, sender_password): def send_eth_to_request(self, request, sender_password):
gas_popup = self.element_by_text_part('Specify amount') gas_popup = self.element_by_text_part('Specify amount')
request.click_until_presence_of_element(gas_popup) request.click_until_presence_of_element(gas_popup)
@ -282,3 +279,10 @@ class ChatView(BaseView):
self.request_command.click() self.request_command.click()
self.send_as_keyevent(amount) self.send_as_keyevent(amount)
self.send_message_button.click() self.send_message_button.click()
def chat_element_by_text(self, text):
info("Looking for full text: '%s'" % text)
element = self.element_types['text'](self.driver)
element.locator = element.Locator.xpath_selector(
"//*[@content-desc='chat-item']//*[starts-with(@text,'%s')]" % text)
return element

View File

@ -1,6 +1,6 @@
from tests import info from tests import info
import time import time
from selenium.common.exceptions import TimeoutException, NoSuchElementException from selenium.common.exceptions import TimeoutException
from views.base_element import BaseButton, BaseText from views.base_element import BaseButton, BaseText
from views.base_view import BaseView from views.base_view import BaseView
@ -29,9 +29,9 @@ class ConsoleButton(BaseButton):
class ChatElement(BaseButton): class ChatElement(BaseButton):
def __init__(self, driver, username): def __init__(self, driver, username_part):
super(ChatElement, self).__init__(driver) super(ChatElement, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='%s']" % username) self.locator = self.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % username_part)
def navigate(self): def navigate(self):
from views.chat_view import ChatView from views.chat_view import ChatView
@ -124,13 +124,9 @@ class HomeView(BaseView):
def swipe_and_delete_chat(self, chat_name: str): def swipe_and_delete_chat(self, chat_name: str):
chat_element = self.get_chat_with_user(chat_name) chat_element = self.get_chat_with_user(chat_name)
location = chat_element.find_element().location
x, y = location['x'], location['y']
size = chat_element.find_element().size
width, height = size['width'], size['height']
counter = 0 counter = 0
while counter < 10: while counter < 10:
self.driver.swipe(start_x=x + width / 2, start_y=y + height / 2, end_x=x, end_y=y + height / 2) chat_element.swipe_element()
if chat_element.swipe_delete_button.is_element_present(): if chat_element.swipe_delete_button.is_element_present():
break break
time.sleep(10) time.sleep(10)

View File

@ -84,7 +84,7 @@ class LogoutDialog(BaseView):
class LogoutButton(BaseButton): class LogoutButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(LogoutDialog.LogoutButton, self).__init__(driver) super(LogoutDialog.LogoutButton, self).__init__(driver)
self.locator = self.Locator.text_selector('LOG OUT') self.locator = self.Locator.xpath_selector("//*[@text='LOG OUT' or @text='Log out']")
def navigate(self): def navigate(self):
from views.sign_in_view import SignInView from views.sign_in_view import SignInView
@ -285,17 +285,16 @@ class ProfileView(BaseView):
return dict(zip(map(int, text[::2]), text[1::2])) return dict(zip(map(int, text[::2]), text[1::2]))
def edit_profile_picture(self, file_name: str): def edit_profile_picture(self, file_name: str):
if AbstractTestCase().environment == 'sauce': if not AbstractTestCase().environment == 'sauce':
self.profile_picture.template = file_name
self.edit_button.click()
self.edit_picture_button.click()
self.select_from_gallery_button.click()
if self.allow_button.is_element_displayed(sec=10):
self.allow_button.click()
self.element_by_text(file_name).click()
self.confirm_button.click()
else:
raise NotImplementedError('Test case is implemented to run on SauceLabs only') raise NotImplementedError('Test case is implemented to run on SauceLabs only')
self.profile_picture.template = file_name
self.edit_button.click()
self.edit_picture_button.click()
self.select_from_gallery_button.click()
if self.allow_button.is_element_displayed(sec=10):
self.allow_button.click()
self.element_by_text(file_name).click()
self.confirm_button.click()
def logout(self): def logout(self):
self.logout_button.click() self.logout_button.click()

View File

@ -1,3 +1,5 @@
from views.base_element import BaseButton, BaseEditBox, BaseText
from views.base_view import BaseView
from views.base_element import BaseElement, BaseButton, BaseEditBox from views.base_element import BaseElement, BaseButton, BaseEditBox
from views.base_view import BaseView, OkButton from views.base_view import BaseView, OkButton
@ -8,6 +10,12 @@ class FirstRecipient(BaseButton):
self.locator = self.Locator.accessibility_id('chat-icon') self.locator = self.Locator.accessibility_id('chat-icon')
class CancelButton(BaseButton):
def __init__(self, driver):
super(CancelButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('cancel-button')
class SignTransactionButton(BaseButton): class SignTransactionButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(SignTransactionButton, self).__init__(driver) super(SignTransactionButton, self).__init__(driver)
@ -21,6 +29,12 @@ class AmountEditBox(BaseEditBox, BaseButton):
self.locator = self.Locator.accessibility_id('amount-input') self.locator = self.Locator.accessibility_id('amount-input')
class SignInPhraseText(BaseText):
def __init__(self, driver):
super(SignInPhraseText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('signing-phrase-text')
class PasswordInput(BaseEditBox): class PasswordInput(BaseEditBox):
def __init__(self, driver): def __init__(self, driver):
super(PasswordInput, self).__init__(driver) super(PasswordInput, self).__init__(driver)
@ -107,8 +121,10 @@ class SendTransactionView(BaseView):
self.recent_recipients_button = RecentRecipientsButton(self.driver) self.recent_recipients_button = RecentRecipientsButton(self.driver)
self.amount_edit_box = AmountEditBox(self.driver) self.amount_edit_box = AmountEditBox(self.driver)
self.cancel_button = CancelButton(self.driver)
self.sign_transaction_button = SignTransactionButton(self.driver) self.sign_transaction_button = SignTransactionButton(self.driver)
self.confirm_button = ConfirmButton(self.driver) self.confirm_button = ConfirmButton(self.driver)
self.sign_in_phrase_text = SignInPhraseText(self.driver)
self.password_input = PasswordInput(self.driver) self.password_input = PasswordInput(self.driver)
self.enter_password_input = EnterPasswordInput(self.driver) self.enter_password_input = EnterPasswordInput(self.driver)
self.got_it_button = GotItButton(self.driver) self.got_it_button = GotItButton(self.driver)

View File

@ -1,7 +1,7 @@
from tests import get_current_time from tests import get_current_time
from views.base_element import BaseButton, BaseEditBox from views.base_element import BaseButton, BaseEditBox
from views.base_view import BaseView from views.base_view import BaseView
import time
class AccountButton(BaseButton): class AccountButton(BaseButton):
@ -104,11 +104,18 @@ class SignInView(BaseView):
self.next_button.click() self.next_button.click()
self.confirm_password_input.set_value(password) self.confirm_password_input.set_value(password)
self.next_button.click() self.next_button.click()
self.name_input.wait_for_element(45)
self.name_input.send_keys('user_%s' % get_current_time()) # bypass StaleElementReferenceException
time.sleep(5)
self.name_input.wait_for_element(10)
self.name_input.click()
username = 'user_%s' % get_current_time()
self.send_as_keyevent(username)
self.next_button.click() self.next_button.click()
self.do_not_share.wait_for_element(10) self.do_not_share.wait_for_visibility_of_element(10)
self.do_not_share.click_until_presence_of_element(self.home_button) self.do_not_share.click_until_presence_of_element(self.home_button)
return username
def recover_access(self, passphrase, password): def recover_access(self, passphrase, password):
recover_access_view = self.i_have_account_button.click() recover_access_view = self.i_have_account_button.click()

View File

@ -118,6 +118,13 @@ class SetUpButton(BaseButton):
self.locator = self.Locator.text_selector("LETS GET SET UP") self.locator = self.Locator.text_selector("LETS GET SET UP")
class SignInPhraseText(BaseText):
def __init__(self, driver):
super(SignInPhraseText, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[contains(@text,'phrase')]/preceding-sibling::*[1]/android.widget.TextView")
class WalletView(BaseView): class WalletView(BaseView):
def __init__(self, driver): def __init__(self, driver):
super(WalletView, self).__init__(driver) super(WalletView, self).__init__(driver)
@ -141,6 +148,7 @@ class WalletView(BaseView):
self.address_text = AddressText(self.driver) self.address_text = AddressText(self.driver)
self.set_up_button = SetUpButton(self.driver) self.set_up_button = SetUpButton(self.driver)
self.sign_in_phrase = SignInPhraseText(self.driver)
def get_usd_total_value(self): def get_usd_total_value(self):
return float(self.usd_total_value.text) return float(self.usd_total_value.text)
@ -172,7 +180,12 @@ class WalletView(BaseView):
info('Transaction received, balance updated!') info('Transaction received, balance updated!')
return return
def get_sign_in_phrase(self):
return ' '.join([element.text for element in self.sign_in_phrase.find_elements()])
def set_up_wallet(self): def set_up_wallet(self):
self.set_up_button.click() self.set_up_button.click()
phrase = self.get_sign_in_phrase()
self.done_button.click() self.done_button.click()
self.yes_button.click() self.yes_button.click()
return phrase