status-react/test/appium/tests/activity_center/test_activity_center.py

501 lines
28 KiB
Python
Raw Normal View History

import base64
import re
2022-05-16 09:07:23 +00:00
import pytest
from selenium.common.exceptions import TimeoutException
2022-05-16 09:07:23 +00:00
from tests import marks, run_in_parallel
2022-05-16 09:07:23 +00:00
from tests.base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
from tests.users import transaction_senders
2022-05-16 09:07:23 +00:00
from views.sign_in_view import SignInView
2022-12-29 13:49:00 +00:00
2023-03-13 13:29:18 +00:00
@pytest.mark.xdist_group(name="new_two_2")
2024-07-12 16:29:44 +00:00
@marks.nightly
2023-03-09 11:06:03 +00:00
class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestCase):
2022-12-29 13:49:00 +00:00
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.username_1, self.username_2 = 'sender', 'receiver'
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
'username': self.username_1}),
(self.device_2.create_user, {'username': self.username_2}))))
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
2022-12-29 13:49:00 +00:00
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
self.public_key_1 = self.home_1.get_public_key()
self.profile_link_2 = self.home_2.get_link_to_profile()
self.home_2.close_share_tab_button.click_until_absense_of_element(self.home_2.link_to_profile_button)
2023-08-18 16:20:40 +00:00
[home.navigate_back_to_home_view() for home in self.homes]
[home.chats_tab.click() for home in self.homes]
2022-12-29 13:49:00 +00:00
2023-03-22 17:09:36 +00:00
@marks.testrail_id(702850)
def test_activity_center_contact_request_decline(self):
2023-12-09 00:25:19 +00:00
app_package = self.device_1.driver.current_package
2022-12-29 13:49:00 +00:00
self.device_1.put_app_to_background()
2023-03-22 17:09:36 +00:00
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
self.home_2.new_chat_button.click_until_presence_of_element(self.home_2.add_a_contact_chat_bottom_sheet_button)
self.home_2.add_a_contact_chat_bottom_sheet_button.click()
2023-12-09 00:25:19 +00:00
self.home_2.driver.set_clipboard_text(self.public_key_1)
2023-03-22 17:09:36 +00:00
self.home_2.element_by_translation_id("paste").click()
self.home_2.element_by_translation_id("user-found").wait_for_visibility_of_element(10)
if self.home_2.user_name_text.is_element_displayed(30):
text_name = self.home_2.user_name_text.text
if text_name != self.username_1 and text_name != "%s...%s" % (
self.public_key_1[:3], self.public_key_1[-6:]):
self.errors.append(
"Neither username nor public key is shown on 'Add contact' page after entering valid public key")
else:
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
2023-03-22 17:09:36 +00:00
chat = self.home_2.get_chat_view()
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_send_contact_request_button)
chat.profile_send_contact_request_button.click()
chat.contact_request_message_input.send_keys("hi")
chat.confirm_send_contact_request_button.click()
chat.close_button.click_until_absense_of_element(chat.close_button)
2023-08-18 16:20:40 +00:00
self.home_2.navigate_back_to_home_view()
2023-03-22 17:09:36 +00:00
self.device_1.just_fyi("Device 1: check there is no PN when receiving new message to activity centre")
2022-12-29 13:49:00 +00:00
self.device_1.open_notification_bar()
if self.home_1.element_by_text_part("Please add me to your contacts").is_element_displayed():
self.errors.append("Push notification with text was received for new message in activity centre")
2023-12-09 00:25:19 +00:00
self.device_1.click_system_back_button()
self.device_1.driver.activate_app(app_package)
self.device_1.wait_for_application_to_be_running(app_package)
2022-12-29 13:49:00 +00:00
self.device_1.just_fyi('Device1 verifies pending contact request')
2024-04-23 13:52:14 +00:00
self.home_1.contacts_tab.click_until_presence_of_element(self.home_1.pending_contact_request_text)
2022-12-29 13:49:00 +00:00
for indicator in (self.home_1.notifications_unread_badge, self.home_1.contact_new_badge):
if not indicator.is_element_displayed():
2023-06-19 11:13:23 +00:00
self.errors.append(
"Unread indicator on contacts tab or on activity center is not shown for incoming CR!")
2022-12-29 13:49:00 +00:00
if self.home_1.pending_contact_request_text.text != '1':
2023-03-01 11:33:58 +00:00
self.errors.append("The amount of contact requests is not shown for incoming CR!")
2022-12-29 13:49:00 +00:00
self.device_1.just_fyi('Device1 declines pending contact request')
self.home_1.handle_contact_request(username=self.username_2, action='decline')
2023-06-19 11:13:23 +00:00
for indicator in (self.home_1.notifications_unread_badge, self.home_1.contact_new_badge,
self.home_1.pending_contact_request_text):
2022-12-29 13:49:00 +00:00
if indicator.is_element_displayed():
2023-06-19 11:13:23 +00:00
self.errors.append(
"Unread indicator on contacts tab or on activity center is shown after declining contact request!")
2022-12-29 13:49:00 +00:00
2023-03-22 17:09:36 +00:00
self.device_1.just_fyi("Check that it is still pending contact after declining on sender device")
2023-08-23 10:36:47 +00:00
self.home_2.navigate_back_to_home_view()
self.home_2.open_activity_center_button.click()
self.home_2.activity_unread_filter_button.click()
element = self.home_2.get_activity_center_element_by_text('connect')
if element.title.text != 'Contact request' or element.context_tag_text != self.username_1 \
or not element.pending_status_tag.is_element_displayed():
2023-06-19 11:13:23 +00:00
self.errors.append(
2023-07-12 09:21:39 +00:00
"Pending contact request is not shown on unread notification element on Activity center!")
self.home_2.close_activity_centre.click()
2023-03-22 17:09:36 +00:00
2022-12-29 13:49:00 +00:00
self.errors.verify_no_errors()
@marks.testrail_id(702851)
2023-03-20 12:58:09 +00:00
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
self.device_2.just_fyi('Creating a new user on Device2')
self.home_2.reopen_app(sign_in=False)
new_username = "new user"
2023-11-06 12:12:04 +00:00
self.device_2.create_user(username=new_username, first_user=False)
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
2023-07-31 12:36:18 +00:00
self.home_2.chats_tab.click()
self.home_2.new_chat_button.click_until_presence_of_element(self.home_2.add_a_contact_chat_bottom_sheet_button)
self.home_2.add_a_contact_chat_bottom_sheet_button.click()
2023-12-09 00:25:19 +00:00
self.home_2.driver.set_clipboard_text(self.public_key_1)
self.home_2.element_by_translation_id("paste").click()
self.home_2.element_by_translation_id("user-found").wait_for_visibility_of_element(10)
chat = self.home_2.get_chat_view()
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_send_contact_request_button)
chat.profile_send_contact_request_button.click()
chat.contact_request_message_input.send_keys("hi")
chat.confirm_send_contact_request_button.click()
chat.close_button.click_until_absense_of_element(chat.close_button)
2022-12-29 13:49:00 +00:00
2023-03-20 12:58:09 +00:00
self.device_1.just_fyi('Device1 accepts pending contact request by swiping')
2022-12-29 13:49:00 +00:00
self.home_1.chats_tab.click()
2023-03-20 12:58:09 +00:00
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(30)
2023-07-31 12:36:18 +00:00
if self.home_1.toast_content_element.is_element_displayed(10):
self.home_1.toast_content_element.wait_for_invisibility_of_element()
2023-03-20 12:58:09 +00:00
self.home_1.open_activity_center_button.click()
self.home_1.just_fyi("Mark all as read")
cr_element = self.home_1.get_element_from_activity_center_view(new_username)
2023-03-20 12:58:09 +00:00
self.home_1.more_options_activity_button.click()
self.home_1.mark_all_read_activity_button.click()
if cr_element.is_element_displayed():
self.errors.append("Contact request is still shown in activity centre after marking all messages as read!")
self.home_1.just_fyi("Check that can accept contact request from read notifications")
self.home_1.activity_unread_filter_button.click()
2023-12-09 00:25:19 +00:00
cr_element.message_body.swipe_right_on_element()
2023-07-24 15:25:36 +00:00
self.home_1.activity_notification_swipe_button.click_inside_element_by_coordinate(rel_x=0.5, rel_y=0.5)
2023-03-20 12:58:09 +00:00
self.home_1.close_activity_centre.click()
2022-12-29 13:49:00 +00:00
self.home_1.contacts_tab.click()
if not self.home_1.contact_details_row(username=new_username).is_element_displayed(20):
2023-03-09 11:06:03 +00:00
self.errors.append("Contact was not added to contact list after accepting contact request (as receiver)")
self.device_2.just_fyi('Device1 check that contact appeared in contact list mutually')
2023-08-18 16:20:40 +00:00
self.home_2.navigate_back_to_home_view()
2023-03-09 11:06:03 +00:00
self.home_2.chats_tab.click()
self.home_2.contacts_tab.click()
2023-06-26 09:59:29 +00:00
if not self.home_2.contact_details_row(username=self.username_1).is_element_displayed(20):
2023-03-09 11:06:03 +00:00
self.errors.append("Contact was not added to contact list after accepting contact request (as sender)")
self.errors.verify_no_errors()
@marks.testrail_id(702777)
def test_add_contact_field_validation(self):
# Profile link encoded data validation
encoded_data = re.findall("u/(.*)#", self.profile_link_2)[0]
decoded_string = base64.b64decode(encoded_data).decode("utf-8", "ignore")
decoded_username = re.sub('[^A-Za-z0-9]+', '', decoded_string)
if decoded_username != self.username_2:
self.errors.append(
"Can't find username '%s' in data which profile link '%s' contains. String '%s' is found instead" % (
self.username_2, self.profile_link_2, decoded_username))
public_key_2 = self.profile_link_2.split("#")[-1]
new_username_1 = "test user 123"
2023-12-26 11:52:10 +00:00
def _device_1_creates_user():
self.home_1.just_fyi("Device 1 creates a new user")
2024-09-13 16:38:35 +00:00
self.home_1.reopen_app(sign_in=False)
self.device_1.create_user(username=new_username_1, first_user=False)
2023-12-26 11:52:10 +00:00
def _device_2_sign_in():
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
self.home_2.reopen_app(sign_in=False)
self.device_2.show_profiles_button.wait_and_click()
2024-06-07 18:21:29 +00:00
self.device_2.get_user_profile_by_name(username=self.username_2).click()
2023-12-26 11:52:10 +00:00
self.device_2.sign_in()
self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
(_device_2_sign_in, {}))))
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
self.home_1.chats_tab.click()
self.home_1.new_chat_button.click_until_presence_of_element(self.home_1.add_a_contact_chat_bottom_sheet_button)
self.home_1.add_a_contact_chat_bottom_sheet_button.click()
self.home_1.driver.set_clipboard_text(self.profile_link_2)
self.home_1.element_by_translation_id("paste").click()
self.home_1.element_by_translation_id("user-found").wait_for_visibility_of_element(10)
if self.home_1.user_name_text.is_element_displayed(30):
text_name = self.home_1.user_name_text.text
if text_name != self.username_2 and text_name != "%s...%s" % (public_key_2[:3], public_key_2[-6:]):
self.errors.append(
"Neither username nor public key is shown on 'Add contact' page after entering valid profile link")
else:
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
chat_1 = self.home_1.get_chat_view()
chat_1.view_profile_new_contact_button.click_until_presence_of_element(
chat_1.profile_send_contact_request_button)
chat_1.profile_send_contact_request_button.click()
chat_1.contact_request_message_input.send_keys("hi")
chat_1.confirm_send_contact_request_button.click()
chat_1.close_button.click_until_absense_of_element(chat_1.close_button)
self.home_2.just_fyi("Device 2 accepts contact request")
self.home_2.handle_contact_request(new_username_1)
self.home_1.just_fyi("Device 1 checks that can find already added contact using public key")
self.home_1.navigate_back_to_home_view()
self.home_1.new_chat_button.click_until_presence_of_element(self.home_1.add_a_contact_chat_bottom_sheet_button)
self.home_1.add_a_contact_chat_bottom_sheet_button.click()
self.home_1.driver.set_clipboard_text(public_key_2)
self.home_1.element_by_translation_id("paste").click()
self.home_1.element_by_translation_id("user-found").wait_for_visibility_of_element(10)
if self.home_1.user_name_text.is_element_displayed(30):
text_name = self.home_1.user_name_text.text
if text_name != self.username_2 and text_name != "%s...%s" % (public_key_2[:3], public_key_2[-6:]):
self.errors.append(
"Neither username nor public key is shown on 'Add contact' page after entering valid public key")
else:
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
self.home_2.just_fyi("Device 2 gets sync code")
self.home_2.navigate_back_to_home_view()
self.home_2.profile_button.click_until_presence_of_element(self.profile_2.default_username_text)
sync_code = self.profile_2.get_sync_code()
invalid_values = [self.public_key_1[:-1], "random string 123",
'0x' + transaction_senders['ETH_ADI_STT_3']['address'], sync_code]
for value in invalid_values:
self.home_1.just_fyi("Device 1 checks adding a contact with invalid value \"%s\"" % value)
chat_1.public_key_edit_box.clear()
self.home_1.element_by_translation_id("invalid-ens-or-key").wait_for_invisibility_of_element()
self.home_1.driver.set_clipboard_text(value)
self.home_1.element_by_translation_id("paste").click()
try:
self.home_1.element_by_translation_id("invalid-ens-or-key").wait_for_visibility_of_element()
except TimeoutException:
self.errors.append("Error message is not shown for value \"%s\"" % value)
self.errors.verify_no_errors()
2023-03-09 11:06:03 +00:00
2023-07-05 09:55:40 +00:00
@pytest.mark.xdist_group(name="new_four_2")
2024-07-12 16:29:44 +00:00
@marks.nightly
@marks.xfail(run=False, reason="Skipped due to waku issue on staging fleet")
2023-03-09 11:06:03 +00:00
class TestActivityMultipleDevicePR(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.username_1, self.username_2 = 'user1', 'user2'
2023-03-09 11:06:03 +00:00
self.loop.run_until_complete(
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
(self.device_2.create_user, {'username': self.username_2}))))
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
2023-03-09 11:06:03 +00:00
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
self.public_key_2 = self.home_2.get_public_key()
2023-08-18 16:20:40 +00:00
self.home_2.navigate_back_to_home_view()
[home.chats_tab.click() for home in self.homes]
2023-03-09 11:06:03 +00:00
self.home_1.add_contact(self.public_key_2)
self.home_2.handle_contact_request(self.username_1)
2023-03-09 11:06:03 +00:00
self.text_message = 'hello'
2022-12-29 13:49:00 +00:00
2023-03-09 11:06:03 +00:00
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
2023-03-24 10:06:20 +00:00
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
self.channel_1 = self.home_1.get_to_community_channel_from_home(self.community_name)
2023-03-24 10:06:20 +00:00
self.channel_1.send_message(self.text_message)
self.community_1, self.community_2 = self.home_1.get_community_view(), self.home_2.get_community_view()
self.community_1.invite_to_community(self.community_name, self.username_2)
self.home_1.get_to_community_channel_from_home(self.community_name)
self.chat_2 = self.home_2.get_chat(self.username_1).click()
2023-03-24 10:06:20 +00:00
self.community_2.join_community()
self.channel_2 = self.community_2.get_channel(self.channel_name).click()
2023-03-09 11:06:03 +00:00
@marks.testrail_id(702936)
2024-05-22 16:19:15 +00:00
@marks.skip("The feature is disabled")
2023-03-09 11:06:03 +00:00
def test_navigation_jump_to(self):
self.community_1.just_fyi("Check Jump to screen and redirect on tap")
2023-12-09 00:25:19 +00:00
self.community_1.click_on_floating_jump_to()
for card in (self.community_name, self.username_2):
2023-03-09 11:06:03 +00:00
if not self.community_1.element_by_text_part(card).is_element_displayed(20):
2022-12-29 13:49:00 +00:00
self.errors.append("Card %s is not shown on Jump to screen!" % card)
2023-03-09 11:06:03 +00:00
self.community_1.element_by_translation_id("community-channel").click()
if not self.channel_1.chat_element_by_text(self.text_message).is_element_displayed(20):
self.errors.append("User was not redirected to community channel after tapping on community channel card!")
self.channel_1.click_system_back_button()
2023-12-09 00:25:19 +00:00
self.community_1.click_on_floating_jump_to()
self.community_1.element_by_text_part(self.username_2).click()
2023-03-09 11:06:03 +00:00
if not self.chat_1.chat_element_by_text(self.one_to_one_message).is_element_displayed(20):
2022-12-29 13:49:00 +00:00
self.errors.append("User was not redirected to 1-1 chat after tapping card!")
self.errors.verify_no_errors()
2023-03-13 13:29:18 +00:00
@marks.testrail_id(702947)
2023-03-20 12:58:09 +00:00
def test_activity_center_reply_read_unread_delete_filter_swipe(self):
2023-03-13 13:29:18 +00:00
message_to_reply, reply_to_message_from_sender = 'something to reply to', 'this is a reply'
2023-08-23 10:36:47 +00:00
self.home_1.navigate_back_to_home_view()
self.home_1.communities_tab.click()
2023-03-13 13:29:18 +00:00
self.home_1.get_chat(self.community_name, community=True).click()
self.community_1.get_channel(self.channel_name).click()
self.channel_1.send_message(message_to_reply)
2023-08-23 10:36:47 +00:00
self.home_1.navigate_back_to_home_view()
self.home_1.communities_tab.click()
2023-06-19 11:13:23 +00:00
self.channel_2.chat_element_by_text(message_to_reply).wait_for_visibility_of_element(120)
2023-03-13 13:29:18 +00:00
self.channel_2.quote_message(message_to_reply)
self.channel_2.send_message(reply_to_message_from_sender)
self.home_1.just_fyi("Checking unread indicators")
2023-03-15 15:44:13 +00:00
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(120)
2023-03-13 13:29:18 +00:00
community_element_1 = self.home_1.get_chat(self.community_name, community=True)
for unread_counter in community_element_1.new_messages_counter, self.home_1.communities_tab.counter:
if not unread_counter.is_element_displayed(60):
self.errors.append('New message counter badge is not shown!')
2023-03-15 15:44:13 +00:00
if int(unread_counter.text) != 1:
2023-03-13 13:29:18 +00:00
self.errors.append('New message counter badge is not 1, it is %s!' % unread_counter.text)
self.home_1.just_fyi("Checking reply attributes in activity center")
self.home_1.open_activity_center_button.click()
reply_element = self.home_1.get_element_from_activity_center_view(reply_to_message_from_sender)
if reply_element.title.text != 'Reply':
self.errors.append("Expected title is not shown, '%s' is instead!" % reply_element.title)
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append("No unread dot is shown on activity center element!")
2023-08-12 18:04:28 +00:00
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
2023-03-13 13:29:18 +00:00
self.home_1.just_fyi("Swiping to 'Replies' on activity center and check unread there")
self.home_1.mention_activity_tab_button.click()
if reply_element.is_element_displayed(2):
self.errors.append("Filter on mentions is not working in Activity centre!")
self.home_1.reply_activity_tab_button.click()
if not self.home_1.reply_activity_tab_button.counter.is_element_displayed(2):
self.errors.append("No unread dot is shown on activity center tab element!")
if not reply_element.is_element_displayed():
self.errors.append("Filter on replies tab is not working in Activity centre!")
2023-08-12 18:04:28 +00:00
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
2023-03-13 13:29:18 +00:00
self.home_1.just_fyi("Mark it as read and check filter")
2023-12-09 00:25:19 +00:00
reply_element.title.swipe_right_on_element(width_percentage=6)
Swipe gestures for Activity Center notifications with CTA (#15284) Implements swipe actions for notifications with call to action (e.g. pending contact requests, unverified identity verifications, etc). Fixes https://github.com/status-im/status-mobile/issues/15118 According to the Design team, the goal is to deliver a consistent experience to users, so whenever the user sees a notification with buttons, the same actions can be taken via the swipe buttons. Note: swipe buttons are using placeholder icons while the Design team works out which ones to use Additionally, a bunch of fixes: - Fix: outgoing pending contact requests were not being removed from the UI when cancelled. - Fix: Membership tab not showing unread indicator. - Fix: dismissed membership notification not marked as read. - Fix: dismissed membership notification was displaying decline/accept buttons. Regression came from changes in status-go related to soft deletion of notifications. - Fix: incorrect check for the pending state of a contact request. - Fixed lots of bugs for identity verification notifications, as it was completely broken. Unfortunately, somebody made lots of changes without actually testing the flows. - Add basic error handling and log if accepting, declining or canceling contact requests fail. The demo shows an identity verification with swipe actions to reply or decline. [identity-verification-swipe-to-reply.webm](https://user-images.githubusercontent.com/46027/223565755-b2ca3f68-12e2-4e1e-9e52-edd52cfcc971.webm) Out of scope: The old quo input is still in use in the identity verification notification. This will eventually be solved by issue https://github.com/status-im/status-mobile/issues/14364 ### Steps to test Notifications with one or more buttons (actions) are affected by this change, because now the user can also swipe left/right to act on them. - Membership notifications: private group chat. The following PR explains how to generate them https://github.com/status-im/status-mobile/pull/14785 - Contact requests, and community gated requests to join (Admin tab). - Identity verifications. I believe the only way to test identity verification flows at the moment is to use the Desktop app, since initiating the challenge is not implemented in Mobile yet. - Mentions and replies don't have new swipe buttons because they don't have call to action buttons throughout their lifecycle. Steps to test identity verification flows: #### Identity verification flow 1 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` declines and the status `Declined` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe delete the notification. - `A` should not receive any notification after `A` declined. #### Identity verification flow 2 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` press `Reply` and a bottom sheet is displayed with a text input. - `B` sends the reply/answer message and the status `Replied` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe to delete the notification. - `A` should receive a notification with the reply from `B`. - `A` can either mark the answer as untrustworthy or accept it (trust it) via the normal buttons, as well as via the swipe left/right buttons. - If `A` accepts the answer, then the status `Confirmed` is shown instead of buttons. On the other hand, if `A` marks as untrustworthy, then the status `Untrustworthy` is shown instead of buttons. - `B` should receive no further notifications due to `A`s actions. - `A` can now either swipe to toggle read/unread or swipe delete the notification.
2023-03-14 15:34:13 +00:00
self.home_1.activity_notification_swipe_button.click()
2023-03-13 13:29:18 +00:00
if reply_element.is_element_displayed(2):
self.errors.append("Message is not marked as read!")
self.home_1.activity_unread_filter_button.click()
if not reply_element.is_element_displayed(2):
self.errors.append("Read filter is not displayed read message!")
2023-08-12 18:04:28 +00:00
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
2023-03-13 13:29:18 +00:00
self.home_1.just_fyi("Mark it as unread and check filter via right swipe")
2023-12-09 00:25:19 +00:00
reply_element.title.swipe_right_on_element(width_percentage=6)
Swipe gestures for Activity Center notifications with CTA (#15284) Implements swipe actions for notifications with call to action (e.g. pending contact requests, unverified identity verifications, etc). Fixes https://github.com/status-im/status-mobile/issues/15118 According to the Design team, the goal is to deliver a consistent experience to users, so whenever the user sees a notification with buttons, the same actions can be taken via the swipe buttons. Note: swipe buttons are using placeholder icons while the Design team works out which ones to use Additionally, a bunch of fixes: - Fix: outgoing pending contact requests were not being removed from the UI when cancelled. - Fix: Membership tab not showing unread indicator. - Fix: dismissed membership notification not marked as read. - Fix: dismissed membership notification was displaying decline/accept buttons. Regression came from changes in status-go related to soft deletion of notifications. - Fix: incorrect check for the pending state of a contact request. - Fixed lots of bugs for identity verification notifications, as it was completely broken. Unfortunately, somebody made lots of changes without actually testing the flows. - Add basic error handling and log if accepting, declining or canceling contact requests fail. The demo shows an identity verification with swipe actions to reply or decline. [identity-verification-swipe-to-reply.webm](https://user-images.githubusercontent.com/46027/223565755-b2ca3f68-12e2-4e1e-9e52-edd52cfcc971.webm) Out of scope: The old quo input is still in use in the identity verification notification. This will eventually be solved by issue https://github.com/status-im/status-mobile/issues/14364 ### Steps to test Notifications with one or more buttons (actions) are affected by this change, because now the user can also swipe left/right to act on them. - Membership notifications: private group chat. The following PR explains how to generate them https://github.com/status-im/status-mobile/pull/14785 - Contact requests, and community gated requests to join (Admin tab). - Identity verifications. I believe the only way to test identity verification flows at the moment is to use the Desktop app, since initiating the challenge is not implemented in Mobile yet. - Mentions and replies don't have new swipe buttons because they don't have call to action buttons throughout their lifecycle. Steps to test identity verification flows: #### Identity verification flow 1 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` declines and the status `Declined` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe delete the notification. - `A` should not receive any notification after `A` declined. #### Identity verification flow 2 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` press `Reply` and a bottom sheet is displayed with a text input. - `B` sends the reply/answer message and the status `Replied` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe to delete the notification. - `A` should receive a notification with the reply from `B`. - `A` can either mark the answer as untrustworthy or accept it (trust it) via the normal buttons, as well as via the swipe left/right buttons. - If `A` accepts the answer, then the status `Confirmed` is shown instead of buttons. On the other hand, if `A` marks as untrustworthy, then the status `Untrustworthy` is shown instead of buttons. - `B` should receive no further notifications due to `A`s actions. - `A` can now either swipe to toggle read/unread or swipe delete the notification.
2023-03-14 15:34:13 +00:00
self.home_1.activity_notification_swipe_button.click()
2023-03-13 13:29:18 +00:00
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append("No unread dot is shown on activity center element after marking it as unread!")
self.home_1.just_fyi("Tap on it and check it marked as read")
reply_element.click()
if not self.channel_1.chat_element_by_text(reply_to_message_from_sender).is_element_displayed():
self.errors.append("Was not redirected to chat after tapping on reply!")
2023-08-23 10:36:47 +00:00
self.home_1.navigate_back_to_home_view()
self.home_1.communities_tab.click()
2023-03-13 13:29:18 +00:00
if self.home_1.notifications_unread_badge.is_element_displayed():
self.errors.append("Notification was not marked as read after opening it in community channel!")
2023-08-12 18:04:28 +00:00
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
2023-03-13 13:29:18 +00:00
self.home_1.just_fyi("Delete it from unread via left swipe")
self.home_1.open_activity_center_button.click()
reply_element.swipe_left_on_element()
Swipe gestures for Activity Center notifications with CTA (#15284) Implements swipe actions for notifications with call to action (e.g. pending contact requests, unverified identity verifications, etc). Fixes https://github.com/status-im/status-mobile/issues/15118 According to the Design team, the goal is to deliver a consistent experience to users, so whenever the user sees a notification with buttons, the same actions can be taken via the swipe buttons. Note: swipe buttons are using placeholder icons while the Design team works out which ones to use Additionally, a bunch of fixes: - Fix: outgoing pending contact requests were not being removed from the UI when cancelled. - Fix: Membership tab not showing unread indicator. - Fix: dismissed membership notification not marked as read. - Fix: dismissed membership notification was displaying decline/accept buttons. Regression came from changes in status-go related to soft deletion of notifications. - Fix: incorrect check for the pending state of a contact request. - Fixed lots of bugs for identity verification notifications, as it was completely broken. Unfortunately, somebody made lots of changes without actually testing the flows. - Add basic error handling and log if accepting, declining or canceling contact requests fail. The demo shows an identity verification with swipe actions to reply or decline. [identity-verification-swipe-to-reply.webm](https://user-images.githubusercontent.com/46027/223565755-b2ca3f68-12e2-4e1e-9e52-edd52cfcc971.webm) Out of scope: The old quo input is still in use in the identity verification notification. This will eventually be solved by issue https://github.com/status-im/status-mobile/issues/14364 ### Steps to test Notifications with one or more buttons (actions) are affected by this change, because now the user can also swipe left/right to act on them. - Membership notifications: private group chat. The following PR explains how to generate them https://github.com/status-im/status-mobile/pull/14785 - Contact requests, and community gated requests to join (Admin tab). - Identity verifications. I believe the only way to test identity verification flows at the moment is to use the Desktop app, since initiating the challenge is not implemented in Mobile yet. - Mentions and replies don't have new swipe buttons because they don't have call to action buttons throughout their lifecycle. Steps to test identity verification flows: #### Identity verification flow 1 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` declines and the status `Declined` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe delete the notification. - `A` should not receive any notification after `A` declined. #### Identity verification flow 2 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` press `Reply` and a bottom sheet is displayed with a text input. - `B` sends the reply/answer message and the status `Replied` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe to delete the notification. - `A` should receive a notification with the reply from `B`. - `A` can either mark the answer as untrustworthy or accept it (trust it) via the normal buttons, as well as via the swipe left/right buttons. - If `A` accepts the answer, then the status `Confirmed` is shown instead of buttons. On the other hand, if `A` marks as untrustworthy, then the status `Untrustworthy` is shown instead of buttons. - `B` should receive no further notifications due to `A`s actions. - `A` can now either swipe to toggle read/unread or swipe delete the notification.
2023-03-14 15:34:13 +00:00
self.home_1.activity_notification_swipe_button.click()
2023-03-13 13:29:18 +00:00
if reply_element.is_element_displayed():
self.errors.append("Reply is still shown after removing from activity centre!")
self.errors.verify_no_errors()
@pytest.mark.xdist_group(name="new_six_2")
2024-07-12 16:29:44 +00:00
@marks.nightly
@marks.xfail(run=False, reason="Skipped due to waku issue on staging fleet")
class TestActivityMultipleDevicePRTwo(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.username_1, self.username_2 = 'user1', 'user2'
self.loop.run_until_complete(
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
(self.device_2.create_user, {'username': self.username_2}))))
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
self.public_key_2 = self.home_2.get_public_key()
self.home_2.navigate_back_to_home_view()
[home.chats_tab.click() for home in self.homes]
self.home_1.add_contact(self.public_key_2)
self.home_2.handle_contact_request(self.username_1)
self.text_message = 'hello'
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
self.channel_1 = self.home_1.get_to_community_channel_from_home(self.community_name)
self.channel_1.send_message(self.text_message)
self.community_1, self.community_2 = self.home_1.get_community_view(), self.home_2.get_community_view()
self.community_1.invite_to_community(self.community_name, self.username_2)
self.home_1.get_to_community_channel_from_home(self.community_name)
self.chat_2 = self.home_2.get_chat(self.username_1).click()
self.community_2.join_community()
self.channel_2 = self.community_2.get_channel(self.channel_name).click()
2023-09-04 10:07:41 +00:00
self.channel_2.chat_message_input.wait_for_visibility_of_element(20)
2023-03-20 12:58:09 +00:00
@marks.testrail_id(702957)
def test_activity_center_mentions(self):
2023-08-23 10:36:47 +00:00
self.home_1.navigate_back_to_home_view()
self.home_1.communities_tab.click()
2023-03-20 12:58:09 +00:00
self.device_2.just_fyi("Invited member sends a message with a mention")
self.channel_2.mention_user(self.username_1)
2023-03-20 12:58:09 +00:00
self.channel_2.send_message_button.click()
self.home_1.just_fyi("Checking unread indicators")
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(120)
community_element_1 = self.home_1.get_chat(self.community_name, community=True)
for unread_counter in community_element_1.new_messages_counter, self.home_1.communities_tab.counter:
if not unread_counter.is_element_displayed(60):
self.errors.append('New message counter badge is not shown while mentioned!')
if int(unread_counter.text) != 1:
self.errors.append('New message counter badge is not 1, it is %s!' % unread_counter.text)
self.home_1.just_fyi("Checking mention attributes in activity center")
self.home_1.open_activity_center_button.click()
mention_element = self.home_1.get_element_from_activity_center_view('@%s' % self.username_1)
2023-03-20 12:58:09 +00:00
if mention_element.title.text != 'Mention':
self.errors.append("Expected title is not shown, '%s' is instead!" % mention_element.title)
if not mention_element.unread_indicator.is_element_displayed():
self.errors.append("No unread dot is shown on activity center element (mention)!")
if mention_element.message_body.text != '@%s' % self.username_1:
2023-06-19 11:13:23 +00:00
self.errors.append(
"Mention body in activity center does not match expected, it is %s!" % mention_element.message_body.text)
2023-03-20 12:58:09 +00:00
self.home_1.just_fyi("Tap on it and check redirect to channel")
mention_element.click()
if not self.channel_1.chat_element_by_text(self.username_1).is_element_displayed():
2023-03-20 12:58:09 +00:00
self.errors.append("Was not redirected to chat after tapping on mention!")
self.errors.verify_no_errors()
@marks.testrail_id(702958)
def test_activity_center_admin_notification_accept_swipe(self):
self.home_2.just_fyi("Clearing history")
2023-08-23 10:36:47 +00:00
self.home_2.navigate_back_to_home_view()
self.home_2.chats_tab.click()
self.home_2.clear_chat_long_press(self.username_1)
2023-03-20 12:58:09 +00:00
2023-08-23 10:36:47 +00:00
[home.navigate_back_to_home_view() for home in (self.home_1, self.home_2)]
2023-08-12 18:04:28 +00:00
2023-03-20 12:58:09 +00:00
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
community_name = 'closed community'
self.channel_name = "dogs"
self.home_1.create_community(community_type="closed")
2023-03-24 10:06:20 +00:00
self.home_1.reopen_app()
self.community_1.invite_to_community(community_name, self.username_2)
2023-03-20 12:58:09 +00:00
2023-03-30 13:14:27 +00:00
self.home_2.just_fyi("Request access to community")
2023-08-23 10:36:47 +00:00
self.home_2.navigate_back_to_home_view()
self.home_2.chats_tab.click()
self.chat_2 = self.home_2.get_chat(self.username_1).click()
2023-09-12 12:39:00 +00:00
self.community_2.join_community(open_community=False)
2023-08-23 10:36:47 +00:00
for home in self.home_1, self.home_2:
home.navigate_back_to_home_view()
home.communities_tab.click()
2023-03-20 12:58:09 +00:00
self.home_1.just_fyi("Checking unread indicators")
try:
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(120)
except TimeoutException:
self.errors.append("Unread indicator is not shown in notifications")
2023-03-20 12:58:09 +00:00
self.home_1.open_activity_center_button.click()
reply_element = self.home_1.get_element_from_activity_center_view(self.username_2)
2023-03-20 12:58:09 +00:00
if reply_element.title.text != 'Join request':
self.errors.append("Expected title is not shown, '%s' is instead!" % reply_element.title)
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append("No unread dot is shown on activity center element!")
2023-12-09 00:25:19 +00:00
reply_element.title.swipe_right_on_element(width_percentage=2.5)
2023-03-20 12:58:09 +00:00
self.home_1.activity_notification_swipe_button.click()
self.home_1.close_activity_centre.click()
self.home_2.just_fyi("Checking that community appeared on the list")
2023-03-20 12:58:09 +00:00
if not self.home_2.element_by_text_part(community_name).is_element_displayed(30):
2023-06-19 11:13:23 +00:00
self.errors.append(
"Community is not appeared in the list after accepting admin request from activity centre")
2023-03-20 12:58:09 +00:00
self.errors.verify_no_errors()