e2e: pin messages in 1-1 and group chats

This commit is contained in:
Yevheniia Berdnyk 2022-11-21 06:49:53 +02:00
parent 72d43ba745
commit 946640339a
No known key found for this signature in database
GPG Key ID: 0642C73C66214825
7 changed files with 256 additions and 56 deletions

View File

@ -62,7 +62,7 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"new_ui_critical\" \
-m \"new_ui_critical or new_ui_medium\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_NAME}
"""

View File

@ -125,7 +125,6 @@ class TestrailReport(BaseTestReport):
test_cases['pr']['one_to_one_chat'] = 50956
test_cases['pr']['deep_links'] = 50967
## Nightly e2e
# test_cases['nightly']['medium'] = 736
# test_cases['nightly']['chat'] = 50811
@ -145,6 +144,10 @@ class TestrailReport(BaseTestReport):
# test_cases['nightly']['mutual_contact_requests'] = 50857
# test_cases['nightly']['keycard'] = 50850
# test_cases['nightly']['wallet'] = 50851
test_cases['nightly']['1_1_chat'] = 50958
test_cases['nightly']['group_chat'] = 50964
## Upgrade e2e
# test_cases['upgrade']['general'] = 881
@ -154,7 +157,7 @@ class TestrailReport(BaseTestReport):
key, value = arg.split('=')
case_ids = value.split(',')
if len(case_ids) == 0:
# if 'critical' in argv:
# if 'critical' in argv:
if 'new_ui_critical' in argv:
for category in test_cases['pr']:
for case in self.get_cases([test_cases['pr'][category]]):

View File

@ -6,6 +6,7 @@ critical = pytest.mark.critical
medium = pytest.mark.medium
# new ui
new_ui_critical = pytest.mark.new_ui_critical
new_ui_medium = pytest.mark.new_ui_medium
flaky = pytest.mark.flaky
upgrade = pytest.mark.upgrade

View File

@ -7,7 +7,7 @@ import pytest
from tests import bootnode_address, mailserver_address, mailserver_ams, used_fleet, background_service_message
from tests import marks
from tests.base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
from tests.users import transaction_senders, ens_user, basic_user
from tests.users import transaction_senders, ens_user
from views.sign_in_view import SignInView
@ -185,7 +185,8 @@ class TestTimelineHistoryNodesBootnodesMultipleDeviceMergedMedium(MultipleShared
self.errors.verify_no_errors()
@marks.testrail_id(702286)
@marks.xfail(reason="flaky; history was not fetched after enabling use_history_node - something needs investigation")
@marks.xfail(
reason="flaky; history was not fetched after enabling use_history_node - something needs investigation")
def test_profile_use_history_node_disable_enable(self):
[home.home_button.double_click() for home in (self.home_1, self.home_2)]
self.home_1.toggle_airplane_mode()
@ -568,37 +569,6 @@ class TestChatMediumMultipleDevice(MultipleSharedDeviceTestCase):
self.errors.verify_no_errors()
@marks.testrail_id(702070)
def test_chat_pin_messages_in_group_chat(self):
[chat.home_button.double_click() for chat in [self.chat_1, self.chat_2]]
self.home_1.just_fyi("Enter group chat and pin message there. It's pinned for both members.")
[home.get_chat(self.new_group_chat_name).click() for home in (self.home_1, self.home_2)]
self.group_chat_1.send_message(self.message_1)
self.group_chat_1.pin_message(self.message_1)
if not (self.group_chat_1.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30) and
self.group_chat_2.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message is not pinned in group chat!")
self.home_1.just_fyi("Check that non admin user can not unpin messages")
self.group_chat_2.chat_element_by_text(self.message_1).long_press_element()
if self.group_chat_2.element_by_translation_id("unpin").is_element_displayed():
self.errors.append("Unpin option is available for non-admin user")
self.home_1.just_fyi("Grant another user with admin rights and check he can unpin message now")
self.group_chat_1.chat_options.click()
group_info = self.group_chat_1.group_info.click()
options = group_info.get_username_options(self.default_username_2).click()
options.make_admin_button.click()
self.group_chat_2.click_system_back_button()
self.group_chat_2.pin_message(self.message_1, action="unpin")
if (self.group_chat_1.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed() and
self.group_chat_2.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed()):
self.errors.append("Message failed be unpinned by user who granted admin permissions!")
self.errors.verify_no_errors()
@marks.testrail_id(702258)
def test_chat_group_chat_set_nickname_and_ens_via_group_info_mention(self):
self.drivers[1].reset()
@ -912,7 +882,8 @@ class TestChatKeycardMentionsMediumMultipleDevice(MultipleSharedDeviceTestCase):
self.errors.verify_no_errors()
@marks.testrail_id(702295)
@marks.xfail(reason="mysterious issue when PNs are not fetched from offline, can not reproduce on real devices; needs investigation")
@marks.xfail(
reason="mysterious issue when PNs are not fetched from offline, can not reproduce on real devices; needs investigation")
def test_keycard_1_1_chat_command_request_and_send_tx_stt_in_1_1_chat_offline_opened_from_push(self):
[home.home_button.double_click() for home in (self.home_1, self.home_2)]
self.home_1.get_chat(self.sender['username']).click()
@ -1141,3 +1112,190 @@ class TestMutualContactRequests(MultipleSharedDeviceTestCase):
chat_2.just_fyi('Verify cannot send messages to user whos request has been declined')
if chat_2.chat_message_input.is_element_displayed():
self.drivers[1].fail('Chat input field is displayed in 1-1 chat with user whos cr was declined')
@pytest.mark.xdist_group(name="three_2")
@marks.new_ui_medium
class TestChatMediumMultipleDeviceNewUI(MultipleSharedDeviceTestCase):
def prepare_devices(self):
self.drivers, self.loop = create_shared_drivers(2)
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
self.home_1 = self.device_1.create_user(enable_notifications=True)
self.home_2 = self.device_2.create_user(enable_notifications=True)
self.home_1.browser_tab.click() # temp, until profile is on browser tab
self.profile_1 = self.home_1.get_profile_view()
self.default_username_1 = self.profile_1.default_username_text.text
self.public_key_2, self.default_username_2 = self.home_2.get_public_key_and_username(return_username=True)
self.profile_1.add_contact_via_contacts_list(self.public_key_2)
self.home_2.click_system_back_button_until_element_is_shown()
self.home_1.click_system_back_button_until_element_is_shown()
self.home_1.chats_tab.click()
self.home_2.chats_tab.click()
self.home_2.handle_contact_request(self.default_username_1)
self.home_2.click_system_back_button_until_element_is_shown()
self.chat_1 = self.home_1.get_chat(self.default_username_2).click()
self.chat_1.send_message('1')
self.chat_2 = self.home_2.get_chat(self.default_username_1).click()
self.message_1, self.message_2, self.message_3, self.message_4 = \
"Message 1", "Message 2", "Message 3", "Message 4"
@marks.testrail_id(702731)
def test_chat_1_1_pin_messages(self):
self.home_1.just_fyi("Check that Device1 can pin own message in 1-1 chat")
self.chat_1.send_message(self.message_1)
self.chat_1.send_message(self.message_2)
self.chat_1.pin_message(self.message_1, 'pin-to-chat')
if not self.chat_1.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed():
self.drivers[0].fail("Message is not pinned!")
self.home_1.just_fyi("Check that Device2 can pin Device1 message in 1-1 chat and two pinned "
"messages are in Device1 profile")
self.chat_2.pin_message(self.message_2, 'pin-to-chat')
for chat_number, chat in enumerate([self.chat_1, self.chat_2]):
chat.pinned_messages_count.wait_for_element_text("2", message="Pinned messages count is not 2 as expected!")
self.home_1.just_fyi("Check pinned message are visible in Pinned panel for user %s" % (chat_number + 1))
chat.pinned_messages_count.click()
for message in self.message_1, self.message_2:
pinned_by = chat.pinned_messages_list.get_message_pinned_by_text(message)
if pinned_by.is_element_displayed():
text = pinned_by.text.strip()
if chat_number == 0:
expected_text = "You" if message == self.message_1 else self.default_username_2
else:
expected_text = "You" if message == self.message_2 else self.default_username_1
if text != expected_text:
self.errors.append(
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, chat_number + 1)
)
else:
self.errors.append(
"Message '%s' is missed on Pinned messages list for user %s" % (message, chat_number + 1)
)
chat.click_system_back_button()
self.home_1.just_fyi("Check that Device1 can not pin more than 3 messages and 'Unpin' dialog appears")
self.chat_1.send_message(self.message_3)
self.chat_1.send_message(self.message_4)
self.chat_1.pin_message(self.message_3, 'pin-to-chat')
self.chat_1.pin_message(self.message_4, 'pin-to-chat')
if self.chat_1.pin_limit_popover.is_element_displayed(30):
self.chat_1.view_pinned_messages_button.click()
self.chat_1.pinned_messages_list.message_element_by_text(
self.message_2).click_inside_element_by_coordinate()
self.home_1.just_fyi("Unpin one message so that another could be pinned")
self.chat_1.element_by_translation_id('unpin-from-chat').double_click()
self.chat_1.chat_element_by_text(self.message_4).click()
self.chat_1.pin_message(self.message_4, 'pin-to-chat')
if not (self.chat_1.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30) and
self.chat_2.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 4 is not pinned in chat after unpinning previous one")
else:
self.errors.append("Can pin more than 3 messages in chat")
self.home_1.just_fyi("Check pinned messages are visible in Pinned panel for both users")
for chat_number, chat in enumerate([self.chat_1, self.chat_2]):
count = chat.pinned_messages_count.text
if count != '3':
self.errors.append("Pinned messages count is not 3 for user %s" % (chat_number + 1))
self.home_1.just_fyi("Unpin one message and check it's unpinned for another user")
self.chat_2.chat_element_by_text(self.message_4).long_press_element()
self.chat_2.element_by_translation_id("unpin-from-chat").click()
self.chat_1.chat_element_by_text(self.message_4).pinned_by_label.wait_for_invisibility_of_element()
if self.chat_1.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed():
self.errors.append("Message_4 is not unpinned!")
for chat_number, chat in enumerate([self.chat_1, self.chat_2]):
count = chat.pinned_messages_count.text
if count != '2':
self.errors.append(
"Pinned messages count is not 2 after unpinning the last pinned message for user %s" % (
chat_number + 1)
)
self.errors.verify_no_errors()
@marks.testrail_id(702732)
def test_chat_pin_messages_in_group_chat(self):
[chat.click_system_back_button_until_element_is_shown() for chat in [self.chat_1, self.chat_2]]
self.home_1.just_fyi("Enter group chat and pin message there. It's pinned for both members.")
self.group_chat_name = "Group Chat"
self.group_chat_1 = self.home_1.create_group_chat(user_names_to_add=[self.default_username_2],
group_chat_name=self.group_chat_name,
new_ui=True)
self.group_chat_2 = self.home_2.get_chat(self.group_chat_name).click()
self.group_chat_2.join_chat_button.click_if_shown()
self.group_chat_1.send_message(self.message_1)
self.group_chat_1.pin_message(self.message_1, "pin-to-chat")
if not (self.group_chat_1.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30) and
self.group_chat_2.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 1 is not pinned in group chat!")
self.home_1.just_fyi("Check that non admin user can not unpin messages")
self.group_chat_2.chat_element_by_text(self.message_1).long_press_element()
if self.group_chat_2.element_by_translation_id("unpin-from-chat").is_element_displayed():
self.errors.append("Unpin option is available for non-admin user")
self.group_chat_2.click_system_back_button()
# not implemented yet :
# self.home_1.just_fyi("Grant another user with admin rights and check he can unpin message now")
# self.group_chat_1.chat_options.click()
# group_info = self.group_chat_1.group_info.click()
# options = group_info.get_username_options(self.default_username_2).click()
# options.make_admin_button.click()
# self.group_chat_2.click_system_back_button()
# self.group_chat_2.pin_message(self.message_1, action="unpin")
# if (self.group_chat_1.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed() and
# self.group_chat_2.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed()):
# self.errors.append("Message failed to be unpinned by user who granted admin permissions!")
for message in self.message_2, self.message_3:
# here group_chat_1 should be changed to group_chat_2 after enabling the previous block
self.group_chat_1.send_message(message)
self.group_chat_1.pin_message(message, 'pin-to-chat')
if not (self.group_chat_1.chat_element_by_text(message).pinned_by_label.is_element_displayed(30) and
self.group_chat_2.chat_element_by_text(message).pinned_by_label.is_element_displayed(30)):
self.errors.append("%s is not pinned in group chat!" % message)
self.group_chat_1.send_message(self.message_4)
self.group_chat_1.pin_message(self.message_4, 'pin-to-chat')
if self.group_chat_1.pin_limit_popover.is_element_displayed(30):
self.group_chat_1.view_pinned_messages_button.click()
self.group_chat_1.pinned_messages_list.message_element_by_text(
self.message_2).click_inside_element_by_coordinate()
self.group_chat_1.element_by_translation_id('unpin-from-chat').click()
self.group_chat_1.chat_element_by_text(self.message_4).click()
self.group_chat_1.pin_message(self.message_4, 'pin-to-chat')
if not (self.group_chat_1.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30) and
self.group_chat_2.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 4 is not pinned in group chat after unpinning previous one")
else:
self.errors.append("Can pin more than 3 messages in group chat")
for chat_number, group_chat in enumerate([self.group_chat_1, self.group_chat_2]):
count = group_chat.pinned_messages_count.text
if count != '3':
self.errors.append(
"Pinned messages count %s doesn't match expected 3 for user %s" % (count, chat_number + 1))
group_chat.pinned_messages_count.click()
for message in self.message_1, self.message_3, self.message_4:
pinned_by = group_chat.pinned_messages_list.get_message_pinned_by_text(message)
if pinned_by.is_element_displayed():
text = pinned_by.text.strip()
expected_text = "You" if chat_number == 0 else self.default_username_1
if text != expected_text:
self.errors.append(
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, chat_number + 1)
)
else:
self.errors.append(
"Message '%s' is missed on Pinned messages list for user %s" % (message, chat_number + 1)
)
self.errors.verify_no_errors()

View File

@ -140,16 +140,17 @@ class BaseElement(object):
return WebDriverWait(self.driver, seconds) \
.until(expected_conditions.invisibility_of_element_located((self.by, self.locator)))
except TimeoutException:
raise TimeoutException("Device %s: %s by %s: `%s` is still visible on the screen after %s seconds after wait_for_invisibility_of_element" % (
self.driver.number, self.name, self.by, self.locator, seconds)) from None
raise TimeoutException(
"Device %s: %s by %s: `%s` is still visible on the screen after %s seconds after wait_for_invisibility_of_element" % (
self.driver.number, self.name, self.by, self.locator, seconds)) from None
def wait_for_element_text(self, text, wait_time=30):
def wait_for_element_text(self, text, wait_time=30, message=None):
counter = 0
self.driver.info("Wait for text element `%s` to be equal to `%s`" % (self.name, text))
while True:
if counter >= wait_time:
self.driver.fail(
"`%s` is not equal to expected `%s` in %s sec" % (self.find_element().text, text, wait_time))
self.driver.fail(message if message else "`%s` is not equal to expected `%s` in %s sec" % (
self.find_element().text, text, wait_time))
elif self.find_element().text != text:
counter += 10
time.sleep(10)

View File

@ -1,16 +1,16 @@
from datetime import datetime, timedelta
import dateutil.parser
import time
import re
import time
from datetime import datetime, timedelta
from time import sleep
from selenium.common.exceptions import NoSuchElementException, TimeoutException
import dateutil.parser
from selenium.common.exceptions import NoSuchElementException
from tests import emojis
from time import sleep
from views.base_element import Button, EditBox, Text, BaseElement, SilentButton
from views.base_view import BaseView
from views.profile_view import ProfilePictureElement
from views.home_view import HomeView
from views.profile_view import ProfilePictureElement
class CommandsButton(Button):
@ -113,6 +113,7 @@ class ProfileBlockContactButton(Button):
self.scroll_to_element()
self.wait_for_element().click()
class ChatElementByText(Text):
def __init__(self, driver, text):
self.message_text = text
@ -155,6 +156,7 @@ class ChatElementByText(Text):
class TimeStampText(Button):
def __init__(self, driver, parent_locator: str):
super().__init__(driver, xpath="%s//*[@content-desc='message-timestamp']" % parent_locator)
return TimeStampText(self.driver, self.locator).text
@property
@ -225,6 +227,7 @@ class ChatElementByText(Text):
return RepliedToUsernameText(self.driver, self.message_locator).text
except NoSuchElementException:
return ''
# Old UI
# def emojis_below_message(self, emoji: str = 'thumbs-up', own=True):
# class EmojisNumber(Text):
@ -250,7 +253,8 @@ class ChatElementByText(Text):
def __init__(self, driver, parent_locator: str):
self.emoji = emoji
self.emojis_id = 'emoji-reaction-%s' % str(emojis[self.emoji])
super().__init__(driver, prefix=parent_locator, xpath="/../..//*[@content-desc='%s']/android.widget.TextView" % self.emojis_id)
super().__init__(driver, prefix=parent_locator,
xpath="/../..//*[@content-desc='%s']/android.widget.TextView" % self.emojis_id)
@property
def text(self):
@ -308,7 +312,8 @@ class GroupChatInfoView(BaseView):
def user_admin(self, username: str):
admin = Button(self.driver,
xpath="//*[@text='%s']/..//*[@text='%s']" % (username, self.get_translation_by_key("group-chat-admin")))
xpath="//*[@text='%s']/..//*[@text='%s']" % (
username, self.get_translation_by_key("group-chat-admin")))
admin.scroll_to_element()
return admin
@ -470,7 +475,7 @@ class TransactionMessage(ChatElementByText):
super().__init__(driver, text=text)
if transaction_value:
self.xpath = "//*[starts-with(@text,'%s')]/../*[@text='%s']/ancestor::android.view.ViewGroup[@content-desc='chat-item']" % (
text, transaction_value)
text, transaction_value)
# Common statuses for incoming and outgoing transactions
self.address_requested = self.get_translation_by_key("address-requested")
self.confirmed = self.get_translation_by_key("status-confirmed")
@ -577,6 +582,22 @@ class UnpinMessagePopUp(BaseElement):
return element
class PinnedMessagesList(BaseElement):
def __init__(self, driver):
super().__init__(driver, xpath="//*[@content-desc='pinned-messages-list']")
def message_element_by_text(self, text):
message_element = Text(self.driver, prefix=self.locator, xpath="//*[starts-with(@text,'%s')]" % text)
self.driver.info("Looking for a pinned message by text: %s" % message_element.exclude_emoji(text))
return message_element
def get_message_pinned_by_text(self, text):
xpath = "//*[starts-with(@text,'%s')]/../../../../*[@content-desc='pinned-by']/android.widget.TextView" % text
pinned_by_element = Text(self.driver, prefix=self.locator, xpath=xpath)
self.driver.info("Looking for a pinned by message with text: %s" % text)
return pinned_by_element
class ChatView(BaseView):
def __init__(self, driver):
super().__init__(driver)
@ -713,6 +734,13 @@ class ChatView(BaseView):
suffix='/following-sibling::android.view.ViewGroup')
self.confirm_create_in_community_button = Button(self.driver, translation_id="create")
# New UI
self.pinned_messages_count = Button(self.driver,
xpath="//*[@content-desc='pins-count']/android.widget.TextView")
self.pinned_messages_list = PinnedMessagesList(self.driver)
self.pin_limit_popover = BaseElement(self.driver, accessibility_id="pin-limit-popover")
self.view_pinned_messages_button = Button(self.driver, accessibility_id="view-pinned-messages")
def get_outgoing_transaction(self, account=None, transaction_value=None) -> object:
if account is None:
account = self.status_account_name
@ -827,7 +855,7 @@ class ChatView(BaseView):
self.chat_message_input.send_keys(message)
self.send_message_button.click()
def send_contact_request(self, message:str = 'Contact request message', wait_chat_input_sec=5):
def send_contact_request(self, message: str = 'Contact request message', wait_chat_input_sec=5):
self.driver.info("Sending contact request message '%s'" % BaseElement(self.driver).exclude_emoji(message))
self.contact_request_button.wait_and_click()
self.chat_message_input.wait_for_element(wait_chat_input_sec)
@ -850,7 +878,8 @@ class ChatView(BaseView):
def delete_message_in_chat(self, message, everyone=True):
self.driver.info("Looking for message '%s' to delete it" % message)
self.element_by_text_part(message).long_press_element()
for_everyone, for_me = self.element_by_translation_id("delete-for-everyone"), self.element_by_translation_id("delete-for-me")
for_everyone, for_me = self.element_by_translation_id("delete-for-everyone"), self.element_by_translation_id(
"delete-for-me")
for_everyone.click() if everyone else for_me.click()
def copy_message_text(self, message_text):

View File

@ -1,8 +1,10 @@
import time
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from tests import test_dapp_url
from views.base_element import Button, Text, BaseElement, SilentButton, CheckBox
from views.base_view import BaseView
from tests import test_dapp_url
class ChatButton(Button):
@ -239,6 +241,9 @@ class HomeView(BaseView):
self.not_connected_to_node_text = Text(self.driver, accessibility_id="not-connected-nodes")
self.not_connected_to_peers_text = Text(self.driver, accessibility_id="not-connected-to-peers")
# New UI
self.new_chat_button = Button(self.driver, accessibility_id="new-chat-button")
def wait_for_syncing_complete(self):
self.driver.info('Waiting for syncing to complete')
while True:
@ -301,9 +306,12 @@ class HomeView(BaseView):
self.driver.info("## 1-1 chat is created successfully!", device=False)
return one_to_one_chat
def create_group_chat(self, user_names_to_add: list, group_chat_name: str = 'new_group_chat'):
def create_group_chat(self, user_names_to_add: list, group_chat_name: str = 'new_group_chat', new_ui=False):
self.driver.info("## Creating group chat '%s'" % group_chat_name, device=False)
self.plus_button.click()
if new_ui:
self.new_chat_button.click()
else:
self.plus_button.click()
chat_view = self.new_group_chat_button.click()
if user_names_to_add:
for user_name in user_names_to_add: