From 2817d007206af74b08df30fdba75b365b1993fc1 Mon Sep 17 00:00:00 2001 From: yevh-berdnyk Date: Thu, 28 Jun 2018 20:46:51 +0200 Subject: [PATCH] Added atomic tests for chats Signed-off-by: yevh-berdnyk --- test/appium/support/api/network_api.py | 5 + .../tests/atomic/chats/test_commands.py | 154 ++++++++++- .../appium/tests/atomic/chats/test_console.py | 35 +++ .../tests/atomic/chats/test_one_to_one.py | 246 +++++++++++++++++- test/appium/tests/atomic/chats/test_public.py | 30 ++- test/appium/tests/atomic/test_sign_in.py | 1 + test/appium/tests/marks.py | 1 + test/appium/tests/test_chat_management.py | 4 +- test/appium/tests/test_message_reliability.py | 22 +- test/appium/tests/test_messaging.py | 20 +- test/appium/tests/test_profile.py | 9 +- test/appium/views/base_element.py | 14 +- test/appium/views/base_view.py | 4 + test/appium/views/chat_view.py | 61 ++--- test/appium/views/console_view.py | 71 ++--- test/appium/views/home_view.py | 11 +- test/appium/views/send_transaction_view.py | 38 ++- test/appium/views/sign_in_view.py | 3 +- test/appium/views/wallet_view.py | 4 +- 19 files changed, 565 insertions(+), 168 deletions(-) create mode 100644 test/appium/tests/atomic/chats/test_console.py diff --git a/test/appium/support/api/network_api.py b/test/appium/support/api/network_api.py index 2e7e5b9e15..0da2f5154d 100644 --- a/test/appium/support/api/network_api.py +++ b/test/appium/support/api/network_api.py @@ -67,6 +67,11 @@ class NetworkApi: info('Transaction is received') return + def verify_balance_is(self, expected_balance: int, recipient_address: str, errors: list): + balance = self.get_balance(recipient_address) + if balance / 1000000000000000000 != expected_balance: + errors.append('Recipients balance is not updated on etherscan') + def faucet(self, address): return requests.request('GET', '%s/0x%s' % (self.faucet_url, address)).json() diff --git a/test/appium/tests/atomic/chats/test_commands.py b/test/appium/tests/atomic/chats/test_commands.py index 1316bccdff..e2d81aa0f2 100644 --- a/test/appium/tests/atomic/chats/test_commands.py +++ b/test/appium/tests/atomic/chats/test_commands.py @@ -1,6 +1,8 @@ +from _pytest.outcomes import Failed +from decimal import Decimal as d from selenium.common.exceptions import TimeoutException -from tests import marks, transaction_users, common_password +from tests import marks, transaction_users, common_password, group_chat_users from tests.base_test_case import MultipleDeviceTestCase from views.sign_in_view import SignInView @@ -10,6 +12,7 @@ from views.sign_in_view import SignInView class TestCommands(MultipleDeviceTestCase): @marks.testrail_case_id(3742) + @marks.testrail_id(3697) def test_network_mismatch_for_send_request_commands(self): sender = self.senders['d_user'] = transaction_users['D_USER'] self.create_drivers(2) @@ -61,3 +64,152 @@ class TestCommands(MultipleDeviceTestCase): self.errors.append('Request funds message was not received') self.verify_no_errors() + + @marks.testrail_id(765) + def test_send_eth_in_1_1_chat(self): + recipient = transaction_users['D_USER'] + sender = self.senders['c_user'] = transaction_users['C_USER'] + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + home_1 = device_1.recover_access(passphrase=sender['passphrase'], password=sender['password']) + home_2 = device_2.recover_access(passphrase=recipient['passphrase'], password=recipient['password']) + wallet_1, wallet_2 = home_1.wallet_button.click(), home_2.wallet_button.click() + wallet_1.set_up_wallet() + wallet_1.home_button.click() + wallet_2.set_up_wallet() + init_balance = wallet_2.get_eth_value() + wallet_2.home_button.click() + + chat_1 = home_1.add_contact(recipient['public_key']) + amount = chat_1.get_unique_amount() + chat_1.commands_button.click() + chat_1.send_command.click() + chat_1.eth_asset.click() + chat_1.send_as_keyevent(amount) + send_transaction_view = chat_1.get_send_transaction_view() + chat_1.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button) + + send_transaction_view.chose_recipient_button.find_element().click() + if send_transaction_view.recent_recipients_button.is_element_displayed(): + self.errors.append('Recipient field is editable') + send_transaction_view.click_system_back_button() + + send_transaction_view.select_asset_button.click() + if not send_transaction_view.chose_recipient_button.is_element_displayed(): + self.errors.append('Asset field is editable') + send_transaction_view.back_button.click() + + if send_transaction_view.amount_edit_box.is_element_displayed(): + self.errors.append('Amount field is editable') + + send_transaction_view.advanced_button.click() + send_transaction_view.transaction_fee_button.click() + gas_limit = '25000' + send_transaction_view.gas_limit_input.clear() + send_transaction_view.gas_limit_input.set_value(gas_limit) + gas_price = '1' + send_transaction_view.gas_price_input.clear() + send_transaction_view.gas_price_input.set_value(gas_price) + send_transaction_view.total_fee_input.click() + if send_transaction_view.total_fee_input.text != '%s ETH' % (d(gas_limit) * d(gas_price) / d(1000000000)): + self.errors.append('Gas limit and/or gas price fields were not edited') + send_transaction_view.done_button.click() + send_transaction_view.sign_transaction(sender['password']) + + if not chat_1.chat_element_by_text(amount).is_element_displayed(): + self.errors.append('Message with the sent amount is not shown for the sender') + chat_2 = home_2.get_chat_with_user(sender['username']).click() + if not chat_2.chat_element_by_text(amount).is_element_displayed(): + self.errors.append('Message with the sent amount is not shown for the recipient') + + chat_2.get_back_to_home_view() + home_2.wallet_button.click() + try: + wallet_2.wait_balance_changed_on_wallet_screen(expected_balance=init_balance + float(amount)) + except Failed as e: + self.errors.append(e.msg) + + self.network_api.verify_balance_is(expected_balance=init_balance + float(amount), + recipient_address=recipient['address'], errors=self.errors) + self.verify_no_errors() + + @marks.testrail_id(1391) + def test_request_and_receive_eth_in_1_1_chat(self): + recipient = transaction_users['C_USER'] + sender = self.senders['d_user'] = transaction_users['D_USER'] + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + home_1 = device_1.recover_access(passphrase=sender['passphrase'], password=sender['password']) + home_2 = device_2.recover_access(passphrase=recipient['passphrase'], password=recipient['password']) + wallet_1, wallet_2 = home_1.wallet_button.click(), home_2.wallet_button.click() + wallet_1.set_up_wallet() + wallet_1.home_button.click() + wallet_2.set_up_wallet() + init_balance = wallet_2.get_eth_value() + wallet_2.home_button.click() + + chat_2 = home_2.add_contact(sender['public_key']) + amount = chat_2.get_unique_amount() + chat_2.request_transaction_in_1_1_chat(amount) + + chat_1 = home_1.get_chat_with_user(recipient['username']).click() + chat_1.send_eth_to_request(amount=amount, sender_password=sender['password']) + + if not chat_1.chat_element_by_text(amount).is_element_displayed(): + self.errors.append('Message with the sent amount is not shown for the sender') + if not chat_2.chat_element_by_text(amount).is_element_displayed(): + self.errors.append('Message with the sent amount is not shown for the recipient') + if chat_2.chat_element_by_text(amount).send_request_button.is_element_displayed(): + self.errors.append("'Send' in a transaction request button is not disabled after receiving transaction") + + chat_2.get_back_to_home_view() + home_2.wallet_button.click() + try: + wallet_2.wait_balance_changed_on_wallet_screen(expected_balance=init_balance + float(amount)) + except Failed as e: + self.errors.append(e.msg) + + self.network_api.verify_balance_is(expected_balance=init_balance + float(amount), + recipient_address=recipient['address'], errors=self.errors) + self.verify_no_errors() + + @marks.testrail_id(1429) + def test_request_eth_in_wallet(self): + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + username_1 = 'user_1' + recipient = group_chat_users['C_USER'] + + home_1 = device_1.create_user(username=username_1) + home_2 = device_2.recover_access(passphrase=recipient['passphrase'], password=recipient['password']) + + home_1.add_contact(recipient['public_key']) + home_1.get_back_to_home_view() + wallet_1 = home_1.wallet_button.click() + wallet_1.set_up_wallet() + + send_transaction_device_1 = wallet_1.request_button.click_until_presence_of_element( + wallet_1.send_transaction_request) + wallet_1.send_transaction_request.click() + send_transaction_device_1.amount_edit_box.scroll_to_element() + amount = home_1.get_unique_amount() + send_transaction_device_1.amount_edit_box.set_value(amount) + send_transaction_device_1.confirm() + send_transaction_device_1.chose_recipient_button.click() + sender_button = send_transaction_device_1.element_by_text(recipient['username']) + send_transaction_device_1.recent_recipients_button.click_until_presence_of_element(sender_button) + sender_button.click() + wallet_1.send_request_button.click() + + chat_2 = home_2.get_chat_with_user(username_1).click() + chat_element = chat_2.chat_element_by_text(amount) + try: + chat_element.wait_for_visibility_of_element(120) + if not chat_element.contains_text('Transaction Request'): + self.errors.append("Request funds message doesn't contain text 'Transaction Request'") + if not chat_element.send_request_button.is_element_displayed(): + self.errors.append("Request funds message doesn't contain 'Send' button") + except TimeoutException: + self.errors.append('Request funds message was not received') + + self.verify_no_errors() diff --git a/test/appium/tests/atomic/chats/test_console.py b/test/appium/tests/atomic/chats/test_console.py new file mode 100644 index 0000000000..6e9f52321b --- /dev/null +++ b/test/appium/tests/atomic/chats/test_console.py @@ -0,0 +1,35 @@ +import time + +from tests import marks +from tests.base_test_case import SingleDeviceTestCase +from views.sign_in_view import SignInView + + +@marks.chat +class TestMessagesPublicChat(SingleDeviceTestCase): + + @marks.testrail_id(1380) + def test_faucet_console_command(self): + sign_in_view = SignInView(self.driver) + sign_in_view.create_user() + profile_view = sign_in_view.profile_button.click() + profile_view.advanced_button.click() + profile_view.debug_mode_toggle.click() + home_view = profile_view.home_button.click() + console_chat = home_view.get_chat_with_user('Status Console') + console_view = console_chat.click() + console_view.send_faucet_request() + first_request_time = time.time() + console_view.chat_element_by_text('Faucet request has been received').wait_for_visibility_of_element() + console_view.send_faucet_request() + console_view.chat_element_by_text('Faucet request error').wait_for_visibility_of_element() + console_view.get_back_to_home_view() + wallet_view = profile_view.wallet_button.click() + wallet_view.set_up_wallet() + wallet_view.wait_balance_changed_on_wallet_screen() + wallet_view.home_button.click() + console_chat.click() + wait_time = 300 - (time.time() - first_request_time) + time.sleep(wait_time if wait_time > 0 else 0) + console_view.send_faucet_request() + console_view.chat_element_by_text('Faucet request has been received').wait_for_visibility_of_element() diff --git a/test/appium/tests/atomic/chats/test_one_to_one.py b/test/appium/tests/atomic/chats/test_one_to_one.py index 3daface572..6528cb1980 100644 --- a/test/appium/tests/atomic/chats/test_one_to_one.py +++ b/test/appium/tests/atomic/chats/test_one_to_one.py @@ -1,19 +1,20 @@ import random import string +import emoji import pytest +from selenium.common.exceptions import TimeoutException -from tests import marks, get_current_time -from tests.base_test_case import MultipleDeviceTestCase +from tests import marks, get_current_time, group_chat_users +from tests.base_test_case import MultipleDeviceTestCase, SingleDeviceTestCase from views.sign_in_view import SignInView @marks.all @marks.chat -class TestMessagesOneToOneChat(MultipleDeviceTestCase): +class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase): - @marks.skip - @marks.testrail_case_id(764) + @marks.testrail_id(764) def test_text_message_1_1_chat(self): self.create_drivers(2) device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) @@ -34,15 +35,13 @@ class TestMessagesOneToOneChat(MultipleDeviceTestCase): if device_1_chat.chat_element_by_text(message).status.text != 'Seen': pytest.fail("'Seen' status is shown under the sent text message") - @marks.skip - @marks.testrail_case_id(772) + @marks.testrail_id(772) def test_offline_messaging_1_1_chat(self): self.create_drivers(2, offline_mode=True) device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2) - 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() + username_2 = 'user_2' + home_1, home_2 = sign_in_1.create_user(), sign_in_2.create_user(username=username_2) public_key_1 = home_1.get_public_key() home_1.home_button.click() @@ -75,14 +74,13 @@ class TestMessagesOneToOneChat(MultipleDeviceTestCase): chat_1.chat_element_by_text(message_2).wait_for_visibility_of_element(180) @marks.testrail_case_id(3741) + @marks.testrail_id(3701) def test_resend_message_offline(self): self.create_drivers(2, offline_mode=True) device_1, device_2 = self.drivers[0], self.drivers[1] sign_in_1, sign_in_2 = SignInView(device_1), SignInView(device_2) username_1 = 'user_%s' % get_current_time() - sign_in_1.create_user(username_1) - sign_in_2.create_user() - home_1, home_2 = sign_in_1.get_home_view(), sign_in_2.get_home_view() + home_1, home_2 = sign_in_1.create_user(username_1), sign_in_2.create_user() public_key_2 = home_2.get_public_key() home_2.home_button.click() @@ -114,8 +112,9 @@ class TestMessagesOneToOneChat(MultipleDeviceTestCase): self.verify_no_errors() @marks.testrail_case_id(3743) + @marks.testrail_id(3710) def test_messaging_in_different_networks(self): - self.create_drivers(2, offline_mode=True) + 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 = 'user_%s' % get_current_time() @@ -145,3 +144,222 @@ class TestMessagesOneToOneChat(MultipleDeviceTestCase): chat_1.chat_message_input.send_keys(message) chat_1.send_message_button.click() chat_2.chat_element_by_text(message).wait_for_visibility_of_element() + + @marks.testrail_id(1386) + def test_send_message_to_newly_added_contact(self): + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + username_1 = 'user_%s' % get_current_time() + + device_1_home, device_2_home = device_1.create_user(username=username_1), device_2.create_user() + + profile_1 = device_1_home.profile_button.click() + file_name = 'sauce_logo.png' + profile_1.edit_profile_picture(file_name) + profile_1.home_button.click() + + device_2_public_key = device_2_home.get_public_key() + device_2_home.home_button.click() + + device_1_chat = device_1_home.add_contact(device_2_public_key) + message = 'hello' + device_1_chat.chat_message_input.send_keys(message) + device_1_chat.send_message_button.click() + + chat_element = device_2_home.get_chat_with_user(username_1) + chat_element.wait_for_visibility_of_element() + device_2_chat = chat_element.click() + if not device_2_chat.chat_element_by_text(message).is_element_displayed(): + self.erros.append("Message with test '%s' was not received" % message) + if not device_2_chat.add_to_contacts.is_element_displayed(): + self.errors.append('Add to contacts button is not shown') + if device_2_chat.user_name_text.text != username_1: + self.errors.append("Real username '%s' is not shown in one-to-one chat" % username_1) + device_2_chat.chat_options.click() + device_2_chat.view_profile_button.click() + if not device_2_chat.contact_profile_picture.is_element_image_equals_template(file_name): + self.errors.append("Updated profile picture is not shown in one-to-one chat") + self.verify_no_errors() + + @marks.testrail_id(1387) + def test_add_to_contacts(self): + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + username_1, username_2 = 'user_1', 'user_2' + + device_1_home, device_2_home = device_1.create_user(username=username_1), device_2.create_user( + username=username_2) + + device_2_public_key = device_2_home.get_public_key() + profile_2 = device_2_home.get_profile_view() + file_name = 'sauce_logo.png' + profile_2.edit_profile_picture(file_name) + profile_2.home_button.click() + + device_1_chat = device_1_home.add_contact(device_2_public_key) + message = 'hello' + device_1_chat.chat_message_input.send_keys(message) + device_1_chat.send_message_button.click() + + chat_element = device_2_home.get_chat_with_user(username_1) + chat_element.wait_for_visibility_of_element() + device_2_chat = chat_element.click() + if not device_2_chat.chat_element_by_text(message).is_element_displayed(): + self.erros.append("Message with test '%s' was not received" % message) + device_2_chat.add_to_contacts.click() + + device_2_chat.get_back_to_home_view() + start_new_chat = device_2_home.plus_button.click() + start_new_chat.start_new_chat_button.click() + if not start_new_chat.element_by_text(username_1).is_element_displayed(): + self.errors.append('%s is not added to contacts' % username_1) + + if device_1_chat.user_name_text.text != username_2: + self.errors.append("Real username '%s' is not shown in one-to-one chat" % username_2) + device_1_chat.chat_options.click() + device_1_chat.view_profile_button.click() + if not device_1_chat.contact_profile_picture.is_element_image_equals_template(file_name): + self.errors.append("Updated profile picture is not shown in one-to-one chat") + self.verify_no_errors() + + @marks.testrail_id(1413) + def test_send_and_open_links(self): + self.create_drivers(2) + device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) + username_1, username_2 = 'user_1', 'user_2' + + home_1, home_2 = device_1.create_user(username=username_1), device_2.create_user(username=username_2) + public_key_2 = home_2.get_public_key() + home_2.home_button.click() + + chat_1 = home_1.add_contact(public_key_2) + url_message = 'status.im' + chat_1.chat_message_input.send_keys(url_message) + chat_1.send_message_button.click() + chat_1.get_back_to_home_view() + home_2.connection_status.wait_for_invisibility_of_element(30) + chat_2 = home_2.get_chat_with_user(username_1).click() + chat_2.element_starts_with_text(url_message, 'button').click() + web_view = chat_2.open_in_browser_button.click() + try: + web_view.find_full_text('Status, the Ethereum discovery tool.') + except TimeoutException: + self.errors.append('URL was not opened from 1-1 chat') + web_view.back_to_home_button.click() + chat_2.get_back_to_home_view() + + chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) + home_1.join_public_chat(chat_name) + home_2.join_public_chat(chat_name) + chat_2.chat_message_input.send_keys(url_message) + chat_2.send_message_button.click() + chat_1.element_starts_with_text(url_message, 'button').click() + web_view = chat_1.open_in_browser_button.click() + try: + web_view.find_full_text('Status, the Ethereum discovery tool.') + except TimeoutException: + self.errors.append('URL was not opened from 1-1 chat') + self.verify_no_errors() + + @marks.testrail_id(1431) + def test_offline_status(self): + self.create_drivers(1, offline_mode=True) + driver = self.drivers[0] + sign_in = SignInView(driver) + home = sign_in.create_user() + + driver.set_network_connection(1) # airplane mode + + if home.connection_status.text != 'Offline': + self.errors.append('Offline status is not shown in home screen') + + chat = home.add_contact(group_chat_users['C_USER']['public_key']) + if chat.connection_status.text != 'Offline': + self.errors.append('Offline status is not shown in 1-1 chat') + chat.get_back_to_home_view() + + public_chat = home.join_public_chat(''.join(random.choice(string.ascii_lowercase) for _ in range(7))) + if public_chat.connection_status.text != 'Offline': + self.errors.append('Offline status is not shown in a public chat') + self.verify_no_errors() + + +@marks.all +@marks.chat +class TestMessagesOneToOneChatSingle(SingleDeviceTestCase): + + @marks.testrail_id(1390) + def test_copy_and_paste_messages(self): + sign_in = SignInView(self.driver) + home = sign_in.create_user() + + 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() + + chat.chat_element_by_text(message_text).long_press_element() + chat.element_by_text('Copy to clipboard').click() + + message_input.paste_text_from_clipboard() + if message_input.text != message_text: + self.errors.append('Message text was not copied in a public chat') + + chat.get_back_to_home_view() + home.add_contact(group_chat_users['A_USER']['public_key']) + message_input.send_keys(message_text) + chat.send_message_button.click() + + chat.chat_element_by_text(message_text).long_press_element() + chat.element_by_text('Copy to clipboard').click() + + message_input.paste_text_from_clipboard() + if message_input.text != message_text: + self.errors.append('Message text was not copied in 1-1 chat') + self.verify_no_errors() + + @marks.testrail_id(1398) + def test_delete_cut_and_paste_messages(self): + sign_in = SignInView(self.driver) + home = sign_in.create_user() + chat = home.add_contact(group_chat_users['B_USER']['public_key']) + + message_text = 'test' + message_input = chat.chat_message_input + message_input.send_keys(message_text) + + message_input.delete_last_symbols(2) + assert message_input.text == message_text[:-2] + + message_input.cut_text() + + message_input.paste_text_from_clipboard() + chat.send_message_button.click() + + chat.chat_element_by_text(message_text[:-2] + ' ').wait_for_visibility_of_element(2) + + @marks.testrail_id(2106) + def test_send_emoji(self): + sign_in = SignInView(self.driver) + home = sign_in.create_user() + + home.join_public_chat(''.join(random.choice(string.ascii_lowercase) for _ in range(7))) + chat = sign_in.get_chat_view() + emoji_name = random.choice(list(emoji.EMOJI_UNICODE)) + emoji_unicode = emoji.EMOJI_UNICODE[emoji_name] + chat.chat_message_input.send_keys(emoji.emojize(emoji_name)) + chat.send_message_button.click() + + if not chat.chat_element_by_text(emoji_unicode).is_element_displayed(): + self.errors.append('Message with emoji was not sent in public chat') + + chat.get_back_to_home_view() + home.add_contact(group_chat_users['C_USER']['public_key']) + chat.chat_message_input.send_keys(emoji.emojize(emoji_name)) + chat.send_message_button.click() + + if not chat.chat_element_by_text(emoji_unicode).is_element_displayed(): + self.errors.append('Message with emoji was not sent in 1-1 chat') + self.verify_no_errors() diff --git a/test/appium/tests/atomic/chats/test_public.py b/test/appium/tests/atomic/chats/test_public.py index 15ed99d94e..320850cc6c 100644 --- a/test/appium/tests/atomic/chats/test_public.py +++ b/test/appium/tests/atomic/chats/test_public.py @@ -9,21 +9,22 @@ from views.sign_in_view import SignInView @marks.chat class TestMessagesPublicChat(MultipleDeviceTestCase): - @marks.skip - @marks.testrail_case_id(1383) + @marks.testrail_id(1383) def test_public_chat(self): self.create_drivers(2) device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) - users = list() - chats = list() - chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) - for sign_in in device_1, device_2: - users.append(sign_in.create_user()) - home = sign_in.get_home_view() - chats.append(home.join_public_chat(chat_name)) - chat_1, chat_2 = chats[0], chats[1] + username_1, username_2 = 'user_1', 'user_2' + home_1, home_2 = device_1.create_user(username=username_1), device_2.create_user(username=username_2) + public_key_2 = home_2.get_public_key() + home_2.home_button.click() - if chat_1.connection_status.text != 'Fetching messages...': + home_1.add_contact(public_key_2) + home_1.get_back_to_home_view() + + public_chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) + chat_1, chat_2 = home_1.join_public_chat(public_chat_name), home_2.join_public_chat(public_chat_name) + + if chat_2.connection_status.text != 'Fetching messages...': self.errors.append("'Fetching messages...' status is not shown") message = 'hello' @@ -31,3 +32,10 @@ class TestMessagesPublicChat(MultipleDeviceTestCase): chat_1.send_message_button.click() chat_2.verify_message_is_under_today_text(message, self.errors) + if chat_2.chat_element_by_text(message).username.text != username_1: + self.errors.append("Username '%s' is not shown next to the received message" % username_1) + + if chat_1.element_by_text(username_1).is_element_displayed(): + self.errors.append("Username '%s' is shown for the sender" % username_1) + + self.verify_no_errors() diff --git a/test/appium/tests/atomic/test_sign_in.py b/test/appium/tests/atomic/test_sign_in.py index f8f494baff..d7aee36703 100644 --- a/test/appium/tests/atomic/test_sign_in.py +++ b/test/appium/tests/atomic/test_sign_in.py @@ -8,6 +8,7 @@ from views.sign_in_view import SignInView class TestSignIn(MultipleDeviceTestCase): @marks.testrail_case_id(3740) + @marks.testrail_id(1432) def test_offline_login(self): self.create_drivers(1, offline_mode=True) driver = self.drivers[0] diff --git a/test/appium/tests/marks.py b/test/appium/tests/marks.py index 13a2af2488..dc2ed4db06 100644 --- a/test/appium/tests/marks.py +++ b/test/appium/tests/marks.py @@ -2,6 +2,7 @@ import pytest pr = pytest.mark.pr testrail_case_id = pytest.mark.testrail_case_id +testrail_id = pytest.mark.testrail_id # atomic tests all = pytest.mark.all api = pytest.mark.api diff --git a/test/appium/tests/test_chat_management.py b/test/appium/tests/test_chat_management.py index 357a605e79..c1ac42ae83 100644 --- a/test/appium/tests/test_chat_management.py +++ b/test/appium/tests/test_chat_management.py @@ -83,11 +83,9 @@ class TestChatManagementMultiple(MultipleDeviceTestCase): def test_public_chat_management(self): self.create_drivers(2) device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) - users = [] chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(19)) for sign_in in device_1, device_2: - users.append(sign_in.create_user()) - home = sign_in.get_home_view() + home = sign_in.create_user() home.join_public_chat(chat_name) chat_1, chat_2 = device_1.get_chat_view(), device_2.get_chat_view() message_1, message_2, message_3, message_4, message_5 = 'm1', 'm2', 'm3', 'm4', 'm5' diff --git a/test/appium/tests/test_message_reliability.py b/test/appium/tests/test_message_reliability.py index b2216348f5..9b5fe6a504 100644 --- a/test/appium/tests/test_message_reliability.py +++ b/test/appium/tests/test_message_reliability.py @@ -36,13 +36,11 @@ class TestMessageReliability(MessageReliabilityTestCase): try: self.create_drivers(2, max_duration=10800, custom_implicitly_wait=2) device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) - device_1.create_user(username='user_a') - device_2.create_user(username='user_b') - device_1_home, device_2_home = device_1.get_home_view(), device_2.get_home_view() + device_1_home, device_2_home = device_1.create_user(username='user_a'), device_2.create_user( + username='user_b') device_2_public_key = device_2_home.get_public_key() device_2_home.home_button.click() - device_1_home.add_contact(device_2_public_key) - device_1_chat = device_1_home.get_chat_view() + device_1_chat = device_1_home.add_contact(device_2_public_key) device_1_chat.chat_message_input.send_keys('hello') device_1_chat.send_message_button.click() device_2_home.element_by_text('hello').click() @@ -86,8 +84,7 @@ class TestMessageReliability(MessageReliabilityTestCase): def test_message_reliability_1_1_chat_with_predefined_user(self, messages_number, user_public_key): self.create_drivers(1, max_duration=10800, custom_implicitly_wait=2) sign_in_view = SignInView(self.drivers[0]) - sign_in_view.create_user(username='user_a') - home_view = sign_in_view.get_home_view() + home_view = sign_in_view.create_user(username='user_a') home_view.add_contact(user_public_key) chat_view = home_view.get_chat_view() for i in range(messages_number): @@ -100,13 +97,12 @@ class TestMessageReliability(MessageReliabilityTestCase): self.public_chat_data['message_time'] = dict() self.create_drivers(participants_number, max_duration=10800, custom_implicitly_wait=2) - users = list() + users = ['user_%s' % i for i in range(participants_number)] chat_views = list() chat_name = chat_name if chat_name else ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) for i in range(participants_number): device = SignInView(self.drivers[i]) - users.append(device.create_user()) - home_view = device.get_home_view() + home_view = device.create_user(username=users[i]) home_view.join_public_chat(chat_name) chat_views.append(home_view.get_chat_view()) @@ -138,8 +134,7 @@ class TestMessageReliability(MessageReliabilityTestCase): self.create_drivers(1, max_duration=10800, custom_implicitly_wait=2, offline_mode=True) driver = self.drivers[0] sign_in_view = SignInView(driver) - sign_in_view.create_user() - home_view = sign_in_view.get_home_view() + home_view = sign_in_view.create_user() chat_name = chat_name if chat_name else ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) home_view.join_public_chat(chat_name) @@ -261,7 +256,8 @@ class TestMessageReliability(MessageReliabilityTestCase): device_2.open_notifications() try: WebDriverWait(device_2, message_wait_time) \ - .until(expected_conditions.presence_of_element_located((MobileBy.XPATH, '//*[contains(@text, "Status")]'))) + .until( + expected_conditions.presence_of_element_located((MobileBy.XPATH, '//*[contains(@text, "Status")]'))) element = BaseButton(device_2) element.locator = element.Locator.xpath_selector("//*[contains(@text,'Status')]") element.click() diff --git a/test/appium/tests/test_messaging.py b/test/appium/tests/test_messaging.py index 41451180b0..7e490291fe 100644 --- a/test/appium/tests/test_messaging.py +++ b/test/appium/tests/test_messaging.py @@ -146,13 +146,10 @@ class TestMessages(MultipleDeviceTestCase): def test_public_chat(self): self.create_drivers(2) device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1]) - users = [] + users = ['user_1', 'user_2'] chat_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(7)) - for sign_in in device_1, device_2: - users.append(sign_in.create_user()) - home = sign_in.get_home_view() - home.join_public_chat(chat_name) - chat_1, chat_2 = device_1.get_chat_view(), device_2.get_chat_view() + home_1, home_2 = device_1.create_user(username=users[0]), device_2.create_user(username=users[1]) + chat_1, chat_2 = home_1.join_public_chat(chat_name), home_2.join_public_chat(chat_name) chat_1.chat_message_input.send_keys('/command') chat_1.send_message_button.click() @@ -189,8 +186,8 @@ class TestMessages(MultipleDeviceTestCase): 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() + username_1, username_2 = 'user_1', 'user_2' + home_1, home_2 = device_1.create_user(username=username_1), device_2.create_user(username=username_2) device_2_public_key = home_2.get_public_key() profile_2 = home_2.get_profile_view() file_name = 'sauce_logo.png' @@ -259,7 +256,7 @@ class TestMessages(MultipleDeviceTestCase): chat.send_message_button.click() # verify correct text is sent - chat.chat_element_by_text(message_text[:-2] + ' ') + chat.chat_element_by_text(message_text[:-2] + ' ').wait_for_visibility_of_element(2) @marks.all @@ -305,9 +302,8 @@ class TestOfflineMessages(MultipleDeviceTestCase): self.create_drivers(2, offline_mode=True) 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() + username_1, username_2 = 'user_1', 'user_2' + home_1, home_2 = sign_in_1.create_user(), sign_in_2.create_user() device_2_public_key = home_2.get_public_key() home_1.add_contact(device_2_public_key) diff --git a/test/appium/tests/test_profile.py b/test/appium/tests/test_profile.py index ccb7261dfb..0115150188 100644 --- a/test/appium/tests/test_profile.py +++ b/test/appium/tests/test_profile.py @@ -118,12 +118,9 @@ class TestProfileView(SingleDeviceTestCase): profile_view.advanced_button.click() profile_view.debug_mode_toggle.click() home_view = profile_view.home_button.click() - chat_view = home_view.get_chat_with_user('Status Console').click() - chat_view.commands_button.click() - chat_view.faucet_command.click() - chat_view.faucet_send_command.click() - chat_view.send_message_button.click() - chat_view.back_button.click() + console_view = home_view.get_chat_with_user('Status Console').click() + console_view.send_faucet_request() + console_view.back_button.click() wallet_view = profile_view.wallet_button.click() wallet_view.set_up_wallet() wallet_view.wait_balance_changed_on_wallet_screen() diff --git a/test/appium/views/base_element.py b/test/appium/views/base_element.py index 78ab72baa9..9248e2d3d4 100644 --- a/test/appium/views/base_element.py +++ b/test/appium/views/base_element.py @@ -68,6 +68,10 @@ class BaseElement(object): info('Looking for %s' % self.name) return self.driver.find_elements(self.locator.by, self.locator.value) + def click(self): + self.find_element().click() + info('Tap on %s' % self.name) + def wait_for_element(self, seconds=10): try: return WebDriverWait(self.driver, seconds) \ @@ -158,11 +162,13 @@ class BaseElement(object): def measure_time_before_element_appears(self, max_wait_time=30): def wrapper(): return self.wait_for_visibility_of_element(max_wait_time) + return timeit(wrapper, number=1) def measure_time_while_element_is_shown(self, max_wait_time=30): def wrapper(): return self.wait_for_invisibility_of_element(max_wait_time) + return timeit(wrapper, number=1) @@ -183,10 +189,6 @@ class BaseEditBox(BaseElement): self.find_element().clear() info('Clear text in %s' % self.name) - def click(self): - self.find_element().click() - 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() @@ -201,7 +203,7 @@ class BaseEditBox(BaseElement): 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() + action.press(x=x + 100, y=y - 50).release().perform() def cut_text(self): info('Cut text in %s' % self.name) @@ -210,7 +212,7 @@ class BaseEditBox(BaseElement): 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() + action.press(x=x + 50, y=y - 50).release().perform() class BaseText(BaseElement): diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index f2a786c5f8..92e1dc9880 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -206,6 +206,10 @@ class BaseView(object): info("Tap 'Confirm' on native keyboard") self.driver.press_keycode(66) + def click_system_back_button(self): + info('Click system back button') + self.driver.press_keycode(4) + def send_as_keyevent(self, string): keys = {'0': 7, '1': 8, '2': 9, '3': 10, '4': 11, '5': 12, '6': 13, '7': 14, '8': 15, '9': 16, diff --git a/test/appium/views/chat_view.py b/test/appium/views/chat_view.py index e53983c287..e6aea802a2 100644 --- a/test/appium/views/chat_view.py +++ b/test/appium/views/chat_view.py @@ -51,19 +51,6 @@ class EthAsset(BaseButton): self.locator = self.Locator.text_selector('ETH') -class FaucetCommand(BaseButton): - def __init__(self, driver): - super(FaucetCommand, self).__init__(driver) - self.locator = self.Locator.xpath_selector( - "//*[contains(@text,'Get some ETH')]/preceding-sibling::*[@text='/faucet']") - - -class FaucetSendCommand(BaseButton): - def __init__(self, driver): - super(FaucetSendCommand, self).__init__(driver) - self.locator = self.Locator.xpath_selector("//*[@text='Status Testnet Faucet']") - - class ChatMenuButton(BaseButton): def __init__(self, driver): super(ChatMenuButton, self).__init__(driver) @@ -136,13 +123,6 @@ class FirstRecipient(BaseButton): self.locator = self.Locator.accessibility_id('contact-item') -class UsernameByMessage(BaseText): - def __init__(self, driver, message): - super(UsernameByMessage, self).__init__(driver) - self.locator = self.Locator.xpath_selector( - "//*[@content-desc='chat-item']//*[contains(@text, '%s')]/../../android.widget.TextView" % message) - - class MoreUsersButton(BaseButton): def __init__(self, driver): super(MoreUsersButton, self).__init__(driver) @@ -190,12 +170,6 @@ class ProfileSendTransactionButton(BaseButton): self.locator = self.Locator.accessibility_id('send-transaction-button') -class SendRequestButton(BaseButton): - def __init__(self, driver, amount): - super(SendRequestButton, self).__init__(driver) - self.locator = self.Locator.xpath_selector('//*[contains(@text, "%s.ETH")]/../*[@text="Send"]' % amount) - - class ChatElementByText(BaseText): def __init__(self, driver, text): super(ChatElementByText, self).__init__(driver) @@ -222,10 +196,28 @@ class ChatElementByText(BaseText): def contains_text(self, text) -> bool: element = BaseText(self.driver) - element.locator = element.Locator.xpath_selector("//android.view.ViewGroup//android.widget.TextView[@text='%s']" - % text) + element.locator = element.Locator.xpath_selector( + self.locator.value + "//android.view.ViewGroup//android.widget.TextView[@text='%s']" % text) return element.is_element_displayed() + @property + def username(self): + class Username(BaseText): + def __init__(self, driver, parent_locator): + super(Username, self).__init__(driver) + self.locator = self.Locator.xpath_selector(parent_locator + "/*[1][name()='android.widget.TextView']") + + return Username(self.driver, self.locator.value) + + @property + def send_request_button(self): + class SendRequestButton(BaseButton): + def __init__(self, driver, parent_locator): + super(SendRequestButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector(parent_locator + '//*[@text="Send"]') + + return SendRequestButton(self.driver, self.locator.value) + class ChatView(BaseView): def __init__(self, driver): @@ -240,8 +232,6 @@ class ChatView(BaseView): self.send_command = SendCommand(self.driver) self.request_command = RequestCommand(self.driver) self.eth_asset = EthAsset(self.driver) - self.faucet_command = FaucetCommand(self.driver) - self.faucet_send_command = FaucetSendCommand(self.driver) self.chat_options = ChatMenuButton(self.driver) self.members_button = MembersButton(self.driver) @@ -298,18 +288,9 @@ class ChatView(BaseView): errors.append('Not received messages from user %s: "%s"' % (username, ', '.join( [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, amount, sender_password, wallet_set_up=False): gas_popup = self.element_by_text_part('Specify amount') - send_request_button = SendRequestButton(self.driver, amount) + send_request_button = self.chat_element_by_text(amount).send_request_button send_request_button.click_until_presence_of_element(gas_popup) send_transaction = self.get_send_transaction_view() if wallet_set_up: diff --git a/test/appium/views/console_view.py b/test/appium/views/console_view.py index 4147c5f7d3..a62d0e0d55 100644 --- a/test/appium/views/console_view.py +++ b/test/appium/views/console_view.py @@ -1,67 +1,28 @@ -from tests import info -from selenium.common.exceptions import NoSuchElementException, TimeoutException -from views.base_element import BaseButton, BaseEditBox -from views.base_view import BaseView +from views.base_element import BaseButton +from views.chat_view import ChatView -class RequestPasswordIcon(BaseButton): - +class FaucetCommand(BaseButton): def __init__(self, driver): - super(RequestPasswordIcon, self).__init__(driver) - self.locator = self.Locator.accessibility_id('request-password') - - def click(self): - self.wait_for_element(10) - self.find_element().click() - info('Tap on %s' % self.name) - return self.navigate() + super(FaucetCommand, self).__init__(driver) + self.locator = self.Locator.xpath_selector( + "//*[contains(@text,'Get some ETH')]/preceding-sibling::*[@text='/faucet']") -class RecoverButton(BaseButton): - +class FaucetSendCommand(BaseButton): def __init__(self, driver): - super(RecoverButton, self).__init__(driver) - self.locator = self.Locator.xpath_selector("//*[@text='Recover']") - - def navigate(self): - from views.recover_access_view import RecoverAccessView - return RecoverAccessView(self.driver) + super(FaucetSendCommand, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Status Testnet Faucet']") -class ChatRequestInput(BaseEditBox): - - def __init__(self, driver): - super(ChatRequestInput, self).__init__(driver) - self.locator = \ - self.Locator.xpath_selector("//android.widget.EditText[@content-desc!='chat-message-input']") - - -class ConsoleView(BaseView): - +class ConsoleView(ChatView): def __init__(self, driver): super(ConsoleView, self).__init__(driver) + self.faucet_command = FaucetCommand(self.driver) + self.faucet_send_command = FaucetSendCommand(self.driver) - self.request_password_icon = RequestPasswordIcon(self.driver) - self.recover_button = RecoverButton(self.driver) - self.chat_request_input = ChatRequestInput(self.driver) - - def create_user(self): - self.request_password_icon.click() - self.chat_request_input.send_keys("qwerty1234") + def send_faucet_request(self): + self.commands_button.click() + self.faucet_command.click() + self.faucet_send_command.click() self.send_message_button.click() - self.chat_request_input.send_keys("qwerty1234") - self.send_message_button.click() - self.find_full_text( - "Here is your signing phrase. You will use it to verify your transactions. Write it down and keep it safe!") - - def recover_access(self, passphrase, password, username): - recover_access_view = self.recover_button.click() - recover_access_view.passphrase_input.send_keys(passphrase) - recover_access_view.password_input.send_keys(password) - recover_access_view.confirm_recover_access.click() - recovered_user = recover_access_view.element_by_text(username, 'button') - recover_access_view.confirm() - recovered_user.click() - recover_access_view.password_input.send_keys(password) - recover_access_view.sign_in_button.click() - recover_access_view.find_full_text('Wallet', 60) diff --git a/test/appium/views/home_view.py b/test/appium/views/home_view.py index 409f485ec4..24b268249e 100644 --- a/test/appium/views/home_view.py +++ b/test/appium/views/home_view.py @@ -31,11 +31,16 @@ class ConsoleButton(BaseButton): class ChatElement(BaseButton): def __init__(self, driver, username_part): super(ChatElement, self).__init__(driver) - self.locator = self.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % username_part) + self.username = username_part + self.locator = self.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % self.username) def navigate(self): - from views.chat_view import ChatView - return ChatView(self.driver) + if self.username == 'Status Console': + from views.console_view import ConsoleView + return ConsoleView(self.driver) + else: + from views.chat_view import ChatView + return ChatView(self.driver) def click(self): from views.chat_view import ChatMessageInput diff --git a/test/appium/views/send_transaction_view.py b/test/appium/views/send_transaction_view.py index 87b537b656..932dc1b30d 100644 --- a/test/appium/views/send_transaction_view.py +++ b/test/appium/views/send_transaction_view.py @@ -110,6 +110,36 @@ class ErrorDialog(BaseView): return element.wait_for_element(wait_time) +class AdvancedButton(BaseButton): + def __init__(self, driver): + super(AdvancedButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id('advanced-button') + + +class TransactionFeeButton(BaseButton): + def __init__(self, driver): + super(TransactionFeeButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id('transaction-fee-button') + + +class GasLimitInput(BaseEditBox): + def __init__(self, driver): + super(GasLimitInput, self).__init__(driver) + self.locator = self.Locator.accessibility_id('gas-limit-input') + + +class GasPriceInput(BaseEditBox): + def __init__(self, driver): + super(GasPriceInput, self).__init__(driver) + self.locator = self.Locator.accessibility_id('gas-price-input') + + +class TotalFeeInput(BaseEditBox): + def __init__(self, driver): + super(TotalFeeInput, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@content-desc='total-fee-input']/android.widget.TextView") + + class SendTransactionView(BaseView): def __init__(self, driver): super(SendTransactionView, self).__init__(driver) @@ -119,8 +149,14 @@ class SendTransactionView(BaseView): self.enter_recipient_address_input = EnterRecipientAddressInput(self.driver) self.first_recipient_button = FirstRecipient(self.driver) self.recent_recipients_button = RecentRecipientsButton(self.driver) - self.amount_edit_box = AmountEditBox(self.driver) + + self.advanced_button = AdvancedButton(self.driver) + self.transaction_fee_button = TransactionFeeButton(self.driver) + self.gas_limit_input = GasLimitInput(self.driver) + self.gas_price_input = GasPriceInput(self.driver) + self.total_fee_input = TotalFeeInput(self.driver) + self.cancel_button = CancelButton(self.driver) self.sign_transaction_button = SignTransactionButton(self.driver) self.confirm_button = ConfirmButton(self.driver) diff --git a/test/appium/views/sign_in_view.py b/test/appium/views/sign_in_view.py index 72994230b3..7a8b87a5b1 100644 --- a/test/appium/views/sign_in_view.py +++ b/test/appium/views/sign_in_view.py @@ -112,7 +112,7 @@ class SignInView(BaseView): self.next_button.click() self.do_not_share.wait_for_visibility_of_element(10) self.do_not_share.click_until_presence_of_element(self.home_button) - return username + return self.get_home_view() def recover_access(self, passphrase, password): recover_access_view = self.i_have_account_button.click() @@ -123,6 +123,7 @@ class SignInView(BaseView): recover_access_view.sign_in_button.click() self.do_not_share.wait_for_element(10) self.do_not_share.click_until_presence_of_element(self.home_button) + return self.get_home_view() def open_status_test_dapp(self): profile_view = self.profile_button.click() diff --git a/test/appium/views/wallet_view.py b/test/appium/views/wallet_view.py index 5dc8d55371..6b5f94e94b 100644 --- a/test/appium/views/wallet_view.py +++ b/test/appium/views/wallet_view.py @@ -167,12 +167,12 @@ class WalletView(BaseView): else: info('Current USD balance %s is ok' % usd) - def wait_balance_changed_on_wallet_screen(self, initial_balance=0, wait_time=300): + def wait_balance_changed_on_wallet_screen(self, expected_balance=0.1, wait_time=300): counter = 0 while True: if counter >= wait_time: pytest.fail('Balance is not changed during %s seconds!' % wait_time) - elif self.get_eth_value() == initial_balance: + elif self.get_eth_value() != expected_balance: counter += 10 time.sleep(10) self.swipe_down()