511 lines
20 KiB
Python
511 lines
20 KiB
Python
import time
|
|
|
|
from selenium.common.exceptions import TimeoutException, NoSuchElementException
|
|
|
|
from tests import common_password
|
|
from views.base_element import BaseButton, BaseEditBox, BaseText, BaseElement
|
|
from views.base_view import BaseView, ProgressBar
|
|
from views.profile_view import ProfilePictureElement, ProfileAddressText
|
|
|
|
|
|
class ChatMessageInput(BaseEditBox):
|
|
def __init__(self, driver):
|
|
super(ChatMessageInput, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('chat-message-input')
|
|
|
|
|
|
class AddToContacts(BaseButton):
|
|
def __init__(self, driver):
|
|
super(AddToContacts, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('add-to-contacts-button')
|
|
|
|
|
|
class AddGroupChatMembersButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(AddGroupChatMembersButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Add members']")
|
|
|
|
def navigate(self):
|
|
from views.contacts_view import ContactsView
|
|
return ContactsView(self.driver)
|
|
|
|
|
|
class UserNameText(BaseText):
|
|
def __init__(self, driver):
|
|
super(UserNameText, self).__init__(driver)
|
|
self.locator = \
|
|
self.Locator.accessibility_id('chat-name-text')
|
|
|
|
|
|
class TransactionPopupText(BaseText):
|
|
def __init__(self, driver):
|
|
super(TransactionPopupText, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Specify amount']")
|
|
|
|
|
|
class SendCommand(BaseButton):
|
|
def __init__(self, driver):
|
|
super(SendCommand, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('send-button')
|
|
|
|
def click(self):
|
|
self.wait_for_element().click()
|
|
self.driver.info('Tap on %s' % self.name)
|
|
return self.navigate()
|
|
|
|
|
|
class RequestCommand(BaseButton):
|
|
def __init__(self, driver):
|
|
super(RequestCommand, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('request-button')
|
|
|
|
def click(self):
|
|
self.wait_for_element().click()
|
|
self.driver.info('Tap on %s' % self.name)
|
|
return self.navigate()
|
|
|
|
|
|
class AssetCommand(BaseButton):
|
|
def __init__(self, driver, asset):
|
|
super(AssetCommand, self).__init__(driver)
|
|
self.locator = self.Locator.text_selector(asset)
|
|
|
|
|
|
class ChatMenuButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(ChatMenuButton, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('chat-menu-button')
|
|
|
|
|
|
class MembersButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(MembersButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="action"])[1]')
|
|
|
|
|
|
class DeleteChatButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(DeleteChatButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Delete chat"]')
|
|
|
|
|
|
class ClearHistoryButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(ClearHistoryButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Clear history"]')
|
|
|
|
|
|
class GroupInfoButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(GroupInfoButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Group info"]')
|
|
|
|
def navigate(self):
|
|
return GroupChatInfoView(self.driver)
|
|
|
|
|
|
class LeaveChatButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(LeaveChatButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Leave public chat"]')
|
|
|
|
|
|
class ClearButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(ClearButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="CLEAR"]')
|
|
|
|
|
|
class LeaveButton(BaseButton):
|
|
|
|
def __init__(self, driver):
|
|
super(LeaveButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="LEAVE"]')
|
|
|
|
|
|
class ChatSettings(BaseButton):
|
|
def __init__(self, driver):
|
|
super(ChatSettings, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Settings']")
|
|
|
|
|
|
class UserOptions(BaseButton):
|
|
def __init__(self, driver):
|
|
super(UserOptions, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('options')
|
|
|
|
|
|
class RemoveButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(RemoveButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//android.widget.TextView[@text='Remove']")
|
|
|
|
|
|
class FirstRecipient(BaseButton):
|
|
def __init__(self, driver):
|
|
super(FirstRecipient, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('contact-item')
|
|
|
|
|
|
class MoreUsersButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(MoreUsersButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//android.widget.TextView[contains(@text, 'MORE')]")
|
|
|
|
|
|
class OpenInStatusButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(OpenInStatusButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//*[@text='Open in Status']")
|
|
|
|
def navigate(self):
|
|
from views.web_views.base_web_view import BaseWebView
|
|
return BaseWebView(self.driver)
|
|
|
|
|
|
class CommandsButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(CommandsButton, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('chat-commands-button')
|
|
|
|
|
|
class ViewProfileButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(ViewProfileButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="View profile"]')
|
|
|
|
|
|
class NoMessagesInChatText(BaseText):
|
|
def __init__(self, driver):
|
|
super(NoMessagesInChatText, self).__init__(driver)
|
|
self.locator = self.Locator.text_part_selector(
|
|
'Any messages you send here are encrypted and can only be read by you and')
|
|
|
|
|
|
class ProfileSendMessageButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(ProfileSendMessageButton, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('start-conversation-button')
|
|
|
|
|
|
class ProfileSendTransactionButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(ProfileSendTransactionButton, self).__init__(driver)
|
|
self.locator = self.Locator.accessibility_id('send-transaction-button')
|
|
|
|
|
|
class JoinChatButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(JoinChatButton, self).__init__(driver)
|
|
self.locator = self.Locator.text_part_selector('Join group')
|
|
|
|
|
|
class DeclineChatButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(DeclineChatButton, self).__init__(driver)
|
|
self.locator = self.Locator.text_part_selector('Decline invitation')
|
|
|
|
|
|
class RemoveFromChatButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(RemoveFromChatButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Remove from chat"]')
|
|
|
|
|
|
class MakeAdminButton(BaseButton):
|
|
def __init__(self, driver):
|
|
super(MakeAdminButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="Make admin"]')
|
|
|
|
|
|
class ChatElementByText(BaseText):
|
|
def __init__(self, driver, text):
|
|
super(ChatElementByText, self).__init__(driver)
|
|
self.message_text = text
|
|
self.locator = self.Locator.xpath_selector(
|
|
"//*[starts-with(@text,'%s')]/ancestor::android.view.ViewGroup[@content-desc='chat-item']" % text)
|
|
|
|
def find_element(self):
|
|
self.driver.info("Looking for message with text '%s'" % self.message_text)
|
|
for _ in range(2):
|
|
try:
|
|
return super(ChatElementByText, self).find_element()
|
|
except NoSuchElementException:
|
|
ChatView(self.driver).reconnect()
|
|
|
|
@property
|
|
def status(self):
|
|
class StatusText(BaseText):
|
|
def __init__(self, driver, parent_locator: str):
|
|
super(StatusText, self).__init__(driver)
|
|
text = "//android.widget.TextView[@text='Seen' or @text='Sent' or " \
|
|
"@text='Not sent. Tap for options' or @text='Network mismatch']"
|
|
self.locator = self.Locator.xpath_selector(parent_locator + text)
|
|
|
|
return StatusText(self.driver, self.locator.value)
|
|
|
|
@property
|
|
def progress_bar(self):
|
|
return ProgressBar(self.driver, self.locator.value)
|
|
|
|
@property
|
|
def member_photo(self):
|
|
class MemberPhoto(BaseButton):
|
|
def __init__(self, driver, parent_locator):
|
|
super(MemberPhoto, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector(parent_locator + "//*[@content-desc='member-photo']")
|
|
|
|
return MemberPhoto(self.driver, self.locator.value)
|
|
|
|
@property
|
|
def username(self):
|
|
class Username(BaseText):
|
|
def __init__(self, driver, parent_locator):
|
|
super(Username, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector(parent_locator + "/*[1][name()='android.widget.TextView']")
|
|
|
|
return Username(self.driver, self.locator.value)
|
|
|
|
@property
|
|
def send_request_button(self):
|
|
class SendRequestButton(BaseButton):
|
|
def __init__(self, driver, parent_locator):
|
|
super(SendRequestButton, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector(parent_locator + '//*[@text="Send"]')
|
|
|
|
return SendRequestButton(self.driver, self.locator.value)
|
|
|
|
def contains_text(self, text, wait_time=5) -> bool:
|
|
element = BaseText(self.driver)
|
|
element.locator = element.Locator.xpath_selector(
|
|
self.locator.value + "//android.view.ViewGroup//android.widget.TextView[contains(@text,'%s')]" % text)
|
|
return element.is_element_displayed(wait_time)
|
|
|
|
|
|
class EmptyPublicChatMessage(BaseText):
|
|
def __init__(self, driver):
|
|
super().__init__(driver)
|
|
self.locator = self.Locator.text_part_selector("It's been quite here")
|
|
|
|
|
|
class ChatItem(BaseElement):
|
|
def __init__(self, driver):
|
|
super().__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@content-desc="chat-item"]')
|
|
|
|
|
|
class HistoryTimeMarker(BaseText):
|
|
def __init__(self, driver, marker='Today'):
|
|
super().__init__(driver)
|
|
self.locator = self.Locator.xpath_selector('//*[@text="%s"]' % marker)
|
|
|
|
|
|
class UsernameOptions(BaseButton):
|
|
def __init__(self, driver, username):
|
|
super(UsernameOptions, self).__init__(driver)
|
|
self.locator = self.Locator.xpath_selector("//*[@text='%s']/..//*[@content-desc='options']" % username)
|
|
|
|
|
|
class GroupChatInfoView(BaseView):
|
|
def __init__(self, driver):
|
|
super(GroupChatInfoView, self).__init__(driver)
|
|
self.add_members = AddGroupChatMembersButton(self.driver)
|
|
|
|
def get_username_options(self, username: str):
|
|
return UsernameOptions(self.driver, username)
|
|
|
|
|
|
class ChatView(BaseView):
|
|
def __init__(self, driver):
|
|
super(ChatView, self).__init__(driver)
|
|
|
|
self.chat_message_input = ChatMessageInput(self.driver)
|
|
self.add_to_contacts = AddToContacts(self.driver)
|
|
self.user_name_text = UserNameText(self.driver)
|
|
self.no_messages_in_chat = NoMessagesInChatText(self.driver)
|
|
self.empty_public_chat_message = EmptyPublicChatMessage(self.driver)
|
|
self.chat_item = ChatItem(self.driver)
|
|
|
|
self.commands_button = CommandsButton(self.driver)
|
|
self.send_command = SendCommand(self.driver)
|
|
self.request_command = RequestCommand(self.driver)
|
|
|
|
self.chat_options = ChatMenuButton(self.driver)
|
|
self.members_button = MembersButton(self.driver)
|
|
self.delete_chat_button = DeleteChatButton(self.driver)
|
|
self.clear_history_button = ClearHistoryButton(self.driver)
|
|
self.clear_button = ClearButton(self.driver)
|
|
|
|
# Group chats
|
|
self.group_info = GroupInfoButton(self.driver)
|
|
self.leave_chat_button = LeaveChatButton(self.driver)
|
|
self.leave_button = LeaveButton(self.driver)
|
|
self.join_chat_button = JoinChatButton(self.driver)
|
|
self.decline_invitation_button = DeclineChatButton(self.driver)
|
|
self.remove_user_button = RemoveFromChatButton(self.driver)
|
|
self.make_admin_button = MakeAdminButton(self.driver)
|
|
|
|
self.chat_settings = ChatSettings(self.driver)
|
|
self.view_profile_button = ViewProfileButton(self.driver)
|
|
self.more_users_button = MoreUsersButton(self.driver)
|
|
self.user_options = UserOptions(self.driver)
|
|
self.remove_button = RemoveButton(self.driver)
|
|
|
|
self.first_recipient_button = FirstRecipient(self.driver)
|
|
|
|
self.open_in_status_button = OpenInStatusButton(self.driver)
|
|
|
|
# Contact's profile
|
|
self.contact_profile_picture = ProfilePictureElement(self.driver)
|
|
self.profile_send_message = ProfileSendMessageButton(self.driver)
|
|
self.profile_send_transaction = ProfileSendTransactionButton(self.driver)
|
|
self.profile_address_text = ProfileAddressText(self.driver)
|
|
|
|
def wait_for_syncing_complete(self):
|
|
self.driver.info('Waiting for syncing complete:')
|
|
while True:
|
|
try:
|
|
sync = self.find_text_part('Syncing', 10)
|
|
self.driver.info(sync.text)
|
|
except TimeoutException:
|
|
break
|
|
|
|
def wait_for_message_in_one_to_one_chat(self, expected_message: str, errors: list, wait_time: int = 20):
|
|
try:
|
|
element = ChatElementByText(self.driver, expected_message)
|
|
element.wait_for_element(wait_time)
|
|
except TimeoutException:
|
|
errors.append('Message with text "%s" was not received' % expected_message)
|
|
|
|
def wait_for_messages(self, username: str, expected_messages: list, errors: list, wait_time: int = 30):
|
|
expected_messages = expected_messages if type(expected_messages) == list else [expected_messages]
|
|
repeat = 0
|
|
received_messages = list()
|
|
while repeat <= wait_time:
|
|
for message in expected_messages:
|
|
if self.element_starts_with_text(message, 'text').is_element_present(1):
|
|
received_messages.append(message)
|
|
if not set(expected_messages) - set(received_messages):
|
|
break
|
|
time.sleep(3)
|
|
repeat += 3
|
|
if set(expected_messages) - set(received_messages):
|
|
errors.append('Not received messages from user %s: "%s"' % (username, ', '.join(
|
|
[i for i in list(set(expected_messages) - set(received_messages))])))
|
|
|
|
def send_funds_to_request(self, amount, sender_password=common_password, wallet_set_up=False):
|
|
gas_popup = self.element_by_text_part('Specify amount')
|
|
send_request_button = self.chat_element_by_text(amount).send_request_button
|
|
send_request_button.click_until_presence_of_element(gas_popup)
|
|
send_transaction = self.get_send_transaction_view()
|
|
if wallet_set_up:
|
|
wallet_view = self.get_wallet_view()
|
|
self.send_message_button.click_until_presence_of_element(wallet_view.sign_in_phrase)
|
|
wallet_view.done_button.click()
|
|
wallet_view.yes_button.click()
|
|
else:
|
|
self.send_message_button.click_until_presence_of_element(send_transaction.sign_transaction_button)
|
|
send_transaction.sign_transaction(sender_password)
|
|
|
|
def delete_chat(self):
|
|
self.chat_options.click()
|
|
self.delete_chat_button.click()
|
|
self.delete_button.click()
|
|
|
|
def clear_history(self):
|
|
self.chat_options.click()
|
|
self.clear_history_button.click()
|
|
self.clear_button.click()
|
|
|
|
def clear_history_via_group_info(self):
|
|
self.chat_options.click()
|
|
self.group_info.click()
|
|
self.clear_history_button.click()
|
|
self.clear_button.click()
|
|
self.back_button.click()
|
|
|
|
def send_transaction_in_1_1_chat(self, asset, amount, password=common_password, wallet_set_up=False, **kwargs):
|
|
self.commands_button.click()
|
|
self.send_command.click()
|
|
self.asset_by_name(asset).click()
|
|
self.send_as_keyevent(amount)
|
|
send_transaction_view = self.get_send_transaction_view()
|
|
if wallet_set_up:
|
|
wallet_view = self.get_wallet_view()
|
|
self.send_message_button.click_until_presence_of_element(wallet_view.sign_in_phrase)
|
|
wallet_view.done_button.click()
|
|
wallet_view.yes_button.click()
|
|
else:
|
|
self.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button)
|
|
if kwargs.get('sign_transaction', True):
|
|
send_transaction_view.sign_transaction(password)
|
|
chat_elem = self.chat_element_by_text(amount)
|
|
chat_elem.wait_for_visibility_of_element()
|
|
chat_elem.progress_bar.wait_for_invisibility_of_element(20)
|
|
if chat_elem.status.text not in ('Sent', 'Delivered', 'Seen'):
|
|
self.driver.fail('Sent transaction message was not sent')
|
|
|
|
def send_transaction_in_group_chat(self, amount, password, recipient):
|
|
self.commands_button.click()
|
|
self.send_command.click()
|
|
self.find_full_text(recipient['username']).click()
|
|
self.send_as_keyevent(amount)
|
|
self.send_message_button.click()
|
|
|
|
send_transaction_view = self.get_send_transaction_view()
|
|
self.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button)
|
|
send_transaction_view.sign_transaction(password)
|
|
send_transaction_view.find_full_text(amount)
|
|
self.find_full_text('to ' + recipient['username'], 10)
|
|
|
|
def add_members_to_group_chat(self, user_names_to_add: list):
|
|
self.chat_options.click()
|
|
group_info_view = self.group_info.click()
|
|
add_members_view = group_info_view.add_members.click()
|
|
for user_name in user_names_to_add:
|
|
user_contact = add_members_view.get_username_checkbox(user_name)
|
|
user_contact.scroll_to_element()
|
|
user_contact.click()
|
|
add_members_view.add_button.click()
|
|
|
|
def get_user_options(self, username: str):
|
|
self.chat_options.click()
|
|
group_info_view = self.group_info.click()
|
|
group_info_view.get_username_options(username).click()
|
|
return self
|
|
|
|
def request_transaction_in_1_1_chat(self, asset, amount):
|
|
self.commands_button.click()
|
|
self.request_command.click()
|
|
self.asset_by_name(asset).click()
|
|
self.send_as_keyevent(amount)
|
|
self.send_message_button.click()
|
|
|
|
def chat_element_by_text(self, text):
|
|
self.driver.info("Looking for a message by text: '%s'" % text)
|
|
return ChatElementByText(self.driver, text)
|
|
|
|
def verify_message_is_under_today_text(self, text, errors):
|
|
message_element = self.chat_element_by_text(text)
|
|
message_element.wait_for_visibility_of_element()
|
|
message_location = message_element.find_element().location['y']
|
|
today_text_element = self.element_by_text('Today').find_element()
|
|
today_location = today_text_element.location['y']
|
|
today_height = today_text_element.size['height']
|
|
if message_location < today_location + today_height:
|
|
errors.append("Message '%s' is not under 'Today' text" % text)
|
|
|
|
def send_message(self, message: str = 'test message'):
|
|
self.chat_message_input.send_keys(message)
|
|
self.send_message_button.click()
|
|
|
|
def move_to_messages_by_time_marker(self, marker='Today'):
|
|
self.driver.info("Moving to messages by time marker: '%s'" % marker)
|
|
HistoryTimeMarker(self.driver, marker).scroll_to_element(depth=50, direction='up')
|