e2e: global refactoring

Signed-off-by: Churikova Tetiana <churikova.tm@gmail.com>
This commit is contained in:
Churikova Tetiana 2021-01-25 17:35:40 +01:00
parent 6c4097f521
commit c2f8f012a8
No known key found for this signature in database
GPG Key ID: 0D4EA7B33B47E6D8
28 changed files with 1161 additions and 3679 deletions

View File

@ -73,6 +73,7 @@ class NetworkApi(object):
pytest.fail('Transaction is not found in Ropsten network')
def find_transaction_by_unique_amount(self, address, amount, token=False, decimals=18, wait_time=600):
additional_info = 'token transactions' if token else 'ETH transactions'
counter = 0
while True:
if counter >= wait_time:
@ -80,29 +81,22 @@ class NetworkApi(object):
self.log('Transaction #%s, amount is %s' %(entry+1, float(int(transactions[entry]['value']) / 10 ** decimals)))
self.log(str(transactions[entry]))
pytest.fail(
'Transaction with amount %s is not found in list of transactions, address is %s' %
(amount, address))
'Transaction with amount %s is not found in list of %s, address is %s during %ss' %
(amount, additional_info, address, wait_time))
else:
counter += 10
time.sleep(10)
try:
if token:
transactions = self.get_token_transactions(address)
additional_info = 'token transactions'
else:
transactions = self.get_transactions(address)
additional_info = 'ETH transactions'
except JSONDecodeError as e:
self.log(str(e))
continue
self.log('Looking for a transaction with unique amount %s in list of %s, address is %s' %
(amount, additional_info, address))
try:
for transaction in transactions:
if float(int(transaction['value']) / 10 ** decimals) == float(amount):
self.log(
'Transaction with unique amount %s is found in list of transactions, address is %s' %
(amount, address))
return transaction
except TypeError as e:
self.log("Failed iterate transactions: " + str(e))
@ -110,7 +104,11 @@ class NetworkApi(object):
def wait_for_confirmation_of_transaction(self, address, amount, confirmations=12, token=False):
start_time = time.time()
self.log('Waiting for transaction to have %s confirmations' % confirmations)
if token:
token_info = "token transaction"
else:
token_info = "ETH transaction"
self.log('Waiting %s %s for %s to have %s confirmations' % (amount, token_info, address, confirmations))
while round(time.time() - start_time, ndigits=2) < 900: # should be < idleTimeout capability
transaction = self.find_transaction_by_unique_amount(address, amount, token)
self.log(

View File

@ -10,8 +10,7 @@ RERUN_ERRORS = [
'504 Gateway Time-out',
'Internal Server Error',
'failed to start the browser or device',
'ERROR The test with session id'
"Message: 'CreateMultiaccountButton' is not found on screen",
'ERROR The test with session id',
"503 Service Unavailable",
"object has no attribute",
"[Errno 104] Connection reset by peer",

View File

@ -1,6 +1,6 @@
import random
from tests import marks, common_password, unique_password
from tests import marks, common_password
from tests.base_test_case import SingleDeviceTestCase
from views.sign_in_view import SignInView
from tests.users import basic_user
@ -11,8 +11,7 @@ class TestCreateAccount(SingleDeviceTestCase):
@marks.testrail_id(5356)
@marks.critical
def test_switch_users_and_add_new_account(self):
sign_in = SignInView(self.driver)
sign_in.create_user()
sign_in = SignInView(self.driver).create_user()
public_key = sign_in.get_public_key_and_username()
profile = sign_in.get_profile_view()
profile.logout()
@ -48,35 +47,30 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.create_password_input.set_value(common_password)
sign_in.confirm_your_password_input.set_value(common_password)
sign_in.next_button.click()
for element in sign_in.maybe_later_button, sign_in.lets_go_button:
element.wait_for_element(10)
element.click()
home_view = sign_in.get_home_view()
texts = ['Chat and transact privately with friends',
'Jump into a public chat and meet new people',
'#status']
[element.wait_and_click(10) for element in (sign_in.maybe_later_button, sign_in.lets_go_button)]
home = sign_in.get_home_view()
texts = ["chat-and-transact", "follow-your-interests"]
for text in texts:
if not home_view.element_by_text(text).is_element_displayed():
self.errors.append("'%s' text is not shown" % text)
if not home.element_by_translation_id(text).is_element_displayed():
self.errors.append("'%s' text is not shown" % self.get_translation_by_key(text))
for chat in ('#status', '#crypto'):
sign_in.element_by_text(chat).click()
sign_in.back_button.click_until_presence_of_element(home_view.search_input)
profile_view = home_view.profile_button.click()
shown_username = profile_view.default_username_text.text
sign_in.back_button.click_until_presence_of_element(home.search_input)
profile = home.profile_button.click()
shown_username = profile.default_username_text.text
if shown_username != username:
self.errors.append("Default username '%s' doesn't match '%s'" % (shown_username, username))
profile_view.home_button.click_until_presence_of_element(home_view.element_by_text('#status'))
home_view.cross_icon_iside_welcome_screen_button.click()
profile.home_button.click_until_presence_of_element(home.element_by_text('#status'))
home.cross_icon_inside_welcome_screen_button.click()
for chat in ('#status', '#crypto'):
home_view.delete_chat_long_press(chat)
if home_view.element_by_text(texts[0]).is_element_displayed():
home.delete_chat_long_press(chat)
if home.element_by_text(texts[0]).is_element_displayed():
self.errors.append("'%s' text is shown, but welcome view was closed" % texts[0])
home_view.relogin()
if home_view.element_by_text(texts[0]).is_element_displayed():
home.relogin()
if home.element_by_text(texts[0]).is_element_displayed():
self.errors.append("'%s' text is shown after relogin, but welcome view was closed" % texts[0])
text_after_closing_welcome_screen = "Your chats will appear here. To start new chats press the ⊕ button"
if not home_view.element_by_text(text_after_closing_welcome_screen).is_element_displayed():
self.errors.append("'%s' text is not shown after welcome view was closed" % text_after_closing_welcome_screen)
if not home.element_by_translation_id("welcome-blank-message").is_element_displayed():
self.errors.append("'%s' text is not shown after welcome view was closed" % home.get_translation_by_key("welcome-blank-message"))
self.errors.verify_no_errors()
@ -88,7 +82,6 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.generate_key_button.click()
sign_in.next_button.click()
sign_in.next_button.click()
mismatch_error = "Passwords don't match"
cases = ['password is not confirmed', 'password is too short', "passwords don't match"]
error = "Can create multiaccount when"
@ -110,8 +103,8 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.just_fyi("Checking case %s" % cases[2])
sign_in.create_password_input.send_keys('1234565')
sign_in.confirm_your_password_input.send_keys('1234567')
if not sign_in.find_text_part(mismatch_error):
self.errors.append("'%s' is not shown" % mismatch_error)
if not sign_in.element_by_translation_id("password_error1").is_element_displayed():
self.errors.append("'%s' is not shown" % sign_in.get_translation_by_key("password_error1"))
sign_in.next_button.click()
if sign_in.maybe_later_button.is_element_displayed(10):
self.driver.fail('%s %s' % (error, cases[2]))

View File

@ -85,7 +85,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.connect_card_button.click()
keycard_flow.enter_another_pin()
keycard_flow.cancel_button.click()
if not keycard_flow.element_by_text_part('Dangerous operation').is_element_displayed():
if not keycard_flow.element_by_translation_id("keycard-cancel-setup-title").is_element_displayed():
self.driver.fail('No Dangerous operation popup is shown on canceling operation from PIN code stage')
keycard_flow.yes_button.click()
@ -96,7 +96,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.wait_for_element_starts_with_text('Write codes down')
pair_code = keycard_flow.pair_code_text.text
keycard_flow.cancel_button.click()
if not keycard_flow.element_by_text_part('Dangerous operation').is_element_displayed():
if not keycard_flow.element_by_translation_id("keycard-cancel-setup-title").is_element_displayed():
self.driver.fail('No Dangerous operation popup is shown on canceling operation from Pair code stage')
keycard_flow.yes_button.click()
@ -108,7 +108,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.confirm_button.click()
keycard_flow.yes_button.click()
keycard_flow.cancel_button.click()
if not keycard_flow.element_by_text_part('Dangerous operation').is_element_displayed():
if not keycard_flow.element_by_translation_id("keycard-cancel-setup-title").is_element_displayed():
self.driver.fail('No Dangerous operation popup is shown on canceling operation during Backup seed phrase stage')
keycard_flow.yes_button.click()
if not keycard_flow.element_by_text_part('Back up seed phrase').is_element_displayed():
@ -118,7 +118,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.cancel_button.click()
keycard_flow.yes_button.click()
keycard_flow.begin_setup_button.click()
keycard_flow.wait_for_element_starts_with_text('Back up seed phrase')
keycard_flow.element_by_translation_id("back-up-seed-phrase").wait_for_element(10)
new_seed_phrase = keycard_flow.get_seed_phrase()
if new_seed_phrase != seed_phrase:
self.errors.append('Another seed phrase is shown after cancelling setup during Back up seed phrase')
@ -146,12 +146,12 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in = SignInView(self.driver)
sign_in.get_started_button.click()
recover_access = sign_in.access_key_button.click()
recover_access.enter_seed_phrase_button.click()
recover_access.seedphrase_input.click()
recover_access.seedphrase_input.set_value(basic_user['passphrase'])
recover_access.next_button.click()
recover_access.reencrypt_your_key_button.click()
sign_in.access_key_button.click()
sign_in.enter_seed_phrase_button.click()
sign_in.seedphrase_input.click()
sign_in.seedphrase_input.set_value(basic_user['passphrase'])
sign_in.next_button.click()
sign_in.reencrypt_your_key_button.click()
keycard_flow = sign_in.keycard_storage_button.click()
sign_in.just_fyi('Cancel on PIN code setup stage')
@ -160,7 +160,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.connect_card_button.click()
keycard_flow.enter_another_pin()
keycard_flow.cancel_button.click()
if not keycard_flow.element_by_text_part('Dangerous operation').is_element_displayed():
if not keycard_flow.element_by_translation_id("keycard-cancel-setup-title").is_element_displayed():
self.driver.fail('No Dangerous operation popup is shown on canceling operation from PIN code stage')
keycard_flow.yes_button.click()
@ -171,7 +171,7 @@ class TestCreateAccount(SingleDeviceTestCase):
keycard_flow.wait_for_element_starts_with_text('Write codes down')
pair_code = keycard_flow.pair_code_text.text
keycard_flow.cancel_button.click()
if not keycard_flow.element_by_text_part('Dangerous operation').is_element_displayed():
if not keycard_flow.element_by_translation_id("keycard-cancel-setup-title").is_element_displayed():
self.driver.fail('No Dangerous operation popup is shown on canceling operation from Pair code stage')
keycard_flow.yes_button.click()
@ -229,12 +229,12 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.just_fyi('Check that username and public key match expected for recovered multiaccount')
public_key, default_username = sign_in.get_public_key_and_username(return_username=True)
profile_view = sign_in.get_profile_view()
profile = sign_in.get_profile_view()
if public_key != recovered_user['public_key']:
self.errors.append('Public key %s does not match expected' % public_key)
if default_username != recovered_user['username']:
self.errors.append('Default username %s does not match expected' % default_username)
profile_view.logout()
profile.logout()
sign_in.just_fyi('Check that can login with recovered keycard account')
sign_in.sign_in(keycard=True)

View File

@ -72,8 +72,6 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
self.errors.append('No redirected to carousel view after deleting last multiaccount')
self.errors.verify_no_errors()
@marks.testrail_id(5741)
@marks.high
def test_mobile_data_usage_popup_continue_syncing(self):
@ -81,14 +79,14 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
sign_in_view.create_user()
sign_in_view.just_fyi("Enable mobile network to see popup and enable syncing")
sign_in_view.toggle_mobile_data()
if not sign_in_view.element_by_text_part("Sync using mobile data?").is_element_displayed():
if not sign_in_view.element_by_translation_id("mobile-syncing-sheet-title").is_element_displayed():
self.driver.fail('No popup about Mobile data is shown')
sign_in_view.wait_for_element_starts_with_text('Continue syncing').click()
sign_in_view.just_fyi("Check that selected option is stored in Profile")
profile_view = sign_in_view.profile_button.click()
profile_view.sync_settings_button.click()
profile_view.element_by_text('Mobile data').click()
profile_view.element_by_translation_id("mobile-network-settings").click()
if not profile_view.use_mobile_data.attribute_value('checked'):
self.errors.append("Use mobile data option is enabled after 'Continue syncing' selected")
if profile_view.ask_me_when_on_mobile_network.attribute_value('checked'):
@ -109,36 +107,35 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
@marks.testrail_id(6228)
@marks.high
def test_mobile_data_usage_popup_stop_syncing(self):
sign_in_view = SignInView(self.driver)
sign_in_view.create_user()
offline_banner_text = "No Wi-fi, message syncing disabled."
sign_in = SignInView(self.driver)
sign_in.create_user()
offline_banner_text = sign_in.get_translation_by_key("mobile-network-sheet-offline")
sign_in_view.just_fyi("Enable mobile network to see popup and stop syncing")
sign_in_view.toggle_mobile_data()
sign_in_view.wait_for_element_starts_with_text('Stop syncing').click()
if not sign_in_view.wait_for_element_starts_with_text(offline_banner_text, 120):
sign_in.just_fyi("Enable mobile network to see popup and stop syncing")
sign_in.toggle_mobile_data()
sign_in.wait_for_element_starts_with_text('Stop syncing').click()
if not sign_in.wait_for_element_starts_with_text(offline_banner_text, 120):
self.driver.fail('No popup about offline history is shown')
sign_in_view.element_by_text_part(offline_banner_text).click()
for item in offline_banner_text, "Start syncing", "Go to settings":
if not sign_in_view.element_by_text(item).is_element_displayed():
self.driver.fail("%s is not shown" % item)
sign_in.element_by_text_part(offline_banner_text).click()
for id in "mobile-network-sheet-offline", "mobile-network-start-syncing", "mobile-network-go-to-settings":
if not sign_in.element_by_translation_id(id).is_element_displayed():
self.driver.fail("%s is not shown" % sign_in.get_translation_by_key(id))
sign_in_view.just_fyi("Start syncing in offline popup")
sign_in_view.element_by_text("Start syncing").click()
sign_in_view.element_by_text_part(offline_banner_text).wait_for_invisibility_of_element(10)
if sign_in_view.element_by_text_part(offline_banner_text).is_element_displayed():
sign_in.just_fyi("Start syncing in offline popup")
sign_in.element_by_translation_id("mobile-network-start-syncing").click()
sign_in.element_by_text_part(offline_banner_text).wait_for_invisibility_of_element(10)
if sign_in.element_by_text_part(offline_banner_text).is_element_displayed():
self.driver.fail("Popup about offline history is shown")
@marks.testrail_id(6229)
@marks.high
def test_mobile_data_usage_settings(self):
sign_in_view = SignInView(self.driver)
sign_in_view.create_user()
sign_in_view = SignInView(self.driver).create_user()
profile_view = sign_in_view.profile_button.click()
sign_in_view.just_fyi("Check default preferences")
profile_view.sync_settings_button.click()
profile_view.element_by_text('Mobile data').click()
profile_view.element_by_translation_id("mobile-network-settings").click()
if profile_view.use_mobile_data.text != 'OFF':
self.errors.append("Mobile data is enabled by default")
@ -148,7 +145,7 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
sign_in_view.just_fyi("Disable 'ask me when on mobile network' and check that it is not shown")
profile_view.ask_me_when_on_mobile_network.click()
sign_in_view.toggle_mobile_data()
if sign_in_view.element_by_text("Start syncing").is_element_displayed(20):
if sign_in_view.element_by_translation_id("mobile-network-start-syncing").is_element_displayed(20):
self.errors.append("Popup is shown, but 'ask me when on mobile network' is disabled")
sign_in_view.just_fyi("Check 'Restore default' setting")
@ -245,8 +242,6 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
@marks.critical
def test_can_add_existing_ens(self):
home = SignInView(self.driver).recover_access(ens_user['passphrase'])
home.just_fyi('switching to Mainnet')
profile = home.profile_button.click()
profile.switch_network('Mainnet with upstream RPC')
home.profile_button.click()
@ -254,11 +249,11 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
dapp_view.just_fyi('check if your name can be added via "ENS usernames" in Profile')
dapp_view.element_by_text('Get started').click()
dapp_view.ens_name.set_value(ens_user['ens'])
dapp_view.ens_name_input.set_value(ens_user['ens'])
dapp_view.check_ens_name.click()
if not dapp_view.find_element_by_translation_id('ens-saved-title').is_element_displayed():
if not dapp_view.element_by_translation_id('ens-saved-title').is_element_displayed():
self.errors.append('No message "Username added" after resolving own username')
dapp_view.find_element_by_translation_id("ens-got-it").click()
dapp_view.element_by_translation_id("ens-got-it").click()
dapp_view.just_fyi('check that after adding username is shown in "ENS usernames" and profile')
if not dapp_view.element_by_text(ens_user['ens']).is_element_displayed():
@ -313,12 +308,12 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
self.driver.fail('Back up seed phrase option is available after seed phrase backed up!')
profile_view.back_button.click()
profile_view.logout()
recover_view = sign_in_view.access_key_button.click()
recover_view.enter_seed_phrase_button.click()
recover_view.seedphrase_input.click()
recover_view.seedphrase_input.set_value(' '.join(recovery_phrase.values()))
recover_view.next_button.click()
recover_view.element_by_text('UNLOCK').click()
sign_in_view.access_key_button.click()
sign_in_view.enter_seed_phrase_button.click()
sign_in_view.seedphrase_input.click()
sign_in_view.seedphrase_input.set_value(' '.join(recovery_phrase.values()))
sign_in_view.next_button.click()
sign_in_view.element_by_text('UNLOCK').click()
sign_in_view.password_input.set_value(common_password)
chats_view = sign_in_view.sign_in_button.click()
chats_view.plus_button.click()
@ -409,18 +404,16 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
profile.plus_button.click()
sign_in_view.just_fyi('Checking %s case' % key)
if 'scanning' in key:
from views.contacts_view import ContactsView
contact_view = ContactsView(self.driver)
contact_view.scan_contact_code_button.click()
if contact_view.allow_button.is_element_displayed():
contact_view.allow_button.click()
contact_view.enter_qr_edit_box.scan_qr(users[key]['contact_code'])
chat_view.scan_contact_code_button.click()
if chat_view.allow_button.is_element_displayed():
chat_view.allow_button.click()
chat_view.enter_qr_edit_box.scan_qr(users[key]['contact_code'])
else:
contact_view.public_key_edit_box.click()
contact_view.public_key_edit_box.send_keys(users[key]['contact_code'])
chat_view.public_key_edit_box.click()
chat_view.public_key_edit_box.send_keys(users[key]['contact_code'])
if 'nickname' in users[key]:
chat_view.nickname_input_field.set_value(users[key]['nickname'])
contact_view.confirm_until_presence_of_element(profile.contacts_button)
chat_view.confirm_until_presence_of_element(profile.contacts_button)
if not profile.element_by_text(users[key]['username']).is_element_displayed():
self.errors.append('In %s case username not found in contact view after scanning' % key)
if 'nickname' in users[key]:
@ -600,8 +593,8 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
base_web_view.click_system_back_button()
home_view = signin_view.create_user()
profile = home_view.profile_button.click()
about_view = profile.about_button.click()
about_view.privacy_policy_button.click()
profile.about_button.click()
profile.privacy_policy_button.click()
if not base_web_view.policy_summary.is_element_displayed():
self.errors.append('{} Profile about view!'.format(no_link_open_error_msg))
@ -677,12 +670,12 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
profile.mail_server_auto_selection_button.click()
profile.mail_server_by_name(h_node).click()
profile.confirm_button.click()
if profile.find_element_by_translation_id("mailserver-error-title").is_element_displayed(10):
if profile.element_by_translation_id("mailserver-error-title").is_element_displayed(10):
h_node = node_hk
profile.find_element_by_translation_id("mailserver-pick-another", uppercase=True).click()
profile.element_by_translation_id("mailserver-pick-another", uppercase=True).click()
profile.mail_server_by_name(h_node).click()
profile.confirm_button.click()
if profile.find_element_by_translation_id("mailserver-error-title").is_element_displayed(10):
if profile.element_by_translation_id("mailserver-error-title").is_element_displayed(10):
self.driver.fail("Couldn't connect to any history node")
profile.just_fyi('check that history node is pinned')
@ -713,7 +706,7 @@ class TestProfileSingleDevice(SingleDeviceTestCase):
dapp_view = profile_view.connect_existing_status_ens(ens_stateofus)
profile_view.element_by_text("Add username").click()
profile_view.element_by_text_part("another domain").click()
dapp_view.ens_name.set_value(ens_not_stateofus)
dapp_view.ens_name_input.set_value(ens_not_stateofus)
dapp_view.check_ens_name.click_until_presence_of_element(dapp_view.element_by_text('Ok, got it'))
dapp_view.element_by_text('Ok, got it').click()
@ -789,7 +782,7 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
@marks.testrail_id(5436)
@marks.medium
@marks.flaky
#@marks.flaky
def test_add_switch_delete_custom_mailserver(self):
self.create_drivers(2)
sign_in_1, sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
@ -888,7 +881,7 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
profile_1.confirm_button.click()
profile_1.just_fyi('check that popup "Error connecting" will not reappear if tap on "Cancel"')
profile_1.find_element_by_translation_id('mailserver-error-title').wait_for_element(30)
profile_1.element_by_translation_id('mailserver-error-title').wait_for_element(30)
profile_1.cancel_button.click()
profile_1.home_button.click()
@ -909,10 +902,10 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
profile_1.just_fyi('check that can RETRY to connect')
for _ in range(2):
public_chat_1.find_element_by_translation_id('mailserver-retry', 'button', uppercase=True).wait_and_click()
public_chat_1.element_by_translation_id('mailserver-retry', 'button', uppercase=True).wait_and_click()
profile_1.just_fyi('check that can pick another mailserver and receive messages')
public_chat_1.find_element_by_translation_id('mailserver-pick-another', 'button', uppercase=True).wait_and_click()
public_chat_1.element_by_translation_id('mailserver-pick-another', 'button', uppercase=True).wait_and_click()
mailserver = profile_1.return_mailserver_name(mailserver_ams, used_fleet)
profile_1.element_by_text(mailserver).click()
profile_1.confirm_button.click()
@ -1156,7 +1149,7 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
home_1.profile_button.click()
dapp_view_1 = profile_1.ens_usernames_button.click()
dapp_view_1.element_by_text('Get started').click()
dapp_view_1.ens_name.set_value(ens_user['ens'])
dapp_view_1.ens_name_input.set_value(ens_user['ens'])
expected_text = 'This user name is owned by you and connected with your chat key.'
if not dapp_view_1.element_by_text_part(expected_text).is_element_displayed():
dapp_view_1.click_system_back_button()

View File

@ -5,7 +5,6 @@ from tests import marks, unique_password
from tests.base_test_case import SingleDeviceTestCase
from tests.users import basic_user, transaction_senders, recovery_users, ens_user
from views.sign_in_view import SignInView
from views.recover_access_view import RecoverAccessView
class TestRecoverAccountSingleDevice(SingleDeviceTestCase):
@ -49,12 +48,10 @@ class TestRecoverAccountSingleDevice(SingleDeviceTestCase):
signin_view = SignInView(self.driver)
signin_view.get_started_button.click_until_presence_of_element(signin_view.access_key_button)
signin_view.access_key_button.click()
recover_access_view = RecoverAccessView(self.driver)
validations = [
{
'case': 'empty value',
'phrase': ' ',
'element to check': recover_access_view.warnings.invalid_recovery_phrase,
'validation message': 'Required field',
'words count': 1,
'popup': False
@ -62,7 +59,6 @@ class TestRecoverAccountSingleDevice(SingleDeviceTestCase):
{
'case': '1 word seed',
'phrase': 'a',
'element to check': recover_access_view.warnings.invalid_recovery_phrase,
'validation message': '',
'words count': 1,
'popup' : False
@ -70,60 +66,58 @@ class TestRecoverAccountSingleDevice(SingleDeviceTestCase):
{
'case': 'mnemonic but checksum validation fails',
'phrase': 'one two three four five six seven eight nine ten eleven twelve',
'element to check': recover_access_view.warnings.invalid_recovery_phrase,
'validation message': '',
'words count': 12,
'popup': True
},
]
recover_access_view.just_fyi("check that seed phrase is required (can't be empty)")
recover_access_view.enter_seed_phrase_button.click()
recover_access_view.next_button.click()
if recover_access_view.reencrypt_your_key_button.is_element_displayed():
signin_view.just_fyi("check that seed phrase is required (can't be empty)")
signin_view.enter_seed_phrase_button.click()
signin_view.next_button.click()
if signin_view.reencrypt_your_key_button.is_element_displayed():
self.errors.append("Possible to create account with empty seed phrase")
signin_view = SignInView(self.driver, skip_popups=False)
for validation in validations:
recover_access_view.just_fyi("Checking %s" % validation.get('case'))
phrase, elm, msg, words_count, popup = validation.get('phrase'), \
validation.get('element to check'), \
signin_view.just_fyi("Checking %s" % validation.get('case'))
phrase, msg, words_count, popup = validation.get('phrase'), \
validation.get('validation message'), \
validation.get('words count'),\
validation.get('popup')
if signin_view.access_key_button.is_element_displayed():
signin_view.access_key_button.click()
if recover_access_view.enter_seed_phrase_button.is_element_displayed():
recover_access_view.enter_seed_phrase_button.click()
if signin_view.enter_seed_phrase_button.is_element_displayed():
signin_view.enter_seed_phrase_button.click()
recover_access_view.send_as_keyevent(phrase)
signin_view.seedphrase_input.set_value(phrase)
if msg:
if not recover_access_view.element_by_text(msg).is_element_displayed():
if not signin_view.element_by_text(msg).is_element_displayed():
self.errors.append('"{}" message is not shown'.format(msg))
recover_access_view.just_fyi('check that words count is shown')
if words_count == 1:
signin_view.just_fyi('check that words count is shown')
if words_count:
if not signin_view.element_by_text('%s word' % words_count):
self.errors.append('"%s word" is not shown ' % words_count)
else:
if not signin_view.element_by_text('%s words' % words_count):
self.errors.append('"%s words" is not shown ' % words_count)
recover_access_view.just_fyi('check that "Next" is disabled unless we use allowed count of words')
signin_view.just_fyi('check that "Next" is disabled unless we use allowed count of words')
if words_count != 12 or 15 or 18 or 21 or 24:
recover_access_view.next_button.click()
if recover_access_view.reencrypt_your_key_button.is_element_displayed():
signin_view.next_button.click()
if signin_view.reencrypt_your_key_button.is_element_displayed():
self.errors.append("Possible to create account with wrong count (%s) of words" % words_count)
recover_access_view.just_fyi('check behavior for popup "Custom seed phrase"')
signin_view.just_fyi('check behavior for popup "Custom seed phrase"')
if popup:
text = 'Invalid seed phrase'
if not recover_access_view.find_full_text(text):
if not signin_view.find_full_text(text):
self.errors.append('"%s" text is not shown' % text)
recover_access_view.cancel_custom_seed_phrase_button.click()
signin_view.cancel_custom_seed_phrase_button.click()
recover_access_view.click_system_back_button()
signin_view.click_system_back_button()
self.errors.verify_no_errors()

View File

@ -124,7 +124,7 @@ class TestWalletManagement(SingleDeviceTestCase):
if not wallet.backup_recovery_phrase_warning_text.is_element_present(30):
self.driver.fail("'Back up your seed phrase' warning is not shown on Wallet with funds")
profile = wallet.get_profile_view()
wallet.backup_recovery_phrase_warning_text.click_until_presence_of_element(profile.ok_continue_button)
wallet.backup_recovery_phrase_warning_text.click()
profile.backup_recovery_phrase()
@marks.testrail_id(5440)

View File

@ -997,9 +997,9 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
home_2.just_fyi('Set ENS name so its visible in chats')
dapp_view = profile_2.ens_usernames_button.click()
dapp_view.element_by_text('Get started').click()
dapp_view.ens_name.set_value(ens_user_message_sender['ens'])
dapp_view.check_ens_name.click_until_presence_of_element(dapp_view.find_element_by_translation_id("ens-got-it"))
dapp_view.find_element_by_translation_id("ens-got-it").click()
dapp_view.ens_name_input.set_value(ens_user_message_sender['ens'])
dapp_view.check_ens_name.click_until_presence_of_element(dapp_view.element_by_translation_id("ens-got-it"))
dapp_view.element_by_translation_id("ens-got-it").click()
device_1.just_fyi('Both devices joining the same public chat and send messages')
chat_name = device_1.get_random_chat_name()

View File

@ -199,10 +199,6 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
self.network_api.wait_for_confirmation_of_transaction(sender['address'], amount, confirmations=15, token=True)
chat_2.toggle_airplane_mode()
chat_2.connection_status.wait_for_invisibility_of_element(30)
try:
self.network_api.find_transaction_by_unique_amount(recipient_address[2:], amount, token=True)
except Failed as e:
self.errors.append(e.msg)
[message.transaction_status.wait_for_element_text('Confirmed') for message in
(chat_2_sender_message, chat_1_request_message)]
self.errors.verify_no_errors()

View File

@ -76,7 +76,7 @@ class TestBrowsing(SingleDeviceTestCase):
for url in ('metamask.site', 'https://www.cryptokitties.domainname'):
daap_view.just_fyi('Checking blocked website %s' % url)
dapp_detail = daap_view.open_url(url)
dapp_detail.find_element_by_translation_id('browsing-site-blocked-title')
dapp_detail.element_by_translation_id('browsing-site-blocked-title')
if dapp_detail.browser_refresh_page_button.is_element_displayed():
self.errors.append("Refresh button is present in blocked site")
dapp_detail.go_back_button.click()
@ -218,7 +218,7 @@ class TestBrowsing(SingleDeviceTestCase):
dapp_view.browser_entry_long_press(edited_name)
dapp_view.open_in_new_tab_button.click()
browsing_view.options_button.click()
if not browsing_view.find_element_by_translation_id('remove-favourite').is_element_displayed():
if not browsing_view.element_by_translation_id('remove-favourite').is_element_displayed():
self.errors.append("Remove favourite is not shown on added bookmark!")
self.errors.verify_no_errors()
@ -242,16 +242,20 @@ class TestBrowsing(SingleDeviceTestCase):
@marks.testrail_id(5354)
@marks.critical
def test_refresh_button_browsing_app_webview(self):
sign_in_view = SignInView(self.driver)
home_view = sign_in_view.create_user()
daap_view = home_view.dapp_tab_button.click()
browsing_view = daap_view.open_url('app.uniswap.org')
browsing_view.allow_button.click()
browsing_view.find_full_text('Select a token').click()
browsing_view.find_text_part("Token Name")
browsing_view.browser_refresh_page_button.click()
if browsing_view.element_by_text_part("Token Name").is_element_displayed():
self.driver.fail("Page failed to be refreshed")
home = SignInView(self.driver).create_user()
daap = home.dapp_tab_button.click()
url = 'app.uniswap.org'
element_on_start_page = daap.element_by_text('ETH')
web_page = daap.open_url(url)
daap.allow_button.click()
element_on_start_page.click()
# when bottom sheet is opened, elements by text couldn't be found
element_on_start_page.wait_for_invisibility_of_element(20)
web_page.browser_refresh_page_button.click()
if not element_on_start_page.is_element_displayed(30):
self.driver.fail("Page failed to be refreshed")
@marks.testrail_id(5456)

View File

@ -143,10 +143,13 @@ class Driver(webdriver.Remote):
return test_suite_data.current_test.testruns[-1].jobs[self.session_id]
def info(self, text: str):
if "Base" not in text:
text = 'Device %s: %s' % (self.number, text)
logging.info(text)
test_suite_data.current_test.testruns[-1].steps.append(text)
# if "Base" not in text:
# text = 'Device %s: %s' % (self.number, text)
# logging.info(text)
# test_suite_data.current_test.testruns[-1].steps.append(text)
text = 'Device %s: %s ' % (self.number, text)
logging.info(text)
test_suite_data.current_test.testruns[-1].steps.append(text)
def fail(self, text: str):
pytest.fail('Device %s: %s' % (self.number, text))

View File

@ -1,28 +0,0 @@
from views.base_element import BaseButton, BaseText
from views.base_view import BaseView
class PrivacyPolicyButton(BaseButton):
def __init__(self, driver):
super(PrivacyPolicyButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'//*[@content-desc="privacy-policy"]')
def navigate(self):
from views.web_views.base_web_view import BaseWebView
return BaseWebView(self.driver)
class VersionText(BaseText):
def __init__(self, driver):
super(VersionText, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'//*[@content-desc="version"]//android.widget.TextView')
class AboutView(BaseView):
def __init__(self, driver):
super(AboutView, self).__init__(driver)
self.privacy_policy_button = PrivacyPolicyButton(self.driver)
self.version = VersionText(self.driver)

View File

@ -1,39 +1,15 @@
from views.base_element import BaseEditBox
from views.base_element import EditBox
from views.base_view import BaseView
class ContractAddressInput(BaseEditBox):
def __init__(self, driver):
super(ContractAddressInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Contract address']/following-sibling::*[2]/android.widget.EditText")
class NameInput(BaseEditBox):
def __init__(self, driver):
super(NameInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Name']/following-sibling::*[1]/android.widget.EditText")
class SymbolInput(BaseEditBox):
def __init__(self, driver):
super(SymbolInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Symbol']/following-sibling::*[2]/android.widget.EditText")
class DecimalsInput(BaseEditBox):
def __init__(self, driver):
super(DecimalsInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Decimals']/following-sibling::*[2]/android.widget.EditText")
class AddCustomTokenView(BaseView):
def __init__(self, driver):
super(AddCustomTokenView, self).__init__(driver)
self.driver = driver
self.contract_address_input = ContractAddressInput(self.driver)
self.name_input = NameInput(self.driver)
self.symbol_input = SymbolInput(self.driver)
self.decimals_input = DecimalsInput(self.driver)
super().__init__(driver)
self.contract_address_input = EditBox(self.driver, translation_id="contract-address",
suffix="/following-sibling::*[2]/android.widget.EditText")
self.name_input = EditBox(self.driver, translation_id="name",
suffix="/following-sibling::*[1]/android.widget.EditText")
self.symbol_input = EditBox(self.driver, translation_id="symbol",
suffix="/following-sibling::*[2]/android.widget.EditText")
self.decimals_input = EditBox(self.driver, translation_id="decimals",
suffix="/following-sibling::*[2]/android.widget.EditText")

View File

@ -1,7 +1,6 @@
import base64
from io import BytesIO
import os
import time
from timeit import timeit
@ -16,50 +15,44 @@ from tests import transl
class BaseElement(object):
class Locator(object):
def __init__(self, by, value):
self.by = by
self.value = value
@classmethod
def xpath_selector(locator, value):
return locator(MobileBy.XPATH, value)
@classmethod
def accessibility_id(locator, value):
return locator(MobileBy.ACCESSIBILITY_ID, value)
@classmethod
def text_selector(locator, text):
return BaseElement.Locator.xpath_selector('//*[@text="' + text + '"]')
@classmethod
def text_part_selector(locator, text):
return BaseElement.Locator.xpath_selector('//*[contains(@text, "' + text + '")]')
@classmethod
def id(locator, value):
return locator(MobileBy.ID, value)
@classmethod
def webview_selector(cls, value):
xpath_expression = '//*[@text="{0}"] | //*[@content-desc="{desc}"]'.format(value, desc=value)
return cls(MobileBy.XPATH, xpath_expression)
@classmethod
def translation_id(cls, id, suffix='', uppercase = False):
text = transl[id]
if uppercase:
text = transl[id].upper()
return BaseElement.Locator.xpath_selector('//*[@text="' + text + '"]' + suffix)
def __str__(self, *args, **kwargs):
return "%s:%s" % (self.by, self.value)
def __init__(self, driver):
def __init__(self, driver, **kwargs):
self.driver = driver
self.by = MobileBy.XPATH
self.locator = None
self.xpath = None
self.accessibility_id = None
self.translation_id = None
self.uppercase = None
self.prefix=''
self.suffix = None
self.id = None
self.webview = None
self.__dict__.update(kwargs)
self.set_locator()
def set_locator(self):
if self.xpath:
self.locator = self.xpath
elif self.accessibility_id:
self.by = MobileBy.ACCESSIBILITY_ID
self.locator = self.accessibility_id
elif self.translation_id:
text = transl[self.translation_id]
self.locator = '//*[@text="%s"]' % text
if self.uppercase:
self.locator = '//*[@text="%s" or @text="%s"]' % (text, text.upper())
if self.suffix:
self.locator += self.suffix
elif self.id:
self.by = MobileBy.ID
self.locator = self.id
elif self.webview:
self.locator = '//*[@text="{0}"] | //*[@content-desc="{desc}"]'.format(self.webview, desc=self.webview)
if self.prefix:
self.locator = self.prefix + self.locator
return self
@property
def name(self):
@ -71,7 +64,8 @@ class BaseElement(object):
def find_element(self):
for _ in range(3):
try:
return self.driver.find_element(self.locator.by, self.locator.value)
self.driver.info('*Find %s by %s:* `%s`' % (self.name, self.by, self.locator))
return self.driver.find_element(self.by, self.locator)
except NoSuchElementException:
raise NoSuchElementException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
@ -80,16 +74,17 @@ class BaseElement(object):
continue
def find_elements(self):
return self.driver.find_elements(self.locator.by, self.locator.value)
return self.driver.find_elements(self.by, self.locator)
def click(self):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
self.driver.info('*Tap on found %s*' % self.name)
return self.navigate()
def wait_for_element(self, seconds=10):
try:
return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.presence_of_element_located((self.locator.by, self.locator.value)))
.until(expected_conditions.presence_of_element_located((self.by, self.locator)))
except TimeoutException:
raise TimeoutException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
@ -97,7 +92,7 @@ class BaseElement(object):
def wait_for_elements(self, seconds=10):
try:
return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.presence_of_all_elements_located((self.locator.by, self.locator.value)))
.until(expected_conditions.presence_of_all_elements_located((self.by, self.locator)))
except TimeoutException:
raise TimeoutException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
@ -105,7 +100,7 @@ class BaseElement(object):
def wait_for_visibility_of_element(self, seconds=10, ignored_exceptions=None):
try:
return WebDriverWait(self.driver, seconds, ignored_exceptions=ignored_exceptions) \
.until(expected_conditions.visibility_of_element_located((self.locator.by, self.locator.value)))
.until(expected_conditions.visibility_of_element_located((self.by, self.locator)))
except TimeoutException:
raise TimeoutException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
@ -113,17 +108,17 @@ class BaseElement(object):
def wait_for_invisibility_of_element(self, seconds=10):
try:
return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.invisibility_of_element_located((self.locator.by, self.locator.value)))
.until(expected_conditions.invisibility_of_element_located((self.by, self.locator)))
except TimeoutException:
raise TimeoutException("Device %s: '%s' is still visible on the screen after %s seconds" % (
self.driver.number, self.name, seconds)) from None
def scroll_to_element(self, depth: int = 9, direction='down'):
self.driver.info('*Scrolling %s to %s*' % (direction, self.name))
for _ in range(depth):
try:
return self.find_element()
except NoSuchElementException:
self.driver.info('Scrolling %s to %s' % (direction, self.name))
size = self.driver.get_window_size()
if direction == 'down':
self.driver.swipe(500, size["height"]*0.4, 500, size["height"]*0.05)
@ -139,14 +134,12 @@ class BaseElement(object):
def is_element_present(self, sec=5):
try:
self.driver.info('Wait for %s' % self.name)
return self.wait_for_element(sec)
except TimeoutException:
return False
def is_element_displayed(self, sec=5, ignored_exceptions=None):
try:
self.driver.info('Wait for %s' % self.name)
return self.wait_for_visibility_of_element(sec, ignored_exceptions=ignored_exceptions)
except TimeoutException:
return False
@ -206,7 +199,7 @@ class BaseElement(object):
def long_press_element(self):
element = self.find_element()
self.driver.info('Long press %s' % self.name)
self.driver.info('*Long press on %s*' % self.name)
action = TouchAction(self.driver)
action.long_press(element).release().perform()
@ -222,33 +215,37 @@ class BaseElement(object):
return timeit(wrapper, number=1)
@staticmethod
def get_translation_by_key(key):
return transl[key]
class BaseEditBox(BaseElement):
def __init__(self, driver):
super(BaseEditBox, self).__init__(driver)
class EditBox(BaseElement):
def __init__(self, driver, **kwargs):
super(EditBox, self).__init__(driver, **kwargs)
def send_keys(self, value):
self.find_element().send_keys(value)
self.driver.info("Type '%s' to %s" % (value, self.name))
self.driver.info("*Type '%s' to %s*" % (value, self.name))
def set_value(self, value):
self.find_element().set_value(value)
self.driver.info("Type '%s' to %s" % (value, self.name))
self.driver.info("*Type '%s' to %s*" % (value, self.name))
def clear(self):
self.find_element().clear()
self.driver.info('Clear text in %s' % self.name)
self.driver.info('*Clear text in %s*' % self.name)
def delete_last_symbols(self, number_of_symbols_to_delete: int):
self.driver.info('Delete last %s symbols from %s' % (number_of_symbols_to_delete, self.name))
self.driver.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):
self.driver.info('Paste text from clipboard into %s' % self.name)
self.driver.info('*Paste text from clipboard into %s*' % self.name)
self.long_press_element()
time.sleep(2)
action = TouchAction(self.driver)
@ -257,7 +254,7 @@ class BaseEditBox(BaseElement):
action.press(x=x + 25, y=y - 50).release().perform()
def cut_text(self):
self.driver.info('Cut text in %s' % self.name)
self.driver.info('-Cut text in %s' % self.name)
location = self.find_element().location
x, y = location['x'], location['y']
action = TouchAction(self.driver)
@ -266,19 +263,20 @@ class BaseEditBox(BaseElement):
action.press(x=x + 50, y=y - 50).release().perform()
class BaseText(BaseElement):
def __init__(self, driver):
super(BaseText, self).__init__(driver)
class Text(BaseElement):
def __init__(self, driver, **kwargs):
super(Text, self).__init__(driver, **kwargs)
self.set_locator()
@property
def text(self):
text = self.find_element().text
self.driver.info('%s is %s' % (self.name, text))
self.driver.info('*%s is %s*' % (self.name, text))
return text
def wait_for_element_text(self, text, wait_time=30):
counter = 0
self.driver.info("*Wait for text element %s to be equal to %s*" % (self.name, text))
while True:
if counter >= wait_time:
self.driver.fail(
@ -286,33 +284,26 @@ class BaseText(BaseElement):
elif self.find_element().text != text:
counter += 10
time.sleep(10)
self.driver.info('Wait for text element %s to be equal to %s' % (self.name, text))
else:
self.driver.info('Element %s text is equal to %s' % (self.name, text))
self.driver.info('*Element %s text is equal to %s*' % (self.name, text))
return
class BaseButton(BaseElement):
class Button(BaseElement):
def __init__(self, driver):
super(BaseButton, self).__init__(driver)
def click(self):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
def __init__(self, driver, **kwargs):
super(Button, self).__init__(driver, **kwargs)
def wait_and_click(self, time=30):
self.driver.info('Waiting for element %s for max %s sec and click when it is available' % (self.name, time))
self.driver.info('*Wait for element %s for max %ss and click when it is available*' % (self.name, time))
self.wait_for_visibility_of_element(time)
self.click()
def click_until_presence_of_element(self, desired_element, attempts=4):
counter = 0
self.driver.info('*Click until %s by %s:*`%s` *is presented*' % (self.name, self.by, self.locator))
while not desired_element.is_element_present(1) and counter <= attempts:
try:
self.driver.info('Tap on %s' % self.name)
self.find_element().click()
self.driver.info('Wait for %s to be displayed' % desired_element.name)
desired_element.wait_for_element(5)
return self.navigate()
except (NoSuchElementException, TimeoutException):
@ -322,11 +313,31 @@ class BaseButton(BaseElement):
def click_until_absense_of_element(self, desired_element, attempts=3):
counter = 0
self.driver.info('*Click until %s by %s:*`%s` *is NOT presented*' % (desired_element.name, desired_element.by, desired_element.locator))
while desired_element.is_element_present(1) and counter <= attempts:
try:
self.driver.info('Tap on %s' % self.name)
self.find_element().click()
self.driver.info('Wait for %s to disappear' % desired_element.name)
counter += 1
except (NoSuchElementException, TimeoutException):
return self.navigate()
class SilentButton(Button):
def find_element(self):
for _ in range(3):
try:
return self.driver.find_element(self.by, self.locator)
except NoSuchElementException:
raise NoSuchElementException(
"Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None
except Exception as exception:
if 'Internal Server Error' in str(exception):
continue
def click(self):
self.find_element().click()
return self.navigate()
@property
def text(self):
text = self.find_element().text
return text

View File

@ -8,326 +8,149 @@ import zbarlight
from PIL import Image
from appium.webdriver.common.touch_action import TouchAction
from datetime import datetime
from eth_keys import datatypes
from io import BytesIO
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException
from support.device_apps import start_web_browser
from tests import common_password, pytest_config_global, geth_log_emulator_path, transl
from views.base_element import BaseButton, BaseElement, BaseEditBox, BaseText
from views.base_element import Button, BaseElement, EditBox, Text
class BackButton(BaseButton):
class BackButton(Button):
def __init__(self, driver):
super(BackButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('back-button')
super().__init__(driver, accessibility_id="back-button")
def click(self, times_to_click: int = 1):
for _ in range(times_to_click):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
class AllowButton(BaseButton):
class AllowButton(Button):
def __init__(self, driver):
super(AllowButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Allow' or @text='ALLOW']")
super().__init__(driver, translation_id="allow", uppercase=True)
def click(self, times_to_click=3):
try:
for _ in range(times_to_click):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
except NoSuchElementException:
pass
class SearchEditBox(BaseEditBox):
def __init__(self, driver):
super(SearchEditBox, self).__init__(driver)
self.locator = self.Locator.text_selector("Search or type web address")
class DenyButton(BaseButton):
def __init__(self, driver):
super(DenyButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Deny' or @text='DENY']")
class CancelButton(BaseButton):
def __init__(self, driver):
super(CancelButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Cancel' or @text='CANCEL']")
class DeleteButton(BaseButton):
def __init__(self, driver):
super(DeleteButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='DELETE']")
class YesButton(BaseButton):
def __init__(self, driver):
super(YesButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='YES' or @text='GOT IT']")
class NoButton(BaseButton):
def __init__(self, driver):
super(NoButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='No']")
class OkButton(BaseButton):
def __init__(self, driver):
super(OkButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='OK'or @text='Ok']")
class ContinueButton(BaseButton):
def __init__(self, driver):
super(ContinueButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='CONTINUE' or @text='Continue']")
class TabButton(BaseButton):
class TabButton(Button):
@property
def counter(self):
class Counter(BaseText):
class Counter(Text):
def __init__(self, driver, parent_locator):
super(Counter, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='%s']//android.view.ViewGroup[2]/android.widget.TextView" % parent_locator)
return Counter(self.driver, self.locator.value)
super().__init__(driver,
xpath="//*[@content-desc='%s']//android.view.ViewGroup[2]/android.widget.TextView" % parent_locator)
return Counter(self.driver, self.locator)
@property
def public_unread_messages(self):
class PublicChatUnreadMessages(BaseElement):
def __init__(self, driver):
super(PublicChatUnreadMessages, self).__init__(driver)
self.locator = self.Locator.accessibility_id('public-unread-badge')
super().__init__(driver, accessibility_id="public-unread-badge")
return PublicChatUnreadMessages(self.driver)
class HomeButton(TabButton):
def __init__(self, driver):
super(HomeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('home-tab-button')
super().__init__(driver, accessibility_id="home-tab-button")
def navigate(self):
from views.home_view import HomeView
return HomeView(self.driver)
def click(self, desired_view='home'):
from views.home_view import PlusButton
from views.chat_view import ChatMessageInput, ProfileNicknameOtherUser
element = None
from views.home_view import HomeView
from views.chat_view import ChatView
if desired_view == 'home':
element = PlusButton(self.driver)
element = HomeView(self.driver).plus_button
elif desired_view == 'chat':
element = ChatMessageInput(self.driver)
element = ChatView(self.driver).chat_message_input
elif desired_view == 'other_user_profile':
element = ProfileNicknameOtherUser(self.driver)
element = ChatView(self.driver).profile_nickname
self.click_until_presence_of_element(element)
return self.navigate()
class ShareButton(BaseButton):
def __init__(self, driver):
super(ShareButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('share-my-contact-code-button')
class DappTabButton(TabButton):
def __init__(self, driver):
super(DappTabButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('dapp-tab-button')
super().__init__(driver, accessibility_id="dapp-tab-button")
def navigate(self):
from views.dapps_view import DappsView
return DappsView(self.driver)
def click(self, desired_element_text = 'enter_url'):
from views.dapps_view import EnterUrlEditbox
from views.dapps_view import DappsView
if desired_element_text == 'enter_url':
self.click_until_presence_of_element(EnterUrlEditbox(self.driver))
self.click_until_presence_of_element(DappsView(self.driver).enter_url_editbox)
else:
base_view = BaseView(self.driver)
self.click_until_presence_of_element(base_view.element_by_text_part(desired_element_text))
return self.navigate()
class WalletButton(TabButton):
def __init__(self, driver):
super(WalletButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('wallet-tab-button')
super().__init__(driver, accessibility_id="wallet-tab-button")
def navigate(self):
from views.wallet_view import WalletView
return WalletView(self.driver)
def click(self):
self.driver.info('Tap on %s' % self.name)
from views.wallet_view import MultiaccountMoreOptions
self.click_until_presence_of_element(MultiaccountMoreOptions(self.driver))
from views.wallet_view import WalletView
self.click_until_presence_of_element(WalletView(self.driver).multiaccount_more_options)
return self.navigate()
class ProfileButton(TabButton):
def __init__(self, driver):
super(ProfileButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('profile-tab-button')
super().__init__(driver, accessibility_id="profile-tab-button")
def navigate(self):
from views.profile_view import ProfileView
return ProfileView(self.driver)
def click(self, desired_element_text = 'privacy'):
from views.profile_view import PrivacyAndSecurityButton
from views.profile_view import ProfileView
if desired_element_text == 'privacy':
self.click_until_presence_of_element(PrivacyAndSecurityButton(self.driver))
self.click_until_presence_of_element(ProfileView(self.driver).privacy_and_security_button)
else:
base_view = BaseView(self.driver)
self.click_until_presence_of_element(base_view.element_by_text_part(desired_element_text))
return self.navigate()
class StatusButton(TabButton):
def __init__(self, driver):
super(StatusButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('status-tab-button')
super().__init__(driver, accessibility_id="status-tab-button")
def navigate(self):
from views.chat_view import ChatView
return ChatView(self.driver)
def click(self):
self.driver.info('Tap on %s' % self.name)
from views.chat_view import AddNewStatusButton
self.click_until_presence_of_element(AddNewStatusButton(self.driver))
return self.navigate()
class SaveButton(BaseButton):
class SendMessageButton(Button):
def __init__(self, driver):
super(SaveButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//android.widget.TextView[@text='Save']")
class NextButton(BaseButton):
def __init__(self, driver):
super(NextButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//android.widget.TextView[@text='Next']")
class AddButton(BaseButton):
def __init__(self, driver):
super(AddButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//android.widget.TextView[@text='Add']")
class DoneButton(BaseButton):
def __init__(self, driver):
super(DoneButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='done-button' or contains(@text, 'Done')]")
class AppsButton(BaseButton):
def __init__(self, driver):
super(AppsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("Apps")
class StatusAppIcon(BaseButton):
def __init__(self, driver):
super(StatusAppIcon, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Status']")
class SendMessageButton(BaseButton):
def __init__(self, driver):
super(SendMessageButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("send-message-button")
def click(self):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
class ConnectionStatusText(BaseText):
def __init__(self, driver):
super(ConnectionStatusText, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='connection-status-text']/android.widget.TextView")
class OkContinueButton(BaseButton):
def __init__(self, driver):
super(OkContinueButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='OK, CONTINUE']")
class DiscardButton(BaseButton):
def __init__(self, driver):
super(DiscardButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='DISCARD']")
class ConfirmButton(BaseButton):
def __init__(self, driver):
super(ConfirmButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='CONFIRM' or @text='Confirm']")
super().__init__(driver, accessibility_id="send-message-button")
class ProgressBar(BaseElement):
def __init__(self, driver, parent_locator: str = ''):
super(ProgressBar, self).__init__(driver)
self.locator = self.Locator.xpath_selector(parent_locator + '//android.widget.ProgressBar')
super().__init__(driver, xpath="%s//android.widget.ProgressBar" % parent_locator)
class CrossIcon(BaseButton):
def __init__(self, driver):
super(CrossIcon, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[1]')
class NativeCloseButton(BaseButton):
def __init__(self, driver):
super(NativeCloseButton, self).__init__(driver)
self.locator = self.Locator.id('android:id/aerr_close')
class CrossIconInWelcomeScreen(BaseButton):
def __init__(self, driver):
super(CrossIconInWelcomeScreen, self).__init__(driver)
self.locator = self.Locator.accessibility_id('hide-home-button')
class ShowRoots(BaseButton):
def __init__(self, driver):
super(ShowRoots, self).__init__(driver)
self.locator = self.Locator.accessibility_id('Show roots')
class GetStartedButton(BaseButton):
def __init__(self, driver):
super(GetStartedButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Get started']")
class AssetButton(BaseButton):
class AssetButton(Button):
def __init__(self, driver, asset_name):
super(AssetButton, self).__init__(driver)
super().__init__(driver, xpath="(//*[@content-desc=':%s-asset-value'])[1]" % asset_name)
self.asset_name = asset_name
self.locator = self.Locator.xpath_selector('(//*[@content-desc=":' + self.asset_name + '-asset-value"])[1]')
@property
def name(self):
@ -335,13 +158,10 @@ class AssetButton(BaseButton):
def click(self):
self.wait_for_element().click()
self.driver.info('Tap on %s' % self.name)
class OpenInStatusButton(BaseButton):
class OpenInStatusButton(Button):
def __init__(self, driver):
super(OpenInStatusButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@text="Open in Status"]')
super().__init__(driver, translation_id="browsing-open-in-status")
def click(self):
self.wait_for_visibility_of_element()
@ -350,104 +170,86 @@ class OpenInStatusButton(BaseButton):
self.swipe_to_web_element()
self.wait_for_element().click()
class StatusInBackgroundButton(BaseButton):
def __init__(self, driver):
super(StatusInBackgroundButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[contains(@content-desc,"Status")]')
class EnterQRcodeEditBox(BaseEditBox):
class EnterQRcodeEditBox(EditBox):
def __init__(self, driver):
super(EnterQRcodeEditBox, self).__init__(driver)
self.locator = self.Locator.text_selector('Message')
super().__init__(driver, translation_id="type-a-message")
def scan_qr(self, value):
self.set_value(value)
OkButton(self.driver).click()
class OkGotItButton(BaseButton):
def __init__(self, driver):
super(OkGotItButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Okay, got it']")
base_view = BaseView(self.driver)
base_view.ok_button.click()
def click(self):
self.wait_for_element().click()
self.wait_for_invisibility_of_element()
class AirplaneModeButton(BaseButton):
class AirplaneModeButton(Button):
def __init__(self, driver):
super(AirplaneModeButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='Airplane mode']")
super().__init__(driver, accessibility_id="Airplane mode")
def click(self):
self.driver.info('Turning on airplane mode')
action = TouchAction(self.driver)
action.press(None, 50, 0).move_to(None, 50, 300).perform()
super(AirplaneModeButton, self).click()
self.driver.press_keycode(4)
class SearchInput(BaseEditBox):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.accessibility_id('search-input')
class BaseView(object):
def __init__(self, driver):
self.driver = driver
self.send_message_button = SendMessageButton(self.driver)
# Tabs
self.home_button = HomeButton(self.driver)
self.wallet_button = WalletButton(self.driver)
self.profile_button = ProfileButton(self.driver)
self.dapp_tab_button = DappTabButton(self.driver)
self.status_button = StatusButton(self.driver)
self.yes_button = YesButton(self.driver)
self.no_button = NoButton(self.driver)
self.yes_button = Button(self.driver, xpath="//*[@text='YES' or @text='GOT IT']")
self.no_button = Button(self.driver, translation_id="no")
self.back_button = BackButton(self.driver)
self.allow_button = AllowButton(self.driver)
self.deny_button = DenyButton(self.driver)
self.continue_button = ContinueButton(self.driver)
self.ok_button = OkButton(self.driver)
self.next_button = NextButton(self.driver)
self.add_button = AddButton(self.driver)
self.save_button = SaveButton(self.driver)
self.done_button = DoneButton(self.driver)
self.delete_button = DeleteButton(self.driver)
self.ok_continue_button = OkContinueButton(self.driver)
self.discard_button = DiscardButton(self.driver)
self.confirm_button = ConfirmButton(self.driver)
self.connection_status = ConnectionStatusText(self.driver)
self.cross_icon = CrossIcon(self.driver)
self.native_close_button = NativeCloseButton(self.driver)
self.show_roots_button = ShowRoots(self.driver)
self.get_started_button = GetStartedButton(self.driver)
self.ok_got_it_button = OkGotItButton(self.driver)
self.deny_button = Button(self.driver, translation_id="deny", uppercase=True)
self.continue_button = Button(self.driver, translation_id="continue", uppercase=True)
self.ok_button = Button(self.driver, xpath="//*[@text='OK' or @text='Ok']")
self.next_button = Button(self.driver, translation_id="next")
self.add_button = Button(self.driver, translation_id="add")
self.save_button = Button(self.driver, translation_id="save")
self.done_button = Button(self.driver, translation_id="done") #self.locator = self.Locator.xpath_selector("//*[@content-desc='done-button' or contains(@text, 'Done')]")
self.delete_button = Button(self.driver, translation_id="delete", uppercase=True)
self.ok_continue_button = Button(self.driver, xpath="//*[@text='OK, CONTINUE' or @text='Okay, continue']")
self.discard_button = Button(self.driver, xpath="//*[@text='DISCARD']")
self.confirm_button = Button(self.driver, translation_id='confirm', uppercase=True)
self.connection_status = Text(self.driver,
xpath="//*[@content-desc='connection-status-text']/android.widget.TextView")
self.cross_icon = Button(self.driver, xpath="(//android.view.ViewGroup[@content-desc='icon'])[1]")
self.native_close_button = Button(self.driver, id="android:id/aerr_close")
self.show_roots_button = Button(self.driver, accessibility_id="Show roots")
self.get_started_button = Button(self.driver, translation_id="get-started")
self.ok_got_it_button = Button(self.driver, translation_id="ok-got-it")
self.progress_bar = ProgressBar(self.driver)
self.cross_icon_iside_welcome_screen_button = CrossIconInWelcomeScreen(self.driver)
self.status_in_background_button = StatusInBackgroundButton(self.driver)
self.cancel_button = CancelButton(self.driver)
self.search_input = SearchInput(self.driver)
self.share_button = ShareButton(self.driver)
self.cross_icon_inside_welcome_screen_button = Button(self.driver, accessibility_id='hide-home-button')
self.status_in_background_button = Button(self.driver, xpath="//*[contains(@content-desc,'Status')]")
self.cancel_button = Button(self.driver, translation_id="cancel", uppercase=True)
self.search_input = EditBox(self.driver, accessibility_id="search-input")
self.share_button = Button(self.driver, accessibility_id="share-my-contact-code-button")
# external browser
self.search_in_google_edit_box = SearchEditBox(self.driver)
self.open_in_status_button = OpenInStatusButton(self.driver)
self.apps_button = AppsButton(self.driver)
self.status_app_icon = StatusAppIcon(self.driver)
self.apps_button = Button(self.driver, accessibility_id="Apps")
self.status_app_icon = Button(self.driver, translation_id="status")
self.airplane_mode_button = AirplaneModeButton(self.driver)
self.enter_qr_edit_box = EnterQRcodeEditBox(self.driver)
self.element_types = {
'base': BaseElement,
'button': BaseButton,
'edit_box': BaseEditBox,
'text': BaseText
'button': Button,
'edit_box': EditBox,
'text': Text
}
@property
@ -468,7 +270,8 @@ class BaseView(object):
pass
iterations += 1
def get_translation_by_key(self, id):
@staticmethod
def get_translation_by_key(id):
return transl[id]
def rooted_device_continue(self):
@ -481,13 +284,8 @@ class BaseView(object):
def close_native_device_dialog(self, alert_text_part):
element = self.element_by_text_part(alert_text_part)
if element.is_element_present(1):
self.driver.info("Closing '%s' alert..." % alert_text_part)
self.dismiss_alert()
def dismiss_alert(self):
self.native_close_button.click()
self.driver.info("Alert closed")
self.driver.info("**Closing '%s' alert..." % alert_text_part)
self.native_close_button.click()
@property
def logcat(self):
@ -497,7 +295,7 @@ class BaseView(object):
raise TimeoutError('Logcat is empty')
def confirm(self):
self.driver.info("Tap 'Confirm' on native keyboard")
self.driver.info("*Tap 'Confirm' on native keyboard*")
self.driver.press_keycode(66)
def confirm_until_presence_of_element(self, desired_element, attempts=3):
@ -516,36 +314,38 @@ class BaseView(object):
self.driver.info(string)
def click_system_back_button(self, times=1):
self.driver.info('Click system back button')
self.driver.info('*Click system back button*')
for _ in range(times):
self.driver.press_keycode(4)
def put_app_to_background_and_back(self, time_in_background=1):
self.driver.info('*Put app to background and back*')
self.driver.press_keycode(187)
time.sleep(time_in_background)
self.status_in_background_button.click()
def click_system_home_button(self):
self.driver.info('Press system Home button')
self.driver.info('*Press system Home button*')
self.driver.press_keycode(3)
def put_app_to_background(self):
self.driver.info('App to background')
self.driver.info('*App to background*')
self.driver.press_keycode(187)
def cut_text(self):
self.driver.info('Cut text')
self.driver.info('*Cut text*')
self.driver.press_keycode(277)
def copy_text(self):
self.driver.info('Copy text')
self.driver.info('*Copy text*')
self.driver.press_keycode(278)
def paste_text(self):
self.driver.info('Paste text')
self.driver.info('*Paste text*')
self.driver.press_keycode(279)
def send_as_keyevent(self, string):
self.driver.info("*Sending as keyevent* `%s`" % string)
keys = {'0': 7, '1': 8, '2': 9, '3': 10, '4': 11, '5': 12, '6': 13, '7': 14, '8': 15, '9': 16,
',': 55, '-': 69, '+': 81, '.': 56, '/': 76, '\\': 73, ';': 74, ' ': 62,
@ -555,7 +355,6 @@ class BaseView(object):
'k': 39, 'l': 40, 'm': 41, 'n': 42, 'o': 43, 'p': 44, 'q': 45, 'r': 46, 's': 47, 't': 48,
'u': 49, 'v': 50, 'w': 51, 'x': 52, 'y': 53, 'z': 54}
time.sleep(3)
self.driver.info("Enter '%s' using native keyboard" % string)
for i in string:
if i.isalpha() and i.isupper():
keycode, metastate = keys[i.lower()], 64 # META_SHIFT_LEFT_ON Constant Value: 64. Example: i='n' -> 'N'
@ -566,72 +365,52 @@ class BaseView(object):
self.driver.press_keycode(keycode=keycode, metastate=metastate)
def find_full_text(self, text, wait_time=60):
self.driver.info("Looking for full text: '%s'" % text)
element = BaseElement(self.driver)
element.locator = element.Locator.text_selector(text)
element = BaseElement(self.driver, xpath="//*[@text='%s']" % text)
return element.wait_for_element(wait_time)
def find_text_part(self, text, wait_time=60):
self.driver.info("Looking for a text part: '%s'" % text)
element = BaseElement(self.driver)
element.locator = element.Locator.text_part_selector(text)
element = BaseElement(self.driver, xpath='//*[contains(@text, "' + text + '")]')
return element.wait_for_element(wait_time)
def element_by_text(self, text, element_type='button'):
self.driver.info("Looking for an element by text: '%s'" % text)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.text_selector(text)
element.locator = '//*[@text="%s"]' % text
return element
def element_by_text_part(self, text, element_type='button'):
self.driver.info("Looking for an element by text part: '%s'" % text)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.text_part_selector(text)
element.locator = '//*[contains(@text, "' + text + '")]'
return element
def element_starts_with_text(self, text, element_type='base'):
self.driver.info("Looking for full text: '%s'" % text)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
def element_starts_with_text(self, text, element_type='button'):
element = self.element_types[element_type](self.driver, xpath="//*[starts-with(@text,'%s')]" % text)
return element
def find_element_by_translation_id(self, id, element_type='base', uppercase=False):
self.driver.info("Looking element by id: '%s'" % id)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.translation_id(id, uppercase=uppercase)
def element_by_translation_id(self, id, element_type='button', uppercase=False):
element = self.element_types[element_type](self.driver, translation_id=id, uppercase=uppercase)
return element
def wait_for_element_starts_with_text(self, text, wait_time=60):
self.driver.info("Looking for element, start with text: '%s'" % text)
element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
element = Button(self.driver, xpath="//*[starts-with(@text,'%s')]" % text)
return element.wait_for_element(wait_time)
def element_by_accessibility_id(self, accessibility_id, element_type='button'):
self.driver.info("Looking for an element by accessibility id: '%s'" % accessibility_id)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.accessibility_id(accessibility_id)
return element
def element_by_xpath(self, xpath, element_type='button'):
self.driver.info("Looking for an element by xpath: '%s'" % xpath)
element = self.element_types[element_type](self.driver)
element.locator = element.Locator.xpath_selector(xpath)
return element
def swipe_up(self):
self.driver.info("*Swiping up*")
size = self.driver.get_window_size()
self.driver.swipe(size["width"]*0.5, size["height"]*0.8, size["width"]*0.5, size["height"]*0.2)
def swipe_down(self):
self.driver.info("*Swiping down*")
size = self.driver.get_window_size()
self.driver.swipe(size["width"]*0.5, size["height"]*0.2, size["width"]*0.5, size["height"]*0.8)
def swipe_left(self):
self.driver.info("*Swiping left*")
size = self.driver.get_window_size()
self.driver.swipe(size["width"]*0.8, size["height"]*0.8, size["width"]*0.2, size["height"]*0.8)
def swipe_right(self):
self.driver.info("*Swiping right*")
size = self.driver.get_window_size()
self.driver.swipe(size["width"]*0.2, size["height"]*0.8, size["width"]*0.8, size["height"]*0.8)
@ -683,10 +462,6 @@ class BaseView(object):
except IndexError:
raise BaseException('No data in QR code')
def public_key_to_address(self, public_key):
raw_public_key = bytearray.fromhex(public_key.replace('0x04', ''))
return datatypes.PublicKey(raw_public_key).to_address()[2:]
def get_back_to_home_view(self, times_to_click_on_back_btn=3):
counter = 0
while BackButton(self.driver).is_element_displayed(2):
@ -710,11 +485,13 @@ class BaseView(object):
sign_in_view.sign_in(password)
def close_share_popup(self):
self.driver.info("*Closing share popup*")
TouchAction(self.driver).tap(None, 255, 104, 1).perform()
time.sleep(3)
def get_public_key_and_username(self, return_username=False):
self.driver.info("**Get public key and username**")
profile_view = self.profile_button.click()
default_username = profile_view.default_username_text.text
profile_view.share_my_profile_button.click()
@ -725,6 +502,7 @@ class BaseView(object):
return user_data
def share_via_messenger(self):
self.driver.info("**Sharing via messenger**")
self.element_by_text_part("Direct share").wait_for_element()
self.element_by_text('Messages').click()
self.element_by_text('New message').click()
@ -732,10 +510,12 @@ class BaseView(object):
self.confirm()
def click_upon_push_notification_by_text(self, text):
self.driver.info("**Click on PN with text:** `%s`" % text)
self.element_by_text_part(text).click()
return self.get_chat_view()
def reconnect(self):
self.driver.info("**Reconnecting**")
connect_status = self.connection_status
for i in range(3):
if connect_status.is_element_displayed(5, ignored_exceptions=StaleElementReferenceException):
@ -755,6 +535,7 @@ class BaseView(object):
logcat = self.logcat
items_in_logcat = list()
for key, value in kwargs.items():
self.driver.info("**Checking in logcat for:** `%s`" % value)
if re.findall(r'\W%s$|\W%s\W' % (value, value), logcat):
items_in_logcat.append('%s in logcat!!!' % key.capitalize())
return items_in_logcat
@ -764,7 +545,7 @@ class BaseView(object):
file = base64.b64decode(b64_log)
result = False
for value in args:
self.driver.info('Checking for %s entry' % value)
self.driver.info('**Checking in geth for:** `%s`' % value)
if re.findall('%s*' % value, file.decode("utf-8")):
self.driver.info('%s was found in geth.log' % value)
result = True
@ -778,15 +559,17 @@ class BaseView(object):
self.driver.open_notifications()
def toggle_airplane_mode(self):
self.driver.info("**Toggling airplane mode**")
self.airplane_mode_button.click()
self.close_native_device_dialog("MmsService")
def toggle_mobile_data(self):
self.driver.info("**Toggling mobile data**")
self.driver.start_activity(app_package='com.android.settings', app_activity='.Settings')
network_and_internet = self.element_by_text('Network & internet')
network_and_internet.wait_for_visibility_of_element()
network_and_internet.click()
toggle = self.element_by_accessibility_id('WiFi')
toggle=Button(self.driver, accessibility_id='WiFi')
toggle.wait_for_visibility_of_element()
toggle.click()
self.driver.back()
@ -794,15 +577,15 @@ class BaseView(object):
def open_universal_web_link(self, deep_link):
start_web_browser(self.driver)
self.driver.info('Open %s web link via web browser' % deep_link)
self.driver.info('**Open web link via web browser:** `%s`' % deep_link)
self.driver.get(deep_link)
def upgrade_app(self):
self.driver.info("**Upgrading apk to apk_upgrade**")
self.driver.install_app(pytest_config_global['apk_upgrade'], replace=True)
self.driver.info('Upgrading apk to apk_upgrade')
def search_by_keyword(self, keyword):
self.driver.info('Search for %s' % keyword)
self.driver.info('**Search for** `%s`' % keyword)
self.search_input.click()
self.search_input.send_keys(keyword)

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
from views.base_element import BaseButton, BaseEditBox
from views.base_view import BaseView
from selenium.common.exceptions import NoSuchElementException
class PlusButton(BaseButton):
def __init__(self, driver):
super(PlusButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//android.widget.TextView[@text='+']")
class PublicKeyEditBox(BaseEditBox):
def __init__(self, driver):
super(PublicKeyEditBox, self).__init__(driver)
self.locator = self.Locator.accessibility_id('enter-contact-code-input')
def set_value(self, value):
for _ in range(2):
if self.text != value:
self.driver.info("Type '%s' to %s" % (value, self.name))
self.find_element().set_value(value)
class ScanContactCodeButton(BaseEditBox):
def __init__(self, driver):
super(ScanContactCodeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('scan-contact-code-button')
class ConfirmPublicKeyButton(BaseButton):
def __init__(self, driver):
super(ConfirmPublicKeyButton, self).__init__(driver)
self.locator = \
self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[3]')
class UsernameCheckbox(BaseButton):
def __init__(self, driver, username):
super(UsernameCheckbox, self).__init__(driver)
self.username = username
self.locator = self.Locator.xpath_selector("//*[@text='%s']" % username)
def click(self):
self.driver.info('Click %s username checkbox' % self.username)
try:
self.scroll_to_element(20).click()
except NoSuchElementException:
self.scroll_to_element(direction='up', depth=20).click()
class ChatNameEditBox(BaseEditBox):
def __init__(self, driver):
super(ChatNameEditBox, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-name-input')
class CreateButton(BaseButton):
def __init__(self, driver):
super(CreateButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('create-group-chat-button')
def navigate(self):
from views.chat_view import ChatView
return ChatView(self.driver)
class ContactsView(BaseView):
def __init__(self, driver):
super(ContactsView, self).__init__(driver)
self.driver = driver
self.plus_button = PlusButton(self.driver)
self.public_key_edit_box = PublicKeyEditBox(self.driver)
self.scan_contact_code_button = ScanContactCodeButton(self.driver)
self.confirm_public_key_button = ConfirmPublicKeyButton(self.driver)
self.chat_name_editbox = ChatNameEditBox(self.driver)
self.create_button = CreateButton(self.driver)
def get_username_checkbox(self, username: str):
return UsernameCheckbox(self.driver, username)

View File

@ -1,31 +1,23 @@
from views.base_element import BaseButton, BaseEditBox, BaseElement
from views.base_element import Button, EditBox, BaseElement
from views.base_view import BaseView
from views.home_view import ChatElement
class DiscoverDappsButton(BaseButton):
class DiscoverDappsButton(Button):
def __init__(self, driver):
super(DiscoverDappsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Discover ÐApps')
super().__init__(driver, translation_id="open-dapp-store")
def navigate(self):
from views.web_views.base_web_view import BaseWebView
return BaseWebView(self.driver)
def click(self):
from views.web_views.base_web_view import BrowserRefreshPageButton
self.click_until_presence_of_element(BrowserRefreshPageButton(self.driver))
from views.web_views.base_web_view import BaseWebView
self.click_until_presence_of_element(BaseWebView(self.driver).browser_refresh_page_button)
return self.navigate()
class EnterUrlEditbox(BaseEditBox):
class EditUrlEditbox(EditBox):
def __init__(self, driver):
super(EnterUrlEditbox, self).__init__(driver)
self.locator = self.Locator.accessibility_id('dapp-url-input')
class EditUrlEditbox(BaseEditBox):
def __init__(self, driver):
super(EditUrlEditbox, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.widget.TextView)[1]')
super().__init__(driver, xpath="(//android.widget.TextView)[1]")
@property
def text(self):
@ -34,102 +26,33 @@ class EditUrlEditbox(BaseEditBox):
class BrowserEntry(ChatElement):
def __init__(self, driver, name):
super(BrowserEntry, self).__init__(driver, name)
self.locator = self.locator.text_part_selector(name)
class EnsName(BaseEditBox):
def __init__(self, driver):
super(EnsName, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.EditText')
class EnsCheckName(BaseButton):
def __init__(self, driver):
super(EnsCheckName, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.EditText//following-sibling::android.view.ViewGroup[1]')
class DeleteBookmarkButton(BaseButton):
def __init__(self, driver):
super(DeleteBookmarkButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('delete-bookmark')
class EditBookmarkButton(BaseButton):
def __init__(self, driver):
super(EditBookmarkButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('edit-bookmark')
class OpenInNewTabButton(BaseButton):
def __init__(self, driver):
super(OpenInNewTabButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('open-in-new-tab')
class SelectAccountButton(BaseButton):
def __init__(self, driver):
super(SelectAccountButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('select-account')
class SelectAccountRadioButton(BaseButton):
def __init__(self, driver, account_name):
super(SelectAccountRadioButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='%s']/../../android.view.ViewGroup/android.view.ViewGroup[2]" % account_name)
class SetPrimaryUsername(BaseButton):
def __init__(self, driver):
super(SetPrimaryUsername, self).__init__(driver)
self.locator = self.Locator.accessibility_id('not-primary-username')
class AlwaysAllowRadioButton(BaseButton):
def __init__(self, driver):
super(AlwaysAllowRadioButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Always allow']/../android.view.ViewGroup")
class CrossCloseWeb3PermissionButton(BaseButton):
def __init__(self, driver):
super(CrossCloseWeb3PermissionButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'//*[contains(@text,"ÐApps can access")]/../android.view.ViewGroup[1]/android.view.ViewGroup')
class WebViewPageElement(BaseElement):
def __init__(self, driver):
super(WebViewPageElement, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.webkit.WebView)[1]')
super().__init__(driver, name)
self.locator = "//*[contains(@content-desc,'%s')]" % name
class DappsView(BaseView):
def __init__(self, driver):
super(DappsView, self).__init__(driver)
self.enter_url_editbox = EnterUrlEditbox(self.driver)
self.enter_url_editbox = EditBox(self.driver, accessibility_id="dapp-url-input")
self.edit_url_editbox = EditUrlEditbox(self.driver)
self.discover_dapps_button = DiscoverDappsButton(self.driver)
self.web_page = WebViewPageElement(self.driver)
self.web_page = BaseElement(self.driver, xpath="(//android.webkit.WebView)[1]")
#ens dapp
self.ens_name = EnsName(self.driver)
self.check_ens_name = EnsCheckName(self.driver)
# Ens dapp
self.ens_name_input = EditBox(self.driver, xpath="//android.widget.EditText")
self.check_ens_name = Button(self.driver, xpath="//android.widget.EditText//following-sibling::android.view.ViewGroup[1]")
#options on long press
self.delete_bookmark_button = DeleteBookmarkButton(self.driver)
self.open_in_new_tab_button = OpenInNewTabButton(self.driver)
self.edit_bookmark_button = EditBookmarkButton(self.driver)
# Options on long press
self.delete_bookmark_button = Button(self.driver, accessibility_id="delete-bookmark")
self.open_in_new_tab_button = Button(self.driver, accessibility_id="open-in-new-tab")
self.edit_bookmark_button = Button(self.driver, accessibility_id="edit-bookmark")
#select account
self.select_account_button = SelectAccountButton(self.driver)
self.select_account_radio_button = SelectAccountRadioButton(self.driver,
account_name=self.status_account_name)
#permissions window
self.always_allow_radio_button = AlwaysAllowRadioButton(self.driver)
self.close_web3_permissions_window_button = CrossCloseWeb3PermissionButton(self.driver)
# Select account
self.select_account_button = Button(self.driver, accessibility_id="select-account")
def open_url(self, url):
self.driver.info("**Open url '%s'**" % url)
self.enter_url_editbox.wait_for_visibility_of_element(10)
self.enter_url_editbox.click()
self.enter_url_editbox.send_keys(url)
@ -141,6 +64,7 @@ class DappsView(BaseView):
return BrowserEntry(self.driver, name)
def browser_entry_long_press(self, name):
self.driver.info("**Long press on '%s' browser entry**" % name)
entry = self.get_browser_entry(name)
entry.scroll_to_element()
entry.long_press_element()
@ -148,8 +72,10 @@ class DappsView(BaseView):
def select_account_by_name(self, account_name=''):
account_name = self.status_account_name if not account_name else account_name
return SelectAccountRadioButton(self.driver, account_name)
self.driver.info("**Select account by '%s'**" % account_name)
return Button(self.driver,
xpath="//*[@text='%s']/../../android.view.ViewGroup/android.view.ViewGroup[2]" % account_name)
def set_primary_ens_username(self, ens_name):
self.driver.info("Set {} as primary ENS name".format(ens_name))
return SetPrimaryUsername(self.driver)
self.driver.info("**Set {} as primary ENS name**".format(ens_name))
return Button(self.driver, accessibility_id="not-primary-username")

View File

@ -1,114 +1,34 @@
import time
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from views.base_element import BaseButton, BaseText, BaseElement, BaseEditBox
from views.base_element import Button, Text, BaseElement, SilentButton
from views.base_view import BaseView
from tests import test_dapp_url
class WelcomeImageElement(BaseElement):
def __init__(self, driver):
super(WelcomeImageElement, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.ImageView')
class PlusButton(BaseButton):
def __init__(self, driver):
super(PlusButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("new-chat-button")
class DeleteChatButton(BaseButton):
def __init__(self, driver):
super(DeleteChatButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("delete-chat-button")
class UniversalQrCodeScannerButton(BaseButton):
def __init__(self, driver):
super(UniversalQrCodeScannerButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("universal-qr-scanner")
class ClearHistoryButton(BaseButton):
def __init__(self, driver):
super(ClearHistoryButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("clear-history-button")
class StartNewChatButton(BaseButton):
def __init__(self, driver):
super(StartNewChatButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('start-1-1-chat-button')
class ChatButton(Button):
def __init__(self, driver, **kwargs):
super().__init__(driver, **kwargs)
def navigate(self):
from views.contacts_view import ContactsView
return ContactsView(self.driver)
from views.chat_view import ChatView
return ChatView(self.driver)
class NewGroupChatButton(BaseButton):
def __init__(self, driver):
super(NewGroupChatButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('start-group-chat-button')
def navigate(self):
from views.contacts_view import ContactsView
return ContactsView(self.driver)
class JoinPublicChatButton(BaseButton):
def __init__(self, driver):
super(JoinPublicChatButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('join-public-chat-button')
def navigate(self):
from views.contacts_view import ContactsView
return ContactsView(self.driver)
class InviteFriendsButton(BaseButton):
def __init__(self, driver):
super(InviteFriendsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('invite-friends-button')
class ChatsMenuInviteFriendsButton(BaseButton):
def __init__(self, driver):
super(ChatsMenuInviteFriendsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chats-menu-invite-friends-button')
class StopStatusServiceButton(BaseButton):
def __init__(self, driver):
super(StopStatusServiceButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('STOP')
class UserNameBelowNewChatButton(BaseButton):
class ChatElement(SilentButton):
def __init__(self, driver, username_part):
super(UserNameBelowNewChatButton, self).__init__(driver)
self.username = username_part
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='enter-contact-code-input']/../..//*[starts-with(@text,'%s')]" % self.username)
class ChatElement(BaseButton):
def __init__(self, driver, username_part):
super(ChatElement, self).__init__(driver)
self.username = username_part
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='chat-name-text'][starts-with(@text,'%s')]/.." % self.username)
super().__init__(driver, xpath="//*[@content-desc='chat-name-text'][starts-with(@text,'%s')]/.." % username_part)
def navigate(self):
from views.chat_view import ChatView
return ChatView(self.driver)
def click(self):
from views.chat_view import ChatMessageInput
desired_element = ChatMessageInput(self.driver)
from views.chat_view import ChatView
desired_element = ChatView(self.driver).chat_message_input
self.click_until_presence_of_element(desired_element=desired_element)
return self.navigate()
def find_element(self):
self.driver.info('Looking for %s' % self.name)
for i in range(2):
try:
return super(ChatElement, self).find_element()
@ -119,78 +39,44 @@ class ChatElement(BaseButton):
e.msg = 'Device %s: Unable to find chat with user %s' % (self.driver.number, self.username)
raise e
@property
def swipe_delete_button(self):
class DeleteButton(BaseButton):
def __init__(self, driver, parent_locator: str):
super(DeleteButton, self).__init__(driver)
locator_str = "/../..//*[@content-desc='icon']"
self.locator = self.Locator.xpath_selector(parent_locator + locator_str)
return DeleteButton(self.driver, self.locator.value)
@property
def new_messages_counter(self):
class UnreadMessagesCountText(BaseText):
class UnreadMessagesCountText(Text):
def __init__(self, driver, parent_locator: str):
super(UnreadMessagesCountText, self).__init__(driver)
# TODO: commented until accessibility-id will be added back
# locator_str = "//*[@content-desc='unread-messages-count-text']"
# self.locator = self.Locator.xpath_selector(parent_locator + locator_str)
locator_str = "//android.widget.TextView)[last()]"
self.locator = self.Locator.xpath_selector("(" + parent_locator + locator_str)
super().__init__(driver, xpath="(%s//android.widget.TextView)[last()]" % parent_locator)
return UnreadMessagesCountText(self.driver, self.locator.value)
return UnreadMessagesCountText(self.driver, self.locator)
@property
def new_messages_public_chat(self):
class UnreadMessagesPublicChat(BaseElement):
def __init__(self, driver):
super(UnreadMessagesPublicChat, self).__init__(driver)
self.locator = self.Locator.accessibility_id('unviewed-messages-public')
super().__init__(driver, accessibility_id="unviewed-messages-public")
return UnreadMessagesPublicChat(self.driver)
class MarkAllMessagesAsReadButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.accessibility_id('mark-all-read-button')
class ChatNameText(BaseText):
def __init__(self, driver):
super(ChatNameText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-name-text')
class ChatUrlText(BaseText):
def __init__(self, driver):
super(ChatUrlText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-url-text')
class HomeView(BaseView):
def __init__(self, driver):
super(HomeView, self).__init__(driver)
self.welcome_image = WelcomeImageElement(self.driver)
self.plus_button = PlusButton(self.driver)
self.chat_name_text = ChatNameText(self.driver)
self.chat_url_text = ChatUrlText(self.driver)
super().__init__(driver)
self.start_new_chat_button = StartNewChatButton(self.driver)
self.universal_qr_scanner_button = UniversalQrCodeScannerButton(self.driver)
self.new_group_chat_button = NewGroupChatButton(self.driver)
self.join_public_chat_button = JoinPublicChatButton(self.driver)
self.invite_friends_button = InviteFriendsButton(self.driver)
self.chats_menu_invite_friends_button = ChatsMenuInviteFriendsButton(self.driver)
self.delete_chat_button = DeleteChatButton(self.driver)
self.clear_history_button = ClearHistoryButton(self.driver)
self.mark_all_messages_as_read_button = MarkAllMessagesAsReadButton(self.driver)
self.stop_status_service_button = StopStatusServiceButton(self.driver)
self.plus_button = Button(self.driver, accessibility_id="new-chat-button")
self.chat_name_text = Text(self.driver, accessibility_id="chat-name-text")
self.start_new_chat_button = ChatButton(self.driver, accessibility_id="start-1-1-chat-button")
self.new_group_chat_button = ChatButton(self.driver, accessibility_id="start-group-chat-button")
self.join_public_chat_button = ChatButton(self.driver, accessibility_id="join-public-chat-button")
self.universal_qr_scanner_button = Button(self.driver, accessibility_id="universal-qr-scanner")
self.invite_friends_button = Button(self.driver, accessibility_id="invite-friends-button")
self.stop_status_service_button = Button(self.driver, accessibility_id="STOP")
# Options on long tap
self.chats_menu_invite_friends_button = Button(self.driver, accessibility_id="chats-menu-invite-friends-button")
self.delete_chat_button = Button(self.driver, accessibility_id="delete-chat-button")
self.clear_history_button = Button(self.driver, accessibility_id="clear-history-button")
self.mark_all_messages_as_read_button = Button(self.driver, accessibility_id="mark-all-read-button")
def wait_for_syncing_complete(self):
self.driver.info('Waiting for syncing complete:')
self.driver.info('**Waiting for syncing complete:**')
while True:
try:
sync = self.find_text_part('Syncing', 10)
@ -199,12 +85,14 @@ class HomeView(BaseView):
break
def get_chat(self, username):
self.driver.info("**Looking for chat '%s'**" % username)
return ChatElement(self.driver, username[:25])
def get_username_below_start_new_chat_button(self, username_part):
return UserNameBelowNewChatButton(self.driver, username_part)
return Text(self.driver, xpath="//*[@content-desc='enter-contact-code-input']/../..//*[starts-with(@text,'%s')]" % username_part)
def add_contact(self, public_key, add_in_contacts=True, nickname=''):
self.driver.info("**Starting 1-1 chat, add in contacts:%s**" % str(add_in_contacts))
self.plus_button.click_until_presence_of_element(self.start_new_chat_button)
contacts_view = self.start_new_chat_button.click()
contacts_view.public_key_edit_box.click()
@ -214,50 +102,46 @@ class HomeView(BaseView):
if add_in_contacts:
one_to_one_chat.add_to_contacts.click()
if nickname:
self.driver.info("**Setting nickname '%s'**" % nickname)
one_to_one_chat.chat_options.click()
one_to_one_chat.view_profile_button.click()
one_to_one_chat.set_nickname(nickname)
one_to_one_chat.back_button.click()
self.driver.info("**1-1 chat is created successfully!**")
return one_to_one_chat
def start_1_1_chat(self, username):
self.plus_button.click()
self.start_new_chat_button.click()
self.element_by_text(username).click()
from views.chat_view import ChatView
return ChatView(self.driver)
def create_group_chat(self, user_names_to_add: list, group_chat_name: str = 'new_group_chat'):
self.driver.info("**Creating group chat '%s'**" % group_chat_name)
self.plus_button.click()
contacts_view = self.new_group_chat_button.click()
chat_view = self.new_group_chat_button.click()
if user_names_to_add:
for user_name in user_names_to_add:
if len(user_names_to_add) > 5:
from views.chat_view import ChatView
contact_view_with_search = ChatView(self.driver)
contact_view_with_search.search_by_keyword(user_name[:4])
contacts_view.get_username_checkbox(user_name).click()
contact_view_with_search.search_input.clear()
chat_view.search_by_keyword(user_name[:4])
chat_view.get_username_checkbox(user_name).click()
chat_view.search_input.clear()
else:
contacts_view.get_username_checkbox(user_name).click()
contacts_view.next_button.click()
contacts_view.chat_name_editbox.send_keys(group_chat_name)
contacts_view.create_button.click()
from views.chat_view import ChatView
return ChatView(self.driver)
chat_view.get_username_checkbox(user_name).click()
chat_view.next_button.click()
chat_view.chat_name_editbox.send_keys(group_chat_name)
chat_view.create_button.click()
self.driver.info("**Group chat %s is created successfully!**" % group_chat_name)
return chat_view
def join_public_chat(self, chat_name: str):
self.driver.info("**Creating group chat %s**" % chat_name)
self.plus_button.click_until_presence_of_element(self.join_public_chat_button, attempts=5)
self.join_public_chat_button.wait_for_visibility_of_element(5)
contacts_view = self.join_public_chat_button.click()
contacts_view.chat_name_editbox.click()
contacts_view.chat_name_editbox.send_keys(chat_name)
chat_view = self.join_public_chat_button.click()
chat_view.chat_name_editbox.click()
chat_view.chat_name_editbox.send_keys(chat_name)
time.sleep(2)
chat_view = self.get_chat_view()
self.confirm_until_presence_of_element(chat_view.chat_message_input)
self.driver.info("**Public chat %s is created successfully!**" % chat_name)
return chat_view
def open_status_test_dapp(self, url=test_dapp_url, allow_all=True):
self.driver.info("**Open dapp '%s', allow all:%s**" % (test_dapp_url, str(allow_all)))
dapp_view = self.dapp_tab_button.click()
dapp_view.open_url(url)
status_test_dapp = dapp_view.get_status_test_dapp_view()
@ -266,22 +150,25 @@ class HomeView(BaseView):
status_test_dapp.allow_button.click_until_absense_of_element(status_test_dapp.allow_button)
else:
status_test_dapp.deny_button.click_until_absense_of_element(status_test_dapp.deny_button)
self.driver.info("**Dapp is opened!**")
return status_test_dapp
def delete_chat_long_press(self, username):
self.driver.info("**Deleting chat %s by long press**" % username)
self.get_chat(username).long_press_element()
self.delete_chat_button.click()
self.delete_button.click()
def leave_chat_long_press(self, username):
self.driver.info("**Leaving chat %s by long press**" % username)
self.get_chat(username).long_press_element()
from views.chat_view import LeaveChatButton, LeaveButton
LeaveChatButton(self.driver).click()
LeaveButton(self.driver).click()
from views.chat_view import ChatView
ChatView(self.driver).leave_chat_button.click()
ChatView(self.driver).leave_button.click()
def clear_chat_long_press(self, username):
self.driver.info("**Clearing history in chat %s by long press**" % username)
self.get_chat(username).long_press_element()
self.clear_history_button.click()
from views.chat_view import ClearButton
self.clear_button = ClearButton(self.driver)
self.clear_button.click()
from views.chat_view import ChatView
ChatView(self.driver).clear_button.click()

View File

@ -1,120 +1,44 @@
from views.base_element import BaseButton, BaseText, BaseEditBox
from views.base_element import Button, Text, EditBox, SilentButton
from views.base_view import BaseView
class BeginSetupButton(BaseButton):
def __init__(self, driver):
super(BeginSetupButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Begin setup")
class OnePinKeyboardButton(BaseButton):
def __init__(self, driver):
super(OnePinKeyboardButton, self).__init__(driver)
self.locator = self.Locator.text_selector("1")
class TwoPinKeyboardButton(BaseButton):
def __init__(self, driver):
super(TwoPinKeyboardButton, self).__init__(driver)
self.locator = self.Locator.text_selector("2")
class ConnectCardButton(BaseButton):
def __init__(self, driver):
super(ConnectCardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("connect-card")
class ConnectSelectedCardButton(BaseButton):
def __init__(self, driver):
super(ConnectSelectedCardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("connect-selected-card")
class DisconnectCardButton(BaseButton):
def __init__(self, driver):
super(DisconnectCardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("disconnect-card")
class ResetCardButton(BaseButton):
def __init__(self, driver):
super(ResetCardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("keycard-reset-state")
class RecoveryWordText(BaseText):
def __init__(self, driver, word_id):
super(RecoveryWordText, self).__init__(driver)
self.word_id = word_id
self.locator = self.Locator.accessibility_id("word%s" % word_id)
class WordNumberText(BaseText):
def __init__(self, driver):
super(WordNumberText, self).__init__(driver)
self.locator = self.Locator.accessibility_id("word-number")
class ConfirmSeedPhraseInput(BaseEditBox):
def __init__(self, driver):
super(ConfirmSeedPhraseInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id("enter-word")
class PairCodeText(BaseText):
def __init__(self, driver):
super(PairCodeText, self).__init__(driver)
self.locator = self.Locator.accessibility_id("pair-code")
class PairCodeInput(BaseEditBox):
def __init__(self, driver):
super(PairCodeInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.EditText")
class PairToThisDeviceButton(BaseButton):
def __init__(self, driver):
super(PairToThisDeviceButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Pair to this device")
class ConnectPairingCardButton(BaseButton):
def __init__(self, driver):
super(ConnectPairingCardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("connect-pairing-card")
class KeycardView(BaseView):
def __init__(self, driver):
super(KeycardView, self).__init__(driver)
self.begin_setup_button = BeginSetupButton(self.driver)
self.connect_card_button = ConnectCardButton(self.driver)
self.disconnect_card_button = DisconnectCardButton(self.driver)
self.reset_card_state_button = ResetCardButton(self.driver)
self.connect_selected_card_button = ConnectSelectedCardButton(self.driver)
self.pair_code_text = PairCodeText(self.driver)
self.pair_code_input = PairCodeInput(self.driver)
self.pair_to_this_device_button = PairToThisDeviceButton(self.driver)
self.connect_pairing_card_button = ConnectPairingCardButton(self.driver)
super().__init__(driver)
self.begin_setup_button = Button(self.driver, translation_id="begin-set-up")
self.connect_card_button = Button(self.driver, accessibility_id="connect-card")
self.disconnect_card_button = Button(self.driver, accessibility_id="disconnect-card")
self.reset_card_state_button = Button(self.driver, accessibility_id="keycard-reset-state")
self.connect_selected_card_button = Button(self.driver, accessibility_id="connect-selected-card")
self.pair_code_text = Text(self.driver, accessibility_id="pair-code")
self.pair_code_input = EditBox(self.driver, xpath="//android.widget.EditText")
self.pair_to_this_device_button = Button(self.driver, translation_id="pair-card")
self.connect_pairing_card_button = Button(self.driver, accessibility_id="connect-pairing-card")
#keyboard
self.one_button = OnePinKeyboardButton(self.driver)
self.two_button = TwoPinKeyboardButton(self.driver)
# Keyboard
self.one_button = SilentButton(self.driver, xpath="//*[@text='1']")
self.two_button = SilentButton(self.driver, xpath="//*[@text='2']")
#backup seed phrase
self.confirm_seed_phrase_edit_box = ConfirmSeedPhraseInput(self.driver)
# Backup seed phrase
self.confirm_seed_phrase_edit_box = EditBox(self.driver, accessibility_id="enter-word")
def enter_default_pin(self):
self.driver.info("**Enter default pin 121212**")
for _ in range(3):
self.one_button.click()
self.two_button.click()
def enter_another_pin(self):
self.driver.info("**Enter not-default pin 222222**")
for _ in range(6):
self.two_button.click()
def get_recovery_word(self, word_id):
word_element = RecoveryWordText(self.driver, word_id)
word_element = SilentButton(self.driver, accessibility_id="word%s" % word_id)
return word_element.text
def get_required_word_number(self):
description = WordNumberText(self.driver)
description = SilentButton(self.driver, accessibility_id="word-number")
full_text = description.text
word_number = ''.join(i for i in full_text if i.isdigit())
return word_number
@ -127,6 +51,7 @@ class KeycardView(BaseView):
return recovery_phrase
def backup_seed_phrase(self):
self.driver.info("**Backing up seed phrase for keycard**")
recovery_phrase = self.get_seed_phrase()
self.confirm_button.click()
self.yes_button.click()

View File

@ -1,132 +1,47 @@
import time
from tests.base_test_case import AbstractTestCase
from views.base_element import BaseText, BaseButton, BaseEditBox, BaseElement
from views.base_element import Text, Button, EditBox, SilentButton
from views.base_view import BaseView
class PublicKeyText(BaseText):
class OptionsButton(Button):
def __init__(self, driver):
super(PublicKeyText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-key')
super().__init__(driver, xpath="(//android.view.ViewGroup[@content-desc='icon'])[2]")
class ProfileAddressText(BaseText):
class AddNewContactButton(Button):
def __init__(self, driver):
super(ProfileAddressText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('profile-public-key')
@property
def text(self):
text = self.scroll_to_element().text
self.driver.info('%s is %s' % (self.name, text))
return text
class OptionsButton(BaseButton):
def __init__(self, driver):
super(OptionsButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'(//android.view.ViewGroup[@content-desc="icon"])[2]')
class UserStatusBox(BaseButton):
def __init__(self, driver):
super(OptionsButton.UserStatusBox, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.widget.ScrollView)[2]//android.widget.TextView')
class UsernameInput(BaseEditBox):
def __init__(self, driver):
super(OptionsButton.UsernameInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('username-input')
class UserStatusInput(BaseEditBox):
def __init__(self, driver):
super(OptionsButton.UserStatusInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.widget.EditText)[2]')
class AddNewContactButton(BaseButton):
def __init__(self, driver):
super(AddNewContactButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-new-contact-button')
super().__init__(driver, accessibility_id="add-new-contact-button")
def navigate(self):
from views.contacts_view import ContactsView
return ContactsView(self.driver)
from views.chat_view import ChatView
return ChatView(self.driver)
class InviteFriendsInContactsButton(BaseButton):
class LogoutButton(Button):
def __init__(self, driver):
super(InviteFriendsInContactsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('invite-friends-button')
class NetworkSettingsButton(BaseButton):
def __init__(self, driver):
super(NetworkSettingsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('network-button')
class NetworkButton(BaseButton):
def __init__(self, driver, network):
super(NetworkSettingsButton.NetworkButton, self).__init__(driver)
self.locator = self.Locator.text_selector(network)
class ConnectButton(BaseButton):
def __init__(self, driver):
super(NetworkSettingsButton.ConnectButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('network-connect-button')
class LogoutButton(BaseButton):
def __init__(self, driver):
super(LogoutButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('log-out-button')
super().__init__(driver, accessibility_id="log-out-button")
def click(self):
self.scroll_to_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
class LogoutDialog(BaseView):
def __init__(self, driver):
super(LogoutDialog, self).__init__(driver)
super().__init__(driver)
self.logout_button = LogoutDialog.LogoutButton(driver)
class LogoutButton(BaseButton):
class LogoutButton(Button):
def __init__(self, driver):
super(LogoutDialog.LogoutButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='LOG OUT' or @text='Log out']")
super().__init__(driver, translation_id="logout", uppercase=True)
def navigate(self):
from views.sign_in_view import SignInView
return SignInView(self.driver)
class ConfirmLogoutButton(BaseButton):
class ENSusernames(Button):
def __init__(self, driver):
super(ConfirmLogoutButton, self).__init__(driver)
self.locator = self.Locator.text_selector('LOG OUT')
class DefaultUserNameText(BaseText):
def __init__(self, driver):
super(DefaultUserNameText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('default-username')
class ENSusernames(BaseButton):
def __init__(self, driver):
super(ENSusernames, self).__init__(driver)
self.locator = self.Locator.text_selector('ENS usernames')
super().__init__(driver, translation_id="ens-usernames")
def navigate(self):
from views.dapps_view import DappsView
@ -136,114 +51,32 @@ class ENSusernames(BaseButton):
self.scroll_to_element().click()
return self.navigate()
class ShareMyProfileButton(BaseButton):
class AdvancedButton(Button):
def __init__(self, driver):
super(ShareMyProfileButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[1]')
class ProfilePictureElement(BaseElement):
def __init__(self, driver):
super(ProfilePictureElement, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-icon')
class ProfileDetailsOtherUser(BaseElement):
def __init__(self, driver):
super(ProfileDetailsOtherUser, self).__init__(driver)
self.locator = self.Locator.accessibility_id('profile-public-key')
class EditPictureButton(BaseButton):
def __init__(self, driver):
super(EditPictureButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'//android.view.ViewGroup[@content-desc="edit-profile-photo-button"]')
class ConfirmEditButton(BaseButton):
def __init__(self, driver):
super(ConfirmEditButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('done-button')
class CrossIcon(BaseButton):
def __init__(self, driver):
super(CrossIcon, self).__init__(driver)
self.locator = self.Locator.accessibility_id('done-button')
class ENSUsernameInShareChatKeyPopup(BaseText):
def __init__(self, driver):
super(ENSUsernameInShareChatKeyPopup, self).__init__(driver)
self.locator = self.Locator.accessibility_id('ens-username')
class AdvancedButton(BaseButton):
def __init__(self, driver):
super(AdvancedButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('advanced-button')
super().__init__(driver, accessibility_id="advanced-button")
def click(self):
self.scroll_to_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
class LogLevelSetting(BaseButton):
class BackupRecoveryPhraseButton(Button):
def __init__(self, driver):
super(LogLevelSetting, self).__init__(driver)
self.locator = self.Locator.accessibility_id('log-level-settings-button')
class FleetSettingButton(BaseButton):
def __init__(self, driver):
super(FleetSettingButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('fleet-settings-button')
class BackupRecoveryPhraseButton(BaseButton):
def __init__(self, driver):
super(BackupRecoveryPhraseButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="back-up-recovery-phrase-button"]')
super().__init__(driver, accessibility_id="back-up-recovery-phrase-button")
def click(self):
self.scroll_to_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
class OkContinueButton(BaseButton):
class RecoveryPhraseTable(Text):
def __init__(self, driver):
super(OkContinueButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Okay, continue']")
class RecoveryPhraseTable(BaseText):
super().__init__(driver, translation_id="your-recovery-phrase",
suffix="/following-sibling::android.view.ViewGroup[1]/android.widget.TextView")
class RecoveryPhraseWordNumberText(Text):
def __init__(self, driver):
super(RecoveryPhraseTable, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Your seed phrase']/following-sibling::android.view.ViewGroup[1]/android.widget.TextView")
class RecoveryPhraseWordNumberText(BaseText):
def __init__(self, driver):
super(RecoveryPhraseWordNumberText, self).__init__(driver)
self.locator = self.Locator.text_part_selector('#')
super().__init__(driver, xpath="//*[contains(@text,'#')]")
@property
def number(self):
@ -251,515 +84,215 @@ class RecoveryPhraseWordNumberText(BaseText):
return int(self.find_element().text.split('#')[1])
class RecoveryPhraseWordInput(BaseEditBox):
class RecoveryPhraseWordInput(EditBox):
def __init__(self, driver):
super(RecoveryPhraseWordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.EditText')
super(RecoveryPhraseWordInput, self).__init__(driver, xpath="//android.widget.EditText")
class DebugModeToggle(BaseButton):
class HelpButton(Button):
def __init__(self, driver):
super(DebugModeToggle, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.Switch")
def click(self):
self.scroll_to_element()
super(DebugModeToggle, self).click()
class SelectFromGalleryButton(BaseButton):
def __init__(self, driver):
super(SelectFromGalleryButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Select from gallery')
class CaptureButton(BaseButton):
def __init__(self, driver):
super(CaptureButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Capture')
class MainCurrencyButton(BaseButton):
def __init__(self, driver):
super(MainCurrencyButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("currency-button")
class PlusButton(BaseButton):
def __init__(self, driver):
super(PlusButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//android.view.ViewGroup[@content-desc='icon'])[2]")
class RopstenChainButton(BaseButton):
def __init__(self, driver):
super(RopstenChainButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[contains(@text,'Ropsten test network')]")
class SpecifyNameInput(BaseEditBox):
def __init__(self, driver):
super(SpecifyNameInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Name']/following-sibling::*[1]/android.widget.EditText")
class CustomNetworkURL(BaseEditBox):
def __init__(self, driver):
super(CustomNetworkURL, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='RPC URL']/following-sibling::*[1]/android.widget.EditText")
class HelpButton(BaseButton):
def __init__(self, driver):
super(HelpButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("help-button")
super().__init__(driver, accessibility_id="help-button")
def click(self):
self.scroll_to_element().click()
class SubmitBugButton(BaseButton):
class FaqButton(Button):
def __init__(self, driver):
super(SubmitBugButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("submit-bug-button")
class RequestFeatureButton(BaseButton):
def __init__(self, driver):
super(RequestFeatureButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("request-a-feature-button")
class FaqButton(BaseButton):
def __init__(self, driver):
super(FaqButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("faq-button")
super().__init__(driver, accessibility_id="faq-button")
def navigate(self):
from views.web_views.base_web_view import BaseWebView
return BaseWebView(self.driver)
class AppVersionText(BaseText):
def __init__(self, driver):
super(AppVersionText, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='app-version']//android.widget.TextView[2]")
class NodeVersionText(BaseText):
def __init__(self, driver):
super(NodeVersionText, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='node-version']//android.widget.TextView[2]")
class BootnodesButton(BaseButton):
def __init__(self, driver):
super(BootnodesButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('bootnodes-settings-button')
class AddBootnodeButton(BaseButton):
def __init__(self, driver):
super(AddBootnodeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("add-bootnode")
class BootnodeAddressInput(BaseEditBox):
def __init__(self, driver):
super(BootnodeAddressInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id("bootnode-address")
class EnableBootnodesToggle(BaseEditBox):
def __init__(self, driver):
super(EnableBootnodesToggle, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.Switch')
class MailServerButton(BaseButton):
def __init__(self, driver):
super(MailServerButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('offline-messages-settings-button')
class MailServerAddressInput(BaseEditBox):
def __init__(self, driver):
super(MailServerAddressInput, self).__init__(driver)
self.locator = self.Locator.translation_id('mailserver-address',
suffix='/following-sibling::*[1]/android.widget.EditText')
class MailServerAutoSelectionButton(BaseButton):
def __init__(self, driver):
super(MailServerAutoSelectionButton, self).__init__(driver)
self.locator = self.Locator.translation_id("mailserver-automatic", '/following-sibling::*[1]')
class UseHistoryNodesButton(BaseButton):
def __init__(self, driver):
super(UseHistoryNodesButton, self).__init__(driver)
self.locator = self.Locator.translation_id('offline-messaging-use-history-nodes', '/following-sibling::*[1]')
class MailServerElement(BaseButton):
class MailServerElement(Button):
def __init__(self, driver, server_name):
super(MailServerElement, self).__init__(driver)
super().__init__(driver, xpath="//*[@content-desc='mailserver-item']//*[@text='%s']" % server_name)
self.server_name = server_name
self.locator = self.Locator.xpath_selector("//*[@content-desc='mailserver-item']//*[@text='%s']" % server_name)
def click(self):
size = self.driver.get_window_size()
self.driver.swipe(500, size["height"]*0.8, 500, size["height"]*0.05)
self.driver.info('Tap on "%s" mailserver value' % self.server_name)
self.find_element().click()
class MailServerConnectButton(BaseButton):
class AboutButton(Button):
def __init__(self, driver):
super(MailServerConnectButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('mailserver-connect-button')
class MailServerDeleteButton(BaseButton):
def __init__(self, driver):
super(MailServerDeleteButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('mailserver-delete-button')
class MailServerConfirmDeleteButton(BaseButton):
def __init__(self, driver):
super(MailServerConfirmDeleteButton, self).__init__(driver)
self.locator = self.Locator.translation_id("delete-mailserver", uppercase=True)
class ActiveNetworkName(BaseText):
def __init__(self, driver):
super(ActiveNetworkName, self).__init__(driver)
self.locator = self.Locator.text_part_selector('with upstream RPC')
class AboutButton(BaseButton):
def __init__(self, driver):
super(AboutButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('about-button')
def navigate(self):
from views.about_view import AboutView
return AboutView(self.driver)
super().__init__(driver, accessibility_id="about-button")
def click(self):
self.scroll_to_element().click()
return self.navigate()
class PrifileNotificationsButton(BaseButton):
class SyncSettingsButton(Button):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.accessibility_id("notifications-settings-button")
class PrifileNotificationsToggleButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='notifications-settings-button']")
class RemovePictureButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector('Remove current photo')
class DevicesButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="pairing-settings-button"]')
class DeviceNameInput(BaseEditBox):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.accessibility_id('device-name')
class ContinueButton(BaseButton):
def __init__(self, driver):
super(ContinueButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Continue')
class SyncSettingsButton(BaseButton):
def __init__(self, driver):
super(SyncSettingsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('sync-settings-button')
super().__init__(driver, accessibility_id="sync-settings-button")
def click(self):
self.scroll_to_element().click()
self.driver.info('Tap on %s' % self.name)
class GoToPairingSettingsButton(BaseButton):
class DappPermissionsButton(Button):
def __init__(self, driver):
super(GoToPairingSettingsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('GO TO PAIRING SETTINGS')
class AdvertiseDeviceButton(BaseButton):
def __init__(self, driver):
super(AdvertiseDeviceButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('advertise-device')
class SyncedDeviceToggle(BaseButton):
def __init__(self, driver, device_name):
super(SyncedDeviceToggle, self).__init__(driver)
self.device_name = device_name
self.locator = self.Locator.xpath_selector(
'//android.widget.TextView[contains(@text,"%s")]/../android.widget.Switch' % device_name)
class SyncAllButton(BaseButton):
def __init__(self, driver):
super(SyncAllButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Sync all devices')
class ContactsButton(BaseButton):
def __init__(self, driver):
super(ContactsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('contacts-button')
class BlockedUsersButton(BaseButton):
def __init__(self, driver):
super(BlockedUsersButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('blocked-users-list-button')
class DappPermissionsButton(BaseButton):
def __init__(self, driver):
super(DappPermissionsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('dapps-permissions-button')
super().__init__(driver, accessibility_id="dapps-permissions-button")
def click(self):
self.scroll_to_element().click()
self.driver.info('Tap on %s' % self.name)
class RevokeAccessButton(BaseButton):
class PrivacyPolicyButton(Button):
def __init__(self, driver):
super(RevokeAccessButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Revoke access')
super().__init__(driver, accessibility_id="privacy-policy")
def navigate(self):
from views.web_views.base_web_view import BaseWebView
return BaseWebView(self.driver)
class PrivacyAndSecurityButton(BaseButton):
def __init__(self, driver):
super(PrivacyAndSecurityButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('privacy-and-security-settings-button')
class DeleteMyProfileButton(BaseButton):
def __init__(self, driver):
super(DeleteMyProfileButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Delete my profile')
class DeleteMyProfilePasswordInput(BaseEditBox):
def __init__(self, driver):
super(DeleteMyProfilePasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.widget.EditText')
class DeleteProfileButton(BaseButton):
def __init__(self, driver):
super(DeleteProfileButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('delete-profile-confirm')
class UseMobileDataToggle(BaseButton):
def __init__(self, driver):
super(UseMobileDataToggle, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Use mobile data']/following-sibling::android.widget.Switch[1]")
class AskMeWhenOnMobileNetworkToggle(BaseButton):
def __init__(self, driver):
super(AskMeWhenOnMobileNetworkToggle, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Ask me when on mobile network']/following-sibling::android.widget.Switch[1]")
class PushNotificationToggle(BaseButton):
def __init__(self, driver):
super(PushNotificationToggle, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='notifications-button']//*[@content-desc='switch']")
class WalletTransactionsButton(BaseButton):
def __init__(self, driver):
super(WalletTransactionsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("notifications-button")
class ENSUsernameInChatSettings(BaseElement):
def __init__(self, driver):
super(ENSUsernameInChatSettings, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='chat-icon']/../android.widget.TextView[2]")
class ProfileView(BaseView):
def __init__(self, driver):
super(ProfileView, self).__init__(driver)
self.driver = driver
super().__init__(driver)
self.options_button = OptionsButton(self.driver)
self.username_input = OptionsButton.UsernameInput(self.driver)
self.user_status_box = OptionsButton.UserStatusBox(self.driver)
self.user_status_input = OptionsButton.UserStatusInput(self.driver)
self.public_key_text = PublicKeyText(self.driver)
self.profile_address_text = ProfileAddressText(self.driver)
self.about_button = AboutButton(self.driver)
self.app_version_text = AppVersionText(self.driver)
self.node_version_text = NodeVersionText(self.driver)
self.network_settings_button = NetworkSettingsButton(self.driver)
self.active_network_name = ActiveNetworkName(self.driver)
self.plus_button = PlusButton(self.driver)
self.ropsten_chain_button = RopstenChainButton(self.driver)
self.custom_network_url = CustomNetworkURL(self.driver)
self.specify_name_input = SpecifyNameInput(self.driver)
self.connect_button = NetworkSettingsButton.ConnectButton(self.driver)
self.logout_button = LogoutButton(self.driver)
self.logout_dialog = LogoutDialog(self.driver)
self.confirm_logout_button = ConfirmLogoutButton(self.driver)
# Header
self.public_key_text = Text(self.driver, accessibility_id="chat-key")
self.default_username_text = Text(self.driver, accessibility_id="default-username")
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
self.profile_picture = Button(self.driver, accesibility_id="chat-icon")
self.edit_picture_button = Button(self.driver, accessibility_id="edit-profile-photo-button")
self.confirm_edit_button = Button(self.driver, accessibility_id="done-button")
self.select_from_gallery_button = Button(self.driver, translation_id="profile-pic-pick")
self.capture_button = Button(self.driver, translation_id="image-source-make-photo")
self.main_currency_button = MainCurrencyButton(self.driver)
# ENS
self.username_in_ens_chat_settings_text = EditBox(self.driver,
xpath="//*[@content-desc='chat-icon']/../android.widget.TextView[2]")
self.ens_usernames_button = ENSusernames(self.driver)
self.ens_name_in_share_chat_key_text = Text(self.driver, accessibility_id="ens-username")
self.default_username_text = DefaultUserNameText(self.driver)
self.share_my_profile_button = ShareMyProfileButton(self.driver)
self.profile_picture = ProfilePictureElement(self.driver)
self.edit_picture_button = EditPictureButton(self.driver)
self.remove_picture_button = RemovePictureButton(self.driver)
self.confirm_edit_button = ConfirmEditButton(self.driver)
self.cross_icon = CrossIcon(self.driver)
self.profile_notifications_button = PrifileNotificationsButton(self.driver)
self.profile_notifications_toggle_button = PrifileNotificationsToggleButton(self.driver)
self.advanced_button = AdvancedButton(self.driver)
self.log_level_setting_button = LogLevelSetting(self.driver)
self.fleet_setting_button = FleetSettingButton(self.driver)
self.debug_mode_toggle = DebugModeToggle(self.driver)
self.contacts_button = ContactsButton(self.driver)
self.blocked_users_button = BlockedUsersButton(self.driver)
# Contacts
self.contacts_button = Button(self.driver, accessibility_id="contacts-button")
self.blocked_users_button = Button(self.driver, accessibility_id="blocked-users-list-button")
self.add_new_contact_button = AddNewContactButton(self.driver)
self.invite_friends_in_contact_button = InviteFriendsInContactsButton(self.driver)
self.dapp_permissions_button = DappPermissionsButton(self.driver)
self.revoke_access_button = RevokeAccessButton(self.driver)
self.privacy_and_security_button = PrivacyAndSecurityButton(self.driver)
self.delete_my_profile_button = DeleteMyProfileButton(self.driver)
self.delete_my_profile_password_input = DeleteMyProfilePasswordInput(self.driver)
self.delete_profile_button = DeleteProfileButton(self.driver)
self.invite_friends_in_contact_button = Button(self.driver, accessibility_id="invite-friends-button")
# Backup recovery phrase
# Privacy and security
self.privacy_and_security_button = Button(self.driver, accessibility_id="privacy-and-security-settings-button")
## Backup recovery phrase
self.backup_recovery_phrase_button = BackupRecoveryPhraseButton(self.driver)
self.ok_continue_button = OkContinueButton(self.driver)
self.recovery_phrase_table = RecoveryPhraseTable(self.driver)
self.recovery_phrase_word_number = RecoveryPhraseWordNumberText(self.driver)
self.recovery_phrase_word_input = RecoveryPhraseWordInput(self.driver)
## Dapps permissions
self.dapp_permissions_button = DappPermissionsButton(self.driver)
self.revoke_access_button = Button(self.driver, translation_id="revoke-access")
## Delete my profile
self.delete_my_profile_button = Button(self.driver, translation_id="delete-my-profile")
self.delete_my_profile_password_input = EditBox(self.driver, xpath="//android.widget.EditText")
self.delete_profile_button = Button(self.driver, accessibility_id="delete-profile-confirm")
self.select_from_gallery_button = SelectFromGalleryButton(self.driver)
self.capture_button = CaptureButton(self.driver)
# Notifications
self.profile_notifications_button = Button(self.driver, accessibility_id="notifications-settings-button")
self.profile_notifications_toggle_button = Button(self.driver, accessibility_id="notifications-settings-button")
self.push_notification_toggle = Button(self.driver,
xpath="//*[@content-desc='notifications-button']//*[@content-desc='switch']")
self.wallet_push_notifications = Button(self.driver, accessibility_id="notifications-button")
self.help_button = HelpButton(self.driver)
self.submit_bug_button = SubmitBugButton(self.driver)
self.request_a_feature_button = RequestFeatureButton(self.driver)
self.faq_button = FaqButton(self.driver)
self.about_button = AboutButton(self.driver)
# Sync settings
self.sync_settings_button = SyncSettingsButton(self.driver)
## Mobile Data
self.use_mobile_data = Button(self.driver, translation_id="mobile-network-use-mobile",
suffix="/following-sibling::android.widget.Switch[1]")
self.ask_me_when_on_mobile_network = Button(self.driver, translation_id="mobile-network-ask-me",
suffix="/following-sibling::android.widget.Switch[1]")
## History nodes
self.mail_server_button = Button(self.driver, accessibility_id="offline-messages-settings-button")
self.mail_server_address_input = EditBox(self.driver, translation_id="mailserver-address",
suffix="/following-sibling::*[1]/android.widget.EditText")
self.mail_server_connect_button = Button(self.driver, accessibility_id="mailserver-connect-button")
self.mail_server_auto_selection_button = Button(self.driver, translation_id="mailserver-automatic",
suffix="/following-sibling::*[1]")
self.use_history_node_button = Button(self.driver, translation_id="offline-messaging-use-history-nodes",
suffix="/following-sibling::*[1]")
self.mail_server_delete_button = Button(self.driver, accessibility_id="mailserver-delete-button")
self.mail_server_confirm_delete_button = Button(self.driver, xpath='//*[@text="%s"]' % self.get_translation_by_key("delete-mailserver").upper())
## Device syncing
self.devices_button = Button(self.driver, accessibility_id="pairing-settings-button")
self.device_name_input = EditBox(self.driver, accessibility_id="device-name")
self.go_to_pairing_settings_button = Button(self.driver, translation_id="pairing-go-to-installation",
uppercase=True)
self.advertise_device_button = Button(self.driver, accessibility_id="advertise-device")
self.sync_all_button = Button(self.driver, translation_id="sync-all-devices")
# Bootnodes
self.bootnodes_button = BootnodesButton(self.driver)
self.bootnode_address_input = BootnodeAddressInput(self.driver)
self.enable_bootnodes = EnableBootnodesToggle(self.driver)
self.add_bootnode_button = AddBootnodeButton(self.driver)
# Advanced
self.advanced_button = AdvancedButton(self.driver)
## Network
self.network_settings_button = Button(self.driver, accessibility_id="network-button")
self.active_network_name = Text(self.driver, xpath="//android.widget.TextView[contains(@text,'with upstream RPC')]")
self.plus_button = Button(self.driver, xpath="(//android.view.ViewGroup[@content-desc='icon'])[2]")
self.ropsten_chain_button = Button(self.driver, translation_id="ropsten-network")
self.custom_network_url_input = EditBox(self.driver, translation_id="rpc-url",
suffix="/following-sibling::*[1]/android.widget.EditText")
self.specify_name_input = EditBox(self.driver, translation_id="name",
suffix="/following-sibling::*[1]/android.widget.EditText")
self.connect_button = Button(self.driver, accessibility_id="network-connect-button")
## Log level
self.log_level_setting_button = Button(self.driver, accessibility_id="log-level-settings-button")
## Fleet
self.fleet_setting_button = Button(self.driver, accessibility_id="fleet-settings-button")
## Bootnodes
self.bootnodes_button = Button(self.driver, accessibility_id="bootnodes-settings-button")
self.bootnode_address_input = EditBox(self.driver, accessibility_id="bootnode-address")
self.enable_bootnodes = Button(self.driver, xpath="//android.widget.Switch")
self.add_bootnode_button = Button(self.driver, accessibility_id="add-bootnode")
# Mailservers
self.mail_server_button = MailServerButton(self.driver)
self.mail_server_address_input = MailServerAddressInput(self.driver)
self.mail_server_connect_button = MailServerConnectButton(self.driver)
self.mail_server_auto_selection_button = MailServerAutoSelectionButton(self.driver)
self.use_history_node_button = UseHistoryNodesButton(self.driver)
self.mail_server_delete_button = MailServerDeleteButton(self.driver)
self.mail_server_confirm_delete_button = MailServerConfirmDeleteButton(self.driver)
#Need help
self.help_button = HelpButton(self.driver)
self.submit_bug_button = Button(self.driver, accessibility_id="submit-bug-button")
self.request_a_feature_button = Button(self.driver, accessibility_id="request-a-feature-button")
self.faq_button = FaqButton(self.driver)
# Pairing
self.devices_button = DevicesButton(self.driver)
self.device_name_input = DeviceNameInput(self.driver)
self.continue_button = ContinueButton(self.driver)
self.go_to_pairing_settings_button = GoToPairingSettingsButton(self.driver)
self.advertise_device_button = AdvertiseDeviceButton(self.driver)
self.sync_all_button = SyncAllButton(self.driver)
#About
self.about_button = AboutButton(self.driver)
self.privacy_policy_button = PrivacyPolicyButton(self.driver)
self.app_version_text = Text(self.driver, xpath="//*[@content-desc='app-version']//android.widget.TextView[2]")
self.node_version_text = Text(self.driver,
xpath="//*[@content-desc='node-version']//android.widget.TextView[2]")
# ENS
self.username_in_ens_chat_settings_text = ENSUsernameInChatSettings(self.driver)
self.ens_usernames_button = ENSusernames(self.driver)
self.ens_name_in_share_chat_key_text = ENSUsernameInShareChatKeyPopup(self.driver)
# Mobile Data
self.use_mobile_data = UseMobileDataToggle(self.driver)
self.ask_me_when_on_mobile_network = AskMeWhenOnMobileNetworkToggle(self.driver)
#Push notifications
self.push_notification_toggle = PushNotificationToggle(self.driver)
self.wallet_push_notifications = WalletTransactionsButton(self.driver)
#Logout
self.logout_button = LogoutButton(self.driver)
self.logout_dialog = LogoutDialog(self.driver)
self.confirm_logout_button = Button(self.driver, translation_id="logout", uppercase=True)
def switch_network(self, network='Mainnet with upstream RPC'):
self.driver.info("**Switching network to '%s'**" % network)
self.advanced_button.click()
self.network_settings_button.click()
network_button = NetworkSettingsButton.NetworkButton(self.driver, network)
network_button = Button(self.driver, xpath="//*[@text='%s']" % network)
network_button.click()
self.connect_button.click_until_presence_of_element(self.confirm_button)
from views.sign_in_view import SignInView
signin_view = SignInView(self.driver)
self.confirm_button.click_until_absense_of_element(self.confirm_button)
signin_view.sign_in()
from views.sign_in_view import SignInView
SignInView(self.driver).sign_in()
def open_contact_from_profile(self, username):
self.driver.info("**Open profile of '%s' via Contacts**" % username)
self.contacts_button.click()
self.element_by_text(username).click()
from views.chat_view import ChatView
return ChatView(self.driver)
def switch_development_mode(self):
self.advanced_button.click()
self.debug_mode_toggle.click()
def add_custom_network(self):
self.driver.info("**Adding predefined custom network**")
self.advanced_button.click()
self.network_settings_button.scroll_to_element()
self.network_settings_button.click()
self.plus_button.click_until_presence_of_element(self.ropsten_chain_button)
self.custom_network_url.send_keys('https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a')
self.custom_network_url_input.send_keys('https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a')
self.specify_name_input.send_keys('custom_ropsten')
self.ropsten_chain_button.scroll_to_element()
self.ropsten_chain_button.click()
@ -775,6 +308,7 @@ class ProfileView(BaseView):
return dict(zip(map(int, text[::2]), text[1::2]))
def backup_recovery_phrase(self):
self.driver.info("**Backing up seed phrase**")
self.ok_continue_button.click()
recovery_phrase = self.get_recovery_phrase()
self.next_button.click()
@ -786,6 +320,7 @@ class ProfileView(BaseView):
self.done_button.click()
self.yes_button.click()
self.ok_got_it_button.click()
self.driver.info("**Seed phrase is backed up!**")
return recovery_phrase
def edit_profile_picture(self, file_name: str):
@ -803,13 +338,8 @@ class ProfileView(BaseView):
self.element_by_text(element_text).click()
picture.click()
def remove_profile_picture(self):
if not AbstractTestCase().environment == 'sauce':
raise NotImplementedError('Test case is implemented to run on SauceLabs only')
self.profile_picture.click()
self.remove_picture_button.click()
def logout(self):
self.driver.info("**Logging out**")
self.logout_button.click()
self.logout_dialog.logout_button.click()
self.logout_button.wait_for_invisibility_of_element(30)
@ -818,9 +348,10 @@ class ProfileView(BaseView):
return MailServerElement(self.driver, server_name)
def get_toggle_device_by_name(self, device_name):
return SyncedDeviceToggle(self.driver, device_name)
return SilentButton(self.driver, xpath="//android.widget.TextView[contains(@text,'%s')]/../android.widget.Switch" % device_name)
def discover_and_advertise_device(self, device_name):
self.driver.info("**Discover and advertise '%s'**" % device_name)
self.sync_settings_button.click()
self.devices_button.scroll_to_element()
self.devices_button.click()
@ -829,32 +360,32 @@ class ProfileView(BaseView):
self.advertise_device_button.click()
def retry_to_connect_to_mailserver(self):
self.driver.info("**Retrying to connect to mailserver 5 times**")
i = 0
while self.element_by_text_part("Error connecting").is_element_present(20) and i < 5:
self.element_by_text('RETRY').click()
while self.element_by_translation_id("mailserver-error-title").is_element_present(20) and i < 5:
self.element_by_translation_id("mailserver-retry", uppercase=True).click()
i += 1
self.just_fyi("retrying to connect: %s attempt" % i)
# TODO: uncomment after https://github.com/status-im/status-react/issues/9269
time.sleep(10)
if i == 5:
self.driver.fail("Failed to connect after %s attempts" % i)
def connect_existing_status_ens(self, name):
self.just_fyi('switching to mainnet and add ENS')
self.driver.info("**Connect existing ENS '%s'**" % name)
profile = self.profile_button.click()
profile.switch_network('Mainnet with upstream RPC')
self.profile_button.click()
dapp_view = self.ens_usernames_button.click()
dapp_view.element_by_text('Get started').click()
dapp_view.ens_name.set_value(name)
dapp_view.check_ens_name.click_until_presence_of_element(self.element_by_text('Ok, got it'))
dapp_view.element_by_text('Ok, got it').click()
dapp_view.element_by_translation_id("get-started").click()
dapp_view.ens_name_input.set_value(name)
dapp_view.check_ens_name.click_until_presence_of_element(self.element_by_translation_id("ens-got-it"))
dapp_view.element_by_translation_id("ens-got-it").click()
return dapp_view
def return_mailserver_name(self, mailserver_name, fleet):
@staticmethod
def return_mailserver_name(mailserver_name, fleet):
return mailserver_name + '.' + fleet
@property
def current_active_network(self):
self.advanced_button.click()

View File

@ -1,104 +0,0 @@
from views.base_element import BaseEditBox, BaseButton, BaseElement
from views.sign_in_view import SignInView
class SeedphraseInput(BaseEditBox):
def __init__(self, driver):
super(SeedphraseInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.EditText")
class EnterSeedPhraseButton(BaseButton):
def __init__(self, driver):
super(EnterSeedPhraseButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("enter-seed-phrase-button")
class ReencryptYourKeyButton(BaseButton):
def __init__(self, driver):
super(ReencryptYourKeyButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Re-encrypt your keys']")
class ConfirmRecoverAccess(BaseButton):
def __init__(self, driver):
super(ConfirmRecoverAccess, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='RECOVER ACCESS']")
class ContinueCustomSeedPhraseButton(BaseButton):
def __init__(self, driver):
super(ContinueCustomSeedPhraseButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("continue-custom-seed-phrase")
class CancelCustomSeedPhraseButton(BaseButton):
def __init__(self, driver):
super(CancelCustomSeedPhraseButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("cancel-custom-seed-phrase")
class RequiredField(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector("Required field")
class InvalidRecoveryPhrase(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector("Recovery phrase is invalid")
class TooShortPassword(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector("Password is too short")
class MisspelledWords(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector("Some words might be misspelled")
class Warnings(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.required_field = RequiredField(driver)
self.invalid_recovery_phrase = InvalidRecoveryPhrase(driver)
self.too_short_password = TooShortPassword(driver)
self.misspelled_words = MisspelledWords(driver)
class ConfirmPhraseButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.id("android:id/button1")
def navigate(self):
from views.home_view import HomeView
return HomeView(self.driver)
class CancelPhraseButton(BaseButton):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.id("android:id/button2")
class RecoverAccessView(SignInView):
def __init__(self, driver):
super(RecoverAccessView, self).__init__(driver, skip_popups=False)
self.driver = driver
self.seedphrase_input = SeedphraseInput(self.driver)
self.enter_seed_phrase_button = EnterSeedPhraseButton(self.driver)
self.confirm_recover_access = ConfirmRecoverAccess(self.driver)
self.reencrypt_your_key_button = ReencryptYourKeyButton(self.driver)
self.warnings = Warnings(self.driver)
self.confirm_phrase_button = ConfirmPhraseButton(self.driver)
self.cancel_button = CancelPhraseButton(self.driver)
self.continue_custom_seed_phrase_button = ContinueCustomSeedPhraseButton(self.driver)
self.cancel_custom_seed_phrase_button = CancelCustomSeedPhraseButton(self.driver)

View File

@ -1,249 +1,56 @@
from tests import common_password
from views.base_element import BaseText, BaseElement
from views.base_element import BaseButton, BaseEditBox
from views.base_view import BaseView, OkButton
from views.base_element import Text, SilentButton
from views.base_element import Button, EditBox
from views.base_view import BaseView
class FirstRecipient(BaseButton):
class AmountEditBox(EditBox, Button):
def __init__(self, driver):
super(FirstRecipient, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-icon')
class CancelButton(BaseButton):
def __init__(self, driver):
super(CancelButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Cancel")
class SignTransactionButton(BaseButton):
def __init__(self, driver):
super(SignTransactionButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('send-transaction-bottom-sheet')
class AmountEditBox(BaseEditBox, BaseButton):
def __init__(self, driver):
super(AmountEditBox, self).__init__(driver)
self.locator = self.Locator.accessibility_id('amount-input')
super(AmountEditBox, self).__init__(driver, accessibility_id="amount-input")
def set_value(self, value):
BaseEditBox.set_value(self, value)
EditBox.set_value(self, value)
self.driver.press_keycode(66)
class SetMaxButton(BaseButton):
class ChooseRecipientButton(Button):
def __init__(self, driver):
super(SetMaxButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Set max')
class SignInPhraseText(BaseText):
def __init__(self, driver):
super(SignInPhraseText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('signing-phrase-text')
class PasswordInput(BaseEditBox):
def __init__(self, driver):
super(PasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Password']")
class EnterPasswordInput(BaseEditBox):
def __init__(self, driver):
super(EnterPasswordInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('enter-password-input')
class GotItButton(BaseButton):
def __init__(self, driver):
super(GotItButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('got-it-button')
class ChooseRecipientButton(BaseButton):
def __init__(self, driver):
super(ChooseRecipientButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('choose-recipient-button')
super(ChooseRecipientButton, self).__init__(driver, accessibility_id="choose-recipient-button")
def click(self):
self.click_until_presence_of_element(AccountsButton(self.driver))
self.click_until_presence_of_element(Button(self.driver, translation_id="my-accounts"))
return self.navigate()
class AccountsButton(BaseButton):
class GasPriceInput(EditBox):
def __init__(self, driver):
super(AccountsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('My accounts')
class EnterRecipientAddressButton(BaseButton):
def __init__(self, driver):
super(EnterRecipientAddressButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('choose-recipient-recipient-code')
class ScanQRCodeButton(BaseButton):
def __init__(self, driver):
super(ScanQRCodeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('scan-contact-code-button')
class EnterRecipientAddressInput(BaseEditBox):
def __init__(self, driver):
super(EnterRecipientAddressInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id("recipient-address-input")
class EnterRecipientAddressInputText(BaseText):
def __init__(self, driver):
super(EnterRecipientAddressInputText, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='choose-recipient-button']//android.widget.TextView")
class RecentRecipientsButton(BaseButton):
def __init__(self, driver):
super(RecentRecipientsButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Contacts']")
class SelectAssetButton(BaseButton):
def __init__(self, driver):
super(SelectAssetButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('choose-asset-button')
class AssetText(BaseText):
def __init__(self, driver):
super(AssetText, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="choose-asset-button"]//android.widget.TextView')
class RecipientText(BaseText):
def __init__(self, driver):
super(RecipientText, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="choose-recipient-button"]//android.widget.TextView')
class ErrorDialog(BaseView):
def __init__(self, driver):
super(ErrorDialog, self).__init__(driver)
self.ok_button = OkButton(driver)
def wait_for_error_message(self, error_message, wait_time=30):
element = self.element_by_text_part(error_message)
return element.wait_for_element(wait_time)
class NetworkFeeButton(BaseButton):
def __init__(self, driver):
super(NetworkFeeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('custom-gas-fee')
class TransactionFeeButton(BaseButton):
def __init__(self, driver):
super(TransactionFeeButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('transaction-fee-button')
class TransactionFeeTotalValue(BaseText):
def __init__(self, driver):
super(TransactionFeeTotalValue, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Total Fee']//following::android.widget.TextView[1]")
class GasLimitInput(BaseEditBox):
def __init__(self, driver):
super(GasLimitInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//*[@text='Gas limit']/..//android.widget.EditText)[1]")
class GasPriceInput(BaseEditBox):
def __init__(self, driver):
super(GasPriceInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//*[@text='Gas limit']/..//android.widget.EditText)[2]")
super(GasPriceInput, self).__init__(driver, prefix="(", translation_id="gas-limit",
suffix="/..//android.widget.EditText)[2]")
@property
def text(self):
return self.find_element().text
class TotalFeeInput(BaseText):
class UpdateFeeButton(Button):
def __init__(self, driver):
super(TotalFeeInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Total Fee']/following-sibling::android.widget.TextView")
class ETHroAssetButtonInSelectAssetBottomSheet(BaseButton):
def __init__(self, driver):
super(ETHroAssetButtonInSelectAssetBottomSheet, self).__init__(driver)
self.locator = self.Locator.accessibility_id(':ETH-asset-value')
class UpdateFeeButton(BaseButton):
def __init__(self, driver):
super(UpdateFeeButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Update']")
super(UpdateFeeButton, self).__init__(driver, translation_id="update")
def click(self):
for _ in range(3):
self.driver.info('Tap on %s' % self.name)
self.find_element().click()
self.driver.info('Wait for no %s' % self.name)
if not self.is_element_displayed():
return self.navigate()
class ValidationErrorOnSendTransaction(BaseButton):
class ValidationErrorOnSendTransaction(Button):
def __init__(self, driver, field):
super(ValidationErrorOnSendTransaction, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='%s']/../*[@content-desc='icon']" % field)
super(ValidationErrorOnSendTransaction, self).__init__(driver, xpath="//*[@text='%s']/../*[@content-desc='icon']" % field)
class ValidationIconOnSendTransaction(BaseButton):
class NotEnoughEthForGas(Text):
def __init__(self, driver):
super(ValidationIconOnSendTransaction, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="custom-gas-fee"]/../android.view.ViewGroup//*[@content-desc="icon"]')
class ShareButton(BaseButton):
def __init__(self, driver):
super(ShareButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('share-address-button')
class RecipientAddToFavoritesButton(BaseButton):
def __init__(self, driver):
super(RecipientAddToFavoritesButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('participant-add-to-favs')
class RecipientDoneButton(BaseButton):
def __init__(self, driver):
super(RecipientDoneButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('participant-done')
class NewFavoriteNameInput(BaseEditBox):
def __init__(self, driver):
super(NewFavoriteNameInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('fav-name')
class NewFavoriteAddFavorite(BaseButton):
def __init__(self, driver):
super(NewFavoriteAddFavorite, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-fav')
class OnboardingMessage(BaseElement):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector('This is your signing phrase')
class NotEnoughEthForGas(BaseText):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector('Not enough ETH for gas')
super().__init__(driver, translation_id="wallet-insufficient-gas")
class ValidationWarnings(object):
@ -251,133 +58,84 @@ class ValidationWarnings(object):
self.not_enough_eth_for_gas = NotEnoughEthForGas(driver)
class SignWithPasswordButton(BaseButton):
class SignWithKeycardButton(Button):
def __init__(self, driver):
super(SignWithPasswordButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Sign with password')
class SignButton(BaseButton):
def __init__(self, driver):
super(SignButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@text="Sign"]')
class SignWithKeycardButton(BaseButton):
def __init__(self, driver):
super(SignWithKeycardButton, self).__init__(driver)
self.locator = self.Locator.text_part_selector('Sign with')
super(SignWithKeycardButton, self).__init__(driver, xpath="//*[contains(@text,'%s')]" % self.get_translation_by_key("sign-with"))
def navigate(self):
from views.keycard_view import KeycardView
return KeycardView(self.driver)
def click(self):
from views.keycard_view import TwoPinKeyboardButton
self.click_until_presence_of_element(TwoPinKeyboardButton(self.driver))
from views.keycard_view import KeycardView
self.click_until_presence_of_element(KeycardView(self.driver).one_button)
return self.navigate()
class SigningPhraseText(BaseText):
def __init__(self, driver):
super(SigningPhraseText, self).__init__(driver)
self.locator = self.Locator.text_part_selector('Signing phrase')
# Elements for commands in 1-1 chat
class UserNameInSendTransactionBottomSheet(BaseButton):
def __init__(self, driver, username_part):
super(UserNameInSendTransactionBottomSheet, self).__init__(driver)
self.username = username_part
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='amount-input']/..//*[starts-with(@text,'%s')]" % self.username)
class AccountNameInSelectAccountBottomSheet(BaseButton):
def __init__(self, driver, account_part):
super(AccountNameInSelectAccountBottomSheet, self).__init__(driver)
self.username = account_part
self.locator = self.Locator.xpath_selector(
"//*[@text='Select account']/..//*[starts-with(@text,'%s')]" % self.username)
class SelectButton(BaseButton):
def __init__(self, driver):
super(SelectButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('select-account-bottom-sheet')
class RequestTransactionButtonBottomSheet(BaseButton):
def __init__(self, driver):
super(RequestTransactionButtonBottomSheet, self).__init__(driver)
self.locator = self.Locator.accessibility_id('request-transaction-bottom-sheet')
class SendTransactionView(BaseView):
def __init__(self, driver):
super(SendTransactionView, self).__init__(driver)
self.chose_recipient_button = ChooseRecipientButton(self.driver)
self.accounts_button = AccountsButton(self.driver)
self.enter_recipient_address_button = EnterRecipientAddressButton(self.driver)
self.scan_qr_code_button = ScanQRCodeButton(self.driver)
self.enter_recipient_address_input = EnterRecipientAddressInput(self.driver)
self.first_recipient_button = FirstRecipient(self.driver)
self.enter_recipient_address_text = EnterRecipientAddressInputText(self.driver)
self.recent_recipients_button = RecentRecipientsButton(self.driver)
self.amount_edit_box = AmountEditBox(self.driver)
self.set_max_button = SetMaxButton(self.driver)
self.validation_error_element = ValidationIconOnSendTransaction(self.driver)
self.accounts_button = Button(self.driver, translation_id="my-accounts")
self.enter_recipient_address_button = Button(self.driver, accessibility_id="choose-recipient-recipient-code")
self.scan_qr_code_button = Button(self.driver, accessibility_id="scan-contact-code-button")
self.enter_recipient_address_input = EditBox(self.driver, accessibility_id="recipient-address-input")
self.first_recipient_button = Button(self.driver, accessibility_id="chat-icon")
self.enter_recipient_address_text = Text(self.driver, xpath="//*[@content-desc='choose-recipient-button']//android.widget.TextView")
self.network_fee_button = NetworkFeeButton(self.driver)
self.transaction_fee_button = TransactionFeeButton(self.driver)
self.transaction_fee_total_value = TransactionFeeTotalValue(self.driver)
self.gas_limit_input = GasLimitInput(self.driver)
self.recent_recipients_button = Button(self.driver, translation_id="recent-recipients")
self.amount_edit_box = AmountEditBox(self.driver)
self.set_max_button = Button(self.driver, translation_id="set-max")
self.validation_error_element = Text(self.driver, xpath="//*[@content-desc='custom-gas-fee']/../android.view.ViewGroup//*[@content-desc='icon']")
self.network_fee_button = Button(self.driver, accessibility_id="custom-gas-fee")
self.transaction_fee_button = Button(self.driver, accessibility_id="transaction-fee-button")
self.transaction_fee_total_value = Text(self.driver, translation_id="wallet-transaction-total-fee", suffix="//following::android.widget.TextView[1]")
self.gas_limit_input = EditBox(self.driver, prefix="(", translation_id="gas-limit", suffix="/..//android.widget.EditText)[1]")
self.gas_price_input = GasPriceInput(self.driver)
self.total_fee_input = TotalFeeInput(self.driver)
self.total_fee_input = EditBox(self.driver, translation_id="wallet-transaction-total-fee", suffix="/following-sibling::android.widget.TextView")
self.update_fee_button = UpdateFeeButton(self.driver)
self.cancel_button = CancelButton(self.driver)
self.sign_transaction_button = SignTransactionButton(self.driver)
self.sign_transaction_button = Button(self.driver, accessibility_id="send-transaction-bottom-sheet")
self.sign_with_keycard_button = SignWithKeycardButton(self.driver)
self.sign_with_password = SignWithPasswordButton(self.driver)
self.sign_button = SignButton(self.driver)
self.sign_in_phrase_text = SignInPhraseText(self.driver)
self.password_input = PasswordInput(self.driver)
self.enter_password_input = EnterPasswordInput(self.driver)
self.got_it_button = GotItButton(self.driver)
self.sign_with_password = Button(self.driver, translation_id="sign-with-password")
self.sign_button = Button(self.driver, translation_id="transactions-sign")
self.sign_in_phrase_text = Text(self.driver, accessibility_id="signing-phrase-text")
self.enter_password_input = EditBox(self.driver, accessibility_id="enter-password-input")
self.got_it_button = Button(self.driver, accessibility_id="got-it-button")
self.select_asset_button = SelectAssetButton(self.driver)
self.asset_text = AssetText(self.driver)
self.recipient_text = RecipientText(self.driver)
self.select_asset_button = Button(self.driver, accessibility_id="choose-asset-button")
self.asset_text = Text(self.driver, xpath="//*[@content-desc='choose-asset-button']//android.widget.TextView")
self.recipient_text = Text(self.driver, xpath="//*[@content-desc='choose-recipient-button']//android.widget.TextView")
self.error_dialog = ErrorDialog(self.driver)
self.share_button = Button(self.driver, accessibility_id="share-address-button")
self.share_button = ShareButton(self.driver)
self.onboarding_message = OnboardingMessage(self.driver)
self.onboarding_message = Text(self.driver, translation_id="this-is-you-signing")
self.validation_warnings = ValidationWarnings(self.driver)
self.eth_asset_in_select_asset_bottom_sheet_button = ETHroAssetButtonInSelectAssetBottomSheet(self.driver)
self.eth_asset_in_select_asset_bottom_sheet_button = Button(self.driver, accessibility_id=":ETH-asset-value")
# Elements for commands in 1-1 chat
self.select_button = SelectButton(self.driver)
self.request_transaction_button = RequestTransactionButtonBottomSheet(self.driver)
self.select_button = Button(self.driver, accessibility_id="select-account-bottom-sheet")
self.request_transaction_button = Button(self.driver, accessibility_id="request-transaction-bottom-sheet")
# Elements on set recipient screen
self.recipient_add_to_favorites = RecipientAddToFavoritesButton(self.driver)
self.recipient_done = RecipientDoneButton(self.driver)
self.new_favorite_name_input = NewFavoriteNameInput(self.driver)
self.new_favorite_add_favorite = NewFavoriteAddFavorite(self.driver)
self.recipient_add_to_favorites = Button(self.driver, accessibility_id="participant-add-to-favs")
self.recipient_done = Button(self.driver, accessibility_id="participant-done")
self.new_favorite_name_input = EditBox(self.driver, accessibility_id="fav-name")
self.new_favorite_add_favorite = Button(self.driver, accessibility_id="add-fav")
def complete_onboarding(self):
if self.onboarding_message.is_element_displayed():
from views.wallet_view import WalletView
wallet_view = WalletView(self.driver)
wallet_view.ok_got_it_button.click()
def set_recipient_address(self, address):
self.driver.info("**Setting recipient address to %s**" % address)
self.chose_recipient_button.click()
self.enter_recipient_address_input.set_value(address)
self.enter_recipient_address_input.click()
self.done_button.click_until_absense_of_element(self.done_button)
def sign_transaction(self, sender_password: str = common_password, keycard=False, default_gas_price=True):
self.driver.info("**Signing transaction (keycard:%s, default_gas_price:%s)" % (str(keycard), str(default_gas_price)))
if not default_gas_price:
self.network_fee_button.click()
default_gas_price = self.gas_price_input.text
@ -394,27 +152,33 @@ class SendTransactionView(BaseView):
self.ok_button.wait_for_element(120)
if self.element_by_text_part('Transaction failed').is_element_displayed():
self.driver.fail('Transaction failed')
self.driver.info("**Transaction is signed!")
self.ok_button.click()
def get_transaction_fee_total(self):
self.driver.info("**Getting transaction fee")
self.network_fee_button.click_until_presence_of_element(self.gas_limit_input)
fee_value = self.transaction_fee_total_value.text.split()[0]
self.update_fee_button.click()
return fee_value
def get_formatted_recipient_address(self, address):
@staticmethod
def get_formatted_recipient_address(address):
return address[:6] + '' + address[-4:]
def get_username_in_transaction_bottom_sheet_button(self, username_part):
return UserNameInSendTransactionBottomSheet(self.driver, username_part)
self.driver.info("**Getting username by '%s' in transaction fee bottom sheet" % username_part)
return SilentButton(self.driver, xpath="//*[@content-desc='amount-input']/..//*[starts-with(@text,'%s')]" % username_part)
def get_account_in_select_account_bottom_sheet_button(self, account_name):
return AccountNameInSelectAccountBottomSheet(self.driver, account_name)
self.driver.info("**Getting account by '%s' in transaction fee bottom sheet" % account_name)
return SilentButton(self.driver, translation_id="select-account", suffix="/..//*[starts-with(@text,'%s')]" % account_name)
def get_validation_icon(self, field='Network fee'):
return ValidationErrorOnSendTransaction(self.driver, field)
def get_values_from_send_transaction_bottom_sheet(self, gas=False):
self.driver.info("**Getting values from send transaction bottom sheet")
data = {
'amount': self.amount_edit_box.text,
'asset': self.asset_text.text,
@ -429,6 +193,7 @@ class SendTransactionView(BaseView):
return data
def add_to_favorites(self, name):
self.driver.info("**Adding '%s' to favorite recipients" % name)
self.recipient_add_to_favorites.click()
self.new_favorite_name_input.set_value(name)
self.new_favorite_add_favorite.click()

View File

@ -2,37 +2,29 @@ from appium.webdriver.common.touch_action import TouchAction
from selenium.common.exceptions import NoSuchElementException
from tests import common_password
from views.base_element import BaseButton, BaseEditBox, BaseText
from views.base_element import Button, EditBox, Text
from views.base_view import BaseView
class MultiAccountButton(BaseButton):
class Username(BaseText):
class MultiAccountButton(Button):
class Username(Text):
def __init__(self, driver, locator_value):
super(MultiAccountButton.Username, self).__init__(driver)
self.locator = self.Locator.xpath_selector(locator_value + "//android.widget.TextView[@content-desc='username']")
super(MultiAccountButton.Username, self).__init__(driver,
xpath="%s//android.widget.TextView[@content-desc='username']" % locator_value)
def __init__(self, driver, position=1):
super(MultiAccountButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='select-account-button-%s']" % position)
self.username = self.Username(driver, self.locator.value)
super(MultiAccountButton, self).__init__(driver,
xpath="//*[@content-desc='select-account-button-%s']" % position)
self.username = self.Username(driver, self.locator)
class MultiAccountOnLoginButton(BaseButton):
class MultiAccountOnLoginButton(Button):
def __init__(self, driver, position=1):
super(MultiAccountOnLoginButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//*[@content-desc='chat-icon'])[%s]/.." % position)
super(MultiAccountOnLoginButton, self).__init__(driver,
xpath="(//*[@content-desc='chat-icon'])[%s]/.." % position)
class RecoverWithKeycardButton(BaseButton):
class BeginRecoveryButton(Button):
def __init__(self, driver):
super(RecoverWithKeycardButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("recover-with-keycard-button")
class BeginRecoveryButton(BaseButton):
def __init__(self, driver):
super(BeginRecoveryButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Begin recovery")
super(BeginRecoveryButton, self).__init__(driver, translation_id="keycard-recovery-intro-button-text")
def navigate(self):
from views.keycard_view import KeycardView
@ -43,74 +35,27 @@ class BeginRecoveryButton(BaseButton):
return self.navigate()
class PairToThisDeviceButton(BaseButton):
class SignInButton(Button):
def __init__(self, driver):
super(PairToThisDeviceButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Pair to this device")
class PasswordInput(BaseEditBox):
def __init__(self, driver):
super(PasswordInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id("password-input")
class RecoverAccountPasswordInput(BaseEditBox):
def __init__(self, driver):
super(RecoverAccountPasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Password']"
"/following-sibling::android.view.ViewGroup/android.widget.EditText")
class FirstKeyForChatText(BaseText):
def __init__(self, driver):
super(FirstKeyForChatText, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="select-account-button-0"]//android.widget.TextView[1]')
class CreatePasswordInput(BaseEditBox):
def __init__(self, driver):
super(CreatePasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//android.widget.EditText[@content-desc='password-input'])[1]")
class ConfirmYourPasswordInput(BaseEditBox):
def __init__(self, driver):
super(ConfirmYourPasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("(//android.widget.EditText[@content-desc='password-input'])[2]")
class SignInButton(BaseButton):
def __init__(self, driver):
super(SignInButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Sign in' or @text='Submit']")
super(SignInButton, self).__init__(driver, translation_id="sign-in")
def navigate(self):
from views.home_view import HomeView
return HomeView(self.driver)
class LetsGoButton(BaseButton):
class AccessKeyButton(Button):
def __init__(self, driver):
super(LetsGoButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('lets-go-button')
super(AccessKeyButton, self).__init__(driver, translation_id="access-existing-keys")
def click(self):
self.scroll_to_element().click()
return self.navigate()
class RecoverAccessButton(BaseButton):
class KeycardKeyStorageButton(Button):
def __init__(self, driver):
super(RecoverAccessButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Recover access']")
def navigate(self):
from views.recover_access_view import RecoverAccessView
return RecoverAccessView(self.driver)
class KeycardKeyStorageButton(BaseButton):
def __init__(self, driver):
super(KeycardKeyStorageButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("select-storage-:advanced")
super(KeycardKeyStorageButton, self).__init__(driver, accessibility_id="select-storage-:advanced")
def navigate(self):
from views.keycard_view import KeycardView
@ -121,86 +66,9 @@ class KeycardKeyStorageButton(BaseButton):
return self.navigate()
class CreateMultiaccountButton(BaseButton):
class PrivacyPolicyLink(Button):
def __init__(self, driver):
super(CreateMultiaccountButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='Create multiaccount' or @text='Create new multiaccount']")
class YourKeysMoreIcon(BaseButton):
def __init__(self, driver):
super(YourKeysMoreIcon, self).__init__(driver)
self.locator = self.Locator.accessibility_id("your-keys-more-icon")
class GenerateKeyButton(BaseButton):
def __init__(self, driver):
super(GenerateKeyButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Generate keys']")
class GenerateNewKeyButton(BaseButton):
def __init__(self, driver):
super(GenerateNewKeyButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('generate-a-new-key')
class IHaveMultiaccountButton(RecoverAccessButton):
def __init__(self, driver):
super(IHaveMultiaccountButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='I already have a multiaccount']")
class AccessKeyButton(RecoverAccessButton):
def __init__(self, driver):
super(AccessKeyButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Access existing keys']")
class MaybeLaterButton(BaseButton):
def __init__(self, driver):
super(MaybeLaterButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("maybe-later")
class EnableNotificationsButton(BaseButton):
def __init__(self, driver):
super(EnableNotificationsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("enable-notifications")
class AddExistingMultiaccountButton(RecoverAccessButton):
def __init__(self, driver):
super(AddExistingMultiaccountButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Add existing multiaccount']")
class ConfirmPasswordInput(BaseEditBox):
def __init__(self, driver):
super(ConfirmPasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Confirm']"
"/following-sibling::android.view.ViewGroup/android.widget.EditText")
class NameInput(BaseEditBox):
def __init__(self, driver):
super(NameInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.EditText")
class OtherMultiAccountsButton(BaseButton):
def __init__(self, driver):
super(OtherMultiAccountsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Other multiaccounts')
class PrivacyPolicyLink(BaseButton):
def __init__(self, driver):
super(PrivacyPolicyLink, self).__init__(driver)
self.locator = self.Locator.text_part_selector('privacy policy')
super(PrivacyPolicyLink, self).__init__(driver, xpath="//*[contains(@text, 'privacy policy')]")
def click(self):
element = self.find_element()
@ -209,7 +77,7 @@ class PrivacyPolicyLink(BaseButton):
x = int(location['x'] + size['width'] * 0.9)
y = int(location['y'] + size['height'] * 0.8)
TouchAction(self.driver).tap(None, x, y).perform()
self.driver.info('Tap on %s' % self.name)
self.driver.info('Click on link %s' % self.name)
return self.navigate()
def navigate(self):
@ -223,47 +91,45 @@ class SignInView(BaseView):
super(SignInView, self).__init__(driver)
self.driver = driver
# if skip_popups:
# self.accept_agreements()
self.password_input = PasswordInput(self.driver)
self.recover_account_password_input = RecoverAccountPasswordInput(self.driver)
# self.accept_agreements()
self.password_input = EditBox(self.driver, accessibility_id="password-input")
self.sign_in_button = SignInButton(self.driver)
self.recover_access_button = RecoverAccessButton(self.driver)
# new design
self.create_multiaccount_button = CreateMultiaccountButton(self.driver)
self.i_have_multiaccount_button = IHaveMultiaccountButton(self.driver)
self.access_key_button = AccessKeyButton(self.driver)
self.generate_key_button = GenerateKeyButton(self.driver)
self.your_keys_more_icon = YourKeysMoreIcon(self.driver)
self.generate_new_key_button = GenerateNewKeyButton(self.driver)
self.add_existing_multiaccount_button = AddExistingMultiaccountButton(self.driver)
self.confirm_password_input = ConfirmPasswordInput(self.driver)
self.create_password_input = CreatePasswordInput(self.driver)
self.confirm_your_password_input = ConfirmYourPasswordInput(self.driver)
self.enable_notifications_button = EnableNotificationsButton(self.driver)
self.maybe_later_button = MaybeLaterButton(self.driver)
self.name_input = NameInput(self.driver)
self.other_multiaccounts_button = OtherMultiAccountsButton(self.driver)
self.multiaccount_button = MultiAccountButton(self.driver)
self.multi_account_on_login_button = MultiAccountOnLoginButton(self.driver)
self.access_key_button = AccessKeyButton(self.driver)
self.generate_key_button = Button(self.driver, translation_id="generate-new-key")
self.your_keys_more_icon = Button(self.driver, accessibility_id="your-keys-more-icon")
self.generate_new_key_button = Button(self.driver, accessibility_id="generate-a-new-key")
self.create_password_input = EditBox(self.driver,
xpath="(//android.widget.EditText[@content-desc='password-input'])[1]")
self.confirm_your_password_input = EditBox(self.driver,
xpath="(//android.widget.EditText[@content-desc='password-input'])[2]")
self.enable_notifications_button = Button(self.driver, accessibility_id="enable-notifications")
self.maybe_later_button = Button(self.driver, accessibility_id="maybe-later")
self.privacy_policy_link = PrivacyPolicyLink(self.driver)
self.lets_go_button = LetsGoButton(self.driver)
self.lets_go_button = Button(self.driver, accessibility_id="lets-go-button")
self.keycard_storage_button = KeycardKeyStorageButton(self.driver)
self.first_username_on_choose_chat_name = FirstKeyForChatText(self.driver)
self.first_username_on_choose_chat_name = Text(self.driver,
xpath="//*[@content-desc='select-account-button-0']//android.widget.TextView[1]")
#keycard recovery
self.recover_with_keycard_button = RecoverWithKeycardButton(self.driver)
self.recover_with_keycard_button = Button(self.driver, accessibility_id="recover-with-keycard-button")
self.begin_recovery_button = BeginRecoveryButton(self.driver)
self.pair_to_this_device_button = PairToThisDeviceButton(self.driver)
self.pair_to_this_device_button = Button(self.driver, translation_id="pair-card")
# restore from seed phrase
self.seedphrase_input = EditBox(self.driver, xpath="//android.widget.EditText")
self.enter_seed_phrase_button = Button(self.driver, accessibility_id="enter-seed-phrase-button")
self.reencrypt_your_key_button = Button(self.driver, translation_id="re-encrypt-key")
self.continue_custom_seed_phrase_button = Button(self.driver, accessibility_id="continue-custom-seed-phrase")
self.cancel_custom_seed_phrase_button = Button(self.driver, accessibility_id="cancel-custom-seed-phrase")
def create_user(self, password=common_password, keycard=False, enable_notifications=False, second_user=False):
self.driver.info("**Creating new multiaccount (password:%s, keycard:%s)**" % (password, str(keycard)))
if not second_user:
self.get_started_button.click()
self.generate_key_button.click_until_presence_of_element(self.next_button)
self.next_button.click_until_absense_of_element(self.element_by_text_part('Choose a chat name'))
self.next_button.click_until_absense_of_element(self.element_by_translation_id("intro-wizard-title2"))
if keycard:
keycard_flow = self.keycard_storage_button.click()
keycard_flow.confirm_pin_and_proceed()
@ -280,24 +146,26 @@ class SignInView(BaseView):
self.maybe_later_button.click_until_presence_of_element(self.lets_go_button)
self.lets_go_button.click_until_absense_of_element(self.lets_go_button)
self.profile_button.wait_for_visibility_of_element(30)
self.driver.info("**New multiaccount is created successfully!**")
return self.get_home_view()
def recover_access(self, passphrase: str, password: str = common_password, keycard=False, enable_notifications=False):
self.driver.info("**Recover access(password:%s, keycard:%s)**" % (password, str(keycard)))
self.get_started_button.click_until_presence_of_element(self.access_key_button)
recover_access_view = self.access_key_button.click()
recover_access_view.enter_seed_phrase_button.click()
recover_access_view.seedphrase_input.click()
recover_access_view.seedphrase_input.set_value(passphrase)
recover_access_view.next_button.click()
recover_access_view.reencrypt_your_key_button.click()
self.access_key_button.click()
self.enter_seed_phrase_button.click()
self.seedphrase_input.click()
self.seedphrase_input.set_value(passphrase)
self.next_button.click()
self.reencrypt_your_key_button.click()
if keycard:
keycard_flow = self.keycard_storage_button.click()
keycard_flow.confirm_pin_and_proceed()
else:
recover_access_view.next_button.click()
recover_access_view.create_password_input.set_value(password)
recover_access_view.confirm_your_password_input.set_value(password)
recover_access_view.next_button.click_until_presence_of_element(self.maybe_later_button)
self.next_button.click()
self.create_password_input.set_value(password)
self.confirm_your_password_input.set_value(password)
self.next_button.click_until_presence_of_element(self.maybe_later_button)
self.maybe_later_button.wait_for_element(30)
if enable_notifications:
self.enable_notifications_button.click_until_presence_of_element(self.lets_go_button)
@ -305,9 +173,11 @@ class SignInView(BaseView):
self.maybe_later_button.click_until_presence_of_element(self.lets_go_button)
self.lets_go_button.click()
self.profile_button.wait_for_visibility_of_element(30)
self.driver.info("**Multiaccount is recovered successfully!**")
return self.get_home_view()
def sign_in(self, password=common_password, keycard=False, position=1):
self.driver.info("**Sign in (password:%s, keycard:%s)**" % (password, str(keycard)))
self.multi_account_on_login_button.wait_for_visibility_of_element(30)
self.get_multiaccount_by_position(position).click()
@ -320,6 +190,7 @@ class SignInView(BaseView):
else:
self.password_input.set_value(password)
self.sign_in_button.click()
self.driver.info("**Signed in successfully!**")
return self.get_home_view()
@ -332,5 +203,6 @@ class SignInView(BaseView):
'Device %s: Unable to find multiaccount by position %s' % (self.driver.number, position)) from None
def open_weblink_and_login(self, url_weblink):
self.driver.info("**Open weblink %s**" % url_weblink)
self.open_universal_web_link(url_weblink)
self.sign_in()

View File

@ -1,51 +1,42 @@
import time
from selenium.common.exceptions import NoSuchElementException
from views.base_element import BaseElement, BaseButton, BaseText
from views.base_element import BaseElement, Button, Text
from views.base_view import BaseView
class OptionsButton(BaseButton):
class OptionsButton(Button):
def __init__(self, driver):
super(OptionsButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'(//android.view.ViewGroup[@content-desc="icon"])[2]')
super().__init__(driver, xpath="(//android.view.ViewGroup[@content-desc='icon'])[2]")
def click(self):
self.click_until_presence_of_element(OptionsButton.CopyTransactionHashButton(self.driver))
class CopyTransactionHashButton(BaseButton):
class CopyTransactionHashButton(Button):
def __init__(self, driver):
super(OptionsButton.CopyTransactionHashButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Copy transaction ID')
super().__init__(driver, translation_id="copy-transaction-hash")
class OpenOnEtherscanButton(BaseButton):
class OpenOnEtherscanButton(Button):
def __init__(self, driver):
super(OptionsButton.OpenOnEtherscanButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Open on Etherscan.io')
super().__init__(driver, translation_id="open-on-etherscan")
class TransactionTable(BaseElement):
def __init__(self, driver):
super(TransactionTable, self).__init__(driver)
super().__init__(driver, xpath="//android.widget.ScrollView")
self.driver = driver
self.locator = self.Locator.xpath_selector("//android.widget.ScrollView")
class TransactionElement(BaseButton):
class TransactionElement(Button):
def __init__(self, driver):
super(TransactionTable.TransactionElement, self).__init__(driver)
super().__init__(driver)
@staticmethod
def by_amount(driver, amount: str, asset):
element = TransactionTable.TransactionElement(driver)
element.locator = element.Locator.xpath_selector(
"(//android.widget.TextView[contains(@text,'%s %s')])" % (amount, asset))
element.locator = "(//android.widget.TextView[contains(@text,'%s %s')])" % (amount, asset)
return element
@staticmethod
def by_index(driver, index: int):
element = TransactionTable.TransactionElement(driver)
element.locator = element.Locator.xpath_selector(
'(//android.view.ViewGroup[@content-desc="transaction-item"])[%d]' % (index + 1))
element.locator = '(//android.view.ViewGroup[@content-desc="transaction-item"])[%d]' % (index + 1)
return element
class TransactionDetailsView(BaseView):
@ -61,11 +52,11 @@ class TransactionTable(BaseElement):
self.locators['sender_address'] = "//*[@content-desc='sender-address-text']"
self.locators['recipient_address'] = "//*[@content-desc='recipient-address-text'][last()]"
class DetailsTextElement(BaseText):
class DetailsTextElement(Text):
def __init__(self, driver, locator):
super(TransactionTable.TransactionElement.TransactionDetailsView.DetailsTextElement,
self).__init__(driver)
self.locator = self.Locator.xpath_selector(locator)
self.locator = locator
def text(self):
text = self.find_element().text
@ -85,12 +76,15 @@ class TransactionTable(BaseElement):
return self.TransactionDetailsView(self.driver)
def transaction_by_index(self, index: int):
self.driver.info('**Finding transaction by index %s**' % index)
return self.TransactionElement.by_index(self.driver, index=index)
def transaction_by_amount(self, amount: str, asset):
self.driver.info('**Finding transaction by amount %s**' % amount)
return self.TransactionElement.by_amount(self.driver, amount=amount.replace(',', '.'), asset=asset)
def find_transaction(self, amount: str, asset='ETH') -> TransactionElement:
self.driver.info('**Finding %s %s transaction**' % (amount, asset))
element = self.transaction_by_amount(amount=amount, asset=asset)
for i in range(9):
try:
@ -106,29 +100,10 @@ class TransactionTable(BaseElement):
def get_transactions_number(self):
element = self.TransactionElement(self.driver)
element.locator = element.Locator.xpath_selector('//android.view.ViewGroup[@content-desc="transaction-item"]')
element.locator = '//android.view.ViewGroup[@content-desc="transaction-item"]'
return len(element.wait_for_elements())
class FiltersButton(BaseButton):
def __init__(self, driver):
super(FiltersButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('filters-button')
class FilterCheckbox(BaseButton):
def __init__(self, driver, filter_name):
super(FilterCheckbox, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@text='%s']/following-sibling::*[@content-desc='checkbox']" % filter_name)
class TransactionsView(BaseView):
def __init__(self, driver):
super(TransactionsView, self).__init__(driver)
self.driver = driver
self.filters_button = FiltersButton(self.driver)
super().__init__(driver)
self.transactions_table = TransactionTable(self.driver)
def filter_checkbox(self, filter_name):
return FilterCheckbox(self.driver, filter_name)

View File

@ -1,491 +1,162 @@
import time
from tests import common_password
from views.base_element import BaseButton, BaseText, BaseEditBox
from views.base_element import Button, Text, EditBox, SilentButton
from views.base_view import BaseView
class SendRequestButton(BaseButton):
class TransactionHistoryButton(Button):
def __init__(self, driver):
super(SendRequestButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('sent-request-button')
class ChooseRecipientButton(BaseButton):
def __init__(self, driver):
super(ChooseRecipientButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('choose-recipient-button')
class TransactionHistoryButton(BaseButton):
def __init__(self, driver):
super(TransactionHistoryButton, self).__init__(driver)
self.locator = self.Locator.text_selector("History")
super().__init__(driver, accessibility_id="History-item-button")
def navigate(self):
from views.transactions_view import TransactionsView
return TransactionsView(self.driver)
class ChooseFromContactsButton(BaseButton):
class SignInPhraseText(Text):
def __init__(self, driver):
super(ChooseFromContactsButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Choose From Contacts")
class ScanQRButton(BaseButton):
def __init__(self, driver):
super(ScanQRButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id("accounts-qr-code")
class AssetText(BaseText):
def __init__(self, driver, asset):
super(AssetText, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.view.ViewGroup[@content-desc=':%s-asset-value']"
"//android.widget.TextView[1]" % asset)
class AssetFullNameInAssets(BaseText):
def __init__(self, driver):
super(AssetFullNameInAssets, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="checkbox"]/../../android.widget.TextView[1]')
class AssetSymbolInAssets(BaseText):
def __init__(self, driver):
super(AssetSymbolInAssets, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="checkbox"]/../../android.widget.TextView[2]')
class CurrencyItemText(BaseText):
def __init__(self, driver):
super(CurrencyItemText, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="currency-item"]//android.widget.TextView')
class UsdTotalValueText(BaseText):
def __init__(self, driver):
super(UsdTotalValueText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('total-amount-value-text')
class SendTransactionRequestButton(BaseButton):
def __init__(self, driver):
super(SendTransactionRequestButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('sent-transaction-request-button')
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class OptionsButton(BaseButton):
def __init__(self, driver):
super(OptionsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('options-menu-button')
class AccountOptionsButton(BaseButton):
def __init__(self, driver, account_name):
super(AccountOptionsButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//*[@text="%s"]/../..//*[@content-desc="icon"])[2]' % account_name)
class ManageAssetsButton(BaseButton):
def __init__(self, driver):
super(ManageAssetsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('wallet-manage-assets')
class ScanTokensButton(BaseButton):
def __init__(self, driver):
super(ScanTokensButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('wallet-scan-token')
class STTCheckBox(BaseButton):
def __init__(self, driver):
super(STTCheckBox, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='STT']"
"/../android.view.ViewGroup[@content-desc='checkbox']")
class QRCodeImage(BaseButton):
def __init__(self, driver):
super(QRCodeImage, self).__init__(driver)
self.locator = self.Locator.accessibility_id('qr-code-image')
class AddressText(BaseButton):
def __init__(self, driver):
super(AddressText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('address-text')
class SetUpButton(BaseButton):
def __init__(self, driver):
super(SetUpButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Lets get set up")
class SetCurrencyButton(BaseButton):
def __init__(self, driver):
super(SetCurrencyButton, self).__init__(driver)
self.locator = self.Locator.text_selector("Set currency")
class SignInPhraseText(BaseText):
def __init__(self, driver):
super(SignInPhraseText, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@text="This is your signing phrase"]'
'//following-sibling::*[2]/android.widget.TextView')
@property
def string(self):
return self.text
super().__init__(driver, translation_id="this-is-you-signing", suffix="//following-sibling::*[2]/android.widget.TextView")
@property
def list(self):
return self.string.split()
return self.text.split()
class RemindMeLaterButton(BaseButton):
def __init__(self, driver):
super(RemindMeLaterButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Show me this again']")
class AssetTextElement(BaseText):
class AssetCheckBox(SilentButton):
def __init__(self, driver, asset_name):
super(AssetTextElement, self).__init__(driver)
self.locator = self.Locator.text_part_selector(asset_name)
class CollectibleTextElement(BaseText):
def __init__(self, driver, collectible_name):
super().__init__(driver)
self.locator = self.Locator.accessibility_id('%s-collectible-value-text' % collectible_name.lower())
class AssetCheckBox(BaseButton):
def __init__(self, driver, asset_name):
super(AssetCheckBox, self).__init__(driver)
self.asset_name = asset_name
self.locator = self.Locator.xpath_selector("//*[@text='%s']" % self.asset_name)
super().__init__(driver, xpath="//*[@text='%s']" % asset_name)
def click(self):
self.scroll_to_element(12).click()
self.driver.info('Click %s asset checkbox' % self.asset_name)
class TotalAmountText(BaseText):
class BackupRecoveryPhrase(Button):
def __init__(self, driver):
super(TotalAmountText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('total-amount-value-text')
class CurrencyText(BaseText):
def __init__(self, driver):
super(CurrencyText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('total-amount-currency-text')
class CollectiblesButton(BaseButton):
def __init__(self, driver):
super(CollectiblesButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Collectibles')
class NumberInCollectiblesButton(BaseButton):
def __init__(self, driver, name):
super(NumberInCollectiblesButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@text="%s"]//following-sibling::android.widget.TextView' % name)
class ViewInCryptoKittiesButton(BaseButton):
def __init__(self, driver):
super(ViewInCryptoKittiesButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('open-collectible-button')
def navigate(self):
from views.web_views.base_web_view import BaseWebView
return BaseWebView(self.driver)
def click(self):
self.wait_for_element(60).click()
self.driver.info('Tap on View in CryptoKitties')
return self.navigate()
class BackupRecoveryPhrase(BaseButton):
def __init__(self, driver):
super(BackupRecoveryPhrase, self).__init__(driver)
self.locator = self.Locator.text_selector('Back up your seed phrase')
super().__init__(driver, translation_id="wallet-backup-recovery-title")
def navigate(self):
from views.profile_view import ProfileView
return ProfileView(self.driver)
class BackupRecoveryPhraseWarningText(BaseButton):
def __init__(self, driver):
super(BackupRecoveryPhraseWarningText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('back-up-your-seed-phrase-warning')
class MultiaccountMoreOptions(BaseButton):
def __init__(self, driver):
super(MultiaccountMoreOptions, self).__init__(driver)
self.locator = self.Locator.accessibility_id('accounts-more-options')
class AccountElementButton(BaseButton):
class AccountElementButton(SilentButton):
def __init__(self, driver, account_name):
super(AccountElementButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"//*[@content-desc='accountcard%s']" % account_name)
super().__init__(driver, xpath="//*[@content-desc='accountcard%s']" % account_name)
def color_matches(self, expected_color_image_name: str):
amount_text = BaseText(self.driver)
amount_text.locator = amount_text.Locator.xpath_selector(self.locator.value + "//*[@content-desc='account-total-value']")
amount_text = Text(self.driver, xpath="%s//*[@content-desc='account-total-value']" % self.locator)
return amount_text.is_element_image_equals_template(expected_color_image_name)
class StatusAccountTotalValueText(BaseText):
class SendTransactionButton(Button):
def __init__(self, driver):
super(StatusAccountTotalValueText, self).__init__(driver)
self.locator = self.Locator.accessibility_id('account-total-value')
class SendTransactionButton(BaseButton):
def __init__(self, driver):
super(SendTransactionButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Send']")
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
def click(self):
self.find_element().click()
self.driver.info('Tap on %s' % self.name)
return self.navigate()
class ReceiveTransactionButton(BaseButton):
def __init__(self, driver):
super(ReceiveTransactionButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Receive']")
super().__init__(driver, translation_id="wallet-send")
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class AddCustomTokenButton(BaseButton):
class ReceiveTransactionButton(Button):
def __init__(self, driver):
super(AddCustomTokenButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Add custom token']")
super().__init__(driver, translation_id="receive")
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class AddCustomTokenButton(Button):
def __init__(self, driver):
super().__init__(driver, translation_id="add-custom-token")
def navigate(self):
from views.add_custom_token_view import AddCustomTokenView
return AddCustomTokenView(self.driver)
class AddAccountButton(BaseButton):
class AccountColorButton(Button):
def __init__(self, driver):
super(AddAccountButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-new-account')
class GenerateAnAccountButton(BaseButton):
def __init__(self, driver):
super(GenerateAnAccountButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-sheet-generate')
class AddAWatchOnlyAddressButton(BaseButton):
def __init__(self, driver):
super(AddAWatchOnlyAddressButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-sheet-watch')
class EnterASeedPhraseButton(BaseButton):
def __init__(self, driver):
super(EnterASeedPhraseButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-sheet-seed')
class EnterAPrivateKeyButton(BaseButton):
def __init__(self, driver):
super(EnterAPrivateKeyButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-sheet-private-key')
class EnterAddressInput(BaseEditBox):
def __init__(self, driver):
super(EnterAddressInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-enter-watch-address')
class EnterSeedPhraseInput(BaseEditBox):
def __init__(self, driver):
super(EnterSeedPhraseInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-enter-seed')
class EnterPrivateKeyInput(BaseEditBox):
def __init__(self, driver):
super(EnterPrivateKeyInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-enter-private-key')
class DeleteAccountButton(BaseButton):
def __init__(self, driver):
super(DeleteAccountButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Delete account')
class EnterYourPasswordInput(BaseEditBox):
def __init__(self, driver):
super(EnterYourPasswordInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-enter-password')
class AccountNameInput(BaseEditBox):
def __init__(self, driver):
super(AccountNameInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('enter-account-name')
class AccountColorButton(BaseButton):
def __init__(self, driver):
super(AccountColorButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Account color']"
"/following-sibling::android.view.ViewGroup[1]")
super().__init__(driver, translation_id="account-color", suffix="/following-sibling::android.view.ViewGroup[1]")
def select_color_by_position(self, position: int):
self.click()
self.driver.find_element_by_xpath(
"((//android.widget.ScrollView)[last()]/*/*)[%s]" % str(position+1)).click()
# Add account on Generate An Account screen
class AddAccountGenerateAnAccountButton(BaseButton):
def __init__(self, driver):
super(AddAccountGenerateAnAccountButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-account-add-account-button')
class AccountSettingsButton(BaseButton):
def __init__(self, driver):
super(AccountSettingsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Account settings')
class ApplySettingsButton(BaseButton):
def __init__(self, driver):
super(ApplySettingsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Apply')
class WalletView(BaseView):
def __init__(self, driver):
super(WalletView, self).__init__(driver)
self.driver = driver
super().__init__(driver)
self.send_transaction_button = SendTransactionButton(self.driver)
self.transaction_history_button = TransactionHistoryButton(self.driver)
self.usd_total_value = UsdTotalValueText(self.driver)
self.usd_total_value = Text(self.driver, accessibility_id="total-amount-value-text")
self.send_transaction_request = SendTransactionRequestButton(self.driver)
self.receive_transaction_button = ReceiveTransactionButton(self.driver)
self.send_request_button = SendRequestButton(self.driver)
self.options_button = OptionsButton(self.driver)
self.manage_assets_button = ManageAssetsButton(self.driver)
self.scan_tokens_button = ScanTokensButton(self.driver)
self.stt_check_box = STTCheckBox(self.driver)
self.all_assets_full_names = AssetFullNameInAssets(self.driver)
self.all_assets_symbols = AssetSymbolInAssets(self.driver)
self.currency_item_text = CurrencyItemText(self.driver)
self.options_button = Button(self.driver, accessibility_id="options-menu-button")
self.manage_assets_button = Button(self.driver, accessibility_id="wallet-manage-assets")
self.scan_tokens_button = Button(self.driver, accessibility_id="wallet-scan-token")
self.stt_check_box = Button(self.driver, xpath="//*[@text='STT']/../android.view.ViewGroup[@content-desc='checkbox']")
self.all_assets_full_names = Text(self.driver, xpath="//*[@content-desc='checkbox']/../../android.widget.TextView[1]")
self.all_assets_symbols = Button(self.driver, xpath="//*[@content-desc='checkbox']/../../android.widget.TextView[2]")
self.currency_item_text = Text(self.driver, xpath="//*[@content-desc='currency-item']//android.widget.TextView")
self.qr_code_image = QRCodeImage(self.driver)
self.address_text = AddressText(self.driver)
self.qr_code_image = Button(self.driver, accessibility_id="qr-code-image")
self.address_text = Text(self.driver, accessibility_id="address-text")
self.set_up_button = SetUpButton(self.driver)
self.sign_in_phrase = SignInPhraseText(self.driver)
self.remind_me_later_button = RemindMeLaterButton(self.driver)
self.remind_me_later_button = Button(self.driver, translation_id="remind-me-later")
self.total_amount_text = TotalAmountText(self.driver)
self.currency_text = CurrencyText(self.driver)
self.total_amount_text = Text(self.driver, accessibility_id="total-amount-value-text")
self.currency_text = Text(self.driver, accessibility_id="total-amount-currency-text")
self.backup_recovery_phrase = BackupRecoveryPhrase(self.driver)
self.backup_recovery_phrase_warning_text = BackupRecoveryPhraseWarningText(self.driver)
self.backup_recovery_phrase_warning_text = Text(self.driver, accessibility_id="back-up-your-seed-phrase-warning")
self.add_custom_token_button = AddCustomTokenButton(self.driver)
# elements for multiaccount
self.multiaccount_more_options = MultiaccountMoreOptions(self.driver)
self.multiaccount_more_options = Button(self.driver, accessibility_id="accounts-more-options")
self.accounts_status_account = AccountElementButton(self.driver, account_name=self.status_account_name)
self.collectibles_button = CollectiblesButton(self.driver)
self.cryptokitties_in_collectibles_number = NumberInCollectiblesButton(self.driver, 'CryptoKitties')
self.view_in_cryptokitties_button = ViewInCryptoKittiesButton(self.driver)
self.set_currency_button = SetCurrencyButton(self.driver)
self.add_account_button = AddAccountButton(self.driver)
self.generate_an_account_button = GenerateAnAccountButton(self.driver)
self.add_watch_only_address_button = AddAWatchOnlyAddressButton(self.driver)
self.enter_a_seed_phrase_button = EnterASeedPhraseButton(self.driver)
self.enter_a_private_key_button = EnterAPrivateKeyButton(self.driver)
self.enter_address_input = EnterAddressInput(self.driver)
self.enter_seed_phrase_input = EnterSeedPhraseInput(self.driver)
self.enter_a_private_key_input = EnterPrivateKeyInput(self.driver)
self.delete_account_button = DeleteAccountButton(self.driver)
self.enter_your_password_input = EnterYourPasswordInput(self.driver)
self.account_name_input = AccountNameInput(self.driver)
self.collectibles_button = Button(self.driver, translation_id="wallet-collectibles")
self.cryptokitties_in_collectibles_number = Text(self.driver, xpath="//*[@text='CryptoKitties']//following-sibling::android.widget.TextView")
self.set_currency_button = Button(self.driver, translation_id="set-currency")
self.add_account_button = Button(self.driver, accessibility_id="add-new-account")
self.generate_an_account_button = Button(self.driver, accessibility_id="add-account-sheet-generate")
self.add_watch_only_address_button = Button(self.driver, accessibility_id="add-account-sheet-watch")
self.enter_a_seed_phrase_button = Button(self.driver, accessibility_id="add-account-sheet-seed")
self.enter_a_private_key_button = Button(self.driver, accessibility_id="add-account-sheet-private-key")
self.enter_address_input = EditBox(self.driver, accessibility_id="add-account-enter-watch-address")
self.enter_seed_phrase_input = EditBox(self.driver, accessibility_id="add-account-enter-seed")
self.enter_a_private_key_input = EditBox(self.driver, accessibility_id="add-account-enter-private-key")
self.delete_account_button = Button(self.driver, translation_id="delete-account")
self.enter_your_password_input = EditBox(self.driver, accessibility_id="add-account-enter-password")
self.account_name_input = EditBox(self.driver, accessibility_id="enter-account-name")
self.account_color_button = AccountColorButton(self.driver)
self.add_account_generate_account_button = AddAccountGenerateAnAccountButton(self.driver)
self.status_account_total_usd_value = StatusAccountTotalValueText(self.driver)
self.scan_qr_button = ScanQRButton(self.driver)
self.add_account_generate_account_button = Button(self.driver, accessibility_id="add-account-add-account-button")
self.status_account_total_usd_value = Text(self.driver, accessibility_id="account-total-value")
self.scan_qr_button = Button(self.driver, accessibility_id="accounts-qr-code")
# individual account settings
self.account_settings_button = AccountSettingsButton(self.driver)
self.apply_settings_button = ApplySettingsButton(self.driver)
def get_usd_total_value(self):
import re
return float(re.sub('[~,]', '', self.usd_total_value.text))
def get_account_options_by_name(self, account_name=''):
account_name = self.status_account_name if not account_name else account_name
return AccountOptionsButton(self.driver, account_name)
def get_asset_amount_by_name(self, asset: str):
asset_value = AssetText(self.driver, asset)
asset_value.scroll_to_element()
try:
return float(asset_value.text.split()[0])
except ValueError:
return 0.0
def verify_currency_balance(self, expected_rate: int, errors: list):
usd = self.get_usd_total_value()
eth = self.get_asset_amount_by_name('ETH')
expected_usd = round(eth * expected_rate, 2)
percentage_diff = abs((usd - expected_usd) / ((usd + expected_usd) / 2)) * 100
if percentage_diff > 2:
errors.append('Difference between current (%s) and expected (%s) USD balance > 2%%!!' % (usd, expected_usd))
else:
self.driver.info('Current USD balance %s is ok' % usd)
self.account_settings_button = Button(self.driver, translation_id="account-settings")
self.apply_settings_button = Button(self.driver, translation_id="apply")
def wait_balance_is_equal_expected_amount(self, asset ='ETH', expected_balance=0.1, wait_time=300):
counter = 0
while True:
if counter >= wait_time:
self.driver.fail('Balance is not changed during %s seconds!' % wait_time)
self.driver.fail('**Balance is not changed during %s seconds!**' % wait_time)
elif self.get_asset_amount_by_name(asset) != expected_balance:
counter += 10
time.sleep(10)
self.swipe_down()
self.driver.info('Waiting %s seconds for %s balance update to be equal to %s' % (counter,asset, expected_balance))
self.driver.info('**Waiting %s seconds for %s balance update to be equal to %s**' % (counter,asset, expected_balance))
else:
self.driver.info('Balance for %s is equal to %s' % (asset, expected_balance))
self.driver.info('**Balance for %s is equal to %s**' % (asset, expected_balance))
return
def wait_balance_is_changed(self, asset ='ETH', initial_balance=0, wait_time=400, scan_tokens=False):
self.driver.info('**Waiting %ss for %s updated balance**' % (wait_time, asset))
counter = 0
while True:
if counter >= wait_time:
@ -497,28 +168,30 @@ class WalletView(BaseView):
counter += 10
time.sleep(10)
[self.wallet_button.click() for _ in range(2)]
self.driver.info('Waiting %s seconds for %s to update' % (counter,asset))
self.driver.info('*Waiting %ss for %s updated balance*' % (counter,asset))
elif not self.asset_by_name(asset).is_element_present(10):
counter += 10
time.sleep(10)
if scan_tokens:
self.scan_tokens()
self.swipe_down()
self.driver.info('Waiting %s seconds for %s to display asset' % (counter, asset))
self.driver.info('*Waiting %s seconds for %s to display asset*' % (counter, asset))
else:
self.driver.info('Balance is updated!')
self.driver.info('**Balance is updated!**')
return self
def get_sign_in_phrase(self):
return ' '.join([element.text for element in self.sign_in_phrase.find_elements()])
def set_up_wallet(self):
phrase = self.sign_in_phrase.string
self.driver.info("**Setting up wallet**")
phrase = self.sign_in_phrase.text
self.ok_got_it_button.click()
return phrase
def get_wallet_address(self, account_name=''):
account_name = self.status_account_name if not account_name else account_name
self.driver.info("**Getting wallet address for '%s'**" % account_name)
self.wallet_account_by_name(account_name).click()
self.receive_transaction_button.click_until_presence_of_element(self.qr_code_image)
address = self.address_text.text
@ -526,25 +199,44 @@ class WalletView(BaseView):
return address
def wallet_account_by_name(self, account_name):
self.driver.info("*Getting '%s' wallet account*" % account_name)
return AccountElementButton(self.driver, account_name)
def get_asset_amount_by_name(self, asset: str):
self.driver.info("*Getting %s amount*" % asset)
asset_value = SilentButton(self.driver, xpath="//android.view.ViewGroup[@content-desc=':%s-asset-value']"
"//android.widget.TextView[1]" % asset)
asset_value.scroll_to_element()
try:
return float(asset_value.text.split()[0])
except ValueError:
return 0.0
def asset_by_name(self, asset_name):
return AssetTextElement(self.driver, asset_name)
self.driver.info("*Selecting %s asset*" % asset_name)
return SilentButton(self.driver, xpath="//*[contains(@text,'%s')]" % asset_name)
def asset_checkbox_by_name(self, asset_name):
self.driver.info("*Selecting %s asset checkbox by name*" % asset_name)
return AssetCheckBox(self.driver, asset_name)
def account_options_by_name(self, account_name):
return AccountOptionsButton(self.driver, account_name)
def get_account_options_by_name(self, account_name=''):
account_name = self.status_account_name if not account_name else account_name
self.driver.info("*Getting '%s'account options*" % account_name)
return SilentButton(self.driver, xpath="(//*[@text='%s']/../..//*[@content-desc='icon'])[2]" % account_name)
def select_asset(self, *args):
self.driver.info("**Selecting asset(s)**")
self.multiaccount_more_options.click()
self.manage_assets_button.click()
for asset in args:
self.asset_checkbox_by_name(asset).click()
self.cross_icon.click()
self.driver.info("**Assets are selected!**")
def scan_tokens(self, *args):
self.driver.info("**Scanning tokens**")
self.multiaccount_more_options.click()
self.scan_tokens_button.click()
counter = 0
@ -565,6 +257,7 @@ class WalletView(BaseView):
return self
def send_transaction(self, **kwargs):
self.driver.info("**Sending transaction**")
send_transaction_view = self.send_transaction_button.click()
send_transaction_view.select_asset_button.click()
asset_name = kwargs.get('asset_name', 'ETH').upper()
@ -589,39 +282,8 @@ class WalletView(BaseView):
sender_password=kwargs.get('sender_password', common_password))
return send_transaction_view
def receive_transaction(self, **kwargs):
self.receive_transaction_button.click()
send_transaction_view = self.send_transaction_request.click()
send_transaction_view.select_asset_button.click()
asset_name = kwargs.get('asset_name', 'ETH').upper()
asset_button = send_transaction_view.asset_by_name(asset_name)
send_transaction_view.select_asset_button.click_until_presence_of_element(asset_button)
asset_button.click()
send_transaction_view.amount_edit_box.click()
transaction_amount = str(kwargs.get('amount')) if kwargs.get('amount') else \
send_transaction_view.get_unique_amount()
send_transaction_view.amount_edit_box.set_value(transaction_amount)
send_transaction_view.confirm()
send_transaction_view.chose_recipient_button.click()
recipient = kwargs.get('recipient')
send_transaction_view.recent_recipients_button.click()
recent_recipient = send_transaction_view.element_by_text(recipient)
send_transaction_view.recent_recipients_button.click_until_presence_of_element(recent_recipient)
recent_recipient.click()
self.send_request_button.click()
def collectible_amount_by_name(self, name):
elm = CollectibleTextElement(self.driver, name)
elm.scroll_to_element()
return elm.text
def set_currency(self, desired_currency='EUR'):
"""
:param desired_currency: defines a currency designator which is expressed by ISO 4217 code
"""
self.driver.info("**Setting '%s' currency**" % desired_currency)
self.multiaccount_more_options.click_until_presence_of_element(self.set_currency_button)
self.set_currency_button.click()
desired_currency = self.element_by_text_part(desired_currency)
@ -629,9 +291,11 @@ class WalletView(BaseView):
desired_currency.click()
def get_account_by_name(self, account_name: str):
self.driver.info("**Getting account '%s'**" % account_name)
return AccountElementButton(self.driver, account_name)
def add_account(self, account_name: str, password: str = common_password, keycard=False):
self.driver.info("**Adding account '%s'**" % account_name)
self.add_account_button.click()
self.generate_an_account_button.click()
self.account_name_input.send_keys(account_name)

View File

@ -1,165 +1,37 @@
import time
import pytest
from views.base_element import BaseElement, BaseEditBox, BaseButton, BaseText
from views.base_element import EditBox, Button
from views.base_view import BaseView
class ProgressBarIcon(BaseElement):
def __init__(self, driver):
super(ProgressBarIcon, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.ProgressBar")
class CloseTabButton(BaseElement):
def __init__(self, driver, name):
super(CloseTabButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[contains(@text, '%s')]/../../../../*[@content-desc='empty-tab']"
% name)
class WebLinkEditBox(BaseEditBox):
def __init__(self, driver):
super(WebLinkEditBox, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.EditText")
class BackToHomeButton(BaseButton):
def __init__(self, driver):
super(BackToHomeButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[1]')
class BrowserPreviousPageButton(BaseButton):
def __init__(self, driver):
super(BrowserPreviousPageButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('previous-page-button')
class BrowserNextPageButton(BaseButton):
def __init__(self, driver):
super(BrowserNextPageButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('next-page-button')
class BrowserRefreshPageButton(BaseButton):
def __init__(self, driver):
super(BrowserRefreshPageButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('refresh-page-button')
class WebViewBrowserButton(BaseButton):
def __init__(self, driver):
super(WebViewBrowserButton, self).__init__(driver)
self.locator = self.Locator.text_part_selector('WebView Browser Tester')
class AlwaysButton(BaseButton):
def __init__(self, driver):
super(AlwaysButton, self).__init__(driver)
self.locator = self.Locator.text_part_selector('ALWAYS')
class WebViewMenuButton(BaseButton):
def __init__(self, driver):
super(WebViewMenuButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('chat-menu-button')
class URLEditBoxLockIcon(BaseButton):
def __init__(self, driver):
super(URLEditBoxLockIcon, self).__init__(driver)
self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[2]')
class PolicySummary(BaseElement):
def __init__(self, driver):
super(PolicySummary, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//*[@content-desc="Policy summary"] | //*[@text="Policy summary"]')
class ShareUrlButton(BaseButton):
def __init__(self, driver):
super(ShareUrlButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('share')
class GoBackButton(BaseButton):
def __init__(self, driver):
super(GoBackButton, self).__init__(driver)
self.locator = self.Locator.translation_id('browsing-site-blocked-go-back')
class OptionsButton(BaseButton):
def __init__(self, driver):
super(OptionsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('browser-options')
class OpenTabsButton(BaseButton):
def __init__(self, driver):
super(OpenTabsButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('browser-open-tabs')
class AddRemoveFavoritesButton(BaseButton):
def __init__(self, driver):
super(AddRemoveFavoritesButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('add-remove-fav')
class BookmarkNameInput(BaseEditBox):
def __init__(self, driver):
super(BookmarkNameInput, self).__init__(driver)
self.locator = self.Locator.accessibility_id('bookmark-input')
class SaveBookmarkButton(BaseEditBox):
def __init__(self, driver):
super(SaveBookmarkButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('save-bookmark')
class CloseAllButton(BaseButton):
def __init__(self, driver):
super(CloseAllButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('close-all')
class ContinueAnywayButton(BaseButton):
def __init__(self, driver):
super(ContinueAnywayButton, self).__init__(driver)
self.locator = self.Locator.translation_id("continue-anyway")
class BaseWebView(BaseView):
def __init__(self, driver):
super(BaseWebView, self).__init__(driver)
self.driver = driver
super().__init__(driver)
self.progress_bar_icon = ProgressBarIcon(self.driver)
self.progress_bar_icon = Button(self.driver, xpath="//android.widget.ProgressBar")
self.url_edit_box_lock_icon = Button(self.driver, xpath="'(//android.view.ViewGroup[@content-desc='icon'])[2]")
self.policy_summary = Button(self.driver, xpath="//*[@content-desc='Policy summary'] | //*[@text='Policy summary']")
self.back_to_home_button = Button(self.driver, xpath="(//android.view.ViewGroup[@content-desc='icon'])[1]")
self.browser_previous_page_button = Button(self.driver, accessibility_id="previous-page-button")
self.browser_next_page_button = Button(self.driver, accessibility_id="next-page-button")
self.url_edit_box_lock_icon = URLEditBoxLockIcon(self.driver)
self.policy_summary = PolicySummary(self.driver)
self.back_to_home_button = BackToHomeButton(self.driver)
self.browser_previous_page_button = BrowserPreviousPageButton(self.driver)
self.browser_next_page_button = BrowserNextPageButton(self.driver)
self.web_view_browser = WebViewBrowserButton(self.driver)
self.web_view_menu_button = WebViewMenuButton(self.driver)
self.always_button = AlwaysButton(self.driver)
self.browser_refresh_page_button = BrowserRefreshPageButton(self.driver)
self.share_url_button = ShareUrlButton(self.driver)
self.go_back_button = GoBackButton(self.driver)
self.options_button = OptionsButton(self.driver)
self.continue_anyway_button = ContinueAnywayButton(self.driver)
self.open_tabs_button = OpenTabsButton(self.driver)
self.close_all_button = CloseAllButton(self.driver)
self.web_view_browser = Button(self.driver, xpath="//*[contains(@text,'WebView Browser Tester')]")
self.always_button = Button(self.driver, xpath="//*[contains(@text,'ALWAYS')]")
self.browser_refresh_page_button = Button(self.driver, accessibility_id="refresh-page-button")
self.share_url_button = Button(self.driver, accessibility_id="share")
self.go_back_button = Button(self.driver, translation_id="browsing-site-blocked-go-back")
self.options_button = Button(self.driver, accessibility_id="browser-options")
self.continue_anyway_button = Button(self.driver, translation_id="continue-anyway")
self.open_tabs_button = Button(self.driver, accessibility_id="browser-open-tabs")
self.close_all_button = Button(self.driver, accessibility_id="close-all")
# bookmarks management
self.add_remove_favorites_button = AddRemoveFavoritesButton(self.driver)
self.bookmark_name_input = BookmarkNameInput(self.driver)
self.save_bookmark_button = SaveBookmarkButton(self.driver)
self.add_remove_favorites_button = Button(self.driver, accessibility_id="add-remove-fav")
self.bookmark_name_input = EditBox(self.driver, accessibility_id="bookmark-input")
self.save_bookmark_button = Button(self.driver, accessibility_id="save-bookmark")
def wait_for_d_aap_to_load(self, wait_time=35):
self.driver.info("**Waiting %ss for dapp to load**" % wait_time)
counter = 0
while self.progress_bar_icon.is_element_present(5):
time.sleep(1)
@ -168,6 +40,7 @@ class BaseWebView(BaseView):
self.driver.fail("Page is not loaded during %s seconds" % wait_time)
def open_in_webview(self):
self.driver.info("**Opening in webview**")
if self.web_view_browser.is_element_displayed():
self.web_view_browser.click()
if self.always_button.is_element_displayed():
@ -176,18 +49,22 @@ class BaseWebView(BaseView):
def remove_tab(self, name='', clear_all=False):
self.open_tabs_button.click()
if clear_all:
self.driver.info("**Closing all tabs**")
self.close_all_button.click()
else:
close_button = CloseTabButton(self.driver, name)
self.driver.info("**Removing '%s' from recent websites**")
close_button = Button(self.driver, xpath="//*[contains(@text, '%s')]/../../../../*[@content-desc='empty-tab']"% name)
close_button.scroll_to_element()
close_button.click()
def edit_bookmark_name(self, name):
self.driver.info("**Editing bookmark name to '%s'**" % name)
self.bookmark_name_input.clear()
self.bookmark_name_input.send_keys(name)
self.save_bookmark_button.click()
def add_to_bookmarks(self, name=''):
self.driver.info("**Adding '%s' to bookmarks**" % name)
self.options_button.click()
self.add_remove_favorites_button.click()
if name:

View File

@ -1,75 +1,56 @@
from views.web_views.base_web_view import BaseWebView, BaseButton
from views.web_views.base_web_view import BaseWebView, Button
import time
class AssetsButton(BaseButton):
class RequestSTTButton(Button):
def __init__(self, driver):
super(AssetsButton, self).__init__(driver)
self.locator = self.Locator.webview_selector('Assets')
super(RequestSTTButton, self).__init__(driver, webview="Request STT")
class RequestETHButton(BaseButton):
def __init__(self, driver):
super(AssetsButton.RequestETHButton, self).__init__(driver)
self.locator = self.Locator.webview_selector('Request Ropsten ETH')
class RequestSTTButton(BaseButton):
def __init__(self, driver):
super(AssetsButton.RequestSTTButton, self).__init__(driver)
self.locator = self.Locator.webview_selector('Request STT')
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class TransactionsButton(BaseButton):
class TransactionsButton(Button):
def __init__(self, driver):
super(TransactionsButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Transactions')
super().__init__(driver, xpath="//*[@text='Transactions']")
class SignMessageButton(BaseButton):
class SignMessageButton(Button):
def __init__(self, driver):
super(TransactionsButton.SignMessageButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Sign message')
super().__init__(driver, xpath="//*[@text='Sign message']")
def click(self):
from views.send_transaction_view import SigningPhraseText
self.click_until_presence_of_element(SigningPhraseText(self.driver))
from views.base_element import Text
self.click_until_presence_of_element(Text(self.driver, translation_id="signing-phrase"))
return self.navigate()
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class SignTypedMessageButton(BaseButton):
class SignTypedMessageButton(Button):
def __init__(self, driver):
super(TransactionsButton.SignTypedMessageButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Sign Typed Message')
super().__init__(driver, xpath="//*[@text='Sign Typed Message']")
def click(self):
from views.send_transaction_view import SigningPhraseText
self.click_until_presence_of_element(SigningPhraseText(self.driver))
from views.base_element import Text
self.click_until_presence_of_element(Text(self.driver, translation_id="signing-phrase"))
return self.navigate()
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class DeployContractButton(BaseButton):
class DeployContractButton(Button):
def __init__(self, driver):
super(TransactionsButton.DeployContractButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Deploy simple contract')
super().__init__(driver, xpath="//*[@text='Deploy simple contract']")
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class SendTwoTxOneByOneButton(BaseButton):
class SendTwoTxOneByOneButton(Button):
def __init__(self, driver):
super(TransactionsButton.SendTwoTxOneByOneButton, self).__init__(driver)
self.locator = self.Locator.webview_selector('Send two Txs, one after another, 0.00001 and 0.00002 ETH')
super().__init__(driver, webview="Send two Txs, one after another, 0.00001 and 0.00002 ETH")
def navigate(self):
from views.send_transaction_view import SendTransactionView
@ -81,40 +62,30 @@ class TransactionsButton(BaseButton):
self.wait_for_visibility_of_element().click()
return self.navigate()
class SendTwoTxInBatchButton(BaseButton):
class SendTwoTxInBatchButton(Button):
def __init__(self, driver):
super(TransactionsButton.SendTwoTxInBatchButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Send two Txs in batch, 0.00001 and 0.00002 ETH')
super().__init__(driver, xpath="//*[@text='Send two Txs in batch, 0.00001 and 0.00002 ETH']")
def navigate(self):
from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver)
class TestFiltersButton(BaseButton):
class TestFiltersButton(Button):
def __init__(self, driver):
super(TransactionsButton.TestFiltersButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Test filters')
super().__init__(driver, xpath="//*[@text='Test filters']")
class StatusAPIButton(BaseButton):
class StatusAPIButton(Button):
def __init__(self, driver):
super(StatusAPIButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Status API')
class RequestContactCodeButton(BaseButton):
def __init__(self, driver):
super(StatusAPIButton.RequestContactCodeButton, self).__init__(driver)
self.locator = self.Locator.text_part_selector('Request contact code')
super().__init__(driver, xpath="//*[@text='%s']")
def click(self):
self.wait_for_visibility_of_element().click()
class SendOneTransactionInBatchButton(BaseButton):
class SendOneTransactionInBatchButton(Button):
def __init__(self, driver):
super().__init__(driver)
self.locator = self.Locator.text_selector('Send one Tx in batch')
super().__init__(driver, xpath="//*[@text='Send one Tx in batch']")
def navigate(self):
from views.send_transaction_view import SendTransactionView
@ -127,9 +98,9 @@ class StatusTestDAppView(BaseWebView):
super(StatusTestDAppView, self).__init__(driver)
self.driver = driver
self.assets_button = AssetsButton(self.driver)
self.request_eth_button = AssetsButton.RequestETHButton(self.driver)
self.request_stt_button = AssetsButton.RequestSTTButton(self.driver)
self.assets_button = Button(self.driver, webview="Assets")
self.request_eth_button = Button(self.driver, webview="Request Ropsten ETH")
self.request_stt_button = RequestSTTButton(self.driver)
self.transactions_button = TransactionsButton(self.driver)
self.sign_message_button = TransactionsButton.SignMessageButton(self.driver)
@ -141,12 +112,14 @@ class StatusTestDAppView(BaseWebView):
self.sign_typed_message_button = TransactionsButton.SignTypedMessageButton(self.driver)
self.status_api_button = StatusAPIButton(self.driver)
self.request_contact_code_button = StatusAPIButton.RequestContactCodeButton(self.driver)
self.request_contact_code_button = Button(self.driver, xpath="//*[contains(text(),'Request contact code']")
def wait_for_d_aap_to_load(self, wait_time=10):
self.driver.info("**Wait %ss for assets in simpledapp**" % wait_time)
self.assets_button.wait_for_visibility_of_element(seconds=wait_time)
def faucet_asset(self, asset='eth'):
self.driver.info("**Faucet %s in dapp**" % asset)
self.wait_for_d_aap_to_load()
self.assets_button.click()
if asset == 'eth':