diff --git a/app/components/post_with_channel_info/channel_info/channel_info.tsx b/app/components/post_with_channel_info/channel_info/channel_info.tsx index 3066473e34..5b3bf254c2 100644 --- a/app/components/post_with_channel_info/channel_info/channel_info.tsx +++ b/app/components/post_with_channel_info/channel_info/channel_info.tsx @@ -39,18 +39,32 @@ type Props = { channelName: ChannelModel['displayName']; post: PostModel; teamName: TeamModel['displayName']; + testID?: string; } -function ChannelInfo({channelName, teamName}: Props) { +function ChannelInfo({channelName, teamName, testID}: Props) { const theme = useTheme(); const styles = getStyleSheet(theme); return ( - - {channelName} + + + {channelName} + {Boolean(teamName) && ( - {teamName} + + {teamName} + )} diff --git a/app/components/post_with_channel_info/post_with_channel_info.tsx b/app/components/post_with_channel_info/post_with_channel_info.tsx index 4c6b217b39..2ed5125276 100644 --- a/app/components/post_with_channel_info/post_with_channel_info.tsx +++ b/app/components/post_with_channel_info/post_with_channel_info.tsx @@ -14,6 +14,7 @@ type Props = { isCRTEnabled: boolean; post: PostModel; location: string; + testID?: string; } const styles = StyleSheet.create({ @@ -27,10 +28,13 @@ const styles = StyleSheet.create({ }, }); -function PostWithChannelInfo({isCRTEnabled, post, location}: Props) { +function PostWithChannelInfo({isCRTEnabled, post, location, testID}: Props) { return ( - + diff --git a/app/screens/home/recent_mentions/components/empty.tsx b/app/screens/home/recent_mentions/components/empty.tsx index 499d12527c..73213678b3 100644 --- a/app/screens/home/recent_mentions/components/empty.tsx +++ b/app/screens/home/recent_mentions/components/empty.tsx @@ -44,13 +44,13 @@ function EmptyMentions() { defaultMessage='No Mentions yet' id='mentions.empty.title' style={styles.title} - testID='empty.mentions.title' + testID='recent_mentions.empty.title' /> ); diff --git a/app/screens/home/recent_mentions/recent_mentions.tsx b/app/screens/home/recent_mentions/recent_mentions.tsx index f78a03d415..92fc139ba9 100644 --- a/app/screens/home/recent_mentions/recent_mentions.tsx +++ b/app/screens/home/recent_mentions/recent_mentions.tsx @@ -157,6 +157,7 @@ const RecentMentionsScreen = ({mentions, currentTimezone, isTimezoneEnabled}: Pr ); }, []); @@ -174,6 +175,7 @@ const RecentMentionsScreen = ({mentions, currentTimezone, isTimezoneEnabled}: Pr @@ -196,6 +198,7 @@ const RecentMentionsScreen = ({mentions, currentTimezone, isTimezoneEnabled}: Pr removeClippedSubviews={true} onViewableItemsChanged={onViewableItemsChanged} style={scrollViewStyle} + testID='recent_mentions.post_list.flat_list' /> diff --git a/app/screens/home/saved_messages/saved_messages.tsx b/app/screens/home/saved_messages/saved_messages.tsx index f05c5b85b4..447ddeb27a 100644 --- a/app/screens/home/saved_messages/saved_messages.tsx +++ b/app/screens/home/saved_messages/saved_messages.tsx @@ -158,6 +158,7 @@ function SavedMessages({posts, currentTimezone, isTimezoneEnabled}: Props) { ); }, [currentTimezone, isTimezoneEnabled, theme]); @@ -175,6 +176,7 @@ function SavedMessages({posts, currentTimezone, isTimezoneEnabled}: Props) { @@ -197,6 +199,7 @@ function SavedMessages({posts, currentTimezone, isTimezoneEnabled}: Props) { removeClippedSubviews={true} onViewableItemsChanged={onViewableItemsChanged} style={scrollViewStyle} + testID='saved_messages.post_list.flat_list' /> diff --git a/app/screens/home/search/results/results.tsx b/app/screens/home/search/results/results.tsx index 0d3180d571..cbd5dd14e6 100644 --- a/app/screens/home/search/results/results.tsx +++ b/app/screens/home/search/results/results.tsx @@ -81,6 +81,7 @@ const SearchResults = ({ ); } @@ -133,6 +134,7 @@ const SearchResults = ({ onScroll={onScroll} removeClippedSubviews={true} ref={scrollRef} + testID='search_results.post_list.flat_list' /> ); }; diff --git a/detox/e2e/support/ui/component/index.ts b/detox/e2e/support/ui/component/index.ts index 4f2109da59..6983353eb8 100644 --- a/detox/e2e/support/ui/component/index.ts +++ b/detox/e2e/support/ui/component/index.ts @@ -10,6 +10,7 @@ import InputQuickAction from './input_quick_action'; import NavigationHeader from './navigation_header'; import PlusMenu from './plus_menu'; import Post from './post'; +import PostChannelInfo from './post_channel_info'; import PostDraft from './post_draft'; import PostList from './post_list'; import ProfilePicture from './profile_picture'; @@ -27,6 +28,7 @@ export { NavigationHeader, PlusMenu, Post, + PostChannelInfo, PostDraft, PostList, ProfilePicture, diff --git a/detox/e2e/support/ui/component/navigation_header.ts b/detox/e2e/support/ui/component/navigation_header.ts index 2185d3444b..1d652257d7 100644 --- a/detox/e2e/support/ui/component/navigation_header.ts +++ b/detox/e2e/support/ui/component/navigation_header.ts @@ -6,11 +6,15 @@ class NavigationHeader { backButton: 'navigation.header.back', headerTitle: 'navigation.header.title', headerSubtitle: 'navigation.header.subtitle', + largeHeaderTitle: 'navigation.large_header.title', + largeHeaderSubtitle: 'navigation.large_header.subtitle', }; backButton = element(by.id(this.testID.backButton)); headerTitle = element(by.id(this.testID.headerTitle)); headerSubtitle = element(by.id(this.testID.headerSubtitle)); + largeHeaderTitle = element(by.id(this.testID.largeHeaderTitle)); + largeHeaderSubtitle = element(by.id(this.testID.largeHeaderSubtitle)); } const navigationHeader = new NavigationHeader(); diff --git a/detox/e2e/support/ui/component/post_channel_info.ts b/detox/e2e/support/ui/component/post_channel_info.ts new file mode 100644 index 0000000000..c3dcddc2b4 --- /dev/null +++ b/detox/e2e/support/ui/component/post_channel_info.ts @@ -0,0 +1,24 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +class PostChannelInfo { + testID = { + channelDisplayName: 'channel_display_name', + teamDisplayName: 'team_display_name', + }; + + getPostChannelInfo = (postItemChannelInfoSourceTestID: string, postId: string) => { + const postItemChannelInfoMatcher = by.id(`${postItemChannelInfoSourceTestID}.${postId}`); + const postItemChannelInfoChannelDisplayNameMatcher = by.id(this.testID.channelDisplayName).withAncestor(postItemChannelInfoMatcher); + const postItemChannelInfoTeamDisplayNameMatcher = by.id(this.testID.teamDisplayName).withAncestor(postItemChannelInfoMatcher); + + return { + postItemChannelInfo: element(postItemChannelInfoMatcher), + postItemChannelInfoChannelDisplayName: element(postItemChannelInfoChannelDisplayNameMatcher), + postItemChannelInfoTeamDisplayName: element(postItemChannelInfoTeamDisplayNameMatcher), + }; + }; +} + +const postChannelInfo = new PostChannelInfo(); +export default postChannelInfo; diff --git a/detox/e2e/support/ui/component/post_list.ts b/detox/e2e/support/ui/component/post_list.ts index 4b47f73a8a..7ab43172c8 100644 --- a/detox/e2e/support/ui/component/post_list.ts +++ b/detox/e2e/support/ui/component/post_list.ts @@ -2,6 +2,7 @@ // See LICENSE.txt for license information. import Post from './post'; +import PostChannelInfo from './post_channel_info'; class PostList { testID: any; @@ -18,6 +19,7 @@ class PostList { threadOverviewUnsaveButton: `${screenPrefix}post_list.thread_overview.unsave.button`, threadOverviewPostOptionsButton: `${screenPrefix}post_list.thread_overview.post_options.button`, postListPostItem: `${screenPrefix}post_list.post`, + postListPostItemChannelInfo: `${screenPrefix}post_list.post_channel_info`, }; } @@ -101,11 +103,17 @@ class PostList { postItemThematicBreak, postItemUnreadDotBadge, } = Post.getPost(this.testID.postListPostItem, postId, postMessage, postProfileOptions); + const { + postItemChannelInfoChannelDisplayName, + postItemChannelInfoTeamDisplayName, + } = PostChannelInfo.getPostChannelInfo(this.testID.postListPostItemChannelInfo, postId); return { postListPostItem: postItem, postListPostItemBlockQuote: postItemBlockQuote, postListPostItemBreak: postItemBreak, + postListPostItemChannelInfoChannelDisplayName: postItemChannelInfoChannelDisplayName, + postListPostItemChannelInfoTeamDisplayName: postItemChannelInfoTeamDisplayName, postListPostItemCheckbox: postItemCheckbox, postListPostItemCodeBlock: postItemCodeBlock, postListPostItemCodeSpan: postItemCodeSpan, diff --git a/detox/e2e/support/ui/screen/channel.ts b/detox/e2e/support/ui/screen/channel.ts index a191ce265c..9b7d5bcbdf 100644 --- a/detox/e2e/support/ui/screen/channel.ts +++ b/detox/e2e/support/ui/screen/channel.ts @@ -28,7 +28,6 @@ class ChannelScreen { introSetHeaderOption: 'channel_post_list.intro_options.set_header.option', introFavoriteOption: 'channel_post_list.intro_options.set_header.option', introChannelDetailsOption: 'channel_post_list.intro_options.channel_details.option', - flatPostList: 'channel.post_list.flat_list', }; channelScreen = element(by.id(this.testID.channelScreen)); @@ -37,7 +36,6 @@ class ChannelScreen { introSetHeaderOption = element(by.id(this.testID.introSetHeaderOption)); introFavoriteOption = element(by.id(this.testID.introFavoriteOption)); introChannelDetailsOption = element(by.id(this.testID.introChannelDetailsOption)); - flatPostList = element(by.id(this.testID.flatPostList)); // convenience props backButton = NavigationHeader.backButton; @@ -73,6 +71,10 @@ class ChannelScreen { return this.postList.getNewMessagesDivider(); }; + getFlatPostList = () => { + return this.postList.getFlatList(); + }; + getPostListPostItem = (postId: string, text = '', postProfileOptions: any = {}) => { return this.postList.getPost(postId, text, postProfileOptions); }; diff --git a/detox/e2e/support/ui/screen/edit_post.ts b/detox/e2e/support/ui/screen/edit_post.ts index e4e2d381d4..dd50eed36e 100644 --- a/detox/e2e/support/ui/screen/edit_post.ts +++ b/detox/e2e/support/ui/screen/edit_post.ts @@ -30,6 +30,7 @@ class EditPostScreen { }; open = async () => { + // # Open edit post screen await PostOptionsScreen.editPostOption.tap(); return this.toBeVisible(); diff --git a/detox/e2e/support/ui/screen/emoji_picker.ts b/detox/e2e/support/ui/screen/emoji_picker.ts index 476b41b6ca..91fce11487 100644 --- a/detox/e2e/support/ui/screen/emoji_picker.ts +++ b/detox/e2e/support/ui/screen/emoji_picker.ts @@ -28,7 +28,7 @@ class EmojiPickerScreen { }; open = async () => { - // # Open add reaction screen + // # Open emoji picker screen await PostOptionsScreen.pickReactionButton.tap(); return this.toBeVisible(); diff --git a/detox/e2e/support/ui/screen/home.ts b/detox/e2e/support/ui/screen/home.ts index c46dd63ea1..c3a32a8eca 100644 --- a/detox/e2e/support/ui/screen/home.ts +++ b/detox/e2e/support/ui/screen/home.ts @@ -10,15 +10,17 @@ import {expect} from 'detox'; class HomeScreen { testID = { - channelListTab: 'tab_bar.channel_list.tab', + channelListTab: 'tab_bar.home.tab', searchTab: 'tab_bar.search.tab', mentionsTab: 'tab_bar.mentions.tab', + savedMessagesTab: 'tab_bar.saved_messages.tab', accountTab: 'tab_bar.account.tab', }; channelListTab = element(by.id(this.testID.channelListTab)); searchTab = element(by.id(this.testID.searchTab)); mentionsTab = element(by.id(this.testID.mentionsTab)); + savedMessagesTab = element(by.id(this.testID.savedMessagesTab)); accountTab = element(by.id(this.testID.accountTab)); toBeVisible = async () => { diff --git a/detox/e2e/support/ui/screen/index.ts b/detox/e2e/support/ui/screen/index.ts index 00fda22d09..b16ca05245 100644 --- a/detox/e2e/support/ui/screen/index.ts +++ b/detox/e2e/support/ui/screen/index.ts @@ -19,6 +19,8 @@ import LoginScreen from './login'; import PermalinkScreen from './permalink'; import PostOptionsScreen from './post_options'; import ReactionsScreen from './reactions'; +import RecentMentionsScreen from './recent_mentions'; +import SavedMessagesScreen from './saved_messages'; import ServerScreen from './server'; import ServerListScreen from './server_list'; import TableScreen from './table'; @@ -45,6 +47,8 @@ export { PermalinkScreen, PostOptionsScreen, ReactionsScreen, + RecentMentionsScreen, + SavedMessagesScreen, ServerScreen, ServerListScreen, TableScreen, diff --git a/detox/e2e/support/ui/screen/recent_mentions.ts b/detox/e2e/support/ui/screen/recent_mentions.ts new file mode 100644 index 0000000000..b1adb49f23 --- /dev/null +++ b/detox/e2e/support/ui/screen/recent_mentions.ts @@ -0,0 +1,81 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import { + NavigationHeader, + PostList, +} from '@support/ui/component'; +import { + HomeScreen, + PostOptionsScreen, +} from '@support/ui/screen'; +import {timeouts, wait} from '@support/utils'; +import {expect} from 'detox'; + +class RecentMentionsScreen { + testID = { + recentMentionsScreenPrefix: 'recent_mentions.', + recentMentionsScreen: 'recent_mentions.screen', + emptyTitle: 'recent_mentions.empty.title', + emptyParagraph: 'recent_mentions.empty.paragraph', + }; + + recentMentionsScreen = element(by.id(this.testID.recentMentionsScreen)); + emptyTitle = element(by.id(this.testID.emptyTitle)); + emptyParagraph = element(by.id(this.testID.emptyParagraph)); + + // convenience propers + largeHeaderTitle = NavigationHeader.largeHeaderTitle; + largeHeaderSubtitle = NavigationHeader.largeHeaderSubtitle; + + postList = new PostList(this.testID.recentMentionsScreenPrefix); + + getFlatPostList = () => { + return this.postList.getFlatList(); + }; + + getPostListPostItem = (postId: string, text = '', postProfileOptions: any = {}) => { + return this.postList.getPost(postId, text, postProfileOptions); + }; + + getPostMessageAtIndex = (index: number) => { + return this.postList.getPostMessageAtIndex(index); + }; + + toBeVisible = async () => { + await waitFor(this.recentMentionsScreen).toExist().withTimeout(timeouts.TEN_SEC); + + return this.recentMentionsScreen; + }; + + open = async () => { + // # Open recent mentions screen + await HomeScreen.mentionsTab.tap(); + + return this.toBeVisible(); + }; + + openPostOptionsFor = async (postId: string, text: string) => { + const {postListPostItem} = this.getPostListPostItem(postId, text); + await expect(postListPostItem).toBeVisible(); + + // # Open post options + await postListPostItem.longPress(); + await PostOptionsScreen.toBeVisible(); + await wait(timeouts.TWO_SEC); + }; + + hasPostMessage = async (postId: string, postMessage: string) => { + const {postListPostItem} = this.getPostListPostItem(postId, postMessage); + await expect(postListPostItem).toBeVisible(); + }; + + hasPostMessageAtIndex = async (index: number, postMessage: string) => { + await expect( + this.getPostMessageAtIndex(index), + ).toHaveText(postMessage); + }; +} + +const recentMentionsScreen = new RecentMentionsScreen(); +export default recentMentionsScreen; diff --git a/detox/e2e/support/ui/screen/saved_messages.ts b/detox/e2e/support/ui/screen/saved_messages.ts new file mode 100644 index 0000000000..df8b979fd8 --- /dev/null +++ b/detox/e2e/support/ui/screen/saved_messages.ts @@ -0,0 +1,81 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import { + NavigationHeader, + PostList, +} from '@support/ui/component'; +import { + HomeScreen, + PostOptionsScreen, +} from '@support/ui/screen'; +import {timeouts, wait} from '@support/utils'; +import {expect} from 'detox'; + +class SavedMessagesScreen { + testID = { + savedMessagesScreenPrefix: 'saved_messages.', + savedMessagesScreen: 'saved_messages.screen', + emptyTitle: 'saved_messages.empty.title', + emptyParagraph: 'saved_messages.empty.paragraph', + }; + + savedMessagesScreen = element(by.id(this.testID.savedMessagesScreen)); + emptyTitle = element(by.id(this.testID.emptyTitle)); + emptyParagraph = element(by.id(this.testID.emptyParagraph)); + + // convenience propers + largeHeaderTitle = NavigationHeader.largeHeaderTitle; + largeHeaderSubtitle = NavigationHeader.largeHeaderSubtitle; + + postList = new PostList(this.testID.savedMessagesScreenPrefix); + + getFlatPostList = () => { + return this.postList.getFlatList(); + }; + + getPostListPostItem = (postId: string, text = '', postProfileOptions: any = {}) => { + return this.postList.getPost(postId, text, postProfileOptions); + }; + + getPostMessageAtIndex = (index: number) => { + return this.postList.getPostMessageAtIndex(index); + }; + + toBeVisible = async () => { + await waitFor(this.savedMessagesScreen).toExist().withTimeout(timeouts.TEN_SEC); + + return this.savedMessagesScreen; + }; + + open = async () => { + // # Open saved messages screen + await HomeScreen.savedMessagesTab.tap(); + + return this.toBeVisible(); + }; + + openPostOptionsFor = async (postId: string, text: string) => { + const {postListPostItem} = this.getPostListPostItem(postId, text); + await expect(postListPostItem).toBeVisible(); + + // # Open post options + await postListPostItem.longPress(); + await PostOptionsScreen.toBeVisible(); + await wait(timeouts.TWO_SEC); + }; + + hasPostMessage = async (postId: string, postMessage: string) => { + const {postListPostItem} = this.getPostListPostItem(postId, postMessage); + await expect(postListPostItem).toBeVisible(); + }; + + hasPostMessageAtIndex = async (index: number, postMessage: string) => { + await expect( + this.getPostMessageAtIndex(index), + ).toHaveText(postMessage); + }; +} + +const savedMessagesScreen = new SavedMessagesScreen(); +export default savedMessagesScreen; diff --git a/detox/e2e/support/ui/screen/thread.ts b/detox/e2e/support/ui/screen/thread.ts index 28d4a3fd9f..b6e57ab476 100644 --- a/detox/e2e/support/ui/screen/thread.ts +++ b/detox/e2e/support/ui/screen/thread.ts @@ -21,14 +21,12 @@ class ThreadScreen { backButton: 'screen.back.button', followButton: 'thread.follow_thread.button', followingButton: 'thread.following_thread.button', - flatPostList: 'thread.post_list.flat_list', }; threadScreen = element(by.id(this.testID.threadScreen)); backButton = element(by.id(this.testID.backButton)); followButton = element(by.id(this.testID.followButton)); followingButton = element(by.id(this.testID.followingButton)); - flatPostList = element(by.id(this.testID.flatPostList)); // convenience props atInputQuickAction = InputQuickAction.getAtInputQuickAction(this.testID.threadScreenPrefix); @@ -74,6 +72,10 @@ class ThreadScreen { return this.postList.getThreadOverviewPostOptionsButton(); }; + getFlatPostList = () => { + return this.postList.getFlatList(); + }; + getPostListPostItem = (postId: string, text = '', postProfileOptions: any = {}) => { return this.postList.getPost(postId, text, postProfileOptions); }; diff --git a/detox/e2e/test/channels/channel_post_list.e2e.ts b/detox/e2e/test/channels/channel_post_list.e2e.ts index fe5294177c..1f13931ab4 100644 --- a/detox/e2e/test/channels/channel_post_list.e2e.ts +++ b/detox/e2e/test/channels/channel_post_list.e2e.ts @@ -83,7 +83,7 @@ describe('Channels - Channel Post List', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Open post options for the message that was just posted, tap delete option and confirm await ChannelScreen.openPostOptionsFor(post.id, message); diff --git a/detox/e2e/test/messaging/markdown_code.e2e.ts b/detox/e2e/test/messaging/markdown_code.e2e.ts index bdd9d92b87..4a88c67d89 100644 --- a/detox/e2e/test/messaging/markdown_code.e2e.ts +++ b/detox/e2e/test/messaging/markdown_code.e2e.ts @@ -62,7 +62,7 @@ describe('Messaging - Markdown Code', () => { // * Verify markdown code block is displayed const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItemCodeBlock} = ChannelScreen.getPostListPostItem(post.id); - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await expect(postListPostItemCodeBlock).toBeVisible(); // # Go back to channel list screen @@ -79,7 +79,7 @@ describe('Messaging - Markdown Code', () => { // * Verify markdown html is displayed const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItemCodeBlock} = ChannelScreen.getPostListPostItem(post.id); - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await expect(postListPostItemCodeBlock).toBeVisible(); // # Go back to channel list screen diff --git a/detox/e2e/test/messaging/markdown_latex.e2e.ts b/detox/e2e/test/messaging/markdown_latex.e2e.ts index b8ff749aed..d519d18333 100644 --- a/detox/e2e/test/messaging/markdown_latex.e2e.ts +++ b/detox/e2e/test/messaging/markdown_latex.e2e.ts @@ -67,7 +67,7 @@ describe('Messaging - Markdown Latex', () => { // * Verify markdown latex code block is displayed const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItemLatexCodeBlock} = ChannelScreen.getPostListPostItem(post.id); - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await expect(postListPostItemLatexCodeBlock).toBeVisible(); // # Go back to channel list screen diff --git a/detox/e2e/test/messaging/markdown_table.e2e.ts b/detox/e2e/test/messaging/markdown_table.e2e.ts index 6995c28cae..6f7aaecc31 100644 --- a/detox/e2e/test/messaging/markdown_table.e2e.ts +++ b/detox/e2e/test/messaging/markdown_table.e2e.ts @@ -95,7 +95,7 @@ describe('Messaging - Markdown Table', () => { await expect(element(by.text('Right text that wraps row'))).toBeVisible(); // # Expand to full view - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await postListPostItemTableExpandButton.tap(); // * Verify on table screen with the markdown table @@ -133,7 +133,7 @@ describe('Messaging - Markdown Table', () => { await expect(element(by.text('Right HS last'))).not.toBeVisible(); // # Expand to full view - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await postListPostItemTableExpandButton.tap(); await TableScreen.toBeVisible(); await expect(element(by.text('Header HS last'))).not.toBeVisible(); @@ -170,7 +170,7 @@ describe('Messaging - Markdown Table', () => { await expect(element(by.text('Right VS last'))).not.toBeVisible(); // # Expand to full view - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await postListPostItemTableExpandButton.tap(); await TableScreen.toBeVisible(); await expect(element(by.text('Header VS last'))).toBeVisible(); @@ -207,7 +207,7 @@ describe('Messaging - Markdown Table', () => { await expect(element(by.text('Right last'))).not.toBeVisible(); // # Expand to full view - await ChannelScreen.flatPostList.scrollTo('bottom'); + await ChannelScreen.getFlatPostList().scrollTo('bottom'); await postListPostItemTableExpandButton.tap(); await TableScreen.toBeVisible(); await expect(element(by.text('Header last'))).not.toBeVisible(); diff --git a/detox/e2e/test/messaging/message_delete.e2e.ts b/detox/e2e/test/messaging/message_delete.e2e.ts index 22c0d7b2f0..ce46f44f8c 100644 --- a/detox/e2e/test/messaging/message_delete.e2e.ts +++ b/detox/e2e/test/messaging/message_delete.e2e.ts @@ -60,7 +60,7 @@ describe('Messaging - Message Delete', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Open post options for the message that was just posted, tap delete option and confirm await ChannelScreen.openPostOptionsFor(post.id, message); @@ -82,14 +82,14 @@ describe('Messaging - Message Delete', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Open post options for the message that was just posted, tap delete option and cancel await ChannelScreen.openPostOptionsFor(post.id, message); await PostOptionsScreen.deletePost({confirm: false}); // * Verify post message is not deleted - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Go back to channel list screen await ChannelScreen.back(); diff --git a/detox/e2e/test/messaging/message_edit.e2e.ts b/detox/e2e/test/messaging/message_edit.e2e.ts index d095964408..61cc07a41f 100644 --- a/detox/e2e/test/messaging/message_edit.e2e.ts +++ b/detox/e2e/test/messaging/message_edit.e2e.ts @@ -61,7 +61,7 @@ describe('Messaging - Message Edit', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem: originalPostListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(originalPostListPostItem).toExist(); + await expect(originalPostListPostItem).toBeVisible(); // # Open post options for the message that was just posted and tap edit option await ChannelScreen.openPostOptionsFor(post.id, message); @@ -77,7 +77,7 @@ describe('Messaging - Message Edit', () => { // * Verify post message is updated and displays edited indicator '(edited)' const {postListPostItem: updatedPostListPostItem, postListPostItemEditedIndicator} = ChannelScreen.getPostListPostItem(post.id, updatedMessage); - await expect(updatedPostListPostItem).toExist(); + await expect(updatedPostListPostItem).toBeVisible(); await expect(postListPostItemEditedIndicator).toHaveText('(edited)'); // # Go back to channel list screen @@ -93,7 +93,7 @@ describe('Messaging - Message Edit', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Open post options for the message that was just posted and tap edit option await ChannelScreen.openPostOptionsFor(post.id, message); @@ -108,7 +108,7 @@ describe('Messaging - Message Edit', () => { await EditPostScreen.closeButton.tap(); // * Verify post message is not updated - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Go back to channel list screen await ChannelScreen.back(); @@ -143,7 +143,7 @@ describe('Messaging - Message Edit', () => { // * Verify reply post message is updated and displays edited indicator '(edited)' const {postListPostItem: updatedReplyPostListPostItem, postListPostItemEditedIndicator} = ThreadScreen.getPostListPostItem(replyPost.id, updatedReplyMessage); - await expect(updatedReplyPostListPostItem).toExist(); + await expect(updatedReplyPostListPostItem).toBeVisible(); await expect(postListPostItemEditedIndicator).toHaveText('(edited)'); // # Go back to channel list screen diff --git a/detox/e2e/test/messaging/message_post.e2e.ts b/detox/e2e/test/messaging/message_post.e2e.ts index d1350542eb..391b130a72 100644 --- a/detox/e2e/test/messaging/message_post.e2e.ts +++ b/detox/e2e/test/messaging/message_post.e2e.ts @@ -70,7 +70,7 @@ describe('Messaging - Message Post', () => { // * Verify message is added to post list, cleared from post draft, and send button is disabled again const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); await expect(ChannelScreen.postInput).not.toHaveValue(message); await expect(ChannelScreen.sendButtonDisabled).toBeVisible(); @@ -88,14 +88,14 @@ describe('Messaging - Message Post', () => { // * Verify long message is posted and displays show more button (chevron down button) const {postListPostItem, postListPostItemShowLessButton, postListPostItemShowMoreButton} = ChannelScreen.getPostListPostItem(post.id, longMessage); - await expect(postListPostItem).toExist(); - await expect(postListPostItemShowMoreButton).toExist(); + await expect(postListPostItem).toBeVisible(); + await expect(postListPostItemShowMoreButton).toBeVisible(); // # Tap on show more button on long message post await postListPostItemShowMoreButton.tap(); // * Verify long message post displays show less button (chevron up button) - await expect(postListPostItemShowLessButton).toExist(); + await expect(postListPostItemShowLessButton).toBeVisible(); // # Go back to channel list screen await ChannelScreen.back(); diff --git a/detox/e2e/test/messaging/message_reply.e2e.ts b/detox/e2e/test/messaging/message_reply.e2e.ts index 44395bb986..380a389a66 100644 --- a/detox/e2e/test/messaging/message_reply.e2e.ts +++ b/detox/e2e/test/messaging/message_reply.e2e.ts @@ -60,7 +60,7 @@ describe('Messaging - Message Reply', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Open post options for the message that was just posted, tap reply option await ChannelScreen.openPostOptionsFor(post.id, message); @@ -69,7 +69,7 @@ describe('Messaging - Message Reply', () => { // * Verify on reply thread screen and parent post is shown await ThreadScreen.toBeVisible(); const {postListPostItem: threadParentPostListPostItem} = ThreadScreen.getPostListPostItem(post.id, message); - await expect(threadParentPostListPostItem).toExist(); + await expect(threadParentPostListPostItem).toBeVisible(); // # Reply to parent post const replyMessage = `${message} reply`; @@ -78,7 +78,7 @@ describe('Messaging - Message Reply', () => { // * Verify reply message is posted const {post: replyPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem: replyPostListPostItem} = ThreadScreen.getPostListPostItem(replyPost.id, replyMessage); - await expect(replyPostListPostItem).toExist(); + await expect(replyPostListPostItem).toBeVisible(); // # Go back to channel list screen await ThreadScreen.back(); @@ -94,7 +94,7 @@ describe('Messaging - Message Reply', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Tap on post to open thread await postListPostItem.tap(); diff --git a/detox/e2e/test/search/recent_mentions.e2e.ts b/detox/e2e/test/search/recent_mentions.e2e.ts new file mode 100644 index 0000000000..75d7cd6439 --- /dev/null +++ b/detox/e2e/test/search/recent_mentions.e2e.ts @@ -0,0 +1,208 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import { + Post, + Setup, +} from '@support/server_api'; +import { + serverOneUrl, + siteOneUrl, +} from '@support/test_config'; +import { + ChannelListScreen, + ChannelScreen, + EditPostScreen, + HomeScreen, + LoginScreen, + PermalinkScreen, + PostOptionsScreen, + RecentMentionsScreen, + SavedMessagesScreen, + ServerScreen, + ThreadScreen, +} from '@support/ui/screen'; +import {expect} from 'detox'; + +describe('Search - Recent Mentions', () => { + const serverOneDisplayName = 'Server 1'; + const channelsCategory = 'channels'; + let testChannel: any; + let testTeam: any; + let testUser: any; + + beforeAll(async () => { + const {channel, team, user} = await Setup.apiInit(siteOneUrl); + testChannel = channel; + testTeam = team; + testUser = user; + + // # Log in to server + await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName); + await LoginScreen.login(testUser); + }); + + beforeEach(async () => { + // * Verify on channel list screen + await ChannelListScreen.toBeVisible(); + }); + + afterAll(async () => { + // # Log out + await HomeScreen.logout(); + }); + + it('MM-T4909_1 - should match elements on recent mentions screen', async () => { + // # Open recent mentions screen + await RecentMentionsScreen.open(); + + // * Verify basic elements on recent mentions screen + await expect(RecentMentionsScreen.largeHeaderTitle).toHaveText('Recent Mentions'); + await expect(RecentMentionsScreen.largeHeaderSubtitle).toHaveText('Messages you\'ve been mentioned in'); + await expect(RecentMentionsScreen.emptyTitle).toHaveText('No Mentions yet'); + await expect(RecentMentionsScreen.emptyParagraph).toHaveText('You\'ll see messages here when someone mentions you or uses terms you\'re monitoring.'); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); + + it('MM-T4909_2 - should be able to display a recent mention in recent mentions screen and navigate to message channel', async () => { + // # Open a channel screen and post a message with at-mention to current user + const message = `@${testUser.username}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + + // * Verify message with at-mention to current user is posted + const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); + await expect(postListPostItem).toBeVisible(); + + // # Go back to channel list screen and open recent mentions screen + await ChannelScreen.back(); + await RecentMentionsScreen.open(); + + // * Verify on recent mentions screen and recent mention is displayed with channel info + await RecentMentionsScreen.toBeVisible(); + const {postListPostItem: recentMentionsPostListPostItem, postListPostItemChannelInfoChannelDisplayName, postListPostItemChannelInfoTeamDisplayName} = RecentMentionsScreen.getPostListPostItem(post.id, message); + await expect(recentMentionsPostListPostItem).toBeVisible(); + await expect(postListPostItemChannelInfoChannelDisplayName).toHaveText(testChannel.display_name); + await expect(postListPostItemChannelInfoTeamDisplayName).toHaveText(testTeam.display_name); + + // # Tap on post and jump to recent messages + await recentMentionsPostListPostItem.tap(); + await PermalinkScreen.jumpToRecentMessages(); + + // * Verify on channel screen and recent mention is displayed + await ChannelScreen.toBeVisible(); + const {postListPostItem: channelPostListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); + await expect(channelPostListPostItem).toBeVisible(); + + // # Go back to channel list screen + await ChannelScreen.back(); + await ChannelListScreen.open(); + }); + + it('MM-T4909_3 - should be able to edit, reply to, and delete a recent mention from recent mentions screen', async () => { + // # Open a channel screen, post a message with at-mention to current user, go back to channel list screen, and open recent mentions screen + const message = `@${testUser.username}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + await ChannelScreen.back(); + await RecentMentionsScreen.open(); + + // * Verify on recent mentions screen + await RecentMentionsScreen.toBeVisible(); + + // # Open post options for recent mention and tap on edit option + const {post: mentionPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await RecentMentionsScreen.openPostOptionsFor(mentionPost.id, message); + await PostOptionsScreen.editPostOption.tap(); + + // * Verify on edit post screen + await EditPostScreen.toBeVisible(); + + // # Edit post message and tap save button + const updatedMessage = `${message} edit`; + await EditPostScreen.messageInput.replaceText(updatedMessage); + await EditPostScreen.saveButton.tap(); + + // * Verify post message is updated and displays edited indicator '(edited)' + const {postListPostItem: updatedPostListPostItem, postListPostItemEditedIndicator} = RecentMentionsScreen.getPostListPostItem(mentionPost.id, updatedMessage); + await expect(updatedPostListPostItem).toBeVisible(); + await expect(postListPostItemEditedIndicator).toHaveText('(edited)'); + + // # Open post options for recent mention and tap on reply option + await RecentMentionsScreen.openPostOptionsFor(mentionPost.id, updatedMessage); + await PostOptionsScreen.replyPostOption.tap(); + + // * Verify on thread screen + await ThreadScreen.toBeVisible(); + + // # Post a reply + const replyMessage = `${message} reply`; + await ThreadScreen.postMessage(replyMessage); + + // * Verify reply is posted + const {post: replyPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + const {postListPostItem} = ThreadScreen.getPostListPostItem(replyPost.id, replyMessage); + await expect(postListPostItem).toBeVisible(); + + // # Go back to recent mentions screen + await ThreadScreen.back(); + + // * Verify reply count and following button + const {postListPostItemFooterReplyCount, postListPostItemFooterFollowingButton} = RecentMentionsScreen.getPostListPostItem(mentionPost.id, updatedMessage); + await expect(postListPostItemFooterReplyCount).toHaveText('1 reply'); + await expect(postListPostItemFooterFollowingButton).toBeVisible(); + + // # Open post options for updated recent mention and delete post + await RecentMentionsScreen.openPostOptionsFor(mentionPost.id, updatedMessage); + await PostOptionsScreen.deletePost({confirm: true}); + + // * Verify updated recent mention is deleted + await expect(postListPostItem).not.toExist(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); + + it('MM-T4909_4 - should be able to save/unsave a recent mention from recent mentions screen', async () => { + // # Open a channel screen, post a message with at-mention to current user, go back to channel list screen, and open recent mentions screen + const message = `@${testUser.username}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + await ChannelScreen.back(); + await RecentMentionsScreen.open(); + + // * Verify on recent mentions screen + await RecentMentionsScreen.toBeVisible(); + + // # Open post options for recent mention, tap on save option, and open saved messages screen + const {post: mentionPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await RecentMentionsScreen.openPostOptionsFor(mentionPost.id, message); + await PostOptionsScreen.savePostOption.tap(); + await SavedMessagesScreen.open(); + + // * Verify recent mention is displayed on saved messages screen + const {postListPostItem} = SavedMessagesScreen.getPostListPostItem(mentionPost.id, message); + await expect(postListPostItem).toBeVisible(); + + // # Go back to recent mentions screen, open post options for recent mention, tap on usave option, and open saved messages screen + await RecentMentionsScreen.open(); + await RecentMentionsScreen.openPostOptionsFor(mentionPost.id, message); + await PostOptionsScreen.unsavePostOption.tap(); + await SavedMessagesScreen.open(); + + // * Verify recent mention is not displayed anymore on saved messages screen + await expect(postListPostItem).not.toExist(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); +}); diff --git a/detox/e2e/test/search/saved_messages.e2e.ts b/detox/e2e/test/search/saved_messages.e2e.ts new file mode 100644 index 0000000000..043f5bea8a --- /dev/null +++ b/detox/e2e/test/search/saved_messages.e2e.ts @@ -0,0 +1,203 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import { + Post, + Setup, +} from '@support/server_api'; +import { + serverOneUrl, + siteOneUrl, +} from '@support/test_config'; +import { + ChannelListScreen, + ChannelScreen, + EditPostScreen, + HomeScreen, + LoginScreen, + PermalinkScreen, + PostOptionsScreen, + SavedMessagesScreen, + ServerScreen, + ThreadScreen, +} from '@support/ui/screen'; +import {getRandomId} from '@support/utils'; +import {expect} from 'detox'; + +describe('Search - Saved Messages', () => { + const serverOneDisplayName = 'Server 1'; + const channelsCategory = 'channels'; + const savedText = 'Saved'; + let testChannel: any; + let testTeam: any; + + beforeAll(async () => { + const {channel, team, user} = await Setup.apiInit(siteOneUrl); + testChannel = channel; + testTeam = team; + + // # Log in to server + await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName); + await LoginScreen.login(user); + }); + + beforeEach(async () => { + // * Verify on channel list screen + await ChannelListScreen.toBeVisible(); + }); + + afterAll(async () => { + // # Log out + await HomeScreen.logout(); + }); + + it('MM-T4910_1 - should match elements on saved messages screen', async () => { + // # Open saved messages screen + await SavedMessagesScreen.open(); + + // * Verify basic elements on saved messages screen + await expect(SavedMessagesScreen.largeHeaderTitle).toHaveText('Saved Messages'); + await expect(SavedMessagesScreen.largeHeaderSubtitle).toHaveText('All messages you\'ve saved for follow up'); + await expect(SavedMessagesScreen.emptyTitle).toHaveText('No saved messages yet'); + await expect(SavedMessagesScreen.emptyParagraph).toHaveText('To save something for later, long-press on a message and choose Save from the menu. Saved messages are only visible to you.'); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); + + it('MM-T4910_2 - should be able to display a saved message in saved messages screen and navigate to message channel', async () => { + // # Open a channel screen, post a message, open post options for message, and tap on save option + const message = `Message ${getRandomId()}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await ChannelScreen.openPostOptionsFor(post.id, message); + await PostOptionsScreen.savePostOption.tap(); + + // * Verify saved text is displayed on the post pre-header + const {postListPostItemPreHeaderText} = ChannelScreen.getPostListPostItem(post.id, message); + await expect(postListPostItemPreHeaderText).toHaveText(savedText); + + // # Go back to channel list screen and open saved messages screen + await ChannelScreen.back(); + await SavedMessagesScreen.open(); + + // * Verify on saved messages screen and saved message is displayed with channel info + await SavedMessagesScreen.toBeVisible(); + const {postListPostItem: savedMessagesPostListPostItem, postListPostItemChannelInfoChannelDisplayName, postListPostItemChannelInfoTeamDisplayName} = SavedMessagesScreen.getPostListPostItem(post.id, message); + await expect(savedMessagesPostListPostItem).toBeVisible(); + await expect(postListPostItemChannelInfoChannelDisplayName).toHaveText(testChannel.display_name); + await expect(postListPostItemChannelInfoTeamDisplayName).toHaveText(testTeam.display_name); + + // # Tap on post and jump to recent messages + await savedMessagesPostListPostItem.tap(); + await PermalinkScreen.jumpToRecentMessages(); + + // * Verify on channel screen and saved message is displayed + await ChannelScreen.toBeVisible(); + const {postListPostItem: channelPostListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); + await expect(channelPostListPostItem).toBeVisible(); + + // # Go back to channel list screen + await ChannelScreen.back(); + await ChannelListScreen.open(); + }); + + it('MM-T4910_3 - should be able to edit, reply to, and delete a saved message from saved messages screen', async () => { + // # Open a channel screen, post a message, open post options for message, tap on save option, go back to channel list screen, and open saved messages screen + const message = `Message ${getRandomId()}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + const {post: savedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await ChannelScreen.openPostOptionsFor(savedPost.id, message); + await PostOptionsScreen.savePostOption.tap(); + await ChannelScreen.back(); + await SavedMessagesScreen.open(); + + // * Verify on saved messages screen + await SavedMessagesScreen.toBeVisible(); + + // # Open post options for saved message and tap on edit option + await SavedMessagesScreen.openPostOptionsFor(savedPost.id, message); + await PostOptionsScreen.editPostOption.tap(); + + // * Verify on edit post screen + await EditPostScreen.toBeVisible(); + + // # Edit post message and tap save button + const updatedMessage = `${message} edit`; + await EditPostScreen.messageInput.replaceText(updatedMessage); + await EditPostScreen.saveButton.tap(); + + // * Verify post message is updated and displays edited indicator '(edited)' + const {postListPostItem: updatedPostListPostItem, postListPostItemEditedIndicator} = SavedMessagesScreen.getPostListPostItem(savedPost.id, updatedMessage); + await expect(updatedPostListPostItem).toBeVisible(); + await expect(postListPostItemEditedIndicator).toHaveText('(edited)'); + + // # Open post options for updated saved message and tap on reply option + await SavedMessagesScreen.openPostOptionsFor(savedPost.id, updatedMessage); + await PostOptionsScreen.replyPostOption.tap(); + + // * Verify on thread screen + await ThreadScreen.toBeVisible(); + + // # Post a reply + const replyMessage = `${updatedMessage} reply`; + await ThreadScreen.postMessage(replyMessage); + + // * Verify reply is posted + const {post: replyPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + const {postListPostItem: replyPostListPostItem} = ThreadScreen.getPostListPostItem(replyPost.id, replyMessage); + await expect(replyPostListPostItem).toBeVisible(); + + // # Go back to saved messages screen + await ThreadScreen.back(); + + // * Verify reply count and following button + const {postListPostItem, postListPostItemFooterReplyCount, postListPostItemFooterFollowingButton} = SavedMessagesScreen.getPostListPostItem(savedPost.id, updatedMessage); + await expect(postListPostItemFooterReplyCount).toHaveText('1 reply'); + await expect(postListPostItemFooterFollowingButton).toBeVisible(); + + // # Open post options for updated saved message and delete post + await SavedMessagesScreen.openPostOptionsFor(savedPost.id, updatedMessage); + await PostOptionsScreen.deletePost({confirm: true}); + + // * Verify updated saved message is deleted + await expect(postListPostItem).not.toExist(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); + + it('MM-T4910_4 - should be able to unsave a message from saved messages screen', async () => { + // # Open a channel screen, post a message, open post options for message, tap on save option, go back to channel list screen, and open saved messages screen + const message = `Message ${getRandomId()}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + const {post: savedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await ChannelScreen.openPostOptionsFor(savedPost.id, message); + await PostOptionsScreen.savePostOption.tap(); + await ChannelScreen.back(); + await SavedMessagesScreen.open(); + + // * Verify on saved messages screen + await SavedMessagesScreen.toBeVisible(); + + // # Open post options for saved message and tap on unsave option + await SavedMessagesScreen.openPostOptionsFor(savedPost.id, message); + await PostOptionsScreen.unsavePostOption.tap(); + + // * Verify saved message is not displayed anymore + const {postListPostItem} = SavedMessagesScreen.getPostListPostItem(savedPost.id, message); + await expect(postListPostItem).not.toExist(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); +}); diff --git a/detox/e2e/test/smoke_test/channels.e2e.ts b/detox/e2e/test/smoke_test/channels.e2e.ts index 289c8c945e..7f27d782a0 100644 --- a/detox/e2e/test/smoke_test/channels.e2e.ts +++ b/detox/e2e/test/smoke_test/channels.e2e.ts @@ -123,7 +123,7 @@ describe('Smoke Test - Channels', () => { // * Verify message is posted const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(postListPostItem).toExist(); + await expect(postListPostItem).toBeVisible(); // # Go back to channel list screen await ChannelScreen.back(); diff --git a/detox/e2e/test/smoke_test/messaging.e2e.ts b/detox/e2e/test/smoke_test/messaging.e2e.ts index 7b7091869c..fd92182a41 100644 --- a/detox/e2e/test/smoke_test/messaging.e2e.ts +++ b/detox/e2e/test/smoke_test/messaging.e2e.ts @@ -69,7 +69,7 @@ describe('Smoke Test - Messaging', () => { // * Verify message is added to post list const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem: originalPostListPostItem} = ChannelScreen.getPostListPostItem(post.id, message); - await expect(originalPostListPostItem).toExist(); + await expect(originalPostListPostItem).toBeVisible(); // # Open post options for the message that was just posted and tap edit option await ChannelScreen.openPostOptionsFor(post.id, message); @@ -85,7 +85,7 @@ describe('Smoke Test - Messaging', () => { // * Verify post message is updated and displays edited indicator '(edited)' const {postListPostItem: updatedPostListPostItem, postListPostItemEditedIndicator} = ChannelScreen.getPostListPostItem(post.id, updatedMessage); - await expect(updatedPostListPostItem).toExist(); + await expect(updatedPostListPostItem).toBeVisible(); await expect(postListPostItemEditedIndicator).toHaveText('(edited)'); // # Open post options for the updated message, tap delete option and confirm @@ -118,7 +118,7 @@ describe('Smoke Test - Messaging', () => { // * Verify reply message is posted const {post: replyPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); const {postListPostItem: replyPostListPostItem} = ThreadScreen.getPostListPostItem(replyPost.id, replyMessage); - await expect(replyPostListPostItem).toExist(); + await expect(replyPostListPostItem).toBeVisible(); // # Go back to channel list screen await ThreadScreen.back(); diff --git a/detox/e2e/test/smoke_test/search.e2e.ts b/detox/e2e/test/smoke_test/search.e2e.ts new file mode 100644 index 0000000000..7a92d0b880 --- /dev/null +++ b/detox/e2e/test/smoke_test/search.e2e.ts @@ -0,0 +1,94 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import { + Post, + Setup, +} from '@support/server_api'; +import { + serverOneUrl, + siteOneUrl, +} from '@support/test_config'; +import { + ChannelListScreen, + ChannelScreen, + HomeScreen, + LoginScreen, + PostOptionsScreen, + RecentMentionsScreen, + SavedMessagesScreen, + ServerScreen, +} from '@support/ui/screen'; +import {getRandomId} from '@support/utils'; +import {expect} from 'detox'; + +describe('Smoke Test - Search', () => { + const serverOneDisplayName = 'Server 1'; + const channelsCategory = 'channels'; + let testChannel: any; + let testUser: any; + + beforeAll(async () => { + const {channel, user} = await Setup.apiInit(siteOneUrl); + testChannel = channel; + testUser = user; + + // # Log in to server + await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName); + await LoginScreen.login(testUser); + }); + + beforeEach(async () => { + // * Verify on channel list screen + await ChannelListScreen.toBeVisible(); + }); + + afterAll(async () => { + // # Log out + await HomeScreen.logout(); + }); + + it('MM-T4911_1 - should be able to display a recent mention on recent mentions screen', async () => { + // # Open a channel screen, post a message with at-mention to current user, go back to channel list screen, and open recent mentions screen + const message = `@${testUser.username}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + await ChannelScreen.back(); + await RecentMentionsScreen.open(); + + // * Verify on recent mentions screen and recent mention is displayed + await RecentMentionsScreen.toBeVisible(); + const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + const {postListPostItem} = RecentMentionsScreen.getPostListPostItem(post.id, message); + await expect(postListPostItem).toBeVisible(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); + + it('MM-T4911_2 - should be able to display a saved message on saved messages screen', async () => { + // # Open a channel screen, post a message, open post options for message, tap on save option, go back to channel list screen, and open saved messages screen + const message = `Message ${getRandomId()}`; + await ChannelScreen.open(channelsCategory, testChannel.name); + await ChannelScreen.postMessage(message); + const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id); + await ChannelScreen.openPostOptionsFor(post.id, message); + await PostOptionsScreen.savePostOption.tap(); + await ChannelScreen.back(); + await SavedMessagesScreen.open(); + + // * Verify on saved messages screen and saved message is displayed + await SavedMessagesScreen.toBeVisible(); + const {postListPostItem} = SavedMessagesScreen.getPostListPostItem(post.id, message); + await expect(postListPostItem).toBeVisible(); + + // # Go back to channel list screen + await ChannelListScreen.open(); + }); +});