2018-01-26 11:07:09 +00:00
|
|
|
|
import base64
|
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
|
2023-07-14 15:08:04 +00:00
|
|
|
|
import time
|
2018-01-03 09:34:40 +00:00
|
|
|
|
from datetime import datetime
|
2023-07-14 15:08:04 +00:00
|
|
|
|
|
2023-09-06 00:36:33 +00:00
|
|
|
|
from appium.webdriver import WebElement
|
2024-02-23 16:13:57 +00:00
|
|
|
|
from appium.webdriver.applicationstate import ApplicationState
|
2021-09-24 10:35:19 +00:00
|
|
|
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
2024-09-13 16:38:35 +00:00
|
|
|
|
from selenium.webdriver import ActionChains
|
2023-09-06 00:36:33 +00:00
|
|
|
|
from selenium.webdriver.support import expected_conditions
|
|
|
|
|
from selenium.webdriver.support.wait import WebDriverWait
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
from support.device_apps import start_web_browser
|
2021-11-11 11:40:31 +00:00
|
|
|
|
from tests import common_password, pytest_config_global, transl
|
2021-12-16 16:25:42 +00:00
|
|
|
|
from views.base_element import Button, BaseElement, EditBox, Text, CheckBox
|
2018-01-14 17:43:36 +00:00
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class BackButton(Button):
|
2017-08-28 10:02:20 +00:00
|
|
|
|
def __init__(self, driver):
|
2022-05-30 11:37:13 +00:00
|
|
|
|
super().__init__(driver, 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()
|
2017-10-05 19:41:17 +00:00
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class AllowButton(Button):
|
2017-11-09 10:55:02 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, translation_id="allow", uppercase=True)
|
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()
|
|
|
|
|
except NoSuchElementException:
|
|
|
|
|
pass
|
|
|
|
|
|
2020-03-26 11:36:41 +00:00
|
|
|
|
|
2023-03-13 13:29:18 +00:00
|
|
|
|
class UnreadMessagesCountText(Text):
|
|
|
|
|
def __init__(self, driver, parent_locator: str):
|
2023-07-18 00:51:04 +00:00
|
|
|
|
super().__init__(driver,
|
2024-02-23 17:29:10 +00:00
|
|
|
|
xpath="%s//*[@resource-id='counter-component']/android.widget.TextView" % parent_locator)
|
2021-11-18 15:16:48 +00:00
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
|
2023-03-13 13:29:18 +00:00
|
|
|
|
class TabButton(Button):
|
2020-03-03 12:06:55 +00:00
|
|
|
|
@property
|
2023-03-13 13:29:18 +00:00
|
|
|
|
def counter(self):
|
|
|
|
|
return UnreadMessagesCountText(self.driver, parent_locator='//*[@content-desc="%s"]' % self.accessibility_id)
|
2020-03-03 12:06:55 +00:00
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
|
|
|
|
|
class HomeButton(TabButton):
|
2017-09-21 17:01:04 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-06-14 17:52:58 +00:00
|
|
|
|
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 1 out of 5')]")
|
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
|
|
|
|
|
2020-10-28 19:39:02 +00:00
|
|
|
|
def click(self, desired_view='home'):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
from views.chat_view import ChatView
|
2021-06-23 15:12:42 +00:00
|
|
|
|
from views.home_view import HomeView
|
2020-10-28 19:39:02 +00:00
|
|
|
|
if desired_view == 'home':
|
2021-06-23 15:12:42 +00:00
|
|
|
|
ChatView(self.driver).get_back_to_home_view()
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element = HomeView(self.driver).plus_button
|
2021-06-23 15:12:42 +00:00
|
|
|
|
if not element.is_element_displayed():
|
|
|
|
|
self.click_until_presence_of_element(element)
|
2020-10-28 19:39:02 +00:00
|
|
|
|
elif desired_view == 'chat':
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element = ChatView(self.driver).chat_message_input
|
2021-06-23 15:12:42 +00:00
|
|
|
|
self.click_until_presence_of_element(element)
|
2020-10-28 19:39:02 +00:00
|
|
|
|
elif desired_view == 'other_user_profile':
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element = ChatView(self.driver).profile_nickname
|
2021-06-23 15:12:42 +00:00
|
|
|
|
self.click_until_presence_of_element(element)
|
2018-07-25 11:09:45 +00:00
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2023-01-26 22:28:46 +00:00
|
|
|
|
|
2022-10-26 15:14:25 +00:00
|
|
|
|
class CommunitiesTab(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super().__init__(driver, accessibility_id="communities-stack-tab")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChatsTab(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super().__init__(driver, accessibility_id="chats-stack-tab")
|
2020-05-20 15:43:29 +00:00
|
|
|
|
|
2022-10-26 15:14:25 +00:00
|
|
|
|
def navigate(self):
|
|
|
|
|
from views.home_view import HomeView
|
|
|
|
|
return HomeView(self.driver)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WalletTab(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super().__init__(driver, accessibility_id="wallet-stack-tab")
|
|
|
|
|
|
2024-04-02 14:59:56 +00:00
|
|
|
|
def navigate(self):
|
|
|
|
|
from views.wallet_view import WalletView
|
|
|
|
|
return WalletView(self.driver)
|
|
|
|
|
|
2023-01-26 22:28:46 +00:00
|
|
|
|
|
2022-10-26 15:14:25 +00:00
|
|
|
|
class BrowserTab(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super().__init__(driver, accessibility_id="browser-stack-tab")
|
2021-12-29 16:10:22 +00:00
|
|
|
|
|
2023-11-28 11:02:40 +00:00
|
|
|
|
def navigate(self):
|
|
|
|
|
from views.dapps_view import DappsView
|
|
|
|
|
return DappsView(self.driver)
|
|
|
|
|
|
2023-01-26 22:28:46 +00:00
|
|
|
|
|
2019-03-13 09:36:51 +00:00
|
|
|
|
class DappTabButton(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
2021-06-14 17:52:58 +00:00
|
|
|
|
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 2 out of 5')]")
|
2019-03-13 09:36:51 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2021-02-08 12:52:20 +00:00
|
|
|
|
def click(self, desired_element_text=None):
|
|
|
|
|
if desired_element_text is None:
|
2021-06-23 15:12:42 +00:00
|
|
|
|
super().click()
|
2021-02-08 12:52:20 +00:00
|
|
|
|
elif desired_element_text == 'webview':
|
2021-02-05 11:29:35 +00:00
|
|
|
|
self.find_element().click()
|
2020-12-14 17:39:29 +00:00
|
|
|
|
else:
|
|
|
|
|
base_view = BaseView(self.driver)
|
|
|
|
|
self.click_until_presence_of_element(base_view.element_by_text_part(desired_element_text))
|
2019-03-13 09:36:51 +00:00
|
|
|
|
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):
|
2021-06-14 17:52:58 +00:00
|
|
|
|
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 3 out of 5')]")
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
|
|
|
|
def navigate(self):
|
2024-04-02 14:59:56 +00:00
|
|
|
|
from views.wallet_view_old_ui import WalletView
|
2018-01-03 09:34:40 +00:00
|
|
|
|
return WalletView(self.driver)
|
2017-10-19 13:49:20 +00:00
|
|
|
|
|
2018-07-25 11:09:45 +00:00
|
|
|
|
def click(self):
|
2024-04-02 14:59:56 +00:00
|
|
|
|
from views.wallet_view_old_ui import WalletView
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.click_until_presence_of_element(WalletView(self.driver).multiaccount_more_options)
|
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):
|
2023-07-14 15:08:04 +00:00
|
|
|
|
super().__init__(driver, accessibility_id="open-profile")
|
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
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
def click(self, desired_element_text='privacy'):
|
2023-03-02 09:55:45 +00:00
|
|
|
|
if not self.is_element_displayed():
|
|
|
|
|
ChatsTab(self.driver).click()
|
2021-01-25 16:35:40 +00:00
|
|
|
|
from views.profile_view import ProfileView
|
2023-12-20 20:29:08 +00:00
|
|
|
|
### Profile - legacy
|
|
|
|
|
# if desired_element_text == 'privacy':
|
|
|
|
|
# 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))
|
|
|
|
|
self.click_until_presence_of_element(ProfileView(self.driver).profile_password_button)
|
2018-07-25 11:09:45 +00:00
|
|
|
|
return self.navigate()
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
|
2020-11-12 17:28:34 +00:00
|
|
|
|
class StatusButton(TabButton):
|
|
|
|
|
def __init__(self, driver):
|
2021-06-14 17:52:58 +00:00
|
|
|
|
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 4 out of 5')]")
|
2020-11-12 17:28:34 +00:00
|
|
|
|
|
|
|
|
|
def navigate(self):
|
|
|
|
|
from views.chat_view import ChatView
|
|
|
|
|
return ChatView(self.driver)
|
|
|
|
|
|
2018-07-06 11:10:48 +00:00
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class SendMessageButton(Button):
|
2018-07-19 09:57:45 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, accessibility_id="send-message-button")
|
2018-07-19 09:57:45 +00:00
|
|
|
|
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class AssetButton(Button):
|
2018-08-30 16:57:18 +00:00
|
|
|
|
def __init__(self, driver, asset_name):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, xpath="(//*[@content-desc=':%s-asset-value'])[1]" % asset_name)
|
2018-08-30 16:57:18 +00:00
|
|
|
|
self.asset_name = asset_name
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def name(self):
|
|
|
|
|
return self.asset_name + self.__class__.__name__
|
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.wait_for_element().click()
|
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class OpenInStatusButton(Button):
|
2019-04-02 15:16:08 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, translation_id="browsing-open-in-status")
|
2019-04-02 15:16:08 +00:00
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
2020-10-30 14:40:14 +00:00
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class EnterQRcodeEditBox(EditBox):
|
2020-06-23 09:01:06 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, translation_id="type-a-message")
|
2020-06-23 09:01:06 +00:00
|
|
|
|
|
2020-10-30 14:40:14 +00:00
|
|
|
|
def scan_qr(self, value):
|
2023-09-06 03:07:12 +00:00
|
|
|
|
self.send_keys(value)
|
2021-01-25 16:35:40 +00:00
|
|
|
|
base_view = BaseView(self.driver)
|
2021-02-19 13:46:29 +00:00
|
|
|
|
base_view.ok_button.click()
|
2019-07-15 15:53:56 +00:00
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
self.wait_for_element().click()
|
|
|
|
|
self.wait_for_invisibility_of_element()
|
|
|
|
|
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
class AirplaneModeButton(Button):
|
2019-07-29 00:35:36 +00:00
|
|
|
|
def __init__(self, driver):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
super().__init__(driver, accessibility_id="Airplane mode")
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2021-12-16 16:25:42 +00:00
|
|
|
|
def open_quick_action_menu(self):
|
2024-09-13 16:38:35 +00:00
|
|
|
|
action = ActionChains(self.driver)
|
2021-09-08 14:44:20 +00:00
|
|
|
|
action.press(None, 200, 0).move_to(None, 200, 300).perform()
|
2021-12-16 16:25:42 +00:00
|
|
|
|
|
|
|
|
|
def click(self):
|
|
|
|
|
counter = 0
|
|
|
|
|
desired_element = AirplaneModeButton(self.driver)
|
2022-10-04 15:44:55 +00:00
|
|
|
|
while not desired_element.is_element_displayed() and counter <= 3:
|
2021-12-16 16:25:42 +00:00
|
|
|
|
try:
|
|
|
|
|
self.open_quick_action_menu()
|
|
|
|
|
desired_element.wait_for_element(5)
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
counter += 1
|
|
|
|
|
else:
|
|
|
|
|
self.driver.info("%s element not found" % desired_element.name)
|
2019-07-29 00:35:36 +00:00
|
|
|
|
super(AirplaneModeButton, self).click()
|
2020-01-28 12:00:05 +00:00
|
|
|
|
self.driver.press_keycode(4)
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
|
2021-06-14 17:52:58 +00:00
|
|
|
|
class SignInPhraseText(Text):
|
|
|
|
|
def __init__(self, driver):
|
2021-11-18 15:16:48 +00:00
|
|
|
|
super().__init__(driver, translation_id="this-is-you-signing",
|
|
|
|
|
suffix="//following-sibling::*[2]/android.widget.TextView")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def list(self):
|
|
|
|
|
return self.text.split()
|
|
|
|
|
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2024-04-02 14:59:56 +00:00
|
|
|
|
class SlideButton(Button):
|
|
|
|
|
def __init__(self, driver):
|
|
|
|
|
super().__init__(driver, xpath="//*[@resource-id='slide-button-track']")
|
|
|
|
|
|
|
|
|
|
def slide(self):
|
|
|
|
|
self.swipe_right_on_element(width_percentage=1.3, start_x=100)
|
|
|
|
|
|
|
|
|
|
|
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)
|
2022-07-02 07:50:03 +00:00
|
|
|
|
self.send_contact_request_button = Button(self.driver, translation_id="send-request")
|
2023-08-30 08:49:31 +00:00
|
|
|
|
self.password_input = EditBox(self.driver, accessibility_id="password-input")
|
2023-10-18 22:17:11 +00:00
|
|
|
|
from views.sign_in_view import LogInButton
|
|
|
|
|
self.login_button = LogInButton(self.driver)
|
2024-07-02 15:27:17 +00:00
|
|
|
|
self.continue_button = Button(self.driver, accessibility_id='continue-button')
|
2021-01-25 16:35:40 +00:00
|
|
|
|
|
2022-10-26 15:14:25 +00:00
|
|
|
|
# Old UI Tabs
|
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)
|
2020-11-12 17:28:34 +00:00
|
|
|
|
self.status_button = StatusButton(self.driver)
|
2018-01-14 17:43:36 +00:00
|
|
|
|
|
2022-10-26 15:14:25 +00:00
|
|
|
|
# New UI Tabs
|
|
|
|
|
self.communities_tab = CommunitiesTab(self.driver)
|
|
|
|
|
self.chats_tab = ChatsTab(self.driver)
|
|
|
|
|
self.browser_tab = BrowserTab(self.driver)
|
|
|
|
|
self.wallet_tab = WalletTab(self.driver)
|
|
|
|
|
|
2023-07-12 09:21:39 +00:00
|
|
|
|
# Floating screens (introduced by https://github.com/status-im/status-mobile/pull/16438)
|
|
|
|
|
self.chat_floating_screen = BaseElement(self.driver, accessibility_id=":chat-floating-screen")
|
2023-07-14 15:08:04 +00:00
|
|
|
|
self.community_floating_screen = BaseElement(self.driver,
|
|
|
|
|
accessibility_id=":community-overview-floating-screen")
|
2023-10-16 13:15:05 +00:00
|
|
|
|
self.discover_communities_floating_screen = BaseElement(self.driver,
|
2023-10-18 22:17:11 +00:00
|
|
|
|
accessibility_id=":discover-communities-floating-screen")
|
2023-07-12 09:21:39 +00:00
|
|
|
|
|
2023-01-26 22:28:46 +00:00
|
|
|
|
self.jump_to_button = Button(self.driver, accessibility_id="jump-to")
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.yes_button = Button(self.driver, xpath="//*[@text='YES' or @text='GOT IT']")
|
|
|
|
|
self.no_button = Button(self.driver, translation_id="no")
|
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)
|
2023-12-09 00:25:19 +00:00
|
|
|
|
self.allow_all_button = Button(self.driver, xpath="//*[@text='Allow all']")
|
2021-02-23 12:19:55 +00:00
|
|
|
|
self.allow_all_the_time = Button(self.driver, xpath="//*[@text='Allow all the time']")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
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.add_button = Button(self.driver, translation_id="add")
|
|
|
|
|
self.save_button = Button(self.driver, translation_id="save")
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.done_button = Button(self.driver, accessibility_id="Done")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.delete_button = Button(self.driver, translation_id="delete", uppercase=True)
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.ok_continue_button = Button(self.driver, accessibility_id="Okay, continue")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.discard_button = Button(self.driver, xpath="//*[@text='DISCARD']")
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.confirm_button = Button(self.driver, accessibility_id='Confirm')
|
2021-02-16 14:57:20 +00:00
|
|
|
|
|
2021-04-19 15:55:25 +00:00
|
|
|
|
self.cross_icon = Button(self.driver, xpath="(//android.widget.ImageView[@content-desc='icon'])[1]")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
self.close_sticker_view_icon = Button(self.driver, xpath="//androidx.appcompat.widget.LinearLayoutCompat")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.native_close_button = Button(self.driver, id="android:id/aerr_close")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
self.close_button = Button(self.driver, accessibility_id="back-button")
|
2022-05-30 11:49:30 +00:00
|
|
|
|
self.navigate_up_button = Button(self.driver, accessibility_id="Navigate Up")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.show_roots_button = Button(self.driver, accessibility_id="Show roots")
|
|
|
|
|
self.get_started_button = Button(self.driver, translation_id="get-started")
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.ok_got_it_button = Button(self.driver, accessibility_id="Okay, got it")
|
2021-01-25 16:35:40 +00:00
|
|
|
|
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")
|
2021-05-25 16:42:58 +00:00
|
|
|
|
self.qr_code_image = Button(self.driver, accessibility_id="qr-code-image")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
self.sign_in_phrase = SignInPhraseText(self.driver)
|
2023-07-14 15:08:04 +00:00
|
|
|
|
self.toast_content_element = BaseElement(self.driver, accessibility_id="toast-content")
|
2024-04-30 12:44:14 +00:00
|
|
|
|
self.next_button = Button(self.driver, accessibility_id="next-button")
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.native_alert_title = Text(self.driver, xpath="//*[@resource-id='android:id/alertTitle']")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
|
2023-12-20 20:29:08 +00:00
|
|
|
|
# share contact screen
|
2024-06-12 22:55:38 +00:00
|
|
|
|
self.show_qr_code_button = Button(self.driver, accessibility_id="show-qr-button")
|
|
|
|
|
|
2023-12-20 20:29:08 +00:00
|
|
|
|
self.link_to_profile_button = Button(self.driver, accessibility_id="share-qr-code-info-text")
|
2024-04-03 10:45:07 +00:00
|
|
|
|
self.sharing_text_native = Text(self.driver, xpath="//*[@resource-id='android:id/content_preview_text']")
|
2023-12-20 20:29:08 +00:00
|
|
|
|
|
2021-12-16 16:25:42 +00:00
|
|
|
|
# checkboxes and toggles
|
2024-10-03 13:34:43 +00:00
|
|
|
|
self.checkbox_button = CheckBox(
|
|
|
|
|
self.driver, xpath="//*[@content-desc='checkbox-off'][@resource-id='checkbox-component']")
|
2024-04-02 14:59:56 +00:00
|
|
|
|
self.slide_button_track = SlideButton(self.driver)
|
2021-12-16 16:25:42 +00:00
|
|
|
|
|
2019-04-02 15:16:08 +00:00
|
|
|
|
# external browser
|
|
|
|
|
self.open_in_status_button = OpenInStatusButton(self.driver)
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.apps_button = Button(self.driver, accessibility_id="Apps")
|
|
|
|
|
self.status_app_icon = Button(self.driver, translation_id="status")
|
2019-07-29 00:35:36 +00:00
|
|
|
|
self.airplane_mode_button = AirplaneModeButton(self.driver)
|
2021-06-18 11:09:03 +00:00
|
|
|
|
self.enter_qr_edit_box = EnterQRcodeEditBox(self.driver)
|
2019-07-29 00:35:36 +00:00
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
self.element_types = {
|
|
|
|
|
'base': BaseElement,
|
2021-01-25 16:35:40 +00:00
|
|
|
|
'button': Button,
|
|
|
|
|
'edit_box': EditBox,
|
|
|
|
|
'text': Text
|
2018-01-03 09:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-11 15:37:27 +00:00
|
|
|
|
@property
|
|
|
|
|
def status_account_name(self):
|
2022-07-05 12:35:53 +00:00
|
|
|
|
return self.get_translation_by_key('main-account')
|
2020-11-11 15:37:27 +00:00
|
|
|
|
|
2018-03-15 20:01:08 +00:00
|
|
|
|
def accept_agreements(self):
|
2018-06-14 17:38:27 +00:00
|
|
|
|
iterations = int()
|
2020-09-09 15:06:07 +00:00
|
|
|
|
self.close_native_device_dialog("Messages has stopped")
|
2020-01-28 12:00:05 +00:00
|
|
|
|
self.close_native_device_dialog("YouTube")
|
2019-12-19 09:19:01 +00:00
|
|
|
|
while iterations <= 1 and (self.ok_button.is_element_displayed(2) or
|
2019-07-11 15:44:12 +00:00
|
|
|
|
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
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
@staticmethod
|
2021-11-18 15:16:48 +00:00
|
|
|
|
def get_translation_by_key(translation_id):
|
|
|
|
|
return transl[translation_id]
|
2020-11-11 15:37:27 +00:00
|
|
|
|
|
2020-03-26 11:36:41 +00:00
|
|
|
|
def rooted_device_continue(self):
|
|
|
|
|
try:
|
|
|
|
|
self.continue_button.wait_for_element(3)
|
|
|
|
|
self.continue_button.click()
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
pass
|
|
|
|
|
|
2019-12-19 09:19:01 +00:00
|
|
|
|
def close_native_device_dialog(self, alert_text_part):
|
|
|
|
|
element = self.element_by_text_part(alert_text_part)
|
2022-10-04 15:44:55 +00:00
|
|
|
|
if element.is_element_displayed(1):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Closing '%s' alert..." % alert_text_part)
|
2021-01-25 16:35:40 +00:00
|
|
|
|
self.native_close_button.click()
|
2019-12-19 09:19:01 +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:
|
2020-07-10 16:00:56 +00:00
|
|
|
|
return str([i for i in logcat if not ('appium' in str(i).lower() or ':1.000000.' in str(i).lower())])
|
2018-07-17 16:27:00 +00:00
|
|
|
|
raise TimeoutError('Logcat is empty')
|
2017-11-09 10:58:11 +00:00
|
|
|
|
|
2017-08-28 10:02:20 +00:00
|
|
|
|
def confirm(self):
|
2021-10-25 16:05:22 +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
|
2022-10-04 15:44:55 +00:00
|
|
|
|
while not desired_element.is_element_displayed(1) and counter <= attempts:
|
2018-08-07 13:23:31 +00:00
|
|
|
|
try:
|
|
|
|
|
self.confirm()
|
2021-10-25 16:05:22 +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
|
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
def just_fyi(self, some_str):
|
|
|
|
|
self.driver.info('# STEP: %s' % some_str, device=False)
|
2022-07-12 15:14:32 +00:00
|
|
|
|
self.driver.execute_script("sauce:context=STEP: %s" % some_str)
|
2019-09-26 09:11:46 +00:00
|
|
|
|
|
2023-04-28 10:15:32 +00:00
|
|
|
|
def hide_keyboard_if_shown(self):
|
|
|
|
|
if self.driver.is_keyboard_shown():
|
2023-06-13 03:24:21 +00:00
|
|
|
|
self.click_system_back_button()
|
2023-04-28 10:15:32 +00:00
|
|
|
|
|
2019-11-20 16:27:29 +00:00
|
|
|
|
def click_system_back_button(self, times=1):
|
2021-10-25 16:05:22 +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
|
|
|
|
|
2023-08-18 16:20:40 +00:00
|
|
|
|
def navigate_back_to_home_view(self, attempts=3):
|
2022-05-06 14:06:29 +00:00
|
|
|
|
counter = 0
|
2023-10-16 13:15:05 +00:00
|
|
|
|
while not self.chat_floating_screen.is_element_disappeared(1) \
|
|
|
|
|
or not self.community_floating_screen.is_element_disappeared(1) \
|
|
|
|
|
or not self.discover_communities_floating_screen.is_element_disappeared(1):
|
2023-07-12 09:21:39 +00:00
|
|
|
|
self.driver.press_keycode(4)
|
2023-08-18 16:20:40 +00:00
|
|
|
|
element = self.chats_tab
|
2022-10-04 15:44:55 +00:00
|
|
|
|
while not element.is_element_displayed(1) and counter <= attempts:
|
2022-09-23 08:55:36 +00:00
|
|
|
|
self.driver.press_keycode(4)
|
2022-05-06 14:06:29 +00:00
|
|
|
|
try:
|
2022-10-04 15:44:55 +00:00
|
|
|
|
element.wait_for_element(2)
|
2022-05-06 14:06:29 +00:00
|
|
|
|
return self
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
counter += 1
|
|
|
|
|
else:
|
2023-08-18 16:20:40 +00:00
|
|
|
|
self.driver.info("Could not reach home view by pressing system back button")
|
|
|
|
|
|
|
|
|
|
def navigate_back_to_chat_view(self, attempts=3):
|
|
|
|
|
counter = 0
|
|
|
|
|
element = self.get_chat_view().chat_message_input
|
|
|
|
|
while not element.is_element_displayed(1) and counter <= attempts:
|
|
|
|
|
self.driver.press_keycode(4)
|
|
|
|
|
try:
|
|
|
|
|
element.wait_for_element(2)
|
|
|
|
|
return
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
counter += 1
|
|
|
|
|
self.driver.info("Could not reach chat view by pressing system back button")
|
2022-05-06 14:06:29 +00:00
|
|
|
|
|
2024-05-14 20:13:02 +00:00
|
|
|
|
def navigate_back_to_wallet_view(self, attempts=3):
|
|
|
|
|
counter = 0
|
|
|
|
|
element = self.get_wallet_view().network_drop_down
|
|
|
|
|
while not element.is_element_displayed(1) and counter <= attempts:
|
|
|
|
|
self.driver.press_keycode(4)
|
|
|
|
|
try:
|
|
|
|
|
element.wait_for_element(2)
|
|
|
|
|
return
|
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
counter += 1
|
|
|
|
|
self.driver.info("Could not reach wallet view by pressing system back button")
|
|
|
|
|
|
2021-04-23 12:36:38 +00:00
|
|
|
|
def get_app_from_background(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Get Status back from Recent apps')
|
2021-04-23 12:36:38 +00:00
|
|
|
|
self.driver.press_keycode(187)
|
|
|
|
|
self.status_in_background_button.click()
|
|
|
|
|
|
2020-11-26 17:33:43 +00:00
|
|
|
|
def put_app_to_background_and_back(self, time_in_background=1):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Put app to background and back')
|
2020-11-26 17:33:43 +00:00
|
|
|
|
self.driver.press_keycode(187)
|
|
|
|
|
time.sleep(time_in_background)
|
|
|
|
|
self.status_in_background_button.click()
|
|
|
|
|
|
2020-07-20 15:13:09 +00:00
|
|
|
|
def click_system_home_button(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Press system Home button')
|
2020-07-20 15:13:09 +00:00
|
|
|
|
self.driver.press_keycode(3)
|
|
|
|
|
|
2020-12-03 12:59:20 +00:00
|
|
|
|
def put_app_to_background(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('App to background')
|
2020-12-03 12:59:20 +00:00
|
|
|
|
self.driver.press_keycode(187)
|
|
|
|
|
|
2018-07-03 18:50:18 +00:00
|
|
|
|
def cut_text(self):
|
2021-10-25 16:05:22 +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):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Copy text')
|
2018-07-03 12:32:01 +00:00
|
|
|
|
self.driver.press_keycode(278)
|
|
|
|
|
|
|
|
|
|
def paste_text(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Paste text')
|
2018-07-03 12:32:01 +00:00
|
|
|
|
self.driver.press_keycode(279)
|
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
def send_as_keyevent(self, keyevent):
|
|
|
|
|
self.driver.info("Sending as keyevent `%s`" % keyevent)
|
2017-10-05 19:41:17 +00:00
|
|
|
|
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)
|
2021-11-18 15:16:48 +00:00
|
|
|
|
for i in keyevent:
|
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
|
|
|
|
|
2018-02-09 15:16:07 +00:00
|
|
|
|
def element_by_text(self, text, element_type='button'):
|
2018-01-03 09:34:40 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element.locator = '//*[@text="%s"]' % 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-01-03 09:34:40 +00:00
|
|
|
|
element = self.element_types[element_type](self.driver)
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element.locator = '//*[contains(@text, "' + text + '")]'
|
2017-11-09 10:55:02 +00:00
|
|
|
|
return element
|
|
|
|
|
|
2021-01-25 16:35:40 +00:00
|
|
|
|
def element_starts_with_text(self, text, element_type='button'):
|
|
|
|
|
element = self.element_types[element_type](self.driver, xpath="//*[starts-with(@text,'%s')]" % text)
|
2018-04-30 09:58:20 +00:00
|
|
|
|
return element
|
|
|
|
|
|
2021-11-18 15:16:48 +00:00
|
|
|
|
def element_by_translation_id(self, translation_id, element_type='button', uppercase=False):
|
|
|
|
|
element = self.element_types[element_type](self.driver, translation_id=translation_id, uppercase=uppercase)
|
2020-11-11 15:37:27 +00:00
|
|
|
|
return element
|
|
|
|
|
|
2018-04-30 09:58:20 +00:00
|
|
|
|
def wait_for_element_starts_with_text(self, text, wait_time=60):
|
2021-01-25 16:35:40 +00:00
|
|
|
|
element = Button(self.driver, xpath="//*[starts-with(@text,'%s')]" % text)
|
2018-04-30 09:58:20 +00:00
|
|
|
|
return element.wait_for_element(wait_time)
|
|
|
|
|
|
2021-06-18 11:09:03 +00:00
|
|
|
|
def swipe_by_custom_coordinates(self, x_start, y_start, x_end, y_end):
|
|
|
|
|
"""Uses percentage values based on device width/height"""
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Swiping based on custom coordinates relative to device height/width")
|
2021-06-18 11:09:03 +00:00
|
|
|
|
size = self.driver.get_window_size()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
self.driver.swipe(size["width"] * x_start, size["height"] * y_start, size["width"] * x_end,
|
|
|
|
|
size["height"] * y_end)
|
2021-06-18 11:09:03 +00:00
|
|
|
|
|
2019-06-24 15:53:02 +00:00
|
|
|
|
def swipe_up(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Swiping up")
|
2019-06-14 15:28:03 +00:00
|
|
|
|
size = self.driver.get_window_size()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
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):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Swiping down")
|
2019-06-24 15:53:02 +00:00
|
|
|
|
size = self.driver.get_window_size()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
self.driver.swipe(size["width"] * 0.5, size["height"] * 0.2, size["width"] * 0.5, size["height"] * 0.8)
|
2019-06-24 15:53:02 +00:00
|
|
|
|
|
2019-06-14 15:28:03 +00:00
|
|
|
|
def swipe_left(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Swiping left")
|
2019-06-14 15:28:03 +00:00
|
|
|
|
size = self.driver.get_window_size()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
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):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Swiping right")
|
2019-09-05 02:32:33 +00:00
|
|
|
|
size = self.driver.get_window_size()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
self.driver.swipe(size["width"] * 0.2, size["height"] * 0.8, size["width"] * 0.8, size["height"] * 0.8)
|
2019-09-05 02:32:33 +00:00
|
|
|
|
|
2021-03-02 10:20:00 +00:00
|
|
|
|
def switch_to_mobile(self, before_login=False, sync=False):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Turning on mobile data, syncing is %s" % str(sync))
|
2021-03-02 10:20:00 +00:00
|
|
|
|
self.driver.set_network_connection(4)
|
|
|
|
|
if before_login is False:
|
|
|
|
|
from views.home_view import HomeView
|
|
|
|
|
home = HomeView(self.driver)
|
|
|
|
|
if sync is True:
|
|
|
|
|
home.continue_syncing_button.wait_and_click()
|
|
|
|
|
else:
|
|
|
|
|
home.stop_syncing_button.wait_and_click()
|
|
|
|
|
|
|
|
|
|
def pull_to_refresh(self, wait_sec=20):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Pull to refresh view")
|
2021-03-02 10:20:00 +00:00
|
|
|
|
self.driver.swipe(500, 500, 500, 1000)
|
|
|
|
|
time.sleep(wait_sec)
|
|
|
|
|
|
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)
|
|
|
|
|
|
2022-06-22 14:09:04 +00:00
|
|
|
|
def get_dapp_view(self):
|
|
|
|
|
from views.dapps_view import DappsView
|
|
|
|
|
return DappsView(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)
|
|
|
|
|
|
2023-02-24 19:05:30 +00:00
|
|
|
|
def get_community_view(self):
|
|
|
|
|
from views.chat_view import CommunityView
|
|
|
|
|
return CommunityView(self.driver)
|
|
|
|
|
|
2018-01-03 09:34:40 +00:00
|
|
|
|
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)
|
|
|
|
|
|
2021-06-08 10:58:26 +00:00
|
|
|
|
def get_transaction_view(self):
|
|
|
|
|
from views.transactions_view import TransactionsView
|
|
|
|
|
return TransactionsView(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)
|
|
|
|
|
|
2021-06-18 11:09:03 +00:00
|
|
|
|
def get_webview_view(self):
|
|
|
|
|
from views.web_views.base_web_view import BaseWebView
|
|
|
|
|
return BaseWebView(self.driver)
|
|
|
|
|
|
2018-06-29 17:27:30 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def get_unique_amount():
|
2022-03-07 21:17:39 +00:00
|
|
|
|
return '0.000%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
|
2020-04-10 10:25:46 +00:00
|
|
|
|
def get_random_chat_name():
|
2018-06-29 17:27:30 +00:00
|
|
|
|
return ''.join(random.choice(string.ascii_lowercase) for _ in range(7))
|
|
|
|
|
|
2021-02-10 14:57:55 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def get_random_message():
|
|
|
|
|
message = 'test message:'
|
|
|
|
|
return message + ''.join(random.choice(string.ascii_lowercase) for _ in range(10))
|
|
|
|
|
|
2020-10-28 08:46:17 +00:00
|
|
|
|
def get_back_to_home_view(self, times_to_click_on_back_btn=3):
|
2018-05-02 16:01:17 +00:00
|
|
|
|
counter = 0
|
2022-08-25 10:49:51 +00:00
|
|
|
|
while self.back_button.is_element_displayed(2) or self.navigate_up_button.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
|
2022-08-23 15:14:56 +00:00
|
|
|
|
if self.back_button.is_element_displayed(2):
|
2022-08-25 10:49:51 +00:00
|
|
|
|
self.back_button.click_until_absense_of_element(self.back_button)
|
2022-05-30 11:49:30 +00:00
|
|
|
|
else:
|
2022-08-25 10:49:51 +00:00
|
|
|
|
self.navigate_up_button.click_until_absense_of_element(self.navigate_up_button)
|
2018-05-02 16:01:17 +00:00
|
|
|
|
counter += 1
|
2020-03-17 09:15:02 +00:00
|
|
|
|
except (NoSuchElementException, TimeoutException):
|
|
|
|
|
continue
|
2022-05-30 11:49:30 +00:00
|
|
|
|
return self
|
2021-06-23 15:12:42 +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
|
|
|
|
|
2023-08-16 16:30:19 +00:00
|
|
|
|
def click_on_floating_jump_to(self):
|
2023-06-13 03:24:21 +00:00
|
|
|
|
self.hide_keyboard_if_shown()
|
2023-08-16 16:30:19 +00:00
|
|
|
|
if self.chat_floating_screen.is_element_displayed(1):
|
|
|
|
|
Button(self.driver, xpath='//*[@content-desc="%s"]//*[@content-desc="%s"]' %
|
2023-08-18 16:20:40 +00:00
|
|
|
|
(self.chat_floating_screen.accessibility_id,
|
|
|
|
|
self.jump_to_button.accessibility_id)).click()
|
2023-08-16 16:30:19 +00:00
|
|
|
|
elif self.community_floating_screen.is_element_displayed(1):
|
|
|
|
|
Button(self.driver, xpath='//*[@content-desc="%s"]//*[@content-desc="%s"]' %
|
|
|
|
|
(self.community_floating_screen.accessibility_id,
|
|
|
|
|
self.jump_to_button.accessibility_id)).click()
|
|
|
|
|
else:
|
|
|
|
|
self.jump_to_button.click()
|
|
|
|
|
|
|
|
|
|
def jump_to_messages_home(self):
|
|
|
|
|
self.click_on_floating_jump_to()
|
|
|
|
|
self.chats_tab.click()
|
2023-01-26 22:28:46 +00:00
|
|
|
|
|
|
|
|
|
def jump_to_communities_home(self):
|
2023-08-16 16:30:19 +00:00
|
|
|
|
self.click_on_floating_jump_to()
|
|
|
|
|
self.communities_tab.click()
|
2023-01-26 22:28:46 +00:00
|
|
|
|
|
2023-03-08 10:31:42 +00:00
|
|
|
|
def jump_to_card_by_text(self, text: str):
|
2023-08-16 16:30:19 +00:00
|
|
|
|
self.click_on_floating_jump_to()
|
2023-03-08 10:31:42 +00:00
|
|
|
|
self.element_by_text(text).click()
|
|
|
|
|
|
2024-02-23 16:13:57 +00:00
|
|
|
|
def wait_for_application_to_be_running(self, app_package: str, wait_time: int = 3):
|
|
|
|
|
for _ in range(wait_time):
|
|
|
|
|
if self.driver.query_app_state(app_package) == ApplicationState.RUNNING_IN_FOREGROUND:
|
|
|
|
|
return
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
raise TimeoutException(msg="Status app is not running in foreground after %s sec" % wait_time)
|
|
|
|
|
|
|
|
|
|
def wait_for_application_to_not_run(self, app_package: str, wait_time: int = 3):
|
|
|
|
|
for _ in range(wait_time):
|
|
|
|
|
if self.driver.query_app_state(app_package) == ApplicationState.NOT_RUNNING:
|
|
|
|
|
return
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
raise TimeoutException(msg="Status app is not terminated after %s sec" % wait_time)
|
|
|
|
|
|
2024-11-20 19:51:06 +00:00
|
|
|
|
def reopen_app(self, password=common_password, sign_in=True, user_name=None):
|
2023-09-06 10:54:16 +00:00
|
|
|
|
app_package = self.driver.current_package
|
2023-09-06 03:07:12 +00:00
|
|
|
|
self.driver.terminate_app(app_package)
|
2024-02-23 16:13:57 +00:00
|
|
|
|
self.wait_for_application_to_not_run(app_package=app_package)
|
2023-09-06 03:07:12 +00:00
|
|
|
|
self.driver.activate_app(app_package)
|
2023-05-04 14:26:59 +00:00
|
|
|
|
if sign_in:
|
|
|
|
|
sign_in_view = self.get_sign_in_view()
|
2024-11-20 19:51:06 +00:00
|
|
|
|
sign_in_view.sign_in(user_name, password)
|
2022-01-27 20:41:57 +00:00
|
|
|
|
|
2019-12-20 17:35:36 +00:00
|
|
|
|
def close_share_popup(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Closing share popup")
|
2024-09-13 16:38:35 +00:00
|
|
|
|
ActionChains(self.driver).tap(None, 255, 104, 1).perform()
|
2020-10-06 14:48:08 +00:00
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
2022-07-02 07:50:03 +00:00
|
|
|
|
def tap_mutual_cr_switcher(self):
|
|
|
|
|
profile_view = self.profile_button.click()
|
|
|
|
|
profile_view.advanced_button.scroll_and_click()
|
|
|
|
|
profile_view.mutual_contact_request_switcher.scroll_and_click()
|
|
|
|
|
profile_view.click_system_back_button()
|
|
|
|
|
|
2018-07-03 12:40:44 +00:00
|
|
|
|
def share_via_messenger(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Sharing via messenger", device=False)
|
2022-05-04 15:40:13 +00:00
|
|
|
|
self.element_by_text('Messages').wait_for_visibility_of_element(40)
|
|
|
|
|
self.element_by_text('Messages').click_until_presence_of_element(self.element_by_text('New message'))
|
2021-09-17 16:20:12 +00:00
|
|
|
|
self.element_by_text('New message').wait_and_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
|
|
|
|
|
2020-07-20 15:13:09 +00:00
|
|
|
|
def click_upon_push_notification_by_text(self, text):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
element = self.element_by_text_part(text)
|
|
|
|
|
self.driver.info("Click on PN with text: '%s'" % element.exclude_emoji(text))
|
|
|
|
|
element.click()
|
2020-07-20 15:13:09 +00:00
|
|
|
|
return self.get_chat_view()
|
|
|
|
|
|
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():
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Checking in logcat for: `%s`" % value)
|
2021-01-28 12:55:23 +00:00
|
|
|
|
escaped_value = re.escape(value)
|
|
|
|
|
if re.findall(r'\W%s$|\W%s\W' % (escaped_value, escaped_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
|
|
|
|
|
2020-11-03 16:15:14 +00:00
|
|
|
|
def find_values_in_geth(self, *args):
|
2023-08-09 21:26:13 +00:00
|
|
|
|
from tests.base_test_case import pull_geth
|
|
|
|
|
b64_log = pull_geth(self.driver)
|
2020-11-03 16:15:14 +00:00
|
|
|
|
file = base64.b64decode(b64_log)
|
|
|
|
|
result = False
|
|
|
|
|
for value in args:
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Checking in geth for: `%s`' % value)
|
2020-11-03 16:15:14 +00:00
|
|
|
|
if re.findall('%s*' % value, file.decode("utf-8")):
|
|
|
|
|
self.driver.info('%s was found in geth.log' % value)
|
|
|
|
|
result = True
|
|
|
|
|
return result
|
|
|
|
|
|
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
|
|
|
|
|
2020-07-20 15:13:09 +00:00
|
|
|
|
def open_notification_bar(self):
|
2020-08-20 10:33:25 +00:00
|
|
|
|
self.driver.open_notifications()
|
2020-07-20 15:13:09 +00:00
|
|
|
|
|
2018-10-22 20:30:32 +00:00
|
|
|
|
def toggle_airplane_mode(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Toggling airplane mode")
|
2019-10-10 17:38:50 +00:00
|
|
|
|
self.airplane_mode_button.click()
|
2019-12-19 09:19:01 +00:00
|
|
|
|
self.close_native_device_dialog("MmsService")
|
2019-04-02 15:16:08 +00:00
|
|
|
|
|
2021-08-02 15:00:18 +00:00
|
|
|
|
def set_device_to_offline(self):
|
2024-10-03 13:34:43 +00:00
|
|
|
|
# setting network connection to data only and switching off Wi-Fi
|
2021-08-02 15:00:18 +00:00
|
|
|
|
self.driver.set_network_connection(2)
|
|
|
|
|
self.driver.toggle_wifi()
|
|
|
|
|
|
|
|
|
|
def set_network_to_cellular_only(self):
|
|
|
|
|
self.driver.set_network_connection(4)
|
|
|
|
|
|
2019-09-25 12:04:40 +00:00
|
|
|
|
def toggle_mobile_data(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Toggling mobile data")
|
2019-09-25 12:04:40 +00:00
|
|
|
|
self.driver.start_activity(app_package='com.android.settings', app_activity='.Settings')
|
2020-03-17 17:27:10 +00:00
|
|
|
|
network_and_internet = self.element_by_text('Network & internet')
|
2019-09-25 12:04:40 +00:00
|
|
|
|
network_and_internet.wait_for_visibility_of_element()
|
|
|
|
|
network_and_internet.click()
|
2021-11-18 15:16:48 +00:00
|
|
|
|
toggle = Button(self.driver, accessibility_id='Wi‑Fi')
|
2019-09-25 12:04:40 +00:00
|
|
|
|
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)
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Open web link via web browser: `%s`' % deep_link)
|
2020-03-26 11:36:41 +00:00
|
|
|
|
self.driver.get(deep_link)
|
2019-02-11 21:24:36 +00:00
|
|
|
|
|
2020-04-21 08:39:45 +00:00
|
|
|
|
def upgrade_app(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Upgrading apk to apk_upgrade")
|
2020-04-21 08:39:45 +00:00
|
|
|
|
self.driver.install_app(pytest_config_global['apk_upgrade'], replace=True)
|
2023-09-06 10:54:16 +00:00
|
|
|
|
if self.driver.is_app_installed('im.status.ethereum'):
|
|
|
|
|
app_package = 'im.status.ethereum'
|
|
|
|
|
else:
|
|
|
|
|
app_package = 'im.status.ethereum.pr'
|
2023-09-06 03:07:12 +00:00
|
|
|
|
self.app = self.driver.activate_app(app_package)
|
2020-04-21 08:39:45 +00:00
|
|
|
|
|
2020-05-20 15:43:29 +00:00
|
|
|
|
def search_by_keyword(self, keyword):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info('Search for `%s`' % keyword)
|
2020-10-20 15:34:52 +00:00
|
|
|
|
self.search_input.click()
|
|
|
|
|
self.search_input.send_keys(keyword)
|
2020-05-20 15:43:29 +00:00
|
|
|
|
|
2021-06-14 17:52:58 +00:00
|
|
|
|
def set_up_wallet_when_sending_tx(self):
|
2021-10-25 16:05:22 +00:00
|
|
|
|
self.driver.info("Setting up wallet")
|
2021-06-14 17:52:58 +00:00
|
|
|
|
phrase = self.sign_in_phrase.text
|
2021-08-19 11:41:41 +00:00
|
|
|
|
self.ok_got_it_button.wait_and_click(20)
|
2021-06-14 17:52:58 +00:00
|
|
|
|
return phrase
|
|
|
|
|
|
2021-06-23 15:12:42 +00:00
|
|
|
|
def get_empty_dapp_tab(self):
|
|
|
|
|
from views.web_views.base_web_view import BaseWebView
|
|
|
|
|
web_view = BaseWebView(self.driver)
|
|
|
|
|
web_view.options_button.click()
|
|
|
|
|
if web_view.new_tab_button.is_element_displayed():
|
|
|
|
|
web_view.new_tab_button.click()
|
|
|
|
|
return web_view
|
|
|
|
|
|
2022-09-08 14:27:38 +00:00
|
|
|
|
def get_test_assets(self, token=False, keycard=False):
|
|
|
|
|
from views.home_view import HomeView
|
|
|
|
|
status_test_dapp = HomeView(self.driver).open_status_test_dapp()
|
|
|
|
|
status_test_dapp.wait_for_d_aap_to_load()
|
|
|
|
|
|
|
|
|
|
self.just_fyi("Requesting test assets in dapp")
|
|
|
|
|
status_test_dapp.assets_button.click()
|
|
|
|
|
if token:
|
|
|
|
|
send_tx = status_test_dapp.request_stt_button.click()
|
|
|
|
|
send_tx.sign_transaction(keycard=keycard)
|
|
|
|
|
wallet = self.wallet_button.click()
|
|
|
|
|
wallet.wait_balance_is_changed(asset='STT', scan_tokens=True)
|
|
|
|
|
else:
|
|
|
|
|
status_test_dapp.request_eth_button.click()
|
|
|
|
|
status_test_dapp.ok_button.wait_and_click()
|
|
|
|
|
wallet = self.wallet_button.click()
|
|
|
|
|
wallet.wait_balance_is_changed()
|
|
|
|
|
|
|
|
|
|
return wallet
|
|
|
|
|
|
|
|
|
|
def donate_leftovers(self, keycard=False):
|
|
|
|
|
self.just_fyi("Send leftovers from test accounts")
|
|
|
|
|
wallet = self.wallet_button.click()
|
|
|
|
|
self.wallet_button.click()
|
|
|
|
|
send_transaction = wallet.send_transaction_from_main_screen.click()
|
|
|
|
|
send_transaction.set_max_button.click()
|
|
|
|
|
send_transaction.confirm()
|
|
|
|
|
send_transaction.chose_recipient_button.click()
|
2022-09-23 08:55:36 +00:00
|
|
|
|
send_transaction.set_recipient_address('0xE2363E6e91d1a29d82C2c695fa8fa2e3Fa5d55eA')
|
2022-09-08 14:27:38 +00:00
|
|
|
|
send_transaction.sign_transaction_button.click()
|
|
|
|
|
send_transaction.sign_transaction(keycard=keycard)
|
|
|
|
|
|
2022-12-30 14:34:19 +00:00
|
|
|
|
def tap_by_coordinates(self, x, y):
|
2024-09-13 16:38:35 +00:00
|
|
|
|
self.driver.tap(positions=[(x, y)])
|
2022-12-30 14:34:19 +00:00
|
|
|
|
|
2020-03-17 17:27:10 +00:00
|
|
|
|
# Method-helper
|
|
|
|
|
def write_page_source_to_file(self, full_path_to_file):
|
|
|
|
|
string_source = self.driver.page_source
|
|
|
|
|
source = open(full_path_to_file, "a+")
|
|
|
|
|
source.write(string_source)
|
2023-07-14 15:08:04 +00:00
|
|
|
|
|
|
|
|
|
def wait_for_current_package_to_be(self, expected_package_name: str, timeout: int = 10):
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
while time.time() - start_time <= timeout:
|
|
|
|
|
package = self.driver.current_package
|
|
|
|
|
if package == expected_package_name:
|
|
|
|
|
return
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
raise TimeoutException("Driver current package is '%s' after %s seconds" % (package, timeout))
|
2023-09-06 00:36:33 +00:00
|
|
|
|
|
|
|
|
|
def wait_for_staleness_of_element(self, element_instance: WebElement, seconds=10):
|
|
|
|
|
try:
|
|
|
|
|
return WebDriverWait(self.driver, seconds).until(expected_conditions.staleness_of(element_instance))
|
|
|
|
|
except TimeoutException:
|
|
|
|
|
raise TimeoutException(
|
|
|
|
|
"Device %s: expected element is not stale after %s seconds" % (self.driver.number, seconds)) from None
|
2023-11-28 11:02:40 +00:00
|
|
|
|
|
2023-11-29 16:03:07 +00:00
|
|
|
|
def open_link_from_google_search_app(self, link_text: str, app_package: str):
|
2023-12-09 00:25:19 +00:00
|
|
|
|
Button(self.driver, accessibility_id="Search").click()
|
2023-11-28 11:02:40 +00:00
|
|
|
|
EditBox(self.driver, xpath="//android.widget.EditText").send_keys(link_text)
|
|
|
|
|
self.driver.press_keycode(66)
|
2023-11-29 16:03:07 +00:00
|
|
|
|
text_to_click = "Status PR" if app_package.endswith(".pr") else "Status"
|
|
|
|
|
Button(self.driver,
|
|
|
|
|
xpath="//*[@resource-id='android:id/resolver_list']//*[@text='%s']" % text_to_click).click_if_shown()
|
2023-11-28 11:02:40 +00:00
|
|
|
|
Button(self.driver, xpath="//*[@resource-id='android:id/button_once']").click()
|