added 'send transaction initiated from the DApp' and 'send transaction with invalid password' tests, basetestcase reworked for smooth local runs

added 'send transaction initiated from the DApp' and 'send transaction with invalid password' tests, basetestcase reworked for smooth local runs
This commit is contained in:
Anton Danchenko 2017-10-05 22:41:17 +03:00
parent d7fcb333da
commit 98beef138f
11 changed files with 285 additions and 65 deletions

View File

@ -6,7 +6,10 @@ from appium import webdriver
from abc import ABCMeta, \ from abc import ABCMeta, \
abstractmethod abstractmethod
import hmac import hmac
import re
import subprocess
from hashlib import md5 from hashlib import md5
from selenium.common.exceptions import WebDriverException
class AbstractTestCase: class AbstractTestCase:
@ -26,21 +29,8 @@ class AbstractTestCase:
return 'http://%s:%s@ondemand.saucelabs.com:80/wd/hub' % (self.sauce_username, self.sauce_access_key) return 'http://%s:%s@ondemand.saucelabs.com:80/wd/hub' % (self.sauce_username, self.sauce_access_key)
@property @property
def capabilities_sauce_lab(self): def executor_local(self):
return 'http://localhost:4723/wd/hub'
desired_caps = dict()
desired_caps['platformName'] = 'Android'
desired_caps['appiumVersion'] = '1.6.5'
desired_caps['platformVersion'] = '6.0'
desired_caps['deviceName'] = 'Android GoogleAPI Emulator'
desired_caps['app'] = pytest.config.getoption('apk')
desired_caps['browserName'] = ''
desired_caps['deviceOrientation'] = "portrait"
desired_caps['name'] = tests_data.name
desired_caps['build'] = pytest.config.getoption('build')
desired_caps['idleTimeout'] = 1000
desired_caps['commandTimeout'] = 600
return desired_caps
def get_public_url(self, driver): def get_public_url(self, driver):
token = hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'), token = hmac.new(bytes(self.sauce_username + ":" + self.sauce_access_key, 'latin-1'),
@ -53,18 +43,42 @@ class AbstractTestCase:
pytest.config.getoption('build'))) pytest.config.getoption('build')))
print(self.get_public_url(driver)) print(self.get_public_url(driver))
def add_local_devices_to_capabilities(self):
updated_capabilities = list()
raw_out = re.split(r'[\r\\n]+', str(subprocess.check_output(['adb', 'devices'])).rstrip())
for line in raw_out[1:]:
serial = re.findall(r"([\d.\d:]*\d+)", line)
if serial:
capabilities = self.capabilities_local
capabilities['udid'] = serial[0]
updated_capabilities.append(capabilities)
return updated_capabilities
@property @property
def executor_local(self): def capabilities_sauce_lab(self):
return 'http://localhost:4723/wd/hub' desired_caps = dict()
desired_caps['app'] = pytest.config.getoption('apk')
desired_caps['build'] = pytest.config.getoption('build')
desired_caps['name'] = tests_data.name
desired_caps['platformName'] = 'Android'
desired_caps['appiumVersion'] = '1.7.1'
desired_caps['platformVersion'] = '6.0'
desired_caps['deviceName'] = 'Android GoogleAPI Emulator'
desired_caps['deviceOrientation'] = "portrait"
desired_caps['commandTimeout'] = 600
desired_caps['idleTimeout'] = 1000
return desired_caps
@property @property
def capabilities_local(self): def capabilities_local(self):
desired_caps = dict() desired_caps = dict()
desired_caps['app'] = pytest.config.getoption('apk')
desired_caps['deviceName'] = 'nexus_5' desired_caps['deviceName'] = 'nexus_5'
desired_caps['platformName'] = 'Android' desired_caps['platformName'] = 'Android'
desired_caps['appiumVersion'] = '1.6.5' desired_caps['appiumVersion'] = '1.7.1'
desired_caps['platformVersion'] = '6.0' desired_caps['platformVersion'] = '6.0'
desired_caps['app'] = pytest.config.getoption('apk') desired_caps['commandTimeout'] = 600
desired_caps['idleTimeout'] = 1000
return desired_caps return desired_caps
@abstractmethod @abstractmethod
@ -75,40 +89,82 @@ class AbstractTestCase:
def teardown_method(self, method): def teardown_method(self, method):
raise NotImplementedError('Should be overridden from a child class') raise NotImplementedError('Should be overridden from a child class')
@property
def environment(self):
return pytest.config.getoption('env')
class SingleDeviceTestCase(AbstractTestCase):
class LocalMultiplyDeviceTestCase(AbstractTestCase):
def setup_method(self, method): def setup_method(self, method):
self.driver = webdriver.Remote(self.executor_sauce_lab, capabilities = self.add_local_devices_to_capabilities()
self.capabilities_sauce_lab) self.driver_1 = webdriver.Remote(self.executor_local, capabilities[0])
self.driver.implicitly_wait(20) self.driver_2 = webdriver.Remote(self.executor_local, capabilities[1])
for driver in self.driver_1, self.driver_2:
driver.implicitly_wait(10)
def teardown_method(self, method): def teardown_method(self, method):
self.print_sauce_lab_info(self.driver) for driver in self.driver_1, self.driver_2:
self.driver.quit() try:
driver.quit()
except WebDriverException:
pass
class MultiplyDeviceTestCase(AbstractTestCase): class SauceMultiplyDeviceTestCase(AbstractTestCase):
@classmethod @classmethod
def setup_class(cls): def setup_class(cls):
cls.loop = asyncio.get_event_loop() cls.loop = asyncio.get_event_loop()
def setup_method(self, method): def setup_method(self, method):
self.driver_1, \ self.driver_1, \
self.driver_2 = self.loop.run_until_complete(start_threads(2, self.driver_2 = self.loop.run_until_complete(start_threads(2,
webdriver.Remote, webdriver.Remote,
self.executor_sauce_lab, self.executor_sauce_lab,
self.capabilities_sauce_lab)) self.capabilities_sauce_lab))
for driver in self.driver_1, self.driver_2: for driver in self.driver_1, self.driver_2:
driver.implicitly_wait(20) driver.implicitly_wait(10)
def teardown_method(self, method): def teardown_method(self, method):
for driver in self.driver_1, self.driver_2: for driver in self.driver_1, self.driver_2:
self.print_sauce_lab_info(driver) self.print_sauce_lab_info(driver)
driver.quit() try:
driver.quit()
except WebDriverException:
pass
@classmethod @classmethod
def teardown_class(cls): def teardown_class(cls):
cls.loop.close() cls.loop.close()
class SingleDeviceTestCase(AbstractTestCase):
def setup_method(self, method):
capabilities = {'local': {'executor': self.executor_local,
'capabilities': self.capabilities_local},
'sauce': {'executor': self.executor_sauce_lab,
'capabilities': self.capabilities_sauce_lab}}
self.driver = webdriver.Remote(capabilities[self.environment]['executor'],
capabilities[self.environment]['capabilities'])
self.driver.implicitly_wait(10)
def teardown_method(self, method):
if self.environment == 'sauce':
self.print_sauce_lab_info(self.driver)
try:
self.driver.quit()
except WebDriverException:
pass
environments = {'local': LocalMultiplyDeviceTestCase,
'sauce': SauceMultiplyDeviceTestCase}
class MultiplyDeviceTestCase(environments[pytest.config.getoption('env')]):
pass

View File

@ -31,6 +31,10 @@ def pytest_addoption(parser):
action='store', action='store',
default='sauce-storage:' + latest_apk, default='sauce-storage:' + latest_apk,
help='Please provide url or local path to apk') help='Please provide url or local path to apk')
parser.addoption('--env',
action='store',
default='sauce',
help='Please specify environment: local/sauce')
def pytest_runtest_setup(item): def pytest_runtest_setup(item):

View File

@ -19,6 +19,9 @@ def recover_access(chats, passphrase, password, username):
login.password_input.send_keys(password) login.password_input.send_keys(password)
login.confirm_recover_access.click() login.confirm_recover_access.click()
recovered_user = login.element_by_text(username, 'button') recovered_user = login.element_by_text(username, 'button')
login.confirm()
recovered_user.click() recovered_user.click()
login.password_input.send_keys(password) login.password_input.send_keys(password)
login.sign_in_button.click() login.sign_in_button.click()
login.find_full_text('Chats', 60)

View File

@ -1,4 +1,5 @@
import pytest import pytest
import time
from tests.basetestcase import SingleDeviceTestCase from tests.basetestcase import SingleDeviceTestCase
from views.home import HomeView from views.home import HomeView
from tests.preconditions import set_password_as_new_user, recover_access from tests.preconditions import set_password_as_new_user, recover_access
@ -6,7 +7,7 @@ from tests import basic_user, transaction_users
@pytest.mark.sanity @pytest.mark.sanity
class TestSanity(SingleDeviceTestCase): class TestAccess(SingleDeviceTestCase):
def test_recover_access(self): def test_recover_access(self):
home = HomeView(self.driver) home = HomeView(self.driver)
@ -23,7 +24,7 @@ class TestSanity(SingleDeviceTestCase):
recovered_user.click() recovered_user.click()
login.password_input.send_keys(basic_user['password']) login.password_input.send_keys(basic_user['password'])
login.sign_in_button.click() login.sign_in_button.click()
home.find_full_text('Chats', 10) home.find_full_text('Chats', 60)
@pytest.mark.parametrize("verification", ["invalid", "valid"]) @pytest.mark.parametrize("verification", ["invalid", "valid"])
def test_sign_in(self, verification): def test_sign_in(self, verification):
@ -62,9 +63,10 @@ class TestSanity(SingleDeviceTestCase):
home.confirm() home.confirm()
home.find_full_text(verifications[verification]["outcome"]) home.find_full_text(verifications[verification]["outcome"])
@pytest.mark.parametrize("test, recipient, sender", [('group_chat', 'A_USER', 'B_USER'), @pytest.mark.parametrize("test, recipient, sender", [('wrong_password', 'A_USER', 'B_USER'),
('group_chat', 'A_USER', 'B_USER'),
('one_to_one_chat', 'B_USER', 'A_USER')], ('one_to_one_chat', 'B_USER', 'A_USER')],
ids=['group_chat', 'one_to_one_chat']) ids=['group_chat', 'one_to_one_chat', 'wrong_password'])
def test_send_transaction(self, test, recipient, sender): def test_send_transaction(self, test, recipient, sender):
home = HomeView(self.driver) home = HomeView(self.driver)
set_password_as_new_user(home) set_password_as_new_user(home)
@ -102,18 +104,52 @@ class TestSanity(SingleDeviceTestCase):
chats.send_funds_button.click() chats.send_funds_button.click()
chats.first_recipient_button.click() chats.first_recipient_button.click()
chats.send_int_as_keyevent(0) chats.send_as_keyevent('0,1')
chats.send_dot_as_keyevent()
chats.send_int_as_keyevent(1)
chats.send_message_button.click() chats.send_message_button.click()
chats.confirm_transaction_button.wait_for_element(60) chats.sign_transaction_button.wait_for_element(20)
chats.confirm_transaction_button.click() chats.sign_transaction_button.click()
chats.password_input.send_keys(transaction_users[sender]['password'])
chats.confirm_button.click()
chats.got_it_button.click()
chats.find_full_text('0.1') if test == 'wrong_password':
chats.find_full_text('Sent', 60) chats.enter_password_input.send_keys('invalid')
if test == 'group_chat': chats.sign_transaction_button.click()
chats.find_full_text('to ' + transaction_users[recipient]['username'], 60) chats.find_full_text('Wrong password', 20)
chats.verify_balance_is_updated(initial_balance_recipient, recipient_address)
else:
chats.enter_password_input.send_keys(transaction_users[recipient]['password'])
chats.sign_transaction_button.click()
chats.find_full_text('0.1')
chats.find_full_text('Sent', 60)
if test == 'group_chat':
chats.find_full_text('to ' + transaction_users[recipient]['username'], 60)
chats.verify_balance_is_updated(initial_balance_recipient, recipient_address)
def test_send_transaction_from_daap(self):
home = HomeView(self.driver)
set_password_as_new_user(home)
chats = home.get_chats()
address = transaction_users['B_USER']['address']
initial_balance = chats.get_balance(address)
recover_access(chats,
transaction_users['B_USER']['passphrase'],
transaction_users['B_USER']['password'],
transaction_users['B_USER']['username'])
if chats.get_balance(address) < 1000000000000000000:
chats.get_donate(address)
contacts = chats.contacts_button.click()
auction_house = contacts.auction_house_button.click()
auction_house.toggle_navigation_button.click()
auction_house.new_auction_button.click()
auction_house.name_to_reserve_input.click()
auction_name = time.strftime('%Y-%m-%d-%H-%M')
auction_house.send_as_keyevent(auction_name)
auction_house.register_name_button.click()
chats.sign_transaction_button.wait_for_element(20)
chats.sign_transaction_button.click()
chats.enter_password_input.send_keys(transaction_users['B_USER']['password'])
chats.sign_transaction_button.click()
auction_house.find_full_text('You are the proud owner of the name: ' + auction_name, 120)
chats.verify_balance_is_updated(initial_balance, address)

View File

@ -40,18 +40,22 @@ class BaseElement(object):
logging.info('Looking for %s' % self.name) logging.info('Looking for %s' % self.name)
return self.driver.find_element(self.locator.by, self.locator.value) return self.driver.find_element(self.locator.by, self.locator.value)
def find_elements(self):
logging.info('Looking for %s' % self.name)
return self.driver.find_elements(self.locator.by, self.locator.value)
def wait_for_element(self, seconds=10): def wait_for_element(self, seconds=10):
return WebDriverWait(self.driver, seconds)\ 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.locator.by, self.locator.value)))
def scroll_to_element(self): def scroll_to_element(self):
action = TouchAction(self.driver)
for _ in range(5): for _ in range(5):
try: try:
self.find_element() self.find_element()
break break
except NoSuchElementException: except NoSuchElementException:
logging.info('Scrolling to %s' % self.name) logging.info('Scrolling to %s' % self.name)
action = TouchAction(self.driver)
action.press(x=0, y=1000).move_to(x=200, y=-1000).release().perform() action.press(x=0, y=1000).move_to(x=200, y=-1000).release().perform()
def is_element_present(self, sec=5): def is_element_present(self, sec=5):
@ -75,6 +79,10 @@ class BaseEditBox(BaseElement):
self.find_element().send_keys(value) self.find_element().send_keys(value)
logging.info('Type %s to %s' % (value, self.name)) logging.info('Type %s to %s' % (value, self.name))
def set_value(self, value):
self.find_element().set_value(value)
logging.info('Set %s to %s' % (value, self.name))
class BaseText(BaseElement): class BaseText(BaseElement):

View File

@ -11,6 +11,12 @@ class BackButton(BaseButton):
super(BackButton, self).__init__(driver) super(BackButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@content-desc='toolbar-back-button']") self.locator = self.Locator.xpath_selector("//*[@content-desc='toolbar-back-button']")
def click(self):
self.wait_for_element(30)
self.find_element().click()
logging.info('Tap on %s' % self.name)
return self.navigate()
class ContactsButton(BaseButton): class ContactsButton(BaseButton):
@ -18,6 +24,10 @@ class ContactsButton(BaseButton):
super(ContactsButton, self).__init__(driver) super(ContactsButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Contacts']") self.locator = self.Locator.xpath_selector("//*[@text='Contacts']")
def navigate(self):
from views.contacts import ContactsViewObject
return ContactsViewObject(self.driver)
class BaseViewObject(object): class BaseViewObject(object):
@ -27,23 +37,25 @@ class BaseViewObject(object):
self.contacts_button = ContactsButton(self.driver) self.contacts_button = ContactsButton(self.driver)
def confirm(self): def confirm(self):
logging.info("Tap 'Confirm' on native keyboard")
self.driver.keyevent(66) self.driver.keyevent(66)
def send_int_as_keyevent(self, integer): def send_as_keyevent(self, string):
keys = {0: 7, 1: 8, 2: 9, 3: 10, 4: 11, keys = {'0': 7, '1': 8, '2': 9, '3': 10, '4': 11, '5': 12, '6': 13, '7': 14, '8': 15, '9': 16,
5: 12, 6: 13, 7: 14, 8: 15, 9: 16} ',': 55, '-': 69}
time.sleep(2) for i in string:
self.driver.keyevent(keys[integer]) logging.info("Tap '%s' on native keyboard" % i)
time.sleep(1)
def send_dot_as_keyevent(self): self.driver.keyevent(keys[i])
self.driver.keyevent(55)
def find_full_text(self, text, wait_time=60): def find_full_text(self, text, wait_time=60):
logging.info("Looking for full text: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]') element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]')
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)
def find_text_part(self, text, wait_time=60): def find_text_part(self, text, wait_time=60):
logging.info("Looking for a text part: '%s'" % text)
element = BaseElement(self.driver) element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]') element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]')
return element.wait_for_element(wait_time) return element.wait_for_element(wait_time)

View File

@ -148,7 +148,6 @@ class SendMessageButton(BaseButton):
self.locator = self.Locator.accessibility_id("send-message-button") self.locator = self.Locator.accessibility_id("send-message-button")
def click(self): def click(self):
time.sleep(10)
self.find_element().click() self.find_element().click()
logging.info('Tap on %s' % self.name) logging.info('Tap on %s' % self.name)
@ -171,14 +170,14 @@ class SendFundsButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(SendFundsButton.FirstRecipient, self).__init__(driver) super(SendFundsButton.FirstRecipient, self).__init__(driver)
self.locator = self.Locator.xpath_selector('//android.view.ViewGroup[4]//' self.locator = self.Locator.xpath_selector("//*[@text='Choose recipient']/.."
'android.widget.ImageView[@content-desc="chat-icon"]') "//android.widget.ImageView[@content-desc='chat-icon']")
class ConfirmTransactionButton(BaseButton): class SignTransactionButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(SendFundsButton.ConfirmTransactionButton, self).__init__(driver) super(SendFundsButton.SignTransactionButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='CONFIRM TRANSACTION']") self.locator = self.Locator.xpath_selector("//*[@text='SIGN TRANSACTION']")
class PasswordInput(BaseEditBox): class PasswordInput(BaseEditBox):
@ -186,6 +185,12 @@ class SendFundsButton(BaseButton):
super(SendFundsButton.PasswordInput, self).__init__(driver) super(SendFundsButton.PasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Password']") self.locator = self.Locator.xpath_selector("//*[@text='Password']")
class EnterPasswordInput(BaseEditBox):
def __init__(self, driver):
super(SendFundsButton.EnterPasswordInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.EditText[@NAF='true']")
class ConfirmButton(BaseButton): class ConfirmButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
@ -233,9 +238,10 @@ class ChatsViewObject(BaseViewObject):
self.send_funds_button = SendFundsButton(self.driver) self.send_funds_button = SendFundsButton(self.driver)
self.first_recipient_button = SendFundsButton.FirstRecipient(self.driver) self.first_recipient_button = SendFundsButton.FirstRecipient(self.driver)
self.confirm_transaction_button = SendFundsButton.ConfirmTransactionButton(self.driver) self.sign_transaction_button = SendFundsButton.SignTransactionButton(self.driver)
self.confirm_button = SendFundsButton.ConfirmButton(self.driver) self.confirm_button = SendFundsButton.ConfirmButton(self.driver)
self.password_input = SendFundsButton.PasswordInput(self.driver) self.password_input = SendFundsButton.PasswordInput(self.driver)
self.enter_password_input = SendFundsButton.EnterPasswordInput(self.driver)
self.got_it_button = SendFundsButton.GotItButton(self.driver) self.got_it_button = SendFundsButton.GotItButton(self.driver)
self.new_contact_button = NewContactButton(self.driver) self.new_contact_button = NewContactButton(self.driver)

View File

@ -0,0 +1,24 @@
from views.base_element import BaseElement, BaseButton, BaseEditBox, BaseText
import logging
import time
import pytest
class AuctionHouseButton(BaseButton):
def __init__(self, driver):
super(AuctionHouseButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
"(//android.widget.TextView[@text='Auction House'])[1]")
def navigate(self):
from views.web_views.auction_house import AuctionHouseWebView
return AuctionHouseWebView(self.driver)
class ContactsViewObject(object):
def __init__(self, driver):
self.driver = driver
self.auction_house_button = AuctionHouseButton(self.driver)

View File

@ -32,7 +32,7 @@ class RequestPasswordIcon(BaseButton):
self.locator = self.Locator.xpath_selector("//*[@content-desc='request-password']") self.locator = self.Locator.xpath_selector("//*[@content-desc='request-password']")
def click(self): def click(self):
self.wait_for_element(60) self.wait_for_element(10)
self.find_element().click() self.find_element().click()
logging.info('Tap on %s' % self.name) logging.info('Tap on %s' % self.name)
return self.navigate() return self.navigate()
@ -44,12 +44,10 @@ class HomeView(BaseViewObject):
super(HomeView, self).__init__(driver) super(HomeView, self).__init__(driver)
self.continue_button_apk = ContinueButtonAPK(driver) self.continue_button_apk = ContinueButtonAPK(driver)
self.ok_button_apk = OkButtonAPK(driver) self.ok_button_apk = OkButtonAPK(driver)
for i in self.ok_button_apk, self.continue_button_apk: for i in self.ok_button_apk, self.continue_button_apk:
try: try:
i.click() i.click()
except (NoSuchElementException, TimeoutException): except (NoSuchElementException, TimeoutException):
pass pass
self.chat_request_input = ChatRequestInput(driver) self.chat_request_input = ChatRequestInput(driver)
self.request_password_icon = RequestPasswordIcon(driver) self.request_password_icon = RequestPasswordIcon(driver)

View File

@ -0,0 +1,43 @@
from views.web_views.base_web_view import *
class ToggleNavigationButton(BaseButton):
def __init__(self, driver):
super(ToggleNavigationButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('Toggle navigation ')
class NewAuctionButton(BaseButton):
def __init__(self, driver):
super(ToggleNavigationButton.NewAuctionButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('New Auction')
class ReserveAssetName(BaseElement):
class NameToReserveInput(BaseEditBox, BaseButton):
def __init__(self, driver):
super(ReserveAssetName.NameToReserveInput, self).__init__(driver)
self.locator = self.Locator.xpath_selector(
'(//android.widget.EditText[@content-desc="eg MyFamousWallet.eth"])[1]')
class RegisterNameButton(BaseButton):
def __init__(self, driver):
super(ReserveAssetName.RegisterNameButton, self).__init__(driver)
self.locator = self.Locator.accessibility_id('Register Name')
class AuctionHouseWebView(BaseWebViewObject):
def __init__(self, driver):
super(AuctionHouseWebView, self).__init__(driver)
self.driver = driver
self.wait_for_page_loaded()
self.toggle_navigation_button = ToggleNavigationButton(self.driver)
self.new_auction_button = ToggleNavigationButton.NewAuctionButton(self.driver)
self.name_to_reserve_input = ReserveAssetName.NameToReserveInput(self.driver)
self.register_name_button = ReserveAssetName.RegisterNameButton(self.driver)

View File

@ -0,0 +1,30 @@
from views.base_view import *
class ProgressBarIcon(BaseElement):
def __init__(self, driver):
super(ProgressBarIcon, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//android.widget.ProgressBar")
class BaseWebViewObject(BaseViewObject):
def __init__(self, driver):
super(BaseWebViewObject, self).__init__(driver)
self.driver = driver
self.progress_bar_icon = ProgressBarIcon(self.driver)
def wait_for_page_loaded(self, wait_time=20):
counter = 0
while self.progress_bar_icon.is_element_present(5):
time.sleep(1)
counter += 1
if counter > wait_time:
pytest.fail("Page is not loaded during %s seconds" % wait_time)
def find_full_text(self, text, wait_time=60):
element = BaseElement(self.driver)
element.locator = element.Locator.xpath_selector('//*[@content-desc="' + text + '"]')
return element.wait_for_element(wait_time)