2017-09-21 17:01:04 +00:00
|
|
|
|
import time
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2018-01-26 11:07:09 +00:00
|
|
|
|
import base64
|
2018-07-09 19:47:50 +00:00
|
|
|
|
import pytest
|
2019-07-29 00:35:36 +00:00
|
|
|
|
import random
|
2018-07-18 12:19:52 +00:00
|
|
|
|
import re
|
2019-07-29 00:35:36 +00:00
|
|
|
|
import string
|
2018-01-26 11:07:09 +00:00
|
|
|
|
import zbarlight
|
|
|
|
|
from PIL import Image
|
2019-07-29 00:35:36 +00:00
|
|
|
|
from appium.webdriver.common.touch_action import TouchAction
|
2018-01-03 09:34:40 +00:00
|
|
|
|
from datetime import datetime
|
2019-07-29 00:35:36 +00:00
|
|
|
|
from eth_keys import datatypes
|
2018-01-26 11:07:09 +00:00
|
|
|
|
from io import BytesIO
|
2019-07-29 00:35:36 +00:00
|
|
|
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException
|
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
from support.device_apps import start_web_browser
|
2019-07-29 00:35:36 +00:00
|
|
|
|
from tests import common_password
|
|
|
|
|
from views.base_element import BaseButton, BaseElement, BaseEditBox, BaseText
|
2018-01-14 17:43:36 +00:00
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
|
|
|
|
class BackButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(BackButton, self).__init__(driver)
|
2018-03-15 20:01:08 +00:00
|
|
|
|
self.locator = self.Locator.accessibility_id('back-button')
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2018-01-14 17:43:36 +00:00
|
|
|
|
def click(self, times_to_click: int = 1):
|
|
|
|
|
for _ in range(times_to_click):
|
2018-02-07 13:18:55 +00:00
|
|
|
|
self.find_element().click()
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Tap on %s' % self.name)
|
2017-10-05 19:41:17 +00:00
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2017-11-09 10:55:02 +00:00
|
|
|
|
class AllowButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(AllowButton, self).__init__(driver)
|
2018-05-02 16:01:17 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Allow' or @text='ALLOW']")
|
2017-11-09 10:55:02 +00:00
|
|
|
|
|
2019-08-02 21:22:23 +00:00
|
|
|
|
def click(self, times_to_click=3):
|
2017-11-09 10:55:02 +00:00
|
|
|
|
try:
|
2019-08-02 21:22:23 +00:00
|
|
|
|
for _ in range(times_to_click):
|
2017-11-09 10:55:02 +00:00
|
|
|
|
self.find_element().click()
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Tap on %s' % self.name)
|
2017-11-09 10:55:02 +00:00
|
|
|
|
except NoSuchElementException:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
2017-10-19 13:49:20 +00:00
|
|
|
|
class DenyButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(DenyButton, self).__init__(driver)
|
2019-03-22 10:03:31 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Deny' or @text='DENY']")
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
|
|
|
|
|
2018-02-19 11:51:53 +00:00
|
|
|
|
class DeleteButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(DeleteButton, self).__init__(driver)
|
2018-03-28 10:21:39 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='DELETE']")
|
2018-02-19 11:51:53 +00:00
|
|
|
|
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
class YesButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(YesButton, self).__init__(driver)
|
2018-11-14 17:18:57 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='YES' or @text='GOT IT']")
|
2018-01-03 09:34:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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']")
|
|
|
|
|
|
|
|
|
|
|
2018-03-15 20:01:08 +00:00
|
|
|
|
class ContinueButton(BaseButton):
|
2018-01-03 09:34:40 +00:00
|
|
|
|
def __init__(self, driver):
|
2018-03-15 20:01:08 +00:00
|
|
|
|
super(ContinueButton, self).__init__(driver)
|
2018-05-16 19:59:36 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='CONTINUE' or @text='Continue']")
|
2018-01-03 09:34:40 +00:00
|
|
|
|
|
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
class TabButton(BaseButton):
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def counter(self):
|
|
|
|
|
class Counter(BaseText):
|
|
|
|
|
def __init__(self, driver, parent_locator):
|
|
|
|
|
super(Counter, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector(
|
2018-07-19 09:57:45 +00:00
|
|
|
|
"//*[@content-desc='%s']//android.view.ViewGroup[2]/android.widget.TextView" % parent_locator)
|
2018-06-29 17:27:30 +00:00
|
|
|
|
|
|
|
|
|
return Counter(self.driver, self.locator.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HomeButton(TabButton):
|
2017-09-21 17:01:04 +00:00
|
|
|
|
def __init__(self, driver):
|
2018-01-14 17:43:36 +00:00
|
|
|
|
super(HomeButton, self).__init__(driver)
|
2018-03-15 20:01:08 +00:00
|
|
|
|
self.locator = self.Locator.accessibility_id('home-tab-button')
|
2017-09-21 17:01:04 +00:00
|
|
|
|
|
2017-10-05 19:41:17 +00:00
|
|
|
|
def navigate(self):
|
2018-01-14 17:43:36 +00:00
|
|
|
|
from views.home_view import HomeView
|
|
|
|
|
return HomeView(self.driver)
|
2017-10-05 19:41:17 +00:00
|
|
|
|
|
2018-07-25 11:09:45 +00:00
|
|
|
|
def click(self):
|
|
|
|
|
from views.home_view import PlusButton
|
|
|
|
|
self.click_until_presence_of_element(PlusButton(self.driver))
|
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2017-09-21 17:01:04 +00:00
|
|
|
|
|
2019-03-13 09:36:51 +00:00
|
|
|
|
class DappTabButton(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(DappTabButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.accessibility_id('dapp-tab-button')
|
|
|
|
|
|
|
|
|
|
def navigate(self):
|
2019-04-05 13:05:23 +00:00
|
|
|
|
from views.dapps_view import DappsView
|
|
|
|
|
return DappsView(self.driver)
|
2019-03-13 09:36:51 +00:00
|
|
|
|
|
|
|
|
|
def click(self):
|
2019-04-05 13:05:23 +00:00
|
|
|
|
from views.dapps_view import EnterUrlEditbox
|
2019-03-13 09:36:51 +00:00
|
|
|
|
self.click_until_presence_of_element(EnterUrlEditbox(self.driver))
|
|
|
|
|
return self.navigate()
|
|
|
|
|
|
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
class WalletButton(TabButton):
|
2017-10-19 13:49:20 +00:00
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(WalletButton, self).__init__(driver)
|
2018-03-15 20:01:08 +00:00
|
|
|
|
self.locator = self.Locator.accessibility_id('wallet-tab-button')
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
|
|
|
|
def navigate(self):
|
2018-01-03 09:34:40 +00:00
|
|
|
|
from views.wallet_view import WalletView
|
|
|
|
|
return WalletView(self.driver)
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
2018-07-25 11:09:45 +00:00
|
|
|
|
def click(self):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Tap on %s' % self.name)
|
2019-07-03 14:29:01 +00:00
|
|
|
|
from views.wallet_view import MultiaccountMoreOptions
|
|
|
|
|
self.click_until_presence_of_element(MultiaccountMoreOptions(self.driver))
|
2019-06-24 15:53:02 +00:00
|
|
|
|
return self.navigate()
|
2018-07-25 11:09:45 +00:00
|
|
|
|
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
class ProfileButton(TabButton):
|
2017-10-30 11:11:58 +00:00
|
|
|
|
def __init__(self, driver):
|
2018-01-14 17:43:36 +00:00
|
|
|
|
super(ProfileButton, self).__init__(driver)
|
2018-03-15 20:01:08 +00:00
|
|
|
|
self.locator = self.Locator.accessibility_id('profile-tab-button')
|
2017-10-30 11:11:58 +00:00
|
|
|
|
|
|
|
|
|
def navigate(self):
|
2018-01-14 17:43:36 +00:00
|
|
|
|
from views.profile_view import ProfileView
|
|
|
|
|
return ProfileView(self.driver)
|
2017-10-23 20:46:49 +00:00
|
|
|
|
|
2018-07-25 11:09:45 +00:00
|
|
|
|
def click(self):
|
2019-08-14 16:05:04 +00:00
|
|
|
|
from views.profile_view import DefaultUserNameText
|
|
|
|
|
self.click_until_presence_of_element(DefaultUserNameText(self.driver))
|
2018-07-25 11:09:45 +00:00
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2017-10-23 20:46:49 +00:00
|
|
|
|
|
2017-10-30 11:11:58 +00:00
|
|
|
|
class SaveButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(SaveButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector(
|
2019-03-21 11:36:09 +00:00
|
|
|
|
"//android.widget.TextView[@text='Save']")
|
2017-10-30 11:11:58 +00:00
|
|
|
|
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
class NextButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(NextButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector(
|
2019-03-14 19:51:54 +00:00
|
|
|
|
"//android.widget.TextView[@text='Next']")
|
2018-01-03 09:34:40 +00:00
|
|
|
|
|
|
|
|
|
|
2018-12-05 14:11:50 +00:00
|
|
|
|
class AddButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(AddButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector(
|
2019-03-22 10:03:31 +00:00
|
|
|
|
"//android.widget.TextView[@text='Add']")
|
2018-12-05 14:11:50 +00:00
|
|
|
|
|
|
|
|
|
|
2018-01-26 11:07:09 +00:00
|
|
|
|
class DoneButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(DoneButton, self).__init__(driver)
|
2019-03-14 19:51:54 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@content-desc='done-button' or contains(@text, 'Done')]")
|
2018-01-26 11:07:09 +00:00
|
|
|
|
|
|
|
|
|
|
2017-11-09 10:58:11 +00:00
|
|
|
|
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']")
|
|
|
|
|
|
|
|
|
|
|
2018-02-19 11:51:53 +00:00
|
|
|
|
class SendMessageButton(BaseButton):
|
2018-03-01 13:22:01 +00:00
|
|
|
|
def __init__(self, driver):
|
2018-02-19 11:51:53 +00:00
|
|
|
|
super(SendMessageButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.accessibility_id("send-message-button")
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.find_element().click()
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Tap on %s' % self.name)
|
2018-03-01 13:22:01 +00:00
|
|
|
|
|
|
|
|
|
|
2018-06-21 16:40:27 +00:00
|
|
|
|
class ConnectionStatusText(BaseText):
|
2018-05-16 19:59:36 +00:00
|
|
|
|
def __init__(self, driver):
|
2018-06-21 16:40:27 +00:00
|
|
|
|
super(ConnectionStatusText, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector(
|
|
|
|
|
"//*[@content-desc='connection-status-text']/android.widget.TextView")
|
2018-05-16 19:59:36 +00:00
|
|
|
|
|
|
|
|
|
|
2018-07-06 11:10:48 +00:00
|
|
|
|
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']")
|
|
|
|
|
|
|
|
|
|
|
2018-07-19 09:57:45 +00:00
|
|
|
|
class ConfirmButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(ConfirmButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='CONFIRM']")
|
|
|
|
|
|
|
|
|
|
|
2018-07-23 11:38:47 +00:00
|
|
|
|
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')
|
|
|
|
|
|
|
|
|
|
|
2018-08-01 00:16:33 +00:00
|
|
|
|
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]')
|
|
|
|
|
|
2019-11-18 09:38:34 +00:00
|
|
|
|
class CrossIconInWelcomeScreen(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(CrossIconInWelcomeScreen, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.accessibility_id('hide-home-button')
|
|
|
|
|
|
2018-08-01 00:16:33 +00:00
|
|
|
|
|
2019-01-28 09:00:55 +00:00
|
|
|
|
class ShowRoots(BaseButton):
|
|
|
|
|
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(ShowRoots, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.accessibility_id('Show roots')
|
|
|
|
|
|
|
|
|
|
|
2019-03-19 09:02:41 +00:00
|
|
|
|
class GetStartedButton(BaseButton):
|
|
|
|
|
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(GetStartedButton, self).__init__(driver)
|
2019-03-14 19:51:54 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Get started']")
|
2019-03-19 09:02:41 +00:00
|
|
|
|
|
|
|
|
|
|
2018-08-30 16:57:18 +00:00
|
|
|
|
class AssetButton(BaseButton):
|
|
|
|
|
def __init__(self, driver, asset_name):
|
|
|
|
|
super(AssetButton, self).__init__(driver)
|
|
|
|
|
self.asset_name = asset_name
|
2019-11-29 17:32:47 +00:00
|
|
|
|
self.locator = self.Locator.xpath_selector('(//*[@content-desc=":' + self.asset_name + '-asset-value"])[2]')
|
2018-08-30 16:57:18 +00:00
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def name(self):
|
|
|
|
|
return self.asset_name + self.__class__.__name__
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.wait_for_element().click()
|
|
|
|
|
self.driver.info('Tap on %s' % self.name)
|
|
|
|
|
|
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
class OpenInStatusButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(OpenInStatusButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Open in Status"]')
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.wait_for_visibility_of_element()
|
2019-11-29 10:27:57 +00:00
|
|
|
|
# using sleep is wrong, but implicit wait for element can't help in particular case
|
|
|
|
|
time.sleep(3)
|
2019-05-17 14:40:35 +00:00
|
|
|
|
self.swipe_to_web_element()
|
2019-04-02 15:16:08 +00:00
|
|
|
|
self.wait_for_element().click()
|
|
|
|
|
|
|
|
|
|
|
2019-07-15 15:53:56 +00:00
|
|
|
|
class OkGotItButton(BaseButton):
|
|
|
|
|
def __init__(self,driver):
|
|
|
|
|
super(OkGotItButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@text='OK, got it']")
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.wait_for_element().click()
|
|
|
|
|
self.wait_for_invisibility_of_element()
|
|
|
|
|
|
|
|
|
|
|
2019-07-29 00:35:36 +00:00
|
|
|
|
class AirplaneModeButton(BaseButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super(AirplaneModeButton, self).__init__(driver)
|
|
|
|
|
self.locator = self.Locator.xpath_selector("//*[@content-desc='Airplane mode']")
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
action = TouchAction(self.driver)
|
|
|
|
|
action.press(None, 50, 0).move_to(None, 50, 300).perform()
|
|
|
|
|
super(AirplaneModeButton, self).click()
|
2019-10-30 18:21:21 +00:00
|
|
|
|
action.press(None, 50, 600).move_to(None, 50, 0).perform()
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
class BaseView(object):
|
2017-08-28 10:02:20 +00:00
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
self.driver = driver
|
2018-02-19 11:51:53 +00:00
|
|
|
|
self.send_message_button = SendMessageButton(self.driver)
|
2018-01-14 17:43:36 +00:00
|
|
|
|
self.home_button = HomeButton(self.driver)
|
2018-02-09 15:16:07 +00:00
|
|
|
|
self.wallet_button = WalletButton(self.driver)
|
2018-01-14 17:43:36 +00:00
|
|
|
|
self.profile_button = ProfileButton(self.driver)
|
2019-03-13 09:36:51 +00:00
|
|
|
|
self.dapp_tab_button = DappTabButton(self.driver)
|
2018-01-14 17:43:36 +00:00
|
|
|
|
|
2017-10-19 13:49:20 +00:00
|
|
|
|
self.yes_button = YesButton(self.driver)
|
|
|
|
|
self.no_button = NoButton(self.driver)
|
2017-08-28 10:02:20 +00:00
|
|
|
|
self.back_button = BackButton(self.driver)
|
2017-11-09 10:55:02 +00:00
|
|
|
|
self.allow_button = AllowButton(self.driver)
|
2017-10-19 13:49:20 +00:00
|
|
|
|
self.deny_button = DenyButton(self.driver)
|
2018-03-15 20:01:08 +00:00
|
|
|
|
self.continue_button = ContinueButton(self.driver)
|
|
|
|
|
self.ok_button = OkButton(self.driver)
|
2018-01-03 09:34:40 +00:00
|
|
|
|
self.next_button = NextButton(self.driver)
|
2018-12-05 14:11:50 +00:00
|
|
|
|
self.add_button = AddButton(self.driver)
|
2017-10-30 11:11:58 +00:00
|
|
|
|
self.save_button = SaveButton(self.driver)
|
2018-01-26 11:07:09 +00:00
|
|
|
|
self.done_button = DoneButton(self.driver)
|
2018-03-01 13:22:01 +00:00
|
|
|
|
self.delete_button = DeleteButton(self.driver)
|
2018-07-06 11:10:48 +00:00
|
|
|
|
self.ok_continue_button = OkContinueButton(self.driver)
|
|
|
|
|
self.discard_button = DiscardButton(self.driver)
|
2018-07-19 09:57:45 +00:00
|
|
|
|
self.confirm_button = ConfirmButton(self.driver)
|
2018-06-21 16:40:27 +00:00
|
|
|
|
self.connection_status = ConnectionStatusText(self.driver)
|
2018-08-01 00:16:33 +00:00
|
|
|
|
self.cross_icon = CrossIcon(self.driver)
|
2019-01-28 09:00:55 +00:00
|
|
|
|
self.show_roots_button = ShowRoots(self.driver)
|
2019-03-19 09:02:41 +00:00
|
|
|
|
self.get_started_button = GetStartedButton(self.driver)
|
2019-07-15 15:53:56 +00:00
|
|
|
|
self.ok_got_it_button = OkGotItButton(self.driver)
|
2019-08-02 21:22:23 +00:00
|
|
|
|
self.progress_bar = ProgressBar(self.driver)
|
2019-11-18 09:38:34 +00:00
|
|
|
|
self.cross_icon_iside_welcome_screen_button = CrossIconInWelcomeScreen(self.driver)
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
# external browser
|
|
|
|
|
self.open_in_status_button = OpenInStatusButton(self.driver)
|
|
|
|
|
|
2018-01-14 17:43:36 +00:00
|
|
|
|
self.apps_button = AppsButton(self.driver)
|
|
|
|
|
self.status_app_icon = StatusAppIcon(self.driver)
|
2017-11-09 10:58:11 +00:00
|
|
|
|
|
2019-07-29 00:35:36 +00:00
|
|
|
|
self.airplane_mode_button = AirplaneModeButton(self.driver)
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
self.element_types = {
|
|
|
|
|
'base': BaseElement,
|
|
|
|
|
'button': BaseButton,
|
|
|
|
|
'edit_box': BaseEditBox,
|
|
|
|
|
'text': BaseText
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 09:38:34 +00:00
|
|
|
|
|
2018-03-15 20:01:08 +00:00
|
|
|
|
def accept_agreements(self):
|
2018-06-14 17:38:27 +00:00
|
|
|
|
iterations = int()
|
2019-07-11 15:44:12 +00:00
|
|
|
|
while iterations <= 2 and (self.ok_button.is_element_displayed(2) or
|
|
|
|
|
self.continue_button.is_element_displayed(2)):
|
2018-06-14 17:38:27 +00:00
|
|
|
|
for button in self.ok_button, self.continue_button:
|
|
|
|
|
try:
|
2018-07-03 18:50:18 +00:00
|
|
|
|
button.wait_for_element(3)
|
2018-06-14 17:38:27 +00:00
|
|
|
|
button.click()
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
pass
|
|
|
|
|
iterations += 1
|
2018-03-15 20:01:08 +00:00
|
|
|
|
|
2017-11-09 10:58:11 +00:00
|
|
|
|
@property
|
|
|
|
|
def logcat(self):
|
2018-07-17 16:27:00 +00:00
|
|
|
|
logcat = self.driver.get_log("logcat")
|
|
|
|
|
if len(logcat) > 1000:
|
|
|
|
|
return str([i for i in logcat if 'appium' not in str(i).lower()])
|
|
|
|
|
raise TimeoutError('Logcat is empty')
|
2017-11-09 10:58:11 +00:00
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
def confirm(self):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Tap 'Confirm' on native keyboard")
|
2018-03-28 10:21:39 +00:00
|
|
|
|
self.driver.press_keycode(66)
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2018-08-07 13:23:31 +00:00
|
|
|
|
def confirm_until_presence_of_element(self, desired_element, attempts=3):
|
|
|
|
|
counter = 0
|
|
|
|
|
while not desired_element.is_element_present(1) and counter <= attempts:
|
|
|
|
|
try:
|
|
|
|
|
self.confirm()
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Wait for %s' % desired_element.name)
|
2018-08-07 13:23:31 +00:00
|
|
|
|
desired_element.wait_for_element(5)
|
|
|
|
|
return
|
|
|
|
|
except TimeoutException:
|
|
|
|
|
counter += 1
|
|
|
|
|
|
2019-09-26 09:11:46 +00:00
|
|
|
|
def just_fyi(self, string):
|
2019-10-04 13:50:44 +00:00
|
|
|
|
self.driver.info('=========================================================================')
|
2019-09-26 09:11:46 +00:00
|
|
|
|
self.driver.info(string)
|
|
|
|
|
|
2019-11-20 16:27:29 +00:00
|
|
|
|
def click_system_back_button(self, times=1):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Click system back button')
|
2019-11-20 16:27:29 +00:00
|
|
|
|
for _ in range(times):
|
|
|
|
|
self.driver.press_keycode(4)
|
2018-06-28 18:46:51 +00:00
|
|
|
|
|
2018-07-03 18:50:18 +00:00
|
|
|
|
def cut_text(self):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Cut text')
|
2018-07-03 18:50:18 +00:00
|
|
|
|
self.driver.press_keycode(277)
|
|
|
|
|
|
2018-07-03 12:32:01 +00:00
|
|
|
|
def copy_text(self):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Copy text')
|
2018-07-03 12:32:01 +00:00
|
|
|
|
self.driver.press_keycode(278)
|
|
|
|
|
|
|
|
|
|
def paste_text(self):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info('Paste text')
|
2018-07-03 12:32:01 +00:00
|
|
|
|
self.driver.press_keycode(279)
|
|
|
|
|
|
2017-10-05 19:41:17 +00:00
|
|
|
|
def send_as_keyevent(self, string):
|
|
|
|
|
keys = {'0': 7, '1': 8, '2': 9, '3': 10, '4': 11, '5': 12, '6': 13, '7': 14, '8': 15, '9': 16,
|
2017-11-17 11:43:38 +00:00
|
|
|
|
|
|
|
|
|
',': 55, '-': 69, '+': 81, '.': 56, '/': 76, '\\': 73, ';': 74, ' ': 62,
|
2018-07-26 18:58:05 +00:00
|
|
|
|
'[': 71, ']': 72, '=': 70, '\n': 66, '_': [69, 5], ':': [74, 5],
|
2017-11-17 11:43:38 +00:00
|
|
|
|
|
|
|
|
|
'a': 29, 'b': 30, 'c': 31, 'd': 32, 'e': 33, 'f': 34, 'g': 35, 'h': 36, 'i': 37, 'j': 38,
|
|
|
|
|
'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}
|
2018-04-26 15:05:53 +00:00
|
|
|
|
time.sleep(3)
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Enter '%s' using native keyboard" % string)
|
2017-10-05 19:41:17 +00:00
|
|
|
|
for i in string:
|
2018-11-16 15:55:12 +00:00
|
|
|
|
if i.isalpha() and i.isupper():
|
|
|
|
|
keycode, metastate = keys[i.lower()], 64 # META_SHIFT_LEFT_ON Constant Value: 64. Example: i='n' -> 'N'
|
|
|
|
|
elif type(keys[i]) is list:
|
2018-04-26 15:05:53 +00:00
|
|
|
|
keycode, metastate = keys[i][0], keys[i][1]
|
|
|
|
|
else:
|
|
|
|
|
keycode, metastate = keys[i], None
|
|
|
|
|
self.driver.press_keycode(keycode=keycode, metastate=metastate)
|
2017-09-21 17:01:04 +00:00
|
|
|
|
|
|
|
|
|
def find_full_text(self, text, wait_time=60):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for full text: '%s'" % text)
|
2017-09-13 14:34:42 +00:00
|
|
|
|
element = BaseElement(self.driver)
|
2018-05-16 19:59:36 +00:00
|
|
|
|
element.locator = element.Locator.text_selector(text)
|
2017-09-21 17:01:04 +00:00
|
|
|
|
return element.wait_for_element(wait_time)
|
2017-09-13 14:34:42 +00:00
|
|
|
|
|
2017-09-21 17:01:04 +00:00
|
|
|
|
def find_text_part(self, text, wait_time=60):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for a text part: '%s'" % text)
|
2017-09-11 10:43:42 +00:00
|
|
|
|
element = BaseElement(self.driver)
|
2018-05-16 19:59:36 +00:00
|
|
|
|
element.locator = element.Locator.text_part_selector(text)
|
2017-09-21 17:01:04 +00:00
|
|
|
|
return element.wait_for_element(wait_time)
|
2017-09-13 14:34:42 +00:00
|
|
|
|
|
2018-02-09 15:16:07 +00:00
|
|
|
|
def element_by_text(self, text, element_type='button'):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for an element by text: '%s'" % text)
|
2018-01-03 09:34:40 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
2018-04-26 06:22:11 +00:00
|
|
|
|
element.locator = element.Locator.text_selector(text)
|
2017-09-13 14:34:42 +00:00
|
|
|
|
return element
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2018-07-03 12:40:44 +00:00
|
|
|
|
def element_by_text_part(self, text, element_type='button'):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for an element by text part: '%s'" % text)
|
2018-01-03 09:34:40 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
2018-04-26 06:22:11 +00:00
|
|
|
|
element.locator = element.Locator.text_part_selector(text)
|
2017-11-09 10:55:02 +00:00
|
|
|
|
return element
|
|
|
|
|
|
2018-04-30 09:58:20 +00:00
|
|
|
|
def element_starts_with_text(self, text, element_type='base'):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for full text: '%s'" % text)
|
2018-04-30 09:58:20 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
|
|
|
|
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
|
|
|
|
|
return element
|
|
|
|
|
|
|
|
|
|
def wait_for_element_starts_with_text(self, text, wait_time=60):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for full text: '%s'" % text)
|
2018-04-30 09:58:20 +00:00
|
|
|
|
element = BaseElement(self.driver)
|
|
|
|
|
element.locator = element.Locator.xpath_selector("//*[starts-with(@text,'%s')]" % text)
|
|
|
|
|
return element.wait_for_element(wait_time)
|
|
|
|
|
|
2018-07-03 12:40:44 +00:00
|
|
|
|
def element_by_accessibility_id(self, accessibility_id, element_type='button'):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for an element by accessibility id: '%s'" % accessibility_id)
|
2018-07-03 12:40:44 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
|
|
|
|
element.locator = element.Locator.accessibility_id(accessibility_id)
|
|
|
|
|
return element
|
|
|
|
|
|
2018-07-20 08:27:33 +00:00
|
|
|
|
def element_by_xpath(self, xpath, element_type='button'):
|
2018-08-15 12:51:52 +00:00
|
|
|
|
self.driver.info("Looking for an element by xpath: '%s'" % xpath)
|
2018-07-20 08:27:33 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
|
|
|
|
element.locator = element.Locator.xpath_selector(xpath)
|
|
|
|
|
return element
|
|
|
|
|
|
2019-06-24 15:53:02 +00:00
|
|
|
|
def swipe_up(self):
|
2019-06-14 15:28:03 +00:00
|
|
|
|
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)
|
2018-06-08 10:02:54 +00:00
|
|
|
|
|
2019-06-24 15:53:02 +00:00
|
|
|
|
def swipe_down(self):
|
|
|
|
|
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)
|
|
|
|
|
|
2019-06-14 15:28:03 +00:00
|
|
|
|
def swipe_left(self):
|
|
|
|
|
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)
|
2019-03-12 12:18:03 +00:00
|
|
|
|
|
2019-09-05 02:32:33 +00:00
|
|
|
|
def swipe_right(self):
|
|
|
|
|
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)
|
|
|
|
|
|
2019-03-19 12:35:15 +00:00
|
|
|
|
def get_status_test_dapp_view(self):
|
|
|
|
|
from views.web_views.status_test_dapp import StatusTestDAppView
|
|
|
|
|
return StatusTestDAppView(self.driver)
|
|
|
|
|
|
2018-01-14 17:43:36 +00:00
|
|
|
|
def get_home_view(self):
|
|
|
|
|
from views.home_view import HomeView
|
|
|
|
|
return HomeView(self.driver)
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
def get_chat_view(self):
|
|
|
|
|
from views.chat_view import ChatView
|
|
|
|
|
return ChatView(self.driver)
|
|
|
|
|
|
|
|
|
|
def get_sign_in_view(self):
|
|
|
|
|
from views.sign_in_view import SignInView
|
|
|
|
|
return SignInView(self.driver)
|
|
|
|
|
|
|
|
|
|
def get_send_transaction_view(self):
|
|
|
|
|
from views.send_transaction_view import SendTransactionView
|
|
|
|
|
return SendTransactionView(self.driver)
|
|
|
|
|
|
2018-02-13 17:22:41 +00:00
|
|
|
|
def get_base_web_view(self):
|
|
|
|
|
from views.web_views.base_web_view import BaseWebView
|
|
|
|
|
return BaseWebView(self.driver)
|
|
|
|
|
|
2018-02-14 13:48:18 +00:00
|
|
|
|
def get_profile_view(self):
|
|
|
|
|
from views.profile_view import ProfileView
|
|
|
|
|
return ProfileView(self.driver)
|
|
|
|
|
|
2018-05-30 15:41:00 +00:00
|
|
|
|
def get_wallet_view(self):
|
|
|
|
|
from views.wallet_view import WalletView
|
|
|
|
|
return WalletView(self.driver)
|
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def get_unique_amount():
|
2019-05-27 16:45:20 +00:00
|
|
|
|
return '0.00%s' % datetime.now().strftime('%-d%-H%-M%-S').strip('0')
|
2018-01-26 11:07:09 +00:00
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def get_public_chat_name():
|
|
|
|
|
return ''.join(random.choice(string.ascii_lowercase) for _ in range(7))
|
|
|
|
|
|
2018-01-26 11:07:09 +00:00
|
|
|
|
def get_text_from_qr(self):
|
|
|
|
|
image = Image.open(BytesIO(base64.b64decode(self.driver.get_screenshot_as_base64())))
|
|
|
|
|
image.load()
|
|
|
|
|
try:
|
|
|
|
|
return str(zbarlight.scan_codes('qrcode', image)[0])[2:][:132]
|
|
|
|
|
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:]
|
2018-05-02 16:01:17 +00:00
|
|
|
|
|
2019-11-08 18:24:55 +00:00
|
|
|
|
def get_back_to_home_view(self, times_to_click_on_back_btn=5):
|
2018-05-02 16:01:17 +00:00
|
|
|
|
counter = 0
|
2019-02-18 16:35:42 +00:00
|
|
|
|
from views.home_view import PlusButton
|
|
|
|
|
while not PlusButton(self.driver).is_element_displayed(2):
|
2018-05-02 16:01:17 +00:00
|
|
|
|
try:
|
2019-11-08 18:24:55 +00:00
|
|
|
|
if counter >= times_to_click_on_back_btn:
|
2019-03-01 16:00:49 +00:00
|
|
|
|
break
|
2018-05-02 16:01:17 +00:00
|
|
|
|
self.back_button.click()
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
counter += 1
|
2018-11-13 08:25:55 +00:00
|
|
|
|
return self.home_button.click()
|
2018-05-02 16:01:17 +00:00
|
|
|
|
|
2018-06-01 16:37:44 +00:00
|
|
|
|
def relogin(self, password=common_password):
|
2019-04-05 13:05:23 +00:00
|
|
|
|
try:
|
|
|
|
|
profile_view = self.profile_button.click()
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
self.get_back_to_home_view()
|
|
|
|
|
profile_view = self.profile_button.click()
|
2018-07-17 16:27:00 +00:00
|
|
|
|
profile_view.logout()
|
2018-05-02 16:01:17 +00:00
|
|
|
|
sign_in_view = self.get_sign_in_view()
|
2018-07-17 16:27:00 +00:00
|
|
|
|
sign_in_view.sign_in(password)
|
2018-06-29 17:27:30 +00:00
|
|
|
|
|
2019-08-14 16:05:04 +00:00
|
|
|
|
def close_share_chat_key_popup(self):
|
|
|
|
|
TouchAction(self.driver).tap(None, 255, 104, 1).perform()
|
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
def get_public_key(self):
|
|
|
|
|
profile_view = self.profile_button.click()
|
2018-10-02 11:33:51 +00:00
|
|
|
|
profile_view.share_my_profile_button.click()
|
2018-06-29 17:27:30 +00:00
|
|
|
|
profile_view.public_key_text.wait_for_visibility_of_element()
|
|
|
|
|
public_key = profile_view.public_key_text.text
|
2019-08-14 16:05:04 +00:00
|
|
|
|
self.close_share_chat_key_popup()
|
2018-06-29 17:27:30 +00:00
|
|
|
|
return public_key
|
2018-07-03 12:40:44 +00:00
|
|
|
|
|
|
|
|
|
def share_via_messenger(self):
|
2019-01-28 09:00:55 +00:00
|
|
|
|
self.element_by_text('Messages').click()
|
2018-07-03 12:40:44 +00:00
|
|
|
|
self.element_by_text('NEW MESSAGE').click()
|
2019-01-28 09:00:55 +00:00
|
|
|
|
self.send_as_keyevent('+0100100101')
|
2018-07-03 12:40:44 +00:00
|
|
|
|
self.confirm()
|
2018-07-03 18:50:18 +00:00
|
|
|
|
|
|
|
|
|
def reconnect(self):
|
|
|
|
|
connect_status = self.connection_status
|
|
|
|
|
for i in range(3):
|
2018-07-19 09:57:45 +00:00
|
|
|
|
if connect_status.is_element_displayed(5, ignored_exceptions=StaleElementReferenceException):
|
|
|
|
|
if 'Tap to reconnect' in connect_status.text:
|
|
|
|
|
try:
|
|
|
|
|
connect_status.click()
|
|
|
|
|
except AttributeError:
|
|
|
|
|
pass
|
|
|
|
|
try:
|
|
|
|
|
connect_status.wait_for_invisibility_of_element()
|
|
|
|
|
except TimeoutException as e:
|
|
|
|
|
if i == 2:
|
2018-08-15 12:51:52 +00:00
|
|
|
|
e.msg = "Device %s: Can't reconnect to mail server after 3 attempts" % self.driver.number
|
2018-07-19 09:57:45 +00:00
|
|
|
|
raise e
|
2018-07-09 19:47:50 +00:00
|
|
|
|
|
2019-09-24 14:22:20 +00:00
|
|
|
|
def find_values_in_logcat(self, **kwargs):
|
2018-07-17 16:27:00 +00:00
|
|
|
|
logcat = self.logcat
|
2019-09-24 14:22:20 +00:00
|
|
|
|
items_in_logcat = list()
|
2018-07-17 16:27:00 +00:00
|
|
|
|
for key, value in kwargs.items():
|
2019-11-29 11:48:07 +00:00
|
|
|
|
if re.findall(r'\W%s$|\W%s\W' % (value, value), logcat):
|
2019-09-24 14:22:20 +00:00
|
|
|
|
items_in_logcat.append('%s in logcat!!!' % key.capitalize())
|
|
|
|
|
return items_in_logcat
|
2018-08-30 16:57:18 +00:00
|
|
|
|
|
|
|
|
|
def asset_by_name(self, asset_name):
|
|
|
|
|
return AssetButton(self.driver, asset_name)
|
2018-10-22 20:30:32 +00:00
|
|
|
|
|
|
|
|
|
def toggle_airplane_mode(self):
|
2019-10-10 17:38:50 +00:00
|
|
|
|
self.airplane_mode_button.click()
|
|
|
|
|
mms_service = self.element_by_text_part("MmsService")
|
|
|
|
|
if mms_service.is_element_displayed():
|
|
|
|
|
self.driver.switch_to.alert().dismiss()
|
2019-04-02 15:16:08 +00:00
|
|
|
|
|
2019-09-25 12:04:40 +00:00
|
|
|
|
def toggle_mobile_data(self):
|
|
|
|
|
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('Wi‑Fi')
|
|
|
|
|
toggle.wait_for_visibility_of_element()
|
|
|
|
|
toggle.click()
|
|
|
|
|
self.driver.back()
|
|
|
|
|
self.driver.back()
|
|
|
|
|
|
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
def open_universal_web_link(self, deep_link):
|
|
|
|
|
start_web_browser(self.driver)
|
|
|
|
|
self.send_as_keyevent(deep_link)
|
|
|
|
|
self.confirm()
|
|
|
|
|
self.open_in_status_button.click()
|
2019-02-11 21:24:36 +00:00
|
|
|
|
|