From ecf76bbdf558c75bbb839de39d43f6fe5959e294 Mon Sep 17 00:00:00 2001 From: Joseph Baylon Date: Thu, 15 Jul 2021 19:05:14 -0700 Subject: [PATCH] MM-37128 Detox/E2E Maintenance: Fix failing tests - iOS (#5544) * MM-37128 Detox/E2E Maintenance: Fix failing tests - iOS * Update function format --- .../at_mention_item/at_mention_item.tsx | 1 + app/screens/user_profile/user_profile_row.js | 2 +- .../e2e/support/ui/component/autocomplete.js | 9 +- detox/e2e/support/utils/email.js | 238 ++++++++++++++++++ .../e2e/support/{utils.js => utils/index.js} | 45 +--- .../e2e/test/autocomplete/autocomplete.e2e.js | 12 +- .../e2e/test/main_sidebar/main_sidebar.e2e.js | 28 +-- detox/e2e/test/messaging/channel_link.e2e.js | 2 +- .../messaging/emojis_and_reactions.e2e.js | 5 +- detox/e2e/test/messaging/hashtags.e2e.js | 15 +- detox/e2e/test/messaging/message_draft.e2e.js | 1 + .../e2e/test/messaging/message_posting.e2e.js | 1 + detox/e2e/test/smoke_test/add_reaction.e2e.js | 5 +- .../smoke_test/email_notifications.e2e.js | 47 ++-- .../test/smoke_test/public_channels.e2e.js | 15 +- 15 files changed, 317 insertions(+), 109 deletions(-) create mode 100644 detox/e2e/support/utils/email.js rename detox/e2e/support/{utils.js => utils/index.js} (60%) diff --git a/app/components/autocomplete/at_mention_item/at_mention_item.tsx b/app/components/autocomplete/at_mention_item/at_mention_item.tsx index 891f9bb5a..5322f4fc1 100644 --- a/app/components/autocomplete/at_mention_item/at_mention_item.tsx +++ b/app/components/autocomplete/at_mention_item/at_mention_item.tsx @@ -128,6 +128,7 @@ const AtMentionItem = ({firstName = '', isBot, isCurrentUser, isGuest, isShared, /> {Boolean(name.length) && ( {iconComponent} diff --git a/detox/e2e/support/ui/component/autocomplete.js b/detox/e2e/support/ui/component/autocomplete.js index 0505c5873..aca5c9a52 100644 --- a/detox/e2e/support/ui/component/autocomplete.js +++ b/detox/e2e/support/ui/component/autocomplete.js @@ -9,8 +9,7 @@ class Autocomplete { atMentionItemProfilePicturePrefix: 'at_mention_item.profile_picture.', channelMentionItemPrefix: 'autocomplete.channel_mention.item.', autocomplete: 'autocomplete', - atMentionItemName: 'at_mention_item.name', - atMentionItemUsername: 'at_mention_item.username', + atMentionItemText: 'at_mention_item.text', atMentionSuggestionList: 'at_mention_suggestion.list', channelMentionSuggestionList: 'channel_mention_suggestion.list', dateSuggestion: 'autocomplete.date_suggestion', @@ -27,15 +26,13 @@ class Autocomplete { getAtMentionItem = (userId) => { const atMentionItemMatcher = by.id(`${this.testID.atMentionItemPrefix}${userId}`); - const atMentionItemNameMatcher = by.id(this.testID.atMentionItemName).withAncestor(atMentionItemMatcher); const atMentionItemProfilePictureMatcher = ProfilePicture.getProfilePictureItemMatcher(this.testID.atMentionItemProfilePicturePrefix, userId).withAncestor(atMentionItemMatcher); - const atMentionItemUsernameMatcher = by.id(this.testID.atMentionItemUsername).withAncestor(atMentionItemMatcher); + const atMentionItemTextMatcher = by.id(this.testID.atMentionItemText).withAncestor(atMentionItemMatcher); return { atMentionItem: element(atMentionItemMatcher), - atMentionItemName: element(atMentionItemNameMatcher), atMentionItemProfilePicture: element(atMentionItemProfilePictureMatcher), - atMentionItemUsername: element(atMentionItemUsernameMatcher), + atMentionItemText: element(atMentionItemTextMatcher), }; } diff --git a/detox/e2e/support/utils/email.js b/detox/e2e/support/utils/email.js new file mode 100644 index 000000000..6d54b5daa --- /dev/null +++ b/detox/e2e/support/utils/email.js @@ -0,0 +1,238 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import axios from 'axios'; +import jestExpect from 'expect'; +import testConfig from '@support/test_config'; + +/** + * Get email url. + * @returns {string} email url + */ +export const getEmailUrl = () => { + const smtpUrl = testConfig.smtpUrl || 'http://localhost:10080'; + + return `${smtpUrl}/api/v1/mailbox`; +}; + +/** + * Get email reset email template. + * @param {string} userEmail - the destination user email + * @returns {string} email template + */ +export const getEmailResetEmailTemplate = (userEmail) => { + return [ + '----------------------', + 'You updated your email', + '----------------------', + '', + `Your email address for Mattermost has been changed to ${userEmail}.`, + 'If you did not make this change, please contact the system administrator.', + '', + 'To change your notification preferences, log in to your team site and go to Account Settings > Notifications.', + ]; +}; + +/** + * Get join email template. + * @param {string} sender - the email sender + * @param {string} userEmail - the destination user email + * @param {Object} team - the team to join + * @param {boolean} isGuest - true if guest; otherwise false + * @returns {string} email template + */ +export const getJoinEmailTemplate = (sender, userEmail, team, isGuest = false) => { + const baseUrl = testConfig.siteUrl; + + return [ + `${sender} invited you to join the ${team.display_name} team.`, + `${isGuest ? 'You were invited as a guest to collaborate with the team' : 'Start collaborating with your team on Mattermost'}`, + '', + ` Join now ( ${baseUrl}/signup_user_complete/?d=${encodeURIComponent(JSON.stringify({display_name: team.display_name.replace(' ', '+'), email: userEmail, name: team.name}))}&t= )`, + '', + 'What is Mattermost?', + 'Mattermost is a flexible, open source messaging platform that enables secure team collaboration.', + 'Learn more ( mattermost.com )', + '', + '© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301', + ]; +}; + +/** + * Get mention email template. + * @param {string} sender - the email sender + * @param {string} message - the email message + * @param {string} postId - the post id where user is mentioned + * @param {string} siteName - the site name + * @param {string} teamName - the team name where user is mentioned + * @param {string} channelDisplayName - the channel display name where user is mentioned + * @@returns {string} email template + */ +export const getMentionEmailTemplate = (sender, message, postId, siteName, teamName, channelDisplayName) => { + const baseUrl = testConfig.siteUrl; + + return [ + `@${sender} mentioned you in a message`, + `While you were away, @${sender} mentioned you in the ${channelDisplayName} channel.`, + '', + `View Message ( ${baseUrl}/landing#/${teamName}/pl/${postId} )`, + '', + `@${sender}`, + '', + '', + channelDisplayName, + message, + '', + 'Want to change your notifications settings?', + `Login to ${siteName} ( ${baseUrl} ) and go to Account Settings > Notifications`, + '', + '© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301', + ]; +}; + +/** + * Get password reset email template. + * @returns {string} email template + */ +export const getPasswordResetEmailTemplate = () => { + const baseUrl = testConfig.siteUrl; + + return [ + 'Reset Your Password', + 'Click the button below to reset your password. If you didn’t request this, you can safely ignore this email.', + '', + ` Reset Password ( http://${baseUrl}/reset_password_complete?token= )`, + '', + 'The password reset link expires in 24 hours.', + '', + '© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301', + ]; +}; + +/** + * Get email verify email template. + * @param {string} userEmail - the destination user email + * @returns {string} email template + */ +export const getEmailVerifyEmailTemplate = (userEmail) => { + const baseUrl = testConfig.siteUrl; + + return [ + 'Verify your email address', + `Thanks for joining ${baseUrl.split('/')[2]}. ( ${baseUrl} )`, + 'Click below to verify your email address.', + '', + ` Verify Email ( ${baseUrl}/do_verify_email?token=&email=${encodeURIComponent(userEmail)} )`, + '', + 'This email address was used to create an account with Mattermost.', + 'If it was not you, you can safely ignore this email.', + '', + '© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301', + ]; +}; + +/** + * Get welcome email template. + * @param {string} userEmail - the destination user email + * @param {string} siteName - the site name + * @param {string} teamName - the team name where user is welcome + * @returns {string} email template + */ +export const getWelcomeEmailTemplate = (userEmail, siteName, teamName) => { + const baseUrl = testConfig.siteUrl; + + return [ + 'Welcome to the team', + `Thanks for joining ${baseUrl.split('/')[2]}. ( ${baseUrl} )`, + 'Click below to verify your email address.', + '', + ` Verify Email ( ${baseUrl}/do_verify_email?token=&email=${encodeURIComponent(userEmail)}&redirect_to=/${teamName} )`, + '', + `This email address was used to create an account with ${siteName}.`, + 'If it was not you, you can safely ignore this email.', + '', + 'Download the desktop and mobile apps', + 'For the best experience, download the apps for PC, Mac, iOS and Android.', + '', + 'Download ( https://mattermost.com/download/#mattermostApps )', + '', + '© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301', + ]; +}; + +/** + * Verify email body. + * @param {string} expectedBody - expected email body + * @param {*} actualBody - actual email body + */ +export const verifyEmailBody = (expectedBody, actualBody) => { + jestExpect(expectedBody.length).toEqual(actualBody.length); + + for (let i = 0; i < expectedBody.length; i++) { + if (expectedBody[i].includes('skip-local-time-check')) { + continue; + } + + if (expectedBody[i].includes('email-verify-link-check')) { + jestExpect(actualBody[i]).toContain('Verify Email'); + jestExpect(actualBody[i]).toContain('do_verify_email?token='); + continue; + } + + if (expectedBody[i].includes('join-link-check')) { + jestExpect(actualBody[i]).toContain('Join now'); + jestExpect(actualBody[i]).toContain('signup_user_complete/?d='); + continue; + } + + if (expectedBody[i].includes('reset-password-link-check')) { + jestExpect(actualBody[i]).toContain('Reset Password'); + jestExpect(actualBody[i]).toContain('reset_password_complete?token='); + continue; + } + + jestExpect(expectedBody[i]).toEqual(actualBody[i]); + } +}; + +/** + * Get recent email. + * @param {string} username - username of email recipient + * @param {string} mailUrl - url of email + */ +export const getRecentEmail = async (username, mailUrl = getEmailUrl()) => { + const mailboxUrl = `${mailUrl}/${username}`; + let response; + let recentEmail; + + try { + response = await axios({url: mailboxUrl, method: 'get'}); + recentEmail = response.data[response.data.length - 1]; + } catch (error) { + return {status: error.status, data: null}; + } + + if (!recentEmail || !recentEmail.id) { + return {status: 501, data: null}; + } + + let recentEmailMessage; + const mailMessageUrl = `${mailboxUrl}/${recentEmail.id}`; + try { + response = await axios({url: mailMessageUrl, method: 'get'}); + recentEmailMessage = response.data; + } catch (error) { + return {status: error.status, data: null}; + } + + return {status: response.status, data: recentEmailMessage}; +}; + +/** + * Split email body text. + * @param {string} text + * @return {string} split text + */ +export const splitEmailBodyText = (text) => { + return text.split('\n').map((d) => d.trim()); +}; diff --git a/detox/e2e/support/utils.js b/detox/e2e/support/utils/index.js similarity index 60% rename from detox/e2e/support/utils.js rename to detox/e2e/support/utils/index.js index a4ddb6582..f6e402c48 100644 --- a/detox/e2e/support/utils.js +++ b/detox/e2e/support/utils/index.js @@ -1,10 +1,11 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import axios from 'axios'; import {v4 as uuidv4} from 'uuid'; import testConfig from '@support/test_config'; +export * from './email'; + /** * Explicit `wait` should not normally used but made available for special cases. * @param {number} ms - duration in millisecond @@ -61,48 +62,6 @@ export const getAdminAccount = () => { }; }; -/** - * Get recent email. - * @param {string} username - username of email recipient - * @param {string} mailUrl - url of email - */ -export const getRecentEmail = async (username, mailUrl = `${testConfig.smtpUrl}/api/v1/mailbox`) => { - const mailboxUrl = `${mailUrl}/${username}`; - let response; - let recentEmail; - - try { - response = await axios({url: mailboxUrl, method: 'get'}); - recentEmail = response.data[response.data.length - 1]; - } catch (error) { - return {status: error.status, data: null}; - } - - if (!recentEmail || !recentEmail.id) { - return {status: 501, data: null}; - } - - let recentEmailMessage; - const mailMessageUrl = `${mailboxUrl}/${recentEmail.id}`; - try { - response = await axios({url: mailMessageUrl, method: 'get'}); - recentEmailMessage = response.data; - } catch (error) { - return {status: error.status, data: null}; - } - - return {status: response.status, data: recentEmailMessage}; -}; - -/** - * Split email body text. - * @param {string} text - * @return {string} split text - */ -export function splitEmailBodyText(text) { - return text.split('\n').map((d) => d.trim()); -} - const SECOND = 1000; const MINUTE = 60 * 1000; diff --git a/detox/e2e/test/autocomplete/autocomplete.e2e.js b/detox/e2e/test/autocomplete/autocomplete.e2e.js index 70b2f04fd..0594e1db4 100644 --- a/detox/e2e/test/autocomplete/autocomplete.e2e.js +++ b/detox/e2e/test/autocomplete/autocomplete.e2e.js @@ -124,12 +124,10 @@ describe('Autocomplete', () => { await expect(atMentionSuggestionList).toExist(); const { atMentionItem, - atMentionItemName, - atMentionItemUsername, + atMentionItemText, } = Autocomplete.getAtMentionItem(testUser.id); await expect(atMentionItem).toExist(); - await expect(atMentionItemName).toHaveText(`${testUser.first_name} ${testUser.last_name}`); - await expect(atMentionItemUsername).toHaveText(`(you) @${testUser.username}`); + await expect(atMentionItemText).toHaveText(`${testUser.first_name} ${testUser.last_name} (you) @${testUser.username}`); }); it('MM-T2349 should have autocomplete using nickname', async () => { @@ -141,12 +139,10 @@ describe('Autocomplete', () => { await expect(atMentionSuggestionList).toExist(); const { atMentionItem, - atMentionItemName, - atMentionItemUsername, + atMentionItemText, } = Autocomplete.getAtMentionItem(testOtherUser.id); await expect(atMentionItem).toExist(); - await expect(atMentionItemName).toHaveText(`${testOtherUser.first_name} ${testOtherUser.last_name} (${testOtherUser.nickname})`); - await expect(atMentionItemUsername).toHaveText(` @${testOtherUser.username}`); + await expect(atMentionItemText).toHaveText(`${testOtherUser.first_name} ${testOtherUser.last_name} (${testOtherUser.nickname}) @${testOtherUser.username}`); }); it('MM-T170 should be able to search usernames as case insensitive', async () => { diff --git a/detox/e2e/test/main_sidebar/main_sidebar.e2e.js b/detox/e2e/test/main_sidebar/main_sidebar.e2e.js index 10442cf77..2d93a6da4 100644 --- a/detox/e2e/test/main_sidebar/main_sidebar.e2e.js +++ b/detox/e2e/test/main_sidebar/main_sidebar.e2e.js @@ -42,20 +42,6 @@ describe('Main Sidebar', () => { await ChannelScreen.logout(); }); - it('MM-T3412 should close the sidebar menu when selecting the same channel', async () => { - // # Go to unread channel - await goToChannel(testChannel.display_name); - - // # Go to the same channel again - await goToChannel(testChannel.display_name); - - // * Verify sidebar menu is not open - await expect(MainSidebar.mainSidebar).not.toBeVisible(); - - // * Selected channel should remain the same - await expect(channelNavBarTitle).toHaveText(testChannel.display_name); - }); - it('MM-T435 should not show switch teams button when jump to search is focused', async () => { // # Open main sidebar await openMainSidebar(); @@ -70,4 +56,18 @@ describe('Main Sidebar', () => { // # Go back to channel await closeMainSidebar(); }); + + it('MM-T3412 should close the sidebar menu when selecting the same channel', async () => { + // # Go to unread channel + await goToChannel(testChannel.display_name); + + // # Go to the same channel again + await goToChannel(testChannel.display_name); + + // * Verify sidebar menu is not open + await expect(MainSidebar.mainSidebar).not.toBeVisible(); + + // * Selected channel should remain the same + await expect(channelNavBarTitle).toHaveText(testChannel.display_name); + }); }); diff --git a/detox/e2e/test/messaging/channel_link.e2e.js b/detox/e2e/test/messaging/channel_link.e2e.js index 9eea56b39..16fb6a8cd 100644 --- a/detox/e2e/test/messaging/channel_link.e2e.js +++ b/detox/e2e/test/messaging/channel_link.e2e.js @@ -56,7 +56,7 @@ describe('Channel Link', () => { await expect(channelNavBarTitle).toHaveText(testChannel.display_name); }); - xit('MM-T178 should be able to open channel by tapping on channel link from reply thread', async () => { // related issue https://mattermost.atlassian.net/browse/MM-36532 + it('MM-T178 should be able to open channel by tapping on channel link from reply thread', async () => { // # Post a channel link await goToChannel(townSquareChannel.display_name); const channelLink = `${testConfig.siteUrl}/${testTeam.name}/channels/${testChannel.name}`; diff --git a/detox/e2e/test/messaging/emojis_and_reactions.e2e.js b/detox/e2e/test/messaging/emojis_and_reactions.e2e.js index 8f141062e..5247202c1 100644 --- a/detox/e2e/test/messaging/emojis_and_reactions.e2e.js +++ b/detox/e2e/test/messaging/emojis_and_reactions.e2e.js @@ -125,8 +125,9 @@ describe('Emojis and Reactions', () => { await AddReactionScreen.open(); // * Verify Emojis exist in recently used section - await expect(element(by.text('🦊').withAncestor(by.id('RECENTLY USED')))).toExist(); - await expect(element(by.text('🐶').withAncestor(by.id('RECENTLY USED')))).toExist(); + await expect(element(by.text('Recent'))).toExist(); + await expect(element(by.text('🦊'))).toExist(); + await expect(element(by.text('🐶'))).toExist(); // # Close AddReaction Screen await AddReactionScreen.close(); diff --git a/detox/e2e/test/messaging/hashtags.e2e.js b/detox/e2e/test/messaging/hashtags.e2e.js index e7f84ae8b..075c3ecc5 100644 --- a/detox/e2e/test/messaging/hashtags.e2e.js +++ b/detox/e2e/test/messaging/hashtags.e2e.js @@ -9,6 +9,7 @@ import { ChannelScreen, + PermalinkScreen, SearchScreen, ThreadScreen, } from '@support/ui/screen'; @@ -86,12 +87,12 @@ describe('Hashtags', () => { await searchInput.typeText(invalid1); await searchInput.tapReturnKey(); await element(by.text(invalid1).withAncestor(by.id(SearchScreen.testID.searchResultsList))).atIndex(1).tap(); - await ThreadScreen.toBeVisible(); - // # Go back to channel - await ThreadScreen.back(); - await searchInput.clearText(); - await SearchScreen.cancel(); + // * Verify at permalink screen + await PermalinkScreen.toBeVisible(); + + // # Jump to recent messages + await PermalinkScreen.jumpToRecentMessages(); }); it('MM-T357 should be able to tap on hashtag from search result reply thread', async () => { @@ -106,8 +107,8 @@ describe('Hashtags', () => { // # Open reply thread from search result and tap on hashtag const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id); - const {searchResultPostItem} = await getSearchResultPostItem(post.id, hashtag); - await searchResultPostItem.tap(); + const {searchResultPostItemHeaderReply} = await getSearchResultPostItem(post.id, hashtag); + await searchResultPostItemHeaderReply.tap(); await ThreadScreen.toBeVisible(); await element(by.text(hashtag)).atIndex(1).tap(); diff --git a/detox/e2e/test/messaging/message_draft.e2e.js b/detox/e2e/test/messaging/message_draft.e2e.js index 74161215a..081316b2c 100644 --- a/detox/e2e/test/messaging/message_draft.e2e.js +++ b/detox/e2e/test/messaging/message_draft.e2e.js @@ -26,6 +26,7 @@ describe('Message Draft', () => { }); afterAll(async () => { + await device.reloadReactNative(); await ChannelScreen.logout(); }); diff --git a/detox/e2e/test/messaging/message_posting.e2e.js b/detox/e2e/test/messaging/message_posting.e2e.js index f93f09fb2..dbe23c9c2 100644 --- a/detox/e2e/test/messaging/message_posting.e2e.js +++ b/detox/e2e/test/messaging/message_posting.e2e.js @@ -82,6 +82,7 @@ describe('Messaging', () => { } = PostOptions; // # Log in as sysadmin + await device.reloadReactNative(); await ChannelScreen.logout(); await ChannelScreen.open(getAdminAccount()); diff --git a/detox/e2e/test/smoke_test/add_reaction.e2e.js b/detox/e2e/test/smoke_test/add_reaction.e2e.js index e547caeee..aad850a89 100644 --- a/detox/e2e/test/smoke_test/add_reaction.e2e.js +++ b/detox/e2e/test/smoke_test/add_reaction.e2e.js @@ -67,8 +67,9 @@ describe('Add Reaction', () => { // * Verify emoji exists in recently used section await openPostOptionsFor(post.id, message); await AddReactionScreen.open(); - await expect(element(by.text('🦊').withAncestor(by.id('RECENTLY USED')))).toExist(); - await expect(element(by.text('🐶').withAncestor(by.id('RECENTLY USED')))).toExist(); + await expect(element(by.text('Recent'))).toExist(); + await expect(element(by.text('🦊'))).toExist(); + await expect(element(by.text('🐶'))).toExist(); // # Close add reaction screen await AddReactionScreen.close(); diff --git a/detox/e2e/test/smoke_test/email_notifications.e2e.js b/detox/e2e/test/smoke_test/email_notifications.e2e.js index 924f76900..b3b32765e 100644 --- a/detox/e2e/test/smoke_test/email_notifications.e2e.js +++ b/detox/e2e/test/smoke_test/email_notifications.e2e.js @@ -26,9 +26,11 @@ import { } from '@support/server_api'; import { capitalize, + getMentionEmailTemplate, getRecentEmail, isAndroid, splitEmailBodyText, + verifyEmailBody, } from '@support/utils'; describe('Email Notifications', () => { @@ -79,23 +81,20 @@ describe('Email Notifications', () => { // # Post an at-mention message to mentioned user by other user const testMessage = `Mention @${testUser.username} by ${testOtherUser1.username}`; await User.apiLogin(testOtherUser1); - await Post.apiCreatePost({ + const {post} = await Post.apiCreatePost({ channelId: testChannel.id, message: testMessage, }); // * Verify mentioned user receives email notification - const response = await getRecentEmail(testUser.username); - verifyEmailNotification( - response, - testConfig.TeamSettings.SiteName, - testTeam.display_name, - testChannel.display_name, + await verifyEmailNotification( + testConfig, + testTeam, + testChannel, testUser, testOtherUser1, - testMessage, - testConfig.EmailSettings.FeedbackEmail, - testConfig.SupportSettings.SupportEmail); + post.id, + testMessage); }); it('MM-T3256_2 should be able to change email notification setting to never', async () => { @@ -192,7 +191,10 @@ async function verifyEmailNotificationsIsSetTo(sendKey) { } } -function verifyEmailNotification(response, siteName, teamDisplayName, channelDisplayName, mentionedUser, byUser, message, feedbackEmail, supportEmail) { +async function verifyEmailNotification(testConfig, team, channel, mentionedUser, sender, postId, message) { + const siteName = testConfig.TeamSettings.SiteName; + const feedbackEmail = testConfig.EmailSettings.FeedbackEmail; + const response = await getRecentEmail(mentionedUser.username); const isoDate = new Date().toISOString().substring(0, 10); const {data, status} = response; @@ -210,18 +212,17 @@ function verifyEmailNotification(response, siteName, teamDisplayName, channelDis jestExpect(data.date).toContain(isoDate); // * Verify that the email subject is correct - jestExpect(data.subject).toContain(`[${siteName}] Notification in ${teamDisplayName}`); + jestExpect(data.subject).toContain(`[${siteName}] Notification in ${team.display_name}`); // * Verify that the email body is correct - const bodyText = splitEmailBodyText(data.body.text); - jestExpect(bodyText.length).toEqual(16); - jestExpect(bodyText[1]).toEqual('You have a new notification.'); - jestExpect(bodyText[4]).toEqual(`Channel: ${channelDisplayName}`); - jestExpect(bodyText[5]).toContain(`@${byUser.username}`); - jestExpect(bodyText[7]).toEqual(message); - jestExpect(bodyText[9]).toContain('Go To Post'); - jestExpect(bodyText[11]).toEqual(`Any questions at all, mail us any time: ${supportEmail}`); - jestExpect(bodyText[12]).toEqual('Best wishes,'); - jestExpect(bodyText[13]).toEqual(`The ${siteName} Team`); - jestExpect(bodyText[15]).toEqual('To change your notification preferences, log in to your team site and go to Account Settings > Notifications.'); + const expectedEmailBody = getMentionEmailTemplate( + sender.username, + message.trim(), + postId, + siteName, + team.name, + channel.display_name, + ); + const actualEmailBody = splitEmailBodyText(data.body.text); + verifyEmailBody(expectedEmailBody, actualEmailBody); } diff --git a/detox/e2e/test/smoke_test/public_channels.e2e.js b/detox/e2e/test/smoke_test/public_channels.e2e.js index 67053618f..ddda3850f 100644 --- a/detox/e2e/test/smoke_test/public_channels.e2e.js +++ b/detox/e2e/test/smoke_test/public_channels.e2e.js @@ -10,6 +10,7 @@ import {MainSidebar} from '@support/ui/component'; import { ChannelInfoScreen, + ChannelMembersScreen, ChannelScreen, MoreChannelsScreen, } from '@support/ui/screen'; @@ -29,6 +30,7 @@ describe('Public Channels', () => { const { archiveChannel, leaveChannel, + manageMembersAction, } = ChannelInfoScreen; const { hasChannelDisplayNameAtIndex, @@ -39,17 +41,19 @@ describe('Public Channels', () => { getFilteredChannelByDisplayName, searchInput, } = MainSidebar; + let testUser; let testPublicChannel; let townSquareChannel; beforeAll(async () => { const {team, user} = await Setup.apiInit(); + testUser = user; ({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square')); ({channel: testPublicChannel} = await Channel.apiCreateChannel({type: 'O', prefix: testPublicChannePrefix, teamId: team.id})); // # Open channel screen - await ChannelScreen.open(user); + await ChannelScreen.open(testUser); }); afterAll(async () => { @@ -64,7 +68,14 @@ describe('Public Channels', () => { await getFilteredChannelByDisplayName(testPublicChannel.display_name).tap(); // * Verify user is added to the channel - await expect(element(by.text('You and @sysadmin joined the channel.'))).toBeVisible(); + await ChannelInfoScreen.open(); + await expect(element(by.id(ChannelInfoScreen.testID.manageMembersAction).withDescendant(by.text('2')))).toBeVisible(); + await manageMembersAction.tap(); + await ChannelMembersScreen.getUserByDisplayUsername(`@${testUser.username}`); + + // # Go back to channel + await ChannelMembersScreen.back(); + await ChannelInfoScreen.close(); }); it('MM-T3202 should be able to leave public channel', async () => {