diff --git a/e2e-tests/playwright/lib/src/ui/components/channels/post_create.ts b/e2e-tests/playwright/lib/src/ui/components/channels/post_create.ts index 15af52e7ff23..0ea6c718219d 100644 --- a/e2e-tests/playwright/lib/src/ui/components/channels/post_create.ts +++ b/e2e-tests/playwright/lib/src/ui/components/channels/post_create.ts @@ -23,6 +23,8 @@ export default class ChannelsPostCreate { readonly suggestionOptions; readonly selectedSuggestion; readonly filePreview; + readonly previewButton; + readonly previewArea; // Burn-on-Read elements readonly burnOnReadButton; @@ -46,6 +48,8 @@ export default class ChannelsPostCreate { this.suggestionOptions = this.suggestionList.getByRole('option'); this.selectedSuggestion = this.suggestionList.getByTestId('suggestion-selected'); this.filePreview = container.getByTestId('file-preview-container'); + this.previewButton = container.getByRole('button', {name: 'preview'}); + this.previewArea = container.locator('.textbox-preview-area'); // Burn-on-Read elements // Use a flexible locator that matches the aria-label pattern @@ -192,6 +196,16 @@ export default class ChannelsPostCreate { await this.emojiButton.click(); } + async togglePreview() { + await expect(this.previewButton).toBeVisible(); + await this.previewButton.click(); + } + + async clickMentionInPreview() { + await expect(this.previewArea).toBeVisible(); + await this.previewArea.locator('.mention-link').click(); + } + async waitUntilFilePreviewContains(files: string[], timeout = duration.ten_sec) { await waitUntil( async () => { diff --git a/e2e-tests/playwright/specs/functional/channels/mentions/preview_mention_popover.spec.ts b/e2e-tests/playwright/specs/functional/channels/mentions/preview_mention_popover.spec.ts new file mode 100644 index 000000000000..ae2f393e9e64 --- /dev/null +++ b/e2e-tests/playwright/specs/functional/channels/mentions/preview_mention_popover.spec.ts @@ -0,0 +1,60 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {expect, setWysiwygUserPreference, test} from '@mattermost/playwright-lib'; + +/** + * @objective Clicking a user at-mention in the composer preview opens the profile popover + * and does not post the draft. + * + * @precondition Two users on the same team. The markdown composer preview is available + * (WYSIWYG editor preference is off). + */ +test( + 'MM-67123 clicking a user mention in composer preview opens the profile popover', + {tag: '@mentions'}, + async ({pw}) => { + // # Create two users on the same team and disable the WYSIWYG editor so preview is available + const {adminClient, user, userClient, team} = await pw.initSetup(); + await setWysiwygUserPreference(userClient, user.id, false); + + const mentionedUser = await adminClient.createUser(await pw.random.user('mentioned'), '', ''); + await adminClient.addToTeam(team.id, mentionedUser.id); + const townSquare = await adminClient.getChannelByName(team.id, 'town-square'); + await adminClient.addToChannel(mentionedUser.id, townSquare.id); + + const {channelsPage} = await pw.testBrowser.login(user); + await channelsPage.goto(team.name, 'town-square'); + await channelsPage.toBeVisible(); + + const unique = `preview-mention-${pw.random.id()}`; + const {postCreate} = channelsPage.centerView; + + // # Type a draft that mentions the other user via autocomplete so the mention resolves + await postCreate.writeMessage(`@${mentionedUser.username}`); + await expect(postCreate.suggestionList).toBeVisible(); + await postCreate.suggestionOptions.first().click(); + await postCreate.input.pressSequentially(` ${unique}`); + const draft = await postCreate.getInputValue(); + + // # Show the composer markdown preview + await postCreate.togglePreview(); + await expect(postCreate.previewArea).toBeVisible(); + await expect(postCreate.previewArea).toContainText(`@${mentionedUser.username}`); + await expect(postCreate.previewArea).toContainText(unique); + + // # Click the rendered mention in the preview + await postCreate.clickMentionInPreview(); + + // * The mentioned user's profile popover opens + await expect(channelsPage.userProfilePopover.container).toBeVisible(); + await expect(channelsPage.userProfilePopover.container).toContainText(`@${mentionedUser.username}`); + + // * The draft remains in the composer and is not posted + await expect(postCreate.input).toHaveValue(draft); + await expect(postCreate.previewArea).toContainText(unique); + + const lastPost = await channelsPage.getLastPost(); + await expect(lastPost.container).not.toContainText(unique); + }, +); diff --git a/webapp/channels/src/components/__snapshots__/user_list.test.tsx.snap b/webapp/channels/src/components/__snapshots__/user_list.test.tsx.snap index 44d76a957e57..994a717d6296 100644 --- a/webapp/channels/src/components/__snapshots__/user_list.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/user_list.test.tsx.snap @@ -26,6 +26,7 @@ exports[`components/UserList should match default snapshot when there are users aria-haspopup="dialog" class="status-wrapper style--none" style="border-radius: 50%; width: 32px; height: 32px;" + type="button" >