diff --git a/apps/webapp/test/e2e_tests/pageManager/webapp/components/conversationSidebar.component.ts b/apps/webapp/test/e2e_tests/pageManager/webapp/components/conversationSidebar.component.ts index e3b52bb0b5a..0815ea141da 100644 --- a/apps/webapp/test/e2e_tests/pageManager/webapp/components/conversationSidebar.component.ts +++ b/apps/webapp/test/e2e_tests/pageManager/webapp/components/conversationSidebar.component.ts @@ -34,6 +34,7 @@ export class ConversationSidebar { readonly manageTeamButton: Locator; readonly sidebar: Locator; readonly supportButton: Locator; + readonly favoritesButton: Locator; constructor(page: Page) { this.page = page; @@ -50,6 +51,7 @@ export class ConversationSidebar { this.manageTeamButton = page.getByTestId('go-team-management'); this.sidebar = page.locator(`.conversations-sidebar-items`); this.supportButton = page.getByRole('link', {name: 'Support'}); + this.favoritesButton = page.getByRole('tab', {name: 'Favorites'}); } async clickPreferencesButton() { diff --git a/apps/webapp/test/e2e_tests/pageManager/webapp/pages/conversationList.page.ts b/apps/webapp/test/e2e_tests/pageManager/webapp/pages/conversationList.page.ts index e0bf4a1ca77..3f9a144ee78 100644 --- a/apps/webapp/test/e2e_tests/pageManager/webapp/pages/conversationList.page.ts +++ b/apps/webapp/test/e2e_tests/pageManager/webapp/pages/conversationList.page.ts @@ -103,6 +103,7 @@ export class ConversationListPage { unarchiveButton: contextMenu.getByRole('button', {name: 'Unarchive'}), blockButton: contextMenu.getByRole('button', {name: 'Block'}), unblockButton: contextMenu.getByRole('button', {name: 'Unblock'}), + addToFavoritesButton: contextMenu.getByRole('button', {name: 'Add to favorites'}), moveToButton: contextMenu.getByRole('button', {name: 'Move to'}), notificationsButton: contextMenu.getByRole('menuitem', {name: 'Notifications'}), clearContentButton: contextMenu.getByRole('button', {name: 'Clear content'}), diff --git a/apps/webapp/test/e2e_tests/specs/Folders/folders.spec.ts b/apps/webapp/test/e2e_tests/specs/Folders/folders.spec.ts index 99fc0d17163..9c367f49402 100644 --- a/apps/webapp/test/e2e_tests/specs/Folders/folders.spec.ts +++ b/apps/webapp/test/e2e_tests/specs/Folders/folders.spec.ts @@ -57,52 +57,61 @@ async function moveConversationToFolder(pageManager: PageManager, conversationNa test.describe('Folders', () => { let userA: User; let userB: User; - let userAPageManager: PageManager; test.beforeEach(async ({createTeam, createPage, createUser}) => { userB = await createUser(); const team = await createTeam('Team', {users: [userB]}); userA = team.owner; - userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); }); - test('I want to move a 1:1 conversation to a new custom folder', {tag: ['@TC-545', '@regression']}, async () => { - const userAPages = userAPageManager.webapp.pages; + test( + 'I want to move a 1:1 conversation to a new custom folder', + {tag: ['@TC-545', '@regression']}, + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); + const userAPages = userAPageManager.webapp.pages; - const customFolderName = 'Custom-Folder'; + const customFolderName = 'Custom-Folder'; - // Step 1: User A opens 1:1 conversation with User B - await userAPages.conversationList().getConversation(userB.fullName).open(); - // Step 2: User A moves 1:1 conversation with User B into new custom folder - await createCustomFolder(userAPageManager, userB.fullName, customFolderName); - // Step 3: 1:1 conversation with User B is in the custom folder - const actualTitle = userAPages.conversationList().conversationListHeaderTitle; + // Step 1: User A opens 1:1 conversation with User B + await userAPages.conversationList().getConversation(userB.fullName).open(); + // Step 2: User A moves 1:1 conversation with User B into new custom folder + await createCustomFolder(userAPageManager, userB.fullName, customFolderName); + // Step 3: 1:1 conversation with User B is in the custom folder + const actualTitle = userAPages.conversationList().conversationListHeaderTitle; - await expect(actualTitle).toHaveText(customFolderName); - }); + await expect(actualTitle).toHaveText(customFolderName); + }, + ); - test('I want to move a group conversation to a new custom folder', {tag: ['@TC-546', '@regression']}, async () => { - const userAPages = userAPageManager.webapp.pages; + test( + 'I want to move a group conversation to a new custom folder', + {tag: ['@TC-546', '@regression']}, + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); + const userAPages = userAPageManager.webapp.pages; - const customFolderName = 'Custom-Folder'; - const conversationName = 'Group Conversation with User A and User B'; + const customFolderName = 'Custom-Folder'; + const conversationName = 'Group Conversation with User A and User B'; - await createGroup(userAPages, conversationName, [userB]); + await createGroup(userAPages, conversationName, [userB]); - // Step 1: User A opens group conversation with User B - await userAPages.conversationList().getConversation(conversationName).open(); - // Step 2: User A moves group conversation with User B in new custom folder - await createCustomFolder(userAPageManager, conversationName, customFolderName); - // Step 3: Group conversation with User B is in the custom folder - const actualTitle = userAPages.conversationList().conversationListHeaderTitle; + // Step 1: User A opens group conversation with User B + await userAPages.conversationList().getConversation(conversationName).open(); + // Step 2: User A moves group conversation with User B in new custom folder + await createCustomFolder(userAPageManager, conversationName, customFolderName); + // Step 3: Group conversation with User B is in the custom folder + const actualTitle = userAPages.conversationList().conversationListHeaderTitle; - await expect(actualTitle).toHaveText(customFolderName); - }); + await expect(actualTitle).toHaveText(customFolderName); + }, + ); test( 'I want to move a 1:1 conversation to an existing custom folder', {tag: ['@TC-547', '@regression']}, - async () => { + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); const {pages: userAPages, components: userAComponents} = userAPageManager.webapp; const customFolderName = 'Custom-Folder'; @@ -126,7 +135,8 @@ test.describe('Folders', () => { test( 'I want to move a group conversation to an existing custom folder', {tag: ['@TC-548', '@regression']}, - async () => { + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); const {pages: userAPages, components: userAComponents} = userAPageManager.webapp; const customFolderName = 'Custom-Folder'; @@ -151,7 +161,8 @@ test.describe('Folders', () => { test.skip( 'I want to see custom folder removed when last conversation is removed', {tag: ['@TC-553', '@regression']}, - async () => { + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); const userAPages = userAPageManager.webapp.pages; const customFolderName = 'Custom-Folder'; @@ -178,39 +189,155 @@ test.describe('Folders', () => { }, ); - test('I should not be able to create a custom folder without a name', {tag: ['@TC-560', '@regression']}, async () => { - const {pages: userAPages, modals: userAModals} = userAPageManager.webapp; + test( + 'I should not be able to create a custom folder without a name', + {tag: ['@TC-560', '@regression']}, + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); + const {pages: userAPages, modals: userAModals} = userAPageManager.webapp; - // Step 1: User A opens 1:1 conversation with User B - const conversation = await userAPages.conversationList().getConversation(userB.fullName).open(); - // Step 2: User A wants to move 1:1 conversation with User B into custom folder - const contextMenu = await conversation.openContextMenu(); - await contextMenu.moveToButton.click(); - await contextMenu.getByRole('button', {name: 'Create new folder'}).click(); + // Step 1: User A opens 1:1 conversation with User B + const conversation = await userAPages.conversationList().getConversation(userB.fullName).open(); + // Step 2: User A wants to move 1:1 conversation with User B into custom folder + const contextMenu = await conversation.openContextMenu(); + await contextMenu.moveToButton.click(); + await contextMenu.getByRole('button', {name: 'Create new folder'}).click(); - // Step 3: 'Create Folder Modal' should still be visible after click on create - await expect(userAModals.optionModal().actionButton).toBeDisabled(); - }); + // Step 3: 'Create Folder Modal' should still be visible after click on create + await expect(userAModals.optionModal().actionButton).toBeDisabled(); + }, + ); - test('I should not see any traces of a deleted custom folder', {tag: ['@TC-568', '@regression']}, async () => { - const userAPages = userAPageManager.webapp.pages; + test( + 'I should not see any traces of a deleted custom folder', + {tag: ['@TC-568', '@regression']}, + async ({createPage}) => { + const userAPageManager = await PageManager.from(createPage(withLogin(userA), withConnectedUser(userB))); + const userAPages = userAPageManager.webapp.pages; - const customFolderName = 'Custom-Folder'; + const customFolderName = 'Custom-Folder'; - // Preconditions: Conversation is in custom folder - const conversation = await userAPages.conversationList().getConversation(userB.fullName).open(); - await createCustomFolder(userAPageManager, userB.fullName, customFolderName); + // Preconditions: Conversation is in custom folder + const conversation = await userAPages.conversationList().getConversation(userB.fullName).open(); + await createCustomFolder(userAPageManager, userB.fullName, customFolderName); - await test.step('User A removes conversation with User B from custom folder', async () => { - const contextMenu = await conversation.openContextMenu(); - await contextMenu.getByRole('button', {name: `Remove from "${customFolderName}"`}).click(); - }); + await test.step('User A removes conversation with User B from custom folder', async () => { + const contextMenu = await conversation.openContextMenu(); + await contextMenu.getByRole('button', {name: `Remove from "${customFolderName}"`}).click(); + }); - await test.step('User A tries to move conversation with User B back into the folder, custom folder name should no longer be visible in the folder menu', async () => { - await conversation.open(); - const contextMenu = await conversation.openContextMenu(); - await contextMenu.moveToButton.click(); - await expect(contextMenu.getByRole('button', {name: customFolderName})).not.toBeVisible(); - }); - }); + await test.step('User A tries to move conversation with User B back into the folder, custom folder name should no longer be visible in the folder menu', async () => { + await conversation.open(); + const contextMenu = await conversation.openContextMenu(); + await contextMenu.moveToButton.click(); + await expect(contextMenu.getByRole('button', {name: customFolderName})).not.toBeVisible(); + }); + }, + ); + + test( + 'I want to see 1:1 and group conversations in Favorites folder', + {tag: ['@TC-742', '@regression']}, + async ({createPage}) => { + const [userAPageManager, userBPageManager] = await Promise.all([ + createPage(withLogin(userA), withConnectedUser(userB)), + createPage(withLogin(userB)), + ]); + + const {pages: userAPages, components: userAComponents} = PageManager.from(userAPageManager).webapp; + const userBPages = PageManager.from(userBPageManager).webapp.pages; + + const groupName = 'Group Name'; + + // Preconditions: User A and User B are in a group conversation created by User B + await createGroup(userBPages, groupName, [userA]); + + await test.step('User A adds group conversation with User B to Favorites', async () => { + const contextMenu = await userAPages.conversationList().getConversation(groupName).openContextMenu(); + await contextMenu.addToFavoritesButton.click(); + + const actualTitle = userAPages.conversationList().conversationListHeaderTitle; + await expect(actualTitle).toHaveText('Favorites'); + + await userAComponents.conversationSidebar().clickAllConversationsButton(); + }); + + await test.step('User A adds 1:1 with User B to Favorites', async () => { + const contextMenu = await userAPages.conversationList().getConversation(userB.fullName).openContextMenu(); + await contextMenu.addToFavoritesButton.click(); + + const actualTitle = userAPages.conversationList().conversationListHeaderTitle; + await expect(actualTitle).toHaveText('Favorites'); + + await userAComponents.conversationSidebar().clickAllConversationsButton(); + await userAPages.conversationList().getConversation(groupName).open(); + }); + + await test.step('User B sends message in 1:1 conversation with User A', async () => { + await userBPages.conversationList().getConversation(userA.fullName, {protocol: 'mls'}).open(); + await userBPages.conversation().sendMessage('Direct'); + }); + + await test.step('User A sees notification in Favorites and opens it', async () => { + await expect(userAComponents.conversationSidebar().favoritesButton.getByTestId('unread-badge')).toBeVisible(); + await userAComponents.conversationSidebar().favoritesButton.click(); + await expect(userAPages.conversationList().getConversation(userB.fullName).unreadIndicator).toBeVisible(); + await userAPages.conversationList().getConversation(userB.fullName, {protocol: 'mls'}).open(); + await expect(userAPages.conversation().getMessage({content: 'Direct', sender: userB})).toBeVisible(); + }); + + await test.step('User B sends message in group conversation with User A', async () => { + await userBPages.conversationList().getConversation(groupName).open(); + await userBPages.conversation().sendMessage('Group'); + }); + + await test.step('User A sees notification in Favorites and opens it', async () => { + await expect(userAComponents.conversationSidebar().favoritesButton.getByTestId('unread-badge')).toBeVisible(); + await expect(userAPages.conversationList().getConversation(groupName).unreadIndicator).toBeVisible(); + await userAPages.conversationList().getConversation(groupName).open(); + await expect(userAPages.conversation().getMessage({content: 'Group', sender: userB})).toBeVisible(); + }); + + await test.step('User B removes User A from group conversation', async () => { + await userBPages.conversationList().getConversation(groupName).open(); + await userBPages.conversation().toggleGroupInformation(); + + await expect(userBPages.conversationDetails().groupMembers.filter({hasText: userA.fullName})).toBeVisible(); + + await userBPages.conversationDetails().openParticipantDetails(userA.fullName); + await userBPages.participantDetails().removeFromGroup(); + }); + + await test.step('User A still sees group conversation in Favorites', async () => { + const actualTitle = userAPages.conversationList().conversationListHeaderTitle; + await expect(actualTitle).toHaveText('Favorites'); + await expect(userAPages.conversationList().getConversation(groupName)).toBeVisible(); + }); + + await test.step('User A removes 1:1 and group conversation with User B from Favorites', async () => { + const contextMenuDirectConversation = await userAPages + .conversationList() + .getConversation(userB.fullName) + .openContextMenu(); + await contextMenuDirectConversation.getByRole('button', {name: 'Remove from favorites'}).click(); + + const contextMenuGroupConversation = await userAPages + .conversationList() + .getConversation(groupName) + .openContextMenu(); + await contextMenuGroupConversation.getByRole('button', {name: 'Remove from favorites'}).click(); + }); + + await test.step('User A sees empty Favorites folder', async () => { + await expect(userAPages.conversationList().getConversation(userB.fullName)).not.toBeVisible(); + await expect(userAPages.conversationList().getConversation(groupName)).not.toBeVisible(); + }); + + await test.step('User A sees 1:1 and group conversation with User B in All Conversation View', async () => { + await userAComponents.conversationSidebar().clickAllConversationsButton(); + await expect(userAPages.conversationList().getConversation(userB.fullName)).toBeVisible(); + await expect(userAPages.conversationList().getConversation(groupName)).toBeVisible(); + }); + }, + ); });