diff --git a/ci/tests/Jenkinsfile.e2e-nightly b/ci/tests/Jenkinsfile.e2e-nightly index d04fae4243..442d2d527c 100644 --- a/ci/tests/Jenkinsfile.e2e-nightly +++ b/ci/tests/Jenkinsfile.e2e-nightly @@ -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} """ diff --git a/test/appium/support/testrail_report.py b/test/appium/support/testrail_report.py index 6d2b58685e..a591349a29 100644 --- a/test/appium/support/testrail_report.py +++ b/test/appium/support/testrail_report.py @@ -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]]): diff --git a/test/appium/tests/marks.py b/test/appium/tests/marks.py index 24770fff14..4377be8c25 100644 --- a/test/appium/tests/marks.py +++ b/test/appium/tests/marks.py @@ -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 diff --git a/test/appium/tests/medium/test_chats_m.py b/test/appium/tests/medium/test_chats_m.py index 0b23af1253..89b70b0834 100644 --- a/test/appium/tests/medium/test_chats_m.py +++ b/test/appium/tests/medium/test_chats_m.py @@ -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() diff --git a/test/appium/views/base_element.py b/test/appium/views/base_element.py index 1a495e6e1b..347a0cac9e 100644 --- a/test/appium/views/base_element.py +++ b/test/appium/views/base_element.py @@ -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) diff --git a/test/appium/views/chat_view.py b/test/appium/views/chat_view.py index 6cc1c98e5c..65542c1603 100644 --- a/test/appium/views/chat_view.py +++ b/test/appium/views/chat_view.py @@ -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): diff --git a/test/appium/views/home_view.py b/test/appium/views/home_view.py index c4f6d67284..f2e2166380 100644 --- a/test/appium/views/home_view.py +++ b/test/appium/views/home_view.py @@ -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: