Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/e2e/ext/allure_files/environment.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
os_platform = linux
os_platform = Windows
python_version = Python 3.10
14 changes: 8 additions & 6 deletions test/e2e/gui/elements/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,17 @@ def native_mouse_click(
def hover(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC):
def _hover():
try:
driver.mouseMove(self.object)
obj = driver.waitForObject(self.real_name, 500)
driver.mouseMove(obj)
LOG.info('%s: mouse hovered', self)
return getattr(self.object, 'hovered', True)
except RuntimeError as err:
LOG.error(err)
time.sleep(1)
return True
except (RuntimeError, LookupError) as err:
LOG.warning('%s: hover failed - %s', self, err)
time.sleep(0.3)
return False

assert driver.waitFor(lambda: _hover(), timeout_msec)
assert driver.waitFor(lambda: _hover(), timeout_msec), \
f'Failed to hover over {self} within {timeout_msec}ms'
return self

@allure.step('Right click on {0}')
Expand Down
1 change: 1 addition & 0 deletions test/e2e/gui/objects_map/messaging_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
mainWindow_inputScrollView_StatusScrollView = {"container": statusDesktop_mainWindow, "id": "inputScrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True}
inputScrollView_messageInputField_TextArea = {"container": mainWindow_inputScrollView_StatusScrollView, "objectName": "messageInputField", "type": "TextArea", "visible": True}
mainWindow_statusChatInputEmojiButton_StatusFlatRoundButton = {"container": statusDesktop_mainWindow, "objectName": "statusChatInputEmojiButton", "type": "StatusFlatRoundButton", "visible": True}
sendMessageButton = {"container": statusDesktop_mainWindow, "objectName": "statusChatInputSendButton", "type": "StatusFlatRoundButton", "visible": True}
mainWindow_imageBtn_StatusFlatRoundButton = {"container": statusDesktop_mainWindow, "id": "imageBtn", "type": "StatusFlatRoundButton", "unnamed": 1, "visible": True}
mainWindow_statusChatInput_StatusChatInput = {"container": statusDesktop_mainWindow, "objectName": "statusChatInput", "type": "Rectangle", "visible": True}
mark_as_Read_StatusMenuItem = {"checkable": False, "container": mainWindow_Overlay, "enabled": True, "objectName": "chatMarkAsReadMenuItem", "type": "StatusMenuItem", "visible": True}
Expand Down
46 changes: 39 additions & 7 deletions test/e2e/gui/screens/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,38 @@ def open_banned_community_invitation(self):

@allure.step('Hover message')
def hover_message(self):
self.delegate_button.hover()
return MessageQuickActions()
# Try to hover over delegate button if found, otherwise hover over the message object itself
if self.delegate_button is not None:
try:
driver.waitFor(lambda: self.delegate_button.is_visible, configs.timeouts.UI_LOAD_TIMEOUT_MSEC)
# Try standard hover first
try:
self.delegate_button.hover()
except AssertionError:
# Fallback to native mouse move
bounds = driver.object.globalBounds(self.delegate_button.object)
driver.nativeMouseMove(int(bounds.x + bounds.width // 2), int(bounds.y + bounds.height // 2))
time.sleep(1) # Increased wait time
except LookupError:
# Fallback to hovering over the main message object
message_obj = QObject(real_name=driver.objectMap.realName(self.object))
bounds = driver.object.globalBounds(message_obj.object)
driver.nativeMouseMove(int(bounds.x + bounds.width // 2), int(bounds.y + bounds.height // 2))
time.sleep(1) # Increased wait time
else:
# Hover over the main message object using native mouse move
message_obj = QObject(real_name=driver.objectMap.realName(self.object))
bounds = driver.object.globalBounds(message_obj.object)
driver.nativeMouseMove(int(bounds.x + bounds.width // 2), int(bounds.y + bounds.height // 2))
time.sleep(1) # Increased wait time

# Wait for quick actions to appear and be ready
quick_actions = MessageQuickActions()
# Wait for the quick actions container to be visible first
driver.waitFor(lambda: quick_actions.is_visible, configs.timeouts.UI_LOAD_TIMEOUT_MSEC)
# Then wait for edit button specifically
driver.waitFor(lambda: quick_actions._edit_button.is_visible, configs.timeouts.UI_LOAD_TIMEOUT_MSEC)
return quick_actions

@allure.step('Get color of message background')
def get_message_color(self) -> str:
Expand Down Expand Up @@ -343,6 +373,7 @@ def __init__(self):
self._message_input_area = QObject(messaging_names.inputScrollView_messageInputField_TextArea)
self._message_field = TextEdit(messaging_names.inputScrollView_Message_PlaceholderText)
self._emoji_button = Button(messaging_names.mainWindow_statusChatInputEmojiButton_StatusFlatRoundButton)
self._send_message_button = Button(messaging_names.sendMessageButton)
self._image_button = Button(messaging_names.mainWindow_imageBtn_StatusFlatRoundButton)
self._link_preview_title = QObject(messaging_names.mainWindow_linkPreviewTitleText_StatusBaseText)
self._link_preview_preview_subtitle = QObject(messaging_names.mainWindow_linkPreviewSubtitleText_StatusBaseText)
Expand Down Expand Up @@ -408,9 +439,8 @@ def type_message(self, message: str):

@allure.step('Confirm sending message')
def confirm_sending_message(self):
self._message_input_area.click()
for i in range(2):
driver.nativeType('<Return>')
self._send_message_button.click()
time.sleep(1)

@allure.step('Click options combobox')
def click_options(self):
Expand Down Expand Up @@ -464,8 +494,8 @@ def choose_image(self, path_or_base64):

@allure.step('Confirm sending message')
def send_message(self):
for i in range(2):
driver.nativeType('<Return>')
self._send_message_button.click()
time.sleep(1)

@allure.step('Remove member from chat')
def remove_member_from_chat(self, member):
Expand Down Expand Up @@ -536,8 +566,10 @@ def reply_own_message(self, text: str):
self._reply_button.click()
assert self._reply_area.exists
self._message_input_area.type_text(text)
time.sleep(0.5)
for i in range(2):
driver.nativeType('<Return>')
time.sleep(0.5)

@allure.step('Delete button is visible')
def is_delete_button_visible(self) -> bool:
Expand Down
9 changes: 9 additions & 0 deletions test/e2e/helpers/multiple_instances_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Helper functions for common operations with multiple instances.
Reduces code duplication across test files.
"""
import time
import allure
from allure_commons._allure import step

Expand All @@ -19,6 +20,8 @@ def switch_to_aut(aut, main_window):
"""
aut.attach()
main_window.prepare()
main_window.set_focus() # Ensure window has focus
time.sleep(0.5) # Give time for focus to be set


@allure.step('Switch to AUT and hide main window')
Expand All @@ -32,6 +35,8 @@ def switch_to_aut_and_hide(aut, main_window):
"""
aut.attach()
main_window.prepare()
main_window.set_focus() # Ensure window has focus before hiding
time.sleep(0.5)
main_window.hide()


Expand All @@ -47,6 +52,8 @@ def authorize_user_in_aut(aut, main_window, user_account):
"""
aut.attach()
main_window.wait_until_appears(configs.timeouts.APP_LOAD_TIMEOUT_MSEC).prepare()
main_window.set_focus() # Ensure window has focus
time.sleep(0.5)
main_window.authorize_user(user_account)
main_window.hide()

Expand All @@ -65,6 +72,8 @@ def get_chat_key(aut, main_window):
"""
aut.attach()
main_window.prepare()
main_window.set_focus() # Ensure window has focus
time.sleep(0.5)
profile_popup = main_window.left_panel.open_online_identifier().open_profile_popup_from_online_identifier()
chat_key = profile_popup.copy_chat_key
main_window.left_panel.click()
Expand Down
13 changes: 12 additions & 1 deletion test/e2e/scripts/utils/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@


def remove_tags(html):
# Handle None or empty input
if html is None:
return ""

# Convert to string if not already
html_str = str(html)

# If empty string, return empty
if not html_str.strip():
return ""

# parse html content
soup = BeautifulSoup(html, "html.parser")
soup = BeautifulSoup(html_str, "html.parser")

for data in soup(['style', 'script']):
# Remove tags
Expand Down
11 changes: 7 additions & 4 deletions test/e2e/tests/crtitical_tests_prs/test_messaging_1x1_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

@pytest.mark.case(703087, 738732, 738734, 738742, 738744, 738745)
@pytest.mark.critical
@pytest.mark.skipif(get_platform() == 'Windows', reason="https://github.com/status-im/status-desktop/issues/18994")
# @pytest.mark.skipif(get_platform() == 'Windows', reason="https://github.com/status-im/status-desktop/issues/18994")
@pytest.mark.smoke
def test_1x1_chat_add_contact_in_settings(multiple_instances):
user_one: UserAccount = RandomUser()
Expand All @@ -48,9 +48,12 @@ def test_1x1_chat_add_contact_in_settings(multiple_instances):
authorize_user_in_aut(aut, main_window, account)

with step(f'User {user_two.name}, get chat key'):
switch_to_aut(aut_two, main_window)
chat_key = get_chat_key(aut_two, main_window)
main_window.hide()

with step(f'User {user_one.name}, send contact request to {user_two.name}'):
switch_to_aut(aut_one, main_window)
contacts_settings = send_contact_request_from_settings(aut_one, main_window, chat_key, f'Hello {user_two.name}')

with step('Verify that contact request was sent and is in pending requests'):
Expand Down Expand Up @@ -109,6 +112,7 @@ def test_1x1_chat_add_contact_in_settings(multiple_instances):
switch_to_aut(aut_two, main_window)
messages_screen = main_window.left_panel.open_messages_screen()
assert user_one.name in messages_screen.left_panel.get_chats_names
main_window.hide()

with step(f'User {user_one.name} send a message to {user_two.name}'):
switch_to_aut(aut_one, main_window)
Expand All @@ -126,8 +130,8 @@ def test_1x1_chat_add_contact_in_settings(multiple_instances):
# with step(f'User {user_one.name}, click address / ens link in message and verify send modal appears'):
# send_modal = chat.open_send_modal_from_link(chat_message1)
# assert str(send_modal.send_modal_recipient_panel.object.selectedRecipientAddress) == chat_message1
left_panel_chat.click()
skip_message_backup_popup_if_visible()
#left_panel_chat.click()
#skip_message_backup_popup_if_visible()

with step(f'User {user_one.name}, edit message and verify it was changed'):
message_actions = message.hover_message()
Expand Down Expand Up @@ -233,7 +237,6 @@ def test_1x1_chat_add_contact_in_settings(multiple_instances):
assert len(messages) != 0, f"The history of messages is empty"

with step(f'User {user_two.name} close chat'):
switch_to_aut(aut_two, main_window)
messages_screen.group_chat.close_chat()
assert user_one.name not in messages_screen.left_panel.get_chats_names, f'{chat} is present in chats list'
main_window.hide()
Expand Down
Loading