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();
+ });
+});