diff --git a/src/status_im2/contexts/chat/home/chat_list_item/view.cljs b/src/status_im2/contexts/chat/home/chat_list_item/view.cljs index 43370192a86..70a2a6c4106 100644 --- a/src/status_im2/contexts/chat/home/chat_list_item/view.cljs +++ b/src/status_im2/contexts/chat/home/chat_list_item/view.cljs @@ -235,8 +235,9 @@ (if-not muted (when show-unread-badge? [quo/info-count - {:style {:top 16 - :right 16}} + {:style {:top 16 + :right 16} + :accessibility-label :new-message-counter} unviewed-messages-count]) [icons/icon :i/muted {:color colors/neutral-40 diff --git a/test/appium/tests/critical/chats/test_1_1_public_chats.py b/test/appium/tests/critical/chats/test_1_1_public_chats.py index 2c22e445bdc..f6044f7a233 100644 --- a/test/appium/tests/critical/chats/test_1_1_public_chats.py +++ b/test/appium/tests/critical/chats/test_1_1_public_chats.py @@ -6,7 +6,7 @@ from _pytest.outcomes import Failed from selenium.common.exceptions import TimeoutException, NoSuchElementException -from tests import marks, common_password, run_in_parallel +from tests import marks, common_password, run_in_parallel, transl from tests.base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers from tests.users import transaction_senders, basic_user, ens_user, ens_user_message_sender from views.sign_in_view import SignInView @@ -1378,6 +1378,48 @@ def test_1_1_chat_is_shown_message_sent_delivered_from_offline(self): self.errors.append('%s after back up online!' % e.msg) self.errors.verify_no_errors() + @marks.testrail_id(703496) + def test_1_1_chat_mute_chat(self): + self.home_1.click_system_back_button_until_element_is_shown() + self.home_1.chats_tab.click() + self.home_1.just_fyi("Mute chat") + self.home_1.mute_chat_long_press(self.username_2) + + muted_message = "should be muted" + self.chat_2.send_message(muted_message) + chat = self.home_1.get_chat(self.username_2) + if chat.new_messages_counter.is_element_displayed(30) or self.home_1.chats_tab.counter.is_element_displayed(10): + self.errors.append("New messages counter is shown after mute") + if not chat.chat_preview.text.startswith(muted_message): + self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message) + chat.click() + if not self.chat_1.chat_element_by_text(muted_message).is_element_displayed(30): + self.errors.append("Message '%s' is not shown in chat for receiver after mute" % muted_message) + + self.chat_1.just_fyi("Unmute chat") + self.chat_1.click_system_back_button_until_element_is_shown() + chat.long_press_element() + if self.home_1.mute_chat_button.text != transl["unmute-chat"]: + self.errors.append("Chat is not muted") + # ToDo: enable the next check when https://github.com/status-im/status-mobile/issues/16768 is fixed + # expected_text = "%s %s" % (transl["muted-until"], transl["until-you-turn-it-back-on"]) + # if not self.home_1.element_by_text(expected_text).is_element_displayed(): + # self.errors.append("Text '%s' is not shown for muted chat" %expected_text) + self.home_1.mute_chat_button.click() + + unmuted_message = "after unmute" + self.chat_2.send_message(unmuted_message) + if not chat.new_messages_counter.is_element_displayed( + 30) or not self.home_1.chats_tab.counter.is_element_displayed(10): + self.errors.append("New messages counter is not shown after unmute") + if not chat.chat_preview.text.startswith(unmuted_message): + self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message) + chat.click() + if not self.chat_1.chat_element_by_text(unmuted_message).is_element_displayed(30): + self.errors.append("Message '%s' is not shown in chat for receiver after unmute" % unmuted_message) + + self.errors.verify_no_errors() + @marks.testrail_id(702784) def test_1_1_chat_delete_via_long_press_relogin(self): self.home_2.click_system_back_button_until_element_is_shown() diff --git a/test/appium/tests/critical/chats/test_group_chat.py b/test/appium/tests/critical/chats/test_group_chat.py index 4c61f969ce4..3603ae2ee45 100644 --- a/test/appium/tests/critical/chats/test_group_chat.py +++ b/test/appium/tests/critical/chats/test_group_chat.py @@ -2,7 +2,7 @@ from _pytest.outcomes import Failed from selenium.common.exceptions import NoSuchElementException, TimeoutException -from tests import marks, run_in_parallel +from tests import marks, run_in_parallel, transl from tests.base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers from views.chat_view import ChatView from views.sign_in_view import SignInView @@ -151,18 +151,18 @@ def prepare_devices(self): self.message_before_adding = 'message before adding new user' self.message_to_admin = 'Hey, admin!' self.public_keys, self.usernames, self.chats = {}, {}, {} - sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers] + self.sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers] self.usernames = ('user admin', 'member_1', 'member_2') self.loop.run_until_complete( run_in_parallel( ( - (sign_in_views[0].create_user, {'enable_notifications': True, 'username': self.usernames[0]}), - (sign_in_views[1].create_user, {'enable_notifications': True, 'username': self.usernames[1]}), - (sign_in_views[2].create_user, {'enable_notifications': True, 'username': self.usernames[2]}) + (self.sign_in_views[0].create_user, {'enable_notifications': True, 'username': self.usernames[0]}), + (self.sign_in_views[1].create_user, {'enable_notifications': True, 'username': self.usernames[1]}), + (self.sign_in_views[2].create_user, {'enable_notifications': True, 'username': self.usernames[2]}) ) ) ) - self.homes = [sign_in.get_home_view() for sign_in in sign_in_views] + self.homes = [sign_in.get_home_view() for sign_in in self.sign_in_views] self.public_keys = self.loop.run_until_complete( run_in_parallel( ( @@ -517,3 +517,92 @@ def test_group_chat_pin_messages(self): ) self.errors.verify_no_errors() + + @marks.testrail_id(703495) + def test_group_chat_mute_chat(self): + [self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)] + + self.homes[1].just_fyi("Member 1 mutes the chat") + self.homes[1].mute_chat_long_press(self.chat_name) + # ToDo: should be redone to some exact period mute after issue with adb commands execution is solved with + # SauceLabs or an option for 1 minute mute is added for e2e apk + # self.homes[1].mute_chat_long_press(self.chat_name, "mute-for-1-hour") + # device_time = self.homes[1].driver.device_time + + self.homes[0].just_fyi("Admin sends a message") + muted_message = "Text message in the muted chat" + self.homes[0].get_chat(self.chat_name).click() + try: + initial_counter = int(self.homes[1].chats_tab.counter.text) + except NoSuchElementException: + initial_counter = 0 + self.chats[0].send_message(muted_message) + self.homes[1].just_fyi("Member 1 checks that chat is muted and message is received") + chat = self.homes[1].get_chat(self.chat_name) + if chat.new_messages_counter.is_element_displayed(30): + self.errors.append("New messages counter near chat name is shown after mute") + try: + after_mute_counter = int(self.homes[1].chats_tab.counter.text) + except NoSuchElementException: + after_mute_counter = 0 + if after_mute_counter > initial_counter: + self.errors.append("New messages counter near chats tab button is %s after mute, but should be %s" % ( + after_mute_counter, initial_counter)) + if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[0], muted_message)): + self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message) + chat.click() + if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30): + self.errors.append( + "Message '%s' is not shown in chat for %s after mute" % (muted_message, self.usernames[1])) + self.chats[1].click_system_back_button_until_element_is_shown() + chat.long_press_element() + if self.homes[1].mute_chat_button.text != transl["unmute-chat"]: + self.errors.append("Chat is not muted") + # ToDo: enable the next check when https://github.com/status-im/status-mobile/issues/16768 is fixed + # # expected_text = "Muted until %s today" % device_time + 1 + # expected_text = "%s %s" % (transl["muted-until"], transl["until-you-turn-it-back-on"]) + # if not self.homes[1].element_by_text(expected_text).is_element_displayed(): + # self.errors.append("Text '%s' is not shown for muted chat" % expected_text) + self.chats[1].just_fyi("Member 1 unmutes the chat") + # self.chats[1].just_fyi("Close app and change device time so chat will be unmuted by timer") + # self.homes[1].put_app_to_background() + # self.homes[1].driver.execute('mobile: shell', { + # 'command': 'date', + # 'args': [str(device_time + 1)] + # }) + # self.homes[1].driver.launch_app() + # self.sign_in_views[1].sign_in() + # self.homes[1].chats_tab.click() + # chat.long_press_element() + # if self.homes[1].element_starts_with_text("Muted until").is_element_displayed(): + # self.errors.append("Chat is still muted after timeout") + # self.errors.verify_no_errors() + # self.homes[1].click_system_back_button() + self.homes[1].mute_chat_button.click() # ToDo: remove when ^ is enabled + + unmuted_message = "Chat is unmuted now" + self.homes[2].just_fyi("Member 2 sends a message") + self.homes[2].get_chat(self.chat_name).click() + try: + initial_counter = int(self.homes[1].chats_tab.counter.text) + except NoSuchElementException: + initial_counter = 0 + self.chats[2].send_message(unmuted_message) + self.homes[1].just_fyi("Member 1 checks that chat is unmuted and message is received") + if not chat.new_messages_counter.is_element_displayed(30): + self.errors.append("New messages counter near chat name is not shown after unmute") + try: + after_mute_counter = int(self.homes[1].chats_tab.counter.text) + except NoSuchElementException: + after_mute_counter = 0 + if after_mute_counter <= initial_counter: + self.errors.append("New messages counter near chats tab button is %s after unmute, but should be %s" % ( + after_mute_counter, initial_counter + 1)) + if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[2], unmuted_message)): + self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message) + chat.click() + if not self.chats[1].chat_element_by_text(unmuted_message).is_element_displayed(30): + self.errors.append( + "Message '%s' is not shown in chat for %s after unmute" % (self.usernames[1], unmuted_message)) + + self.errors.verify_no_errors() diff --git a/test/appium/tests/critical/test_public_chat_browsing.py b/test/appium/tests/critical/test_public_chat_browsing.py index 11e9a2c65a1..4fe6f947f1b 100644 --- a/test/appium/tests/critical/test_public_chat_browsing.py +++ b/test/appium/tests/critical/test_public_chat_browsing.py @@ -1,3 +1,4 @@ +import datetime import random from datetime import timedelta @@ -7,7 +8,7 @@ from dateutil import parser from selenium.common.exceptions import NoSuchElementException, TimeoutException -from tests import marks, test_dapp_name, test_dapp_url, run_in_parallel, pytest_config_global +from tests import marks, test_dapp_name, test_dapp_url, run_in_parallel, pytest_config_global, transl from tests.base_test_case import create_shared_drivers, MultipleSharedDeviceTestCase from views.chat_view import CommunityView from views.dbs.waku_backup import user as waku_user @@ -316,8 +317,8 @@ def prepare_devices(self): self.community = self.home.create_community(name=self.community_name, description='test description') self.home.get_chat(self.community_name, community=True).click() - community_view = self.home.get_community_view() - self.channel = community_view.get_channel(self.channel_name).click() + self.community_view = self.home.get_community_view() + self.channel = self.community_view.get_channel(self.channel_name).click() @marks.testrail_id(702846) def test_community_navigate_to_channel_when_relaunch(self): @@ -348,6 +349,58 @@ def test_community_copy_and_paste_message_in_chat_input(self): self.errors.verify_no_errors() + @marks.testrail_id(703382) + def test_community_mute_community_and_channel(self): + self.home.jump_to_communities_home() + self.home.just_fyi("Mute community and check that channels are also muted") + self.home.mute_chat_long_press(chat_name=self.community_name, mute_period="mute-for-1-hour", community=True) + device_time = self.home.driver.device_time + current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z") + expected_time = current_time + datetime.timedelta(hours=1) + expected_text = "Muted until %s %s" % ( + expected_time.strftime('%H:%M'), + "today" if current_time.hour < 23 else "tomorrow" + ) + self.home.get_chat(self.community_name).long_press_element() + if not self.home.element_by_text(expected_text).is_element_displayed(): + self.errors.append("Text '%s' is not shown for muted community" % expected_text) + self.home.click_system_back_button() + + self.home.get_chat(self.community_name, community=True).click() + self.community_view.get_channel(self.channel_name).long_press_element() + if not self.home.element_by_text(expected_text).is_element_displayed(): + self.errors.append("Text '%s' is not shown for a channel in muted community" % expected_text) + + self.home.just_fyi("Unmute channel and check that the community is also unmuted") + self.home.mute_channel_button.click() + self.home.jump_to_communities_home() + self.home.get_chat(self.community_name).long_press_element() + if not self.home.element_by_text("Mute community").is_element_displayed(): + self.errors.append("Community is not unmuted when channel is unmuted") + self.home.click_system_back_button() + + self.home.just_fyi("Mute channel and check that community is not muted") + self.home.get_chat(self.community_name, community=True).click() + self.home.mute_chat_long_press(chat_name=self.channel_name, mute_period="mute-for-1-week", + community_channel=True) + device_time = self.home.driver.device_time + current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z") + expected_time = current_time + datetime.timedelta(days=7) + expected_text = "Muted until %s" % expected_time.strftime('%H:%M %a %d %b') + self.community_view.get_channel(self.channel_name).long_press_element() + if not self.home.element_by_text(expected_text).is_element_displayed(): + self.errors.append("Text '%s' is not shown for a muted community channel" % expected_text) + self.home.click_system_back_button() + + self.home.jump_to_communities_home() + self.home.get_chat(self.community_name).long_press_element() + if self.home.element_by_text(expected_text).is_element_displayed() or self.home.mute_community_button.text != \ + transl["mute-community"]: + self.errors.append("Community is muted when channel is muted") + self.home.click_system_back_button() + + self.errors.verify_no_errors() + @marks.testrail_id(703133) def test_restore_multiaccount_with_waku_backup_remove_switch(self): self.home.jump_to_communities_home() diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index bc0e1c627b9..6b7f5ea9600 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -37,7 +37,8 @@ def click(self, times_to_click=3): class UnreadMessagesCountText(Text): def __init__(self, driver, parent_locator: str): - super().__init__(driver, xpath="(%s//android.widget.TextView)[last()]" % parent_locator) + super().__init__(driver, + xpath="%s/*[@resource-id='counter-component']/android.widget.TextView" % parent_locator) class TabButton(Button): diff --git a/test/appium/views/home_view.py b/test/appium/views/home_view.py index a2cf56275dd..751336e7fbb 100644 --- a/test/appium/views/home_view.py +++ b/test/appium/views/home_view.py @@ -1,10 +1,11 @@ import time +from appium.webdriver.common.mobileby import MobileBy from selenium.common.exceptions import TimeoutException, NoSuchElementException from tests import test_dapp_url from views.base_element import Button, Text, BaseElement, SilentButton, CheckBox, EditBox -from views.base_view import BaseView +from views.base_view import BaseView, UnreadMessagesCountText class ChatButton(Button): @@ -72,9 +73,16 @@ def find_element(self): @property def new_messages_counter(self): - from views.base_view import UnreadMessagesCountText - desired_counter = UnreadMessagesCountText(self.driver, self.locator) - return desired_counter + if self.community: + return UnreadMessagesCountText(self.driver, self.locator) + + class NewMessageCounterText(Text): + def __init__(self, driver, parent_locator: str): + super().__init__( + driver, + xpath="%s//*[@content-desc='new-message-counter']/android.widget.TextView" % parent_locator) + + return NewMessageCounterText(self.driver, self.locator) @property def chat_preview(self): @@ -202,6 +210,15 @@ def __init__(self, driver, username=None, index=None): self.username_text = Text(self.driver, xpath="(%s//android.widget.TextView)[2]" % xpath_locator) +class MuteButton(Button): + def __init__(self, driver, accessibility_id): + super().__init__(driver=driver, accessibility_id=accessibility_id) + + @property + def text(self): + return self.find_element().find_element(by=MobileBy.CLASS_NAME, value="android.widget.TextView").text + + class HomeView(BaseView): def __init__(self, driver): super().__init__(driver) @@ -254,6 +271,9 @@ def __init__(self, driver): self.chats_menu_invite_friends_button = Button(self.driver, accessibility_id="chats-menu-invite-friends-button") self.delete_chat_button = Button(self.driver, translation_id="delete-chat") self.clear_history_button = Button(self.driver, accessibility_id="clear-history") + self.mute_chat_button = MuteButton(self.driver, accessibility_id="mute-chat") + self.mute_community_button = MuteButton(self.driver, accessibility_id="mute-community") + self.mute_channel_button = MuteButton(self.driver, accessibility_id="chat-toggle-muted") self.mark_all_messages_as_read_button = Button(self.driver, accessibility_id="mark-as-read") # Connection icons @@ -477,6 +497,17 @@ def clear_chat_long_press(self, username): from views.chat_view import ChatView ChatView(self.driver).clear_button.click() + def mute_chat_long_press(self, chat_name, mute_period="mute-till-unmute", community=False, community_channel=False): + self.driver.info("Muting chat with %s" % chat_name) + self.get_chat(username=chat_name, community_channel=community_channel).long_press_element() + if community: + self.mute_community_button.click() + elif community_channel: + self.mute_channel_button.click() + else: + self.mute_chat_button.click() + self.element_by_translation_id(mute_period).click() + def get_pn(self, pn_text: str): self.driver.info("Getting PN by '%s'" % pn_text) expected_element = PushNotificationElement(self.driver, pn_text)