From 19b843cf24955cf6eb72120279cd625bbc92a608 Mon Sep 17 00:00:00 2001 From: M-ZubairAhmed Date: Wed, 13 Sep 2023 11:58:35 +0530 Subject: [PATCH] MM-54404 : E2E tests for the Gif picker (#24486) --- .../components/channels/emoji_gif_picker.ts | 61 ++++++++++++ .../playwright/support/ui/components/index.ts | 2 + .../playwright/support/ui/pages/channels.ts | 5 + .../gif_picker/gif_picker_search.spec.ts | 95 +++++++++++++++++++ .../advanced_text_editor.tsx | 6 +- .../src/components/edit_post/edit_post.tsx | 6 +- .../emoji_picker/emoji_picker_tabs.tsx | 15 +-- webapp/channels/src/i18n/en.json | 2 +- 8 files changed, 174 insertions(+), 18 deletions(-) create mode 100644 e2e-tests/playwright/support/ui/components/channels/emoji_gif_picker.ts create mode 100644 e2e-tests/playwright/tests/functional/channels/gif_picker/gif_picker_search.spec.ts diff --git a/e2e-tests/playwright/support/ui/components/channels/emoji_gif_picker.ts b/e2e-tests/playwright/support/ui/components/channels/emoji_gif_picker.ts new file mode 100644 index 0000000000..17159c4a1d --- /dev/null +++ b/e2e-tests/playwright/support/ui/components/channels/emoji_gif_picker.ts @@ -0,0 +1,61 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {expect, Locator} from '@playwright/test'; + +export default class EmojiGifPicker { + readonly container: Locator; + + readonly gifTab: Locator; + readonly gifSearchInput: Locator; + readonly gifPickerItems: Locator; + + constructor(container: Locator) { + this.container = container; + + this.gifTab = container.getByText('GIFs'); + this.gifSearchInput = container.getByPlaceholder('Search GIPHY'); + this.gifPickerItems = container.locator('.gif-picker__items') + } + + async toBeVisible() { + await expect(this.container).toBeVisible(); + } + + async openGifTab() { + await expect(this.gifTab).toBeVisible(); + + await this.gifTab.click({force: true}); + + await expect(this.gifSearchInput).toBeVisible(); + await expect(this.gifPickerItems).toBeVisible(); + } + + async searchGif(name: string) { + await this.gifSearchInput.fill(name); + await expect(this.gifSearchInput).toHaveValue(name); + } + + async getNthGif(n: number) { + await expect(this.gifPickerItems).toBeVisible(); + + await this.gifPickerItems.locator('img').nth(n).waitFor(); + const nthGif = this.gifPickerItems.locator('img').nth(n); + await expect(nthGif).toBeVisible() + + const nthGifSrc = await nthGif.getAttribute('src'); + const nthGifAlt = await nthGif.getAttribute('alt'); + + if (!nthGifSrc || !nthGifAlt) { + throw new Error('Gif src or alt is empty'); + } + + return { + src: nthGifSrc, + alt: nthGifAlt, + img: nthGif, + }; + } +} + +export {EmojiGifPicker}; diff --git a/e2e-tests/playwright/support/ui/components/index.ts b/e2e-tests/playwright/support/ui/components/index.ts index bd97951652..3488bf2d57 100644 --- a/e2e-tests/playwright/support/ui/components/index.ts +++ b/e2e-tests/playwright/support/ui/components/index.ts @@ -19,6 +19,7 @@ import {PostDotMenu} from './channels/post_dot_menu'; import {PostReminderMenu} from './channels/post_reminder_menu'; import {PostMenu} from './channels/post_menu'; import {ThreadFooter} from './channels/thread_footer'; +import {EmojiGifPicker} from './channels/emoji_gif_picker'; const components = { BoardsSidebar, @@ -39,6 +40,7 @@ const components = { Footer, MainHeader, PostReminderMenu, + EmojiGifPicker, }; export { diff --git a/e2e-tests/playwright/support/ui/pages/channels.ts b/e2e-tests/playwright/support/ui/pages/channels.ts index 3fb729131b..a480e29390 100644 --- a/e2e-tests/playwright/support/ui/pages/channels.ts +++ b/e2e-tests/playwright/support/ui/pages/channels.ts @@ -23,6 +23,8 @@ export default class ChannelsPage { readonly postDotMenu; readonly postReminderMenu; + readonly emojiGifPickerPopup; + constructor(page: Page) { this.page = page; @@ -40,6 +42,9 @@ export default class ChannelsPage { // Menus this.postDotMenu = new components.PostDotMenu(page.getByRole('menu', {name: 'Post extra options'})); this.postReminderMenu = new components.PostReminderMenu(page.getByRole('menu', {name: 'Set a reminder for:'})); + + // Popovers + this.emojiGifPickerPopup = new components.EmojiGifPicker(page.locator('#emojiGifPicker')); } async toBeVisible() { diff --git a/e2e-tests/playwright/tests/functional/channels/gif_picker/gif_picker_search.spec.ts b/e2e-tests/playwright/tests/functional/channels/gif_picker/gif_picker_search.spec.ts new file mode 100644 index 0000000000..7a17fdefd8 --- /dev/null +++ b/e2e-tests/playwright/tests/functional/channels/gif_picker/gif_picker_search.spec.ts @@ -0,0 +1,95 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {expect, test} from '@e2e-support/test_fixture'; + +test('MM-T5445 Should search, select and post correct Gif when Gif picker is opened from center textbox', async ({ + pw, + pages, +}) => { + const {user} = await pw.initSetup(); + + // # Log in as a user in new browser context + const {page} = await pw.testBrowser.login(user); + + // # Visit default channel page + const channelPage = new pages.ChannelsPage(page); + await channelPage.goto(); + await channelPage.toBeVisible(); + + // # Open emoji/gif picker + await channelPage.centerView.postCreate.openEmojiPicker(); + await channelPage.emojiGifPickerPopup.toBeVisible(); + + // # Open gif tab + await channelPage.emojiGifPickerPopup.openGifTab(); + + // # Search for gif + await channelPage.emojiGifPickerPopup.searchGif('hello'); + + // # Select the first gif + const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} = await channelPage.emojiGifPickerPopup.getNthGif(0); + await firstSearchGifResult.click(); + + // # Send the selected gif as a message + await channelPage.centerView.postCreate.sendMessage(); + + // * Verify that last message has the gif + const lastPost = await channelPage.centerView.getLastPost(); + await lastPost.toBeVisible(); + await expect(lastPost.body.getByLabel('file thumbnail')).toHaveAttribute('alt', altOfFirstSearchGifResult); +}); + +test('MM-T5446 Should search, select and post correct Gif when Gif picker is opened from RHS textbox', async ({ + pw, + pages, +}) => { + const {user} = await pw.initSetup(); + + // # Log in as a user in new browser context + const {page} = await pw.testBrowser.login(user); + + // # Visit default channel page + const channelPage = new pages.ChannelsPage(page); + await channelPage.goto(); + await channelPage.toBeVisible(); + + // # Send a message + await channelPage.centerView.postCreate.postMessage('Message to open RHS'); + + // # Open the last post sent in RHS + const lastPost = await channelPage.centerView.getLastPost(); + await lastPost.hover(); + await lastPost.postMenu.toBeVisible(); + await lastPost.postMenu.reply(); + + const sidebarRight = channelPage.sidebarRight; + await sidebarRight.toBeVisible(); + + // # Send a message in the thread + await sidebarRight.postCreate.toBeVisible(); + await sidebarRight.postCreate.writeMessage('Replying to a thread'); + await sidebarRight.postCreate.sendMessage(); + + // # Open emoji/gif picker + await sidebarRight.postCreate.openEmojiPicker(); + await channelPage.emojiGifPickerPopup.toBeVisible(); + + // # Open gif tab + await channelPage.emojiGifPickerPopup.openGifTab(); + + // # Search for gif + await channelPage.emojiGifPickerPopup.searchGif('hello'); + + // # Select the first gif + const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} = await channelPage.emojiGifPickerPopup.getNthGif(0); + await firstSearchGifResult.click(); + + // # Send the selected gif as a message in the thread + await sidebarRight.postCreate.sendMessage(); + + // * Verify that last message has the gif + const lastPostInRHS = await sidebarRight.getLastPost(); + await lastPostInRHS.toBeVisible(); + await expect(lastPostInRHS.body.getByLabel('file thumbnail')).toHaveAttribute('alt', altOfFirstSearchGifResult); +}); diff --git a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx index 63aaf8db70..89d6f71a16 100644 --- a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx +++ b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx @@ -232,10 +232,6 @@ const AdvanceTextEditor = ({ }; let emojiPicker = null; - const emojiButtonAriaLabel = formatMessage({ - id: 'emoji_picker.emojiPicker', - defaultMessage: 'Emoji Picker', - }).toLowerCase(); if (enableEmojiPicker && !readOnlyChannel) { const emojiPickerTooltip = ( @@ -269,7 +265,7 @@ const AdvanceTextEditor = ({ ref={emojiPickerRef} onClick={toggleEmojiPicker} type='button' - aria-label={emojiButtonAriaLabel} + aria-label={formatMessage({id: 'emoji_picker.emojiPicker.button.ariaLabel', defaultMessage: 'select an emoji'})} disabled={shouldShowPreview} className={classNames({active: showEmojiPicker})} > diff --git a/webapp/channels/src/components/edit_post/edit_post.tsx b/webapp/channels/src/components/edit_post/edit_post.tsx index 31a552da2e..ef9beedb66 100644 --- a/webapp/channels/src/components/edit_post/edit_post.tsx +++ b/webapp/channels/src/components/edit_post/edit_post.tsx @@ -446,10 +446,6 @@ const EditPost = ({editingPost, actions, canEditPost, config, channelId, draft, const getEmojiTargetRef = useCallback(() => emojiButtonRef.current, [emojiButtonRef]); let emojiPicker = null; - const emojiButtonAriaLabel = formatMessage({ - id: 'emoji_picker.emojiPicker', - defaultMessage: 'Emoji Picker', - }).toLowerCase(); if (config.EnableEmojiPicker === 'true') { emojiPicker = ( @@ -466,7 +462,7 @@ const EditPost = ({editingPost, actions, canEditPost, config, channelId, draft, rightOffset={RIGHT_OFFSET} />