diff --git a/app/components/channel_actions/channel_actions.tsx b/app/components/channel_actions/channel_actions.tsx
index 3f1d3963ad..87b471851d 100644
--- a/app/components/channel_actions/channel_actions.tsx
+++ b/app/components/channel_actions/channel_actions.tsx
@@ -46,13 +46,13 @@ const ChannelActions = ({channelId, channelType, inModal = false, testID}: Props
{channelType && DIRECT_CHANNELS.includes(channelType) &&
diff --git a/app/components/channel_actions/favorite_box/favorite_box.tsx b/app/components/channel_actions/favorite_box/favorite_box.tsx
index dae9aeb4bc..06950b36f0 100644
--- a/app/components/channel_actions/favorite_box/favorite_box.tsx
+++ b/app/components/channel_actions/favorite_box/favorite_box.tsx
@@ -27,6 +27,8 @@ const FavoriteBox = ({channelId, containerStyle, isFavorited, showSnackBar = fal
toggleFavoriteChannel(serverUrl, channelId, showSnackBar);
}, [serverUrl, channelId, showSnackBar]);
+ const favoriteActionTestId = isFavorited ? `${testID}.unfavorite.action` : `${testID}.favorite.action`;
+
return (
);
diff --git a/app/components/channel_actions/mute_box/mute_box.tsx b/app/components/channel_actions/mute_box/mute_box.tsx
index fc7ae62402..4d96c7d5d2 100644
--- a/app/components/channel_actions/mute_box/mute_box.tsx
+++ b/app/components/channel_actions/mute_box/mute_box.tsx
@@ -27,6 +27,8 @@ const MutedBox = ({channelId, containerStyle, isMuted, showSnackBar = false, tes
toggleMuteChannel(serverUrl, channelId, showSnackBar);
}, [channelId, isMuted, serverUrl, showSnackBar]);
+ const muteActionTestId = isMuted ? `${testID}.unmute.action` : `${testID}.mute.action`;
+
return (
);
diff --git a/app/components/post_draft/archived/index.tsx b/app/components/post_draft/archived/index.tsx
index a51d5bfa9d..1a47041769 100644
--- a/app/components/post_draft/archived/index.tsx
+++ b/app/components/post_draft/archived/index.tsx
@@ -95,6 +95,7 @@ export default function Archived({
}
{children}
diff --git a/app/screens/channel/channel_post_list/intro/options/index.tsx b/app/screens/channel/channel_post_list/intro/options/index.tsx
index 9cfe52705a..2d848eba1f 100644
--- a/app/screens/channel/channel_post_list/intro/options/index.tsx
+++ b/app/screens/channel/channel_post_list/intro/options/index.tsx
@@ -46,27 +46,27 @@ const IntroOptions = ({channelId, header, favorite, people}: Props) => {
}
{header &&
}
{favorite &&
}
);
diff --git a/app/screens/channel/header/header.tsx b/app/screens/channel/header/header.tsx
index 8ccdbbec72..1126c87b54 100644
--- a/app/screens/channel/header/header.tsx
+++ b/app/screens/channel/header/header.tsx
@@ -154,6 +154,7 @@ const ChannelHeader = ({
iconName: Platform.select({android: 'dots-vertical', default: 'dots-horizontal'}),
onPress: onChannelQuickAction,
buttonType: 'opacity',
+ testID: 'channel_header.channel_quick_actions.button',
}]), [isTablet, searchTerm, onChannelQuickAction]);
let title = displayName;
diff --git a/app/screens/channel/header/quick_actions/index.tsx b/app/screens/channel/header/quick_actions/index.tsx
index dd58a8080a..769e2ba61c 100644
--- a/app/screens/channel/header/quick_actions/index.tsx
+++ b/app/screens/channel/header/quick_actions/index.tsx
@@ -47,6 +47,7 @@ const ChannelQuickAction = ({channelId}: Props) => {
);
}
diff --git a/detox/e2e/support/server_api/default_config.json b/detox/e2e/support/server_api/default_config.json
index bc6cc76d91..9a7ec1cd93 100644
--- a/detox/e2e/support/server_api/default_config.json
+++ b/detox/e2e/support/server_api/default_config.json
@@ -73,6 +73,7 @@
"ExperimentalGroupUnreadChannels": "disabled",
"ExperimentalChannelOrganization": false,
"ExperimentalChannelSidebarOrganization": "disabled",
+ "EnableAPIChannelDeletion": true,
"EnableAPITeamDeletion": true,
"ExperimentalEnableHardenedMode": false,
"DisableLegacyMFA": true,
@@ -81,7 +82,9 @@
"DisableBotsWhenOwnerIsDeactivated": true,
"EnableBotAccountCreation": true,
"EnableSVGs": true,
- "EnableLatex": false
+ "EnableLatex": true,
+ "EnableInlineLatex": true,
+ "CollapsedThreads": "always_on"
},
"TeamSettings": {
"SiteName": "Mattermost",
@@ -110,7 +113,7 @@
"MaxNotificationsPerChannel": 1000,
"EnableConfirmNotificationsToChannel": true,
"TeammateNameDisplay": "username",
- "ExperimentalViewArchivedChannels": false,
+ "ExperimentalViewArchivedChannels": true,
"ExperimentalEnableAutomaticReplies": false,
"ExperimentalHideTownSquareinLHS": false,
"ExperimentalTownSquareIsReadOnly": false,
diff --git a/detox/e2e/support/ui/component/alert.ts b/detox/e2e/support/ui/component/alert.ts
index 650cea6606..7aae763b7a 100644
--- a/detox/e2e/support/ui/component/alert.ts
+++ b/detox/e2e/support/ui/component/alert.ts
@@ -6,7 +6,10 @@ import {isAndroid} from '@support/utils';
class Alert {
// alert titles
confirmSendingNotificationsTitle = isAndroid() ? element(by.text('Confirm sending notifications to entire channel')) : element(by.label('Confirm sending notifications to entire channel')).atIndex(0);
+ archivePrivateChannelTitle = isAndroid() ? element(by.text('Archive Private Channel')) : element(by.label('Archive Private Channel')).atIndex(0);
+ archivePublicChannelTitle = isAndroid() ? element(by.text('Archive Public Channel')) : element(by.label('Archive Public Channel')).atIndex(0);
deletePostTitle = isAndroid() ? element(by.text('Delete Post')) : element(by.label('Delete Post')).atIndex(0);
+ leaveChannelTitle = isAndroid() ? element(by.text('Leave channel')) : element(by.label('Leave channel')).atIndex(0);
logoutTitle = (serverDisplayName: string) => {
const title = `Are you sure you want to log out of ${serverDisplayName}?`;
@@ -19,15 +22,20 @@ class Alert {
return isAndroid() ? element(by.text(title)) : element(by.label(title)).atIndex(0);
};
+ unarchivePrivateChannelTitle = isAndroid() ? element(by.text('Unarchive Private Channel')) : element(by.label('Unarchive Private Channel')).atIndex(0);
+ unarchivePublicChannelTitle = isAndroid() ? element(by.text('Unarchive Public Channel')) : element(by.label('Unarchive Public Channel')).atIndex(0);
// alert buttons
cancelButton = isAndroid() ? element(by.text('CANCEL')) : element(by.label('Cancel')).atIndex(1);
confirmButton = isAndroid() ? element(by.text('CONFIRM')) : element(by.label('Confirm')).atIndex(1);
deleteButton = isAndroid() ? element(by.text('DELETE')) : element(by.label('Delete')).atIndex(0);
+ leaveButton = isAndroid() ? element(by.text('LEAVE')) : element(by.label('Leave')).atIndex(0);
logoutButton = isAndroid() ? element(by.text('LOG OUT')) : element(by.label('Log out')).atIndex(1);
markReadButton = isAndroid() ? element(by.text('MARK READ')) : element(by.label('Mark read')).atIndex(1);
+ noButton = isAndroid() ? element(by.text('NO')) : element(by.label('No')).atIndex(1);
okButton = isAndroid() ? element(by.text('OK')) : element(by.label('OK')).atIndex(1);
removeButton = isAndroid() ? element(by.text('REMOVE')) : element(by.label('Remove')).atIndex(1);
+ yesButton = isAndroid() ? element(by.text('YES')) : element(by.label('Yes')).atIndex(1);
}
const alert = new Alert();
diff --git a/detox/e2e/support/ui/component/post_draft.ts b/detox/e2e/support/ui/component/post_draft.ts
index 4e3168a076..c9f26a6f98 100644
--- a/detox/e2e/support/ui/component/post_draft.ts
+++ b/detox/e2e/support/ui/component/post_draft.ts
@@ -17,6 +17,10 @@ class PostDraft {
return element(by.id(`${screenPrefix}${this.testID.postDraftArchivedSuffix}`));
};
+ getPostDraftArchivedCloseChannelButton = (screenPrefix: string) => {
+ return element(by.id(`${screenPrefix}${this.testID.postDraftArchivedSuffix}.close_channel.button`));
+ };
+
getPostDraftReadOnly = (screenPrefix: string) => {
return element(by.id(`${screenPrefix}${this.testID.postDraftReadOnlySuffix}`));
};
diff --git a/detox/e2e/support/ui/screen/channel.ts b/detox/e2e/support/ui/screen/channel.ts
index 9b7d5bcbdf..d841bacd3f 100644
--- a/detox/e2e/support/ui/screen/channel.ts
+++ b/detox/e2e/support/ui/screen/channel.ts
@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import {
+ Alert,
CameraQuickAction,
FileQuickAction,
ImageQuickAction,
@@ -23,19 +24,43 @@ class ChannelScreen {
testID = {
channelScreenPrefix: 'channel.',
channelScreen: 'channel.screen',
+ channelQuickActionsButton: 'channel_header.channel_quick_actions.button',
+ favoriteQuickAction: 'channel.quick_actions.favorite.action',
+ unfavoriteQuickAction: 'channel.quick_actions.unfavorite.action',
+ muteQuickAction: 'channel.quick_actions.mute.action',
+ unmuteQuickAction: 'channel.quick_actions.unmute.action',
+ setHeaderQuickAction: 'channel.quick_actions.set_header.action',
+ addPeopleQuickAction: 'channel.quick_actions.add_people.action',
+ copyChannelLinkQuickAction: 'channel.quick_actions.copy_channel_link.action',
+ channelInfoQuickAction: 'channel.quick_actions.channel_info.action',
+ leaveChannelQuickAction: 'channel.quick_actions.leave_channel.action',
introDisplayName: 'channel_post_list.intro.display_name',
- introAddPeopleOption: 'channel_post_list.intro_options.add_people.option',
- 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',
+ introAddPeopleAction: 'channel_post_list.intro_options.add_people.action',
+ introSetHeaderAction: 'channel_post_list.intro_options.set_header.action',
+ introFavoriteAction: 'channel_post_list.intro_options.favorite.action',
+ introUnfavoriteAction: 'channel_post_list.intro_options.unfavorite.action',
+ introChannelInfoAction: 'channel_post_list.intro_options.channel_info.action',
+ toastMessage: 'toast.message',
};
channelScreen = element(by.id(this.testID.channelScreen));
+ channelQuickActionsButton = element(by.id(this.testID.channelQuickActionsButton));
+ favoriteQuickAction = element(by.id(this.testID.favoriteQuickAction));
+ unfavoriteQuickAction = element(by.id(this.testID.unfavoriteQuickAction));
+ muteQuickAction = element(by.id(this.testID.muteQuickAction));
+ unmuteQuickAction = element(by.id(this.testID.unmuteQuickAction));
+ setHeaderQuickAction = element(by.id(this.testID.setHeaderQuickAction));
+ addPeopleQuickAction = element(by.id(this.testID.addPeopleQuickAction));
+ copyChannelLinkQuickAction = element(by.id(this.testID.copyChannelLinkQuickAction));
+ channelInfoQuickAction = element(by.id(this.testID.channelInfoQuickAction));
+ leaveChannelQuickAction = element(by.id(this.testID.leaveChannelQuickAction));
introDisplayName = element(by.id(this.testID.introDisplayName));
- introAddPeopleOption = element(by.id(this.testID.introAddPeopleOption));
- introSetHeaderOption = element(by.id(this.testID.introSetHeaderOption));
- introFavoriteOption = element(by.id(this.testID.introFavoriteOption));
- introChannelDetailsOption = element(by.id(this.testID.introChannelDetailsOption));
+ introAddPeopleAction = element(by.id(this.testID.introAddPeopleAction));
+ introSetHeaderAction = element(by.id(this.testID.introSetHeaderAction));
+ introFavoriteAction = element(by.id(this.testID.introFavoriteAction));
+ introUnfavoriteAction = element(by.id(this.testID.introUnfavoriteAction));
+ introChannelInfoAction = element(by.id(this.testID.introChannelInfoAction));
+ toastMessage = element(by.id(this.testID.toastMessage));
// convenience props
backButton = NavigationHeader.backButton;
@@ -52,6 +77,7 @@ class ChannelScreen {
cameraQuickActionDisabled = CameraQuickAction.getCameraQuickActionDisabled(this.testID.channelScreenPrefix);
postDraft = PostDraft.getPostDraft(this.testID.channelScreenPrefix);
postDraftArchived = PostDraft.getPostDraftArchived(this.testID.channelScreenPrefix);
+ postDraftArchivedCloseChannelButton = PostDraft.getPostDraftArchivedCloseChannelButton(this.testID.channelScreenPrefix);
postDraftReadOnly = PostDraft.getPostDraftReadOnly(this.testID.channelScreenPrefix);
postInput = PostDraft.getPostInput(this.testID.channelScreenPrefix);
sendButton = SendButton.getSendButton(this.testID.channelScreenPrefix);
@@ -101,6 +127,28 @@ class ChannelScreen {
await expect(this.channelScreen).not.toBeVisible();
};
+ leaveChannel = async ({confirm = true} = {}) => {
+ await waitFor(this.leaveChannelQuickAction).toExist().withTimeout(timeouts.TWO_SEC);
+ await this.leaveChannelQuickAction.tap({x: 1, y: 1});
+ const {
+ leaveChannelTitle,
+ cancelButton,
+ leaveButton,
+ } = Alert;
+ await expect(leaveChannelTitle).toBeVisible();
+ await expect(cancelButton).toBeVisible();
+ await expect(leaveButton).toBeVisible();
+ if (confirm) {
+ await leaveButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelScreen).not.toExist();
+ } else {
+ await cancelButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.leaveChannelQuickAction).toExist();
+ }
+ };
+
openPostOptionsFor = async (postId: string, text: string) => {
const {postListPostItem} = this.getPostListPostItem(postId, text);
await expect(postListPostItem).toBeVisible();
diff --git a/detox/e2e/support/ui/screen/channel_info.ts b/detox/e2e/support/ui/screen/channel_info.ts
index 588c7c7782..1f13cd3ae2 100644
--- a/detox/e2e/support/ui/screen/channel_info.ts
+++ b/detox/e2e/support/ui/screen/channel_info.ts
@@ -1,9 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ProfilePicture} from '@support/ui/component';
+import {
+ Alert,
+ ProfilePicture,
+} from '@support/ui/component';
import {ChannelScreen} from '@support/ui/screen';
-import {timeouts} from '@support/utils';
+import {timeouts, wait} from '@support/utils';
import {expect} from 'detox';
class ChannelInfoScreen {
@@ -16,7 +19,9 @@ class ChannelInfoScreen {
publicPrivateTitleDisplayName: 'channel_info.title.public_private.display_name',
publicPrivateTitlePurpose: 'channel_info.title.public_private.purpose',
favoriteAction: 'channel_info.channel_actions.favorite.action',
+ unfavoriteAction: 'channel_info.channel_actions.unfavorite.action',
muteAction: 'channel_info.channel_actions.mute.action',
+ unmuteAction: 'channel_info.channel_actions.unmute.action',
setHeaderAction: 'channel_info.channel_actions.set_header.action',
addPeopleAction: 'channel_info.channel_actions.add_people.action',
copyChannelLinkAction: 'channel_info.channel_actions.copy_channel_link.action',
@@ -32,6 +37,7 @@ class ChannelInfoScreen {
convertPrivateOption: 'channel_info.options.convert_private.option',
leaveChannelOption: 'channel_info.options.leave_channel.option',
archiveChannelOption: 'channel_info.options.archive_channel.option',
+ unarchiveChannelOption: 'channel_info.options.unarchive_channel.option',
};
channelInfoScreen = element(by.id(this.testID.channelInfoScreen));
@@ -41,7 +47,9 @@ class ChannelInfoScreen {
publicPrivateTitleDisplayName = element(by.id(this.testID.publicPrivateTitleDisplayName));
publicPrivateTitlePurpose = element(by.id(this.testID.publicPrivateTitlePurpose));
favoriteAction = element(by.id(this.testID.favoriteAction));
+ unfavoriteAction = element(by.id(this.testID.unfavoriteAction));
muteAction = element(by.id(this.testID.muteAction));
+ unmuteAction = element(by.id(this.testID.unmuteAction));
setHeaderAction = element(by.id(this.testID.setHeaderAction));
addPeopleAction = element(by.id(this.testID.addPeopleAction));
copyChannelLinkAction = element(by.id(this.testID.copyChannelLinkAction));
@@ -57,6 +65,7 @@ class ChannelInfoScreen {
convertPrivateOption = element(by.id(this.testID.convertPrivateOption));
leaveChannelOption = element(by.id(this.testID.leaveChannelOption));
archiveChannelOption = element(by.id(this.testID.archiveChannelOption));
+ unarchiveChannelOption = element(by.id(this.testID.unarchiveChannelOption));
getDirectMessageTitle = async (userId: string) => {
const directMessageTitleTestId = `${this.testID.directMessageTitlePrefix}${userId}`;
@@ -95,6 +104,59 @@ class ChannelInfoScreen {
await expect(this.channelInfoScreen).not.toBeVisible();
};
+ archiveChannel = async (alertArchiveChannelTitle: Detox.NativeElement, {confirm = true} = {}) => {
+ await this.scrollView.scrollTo('bottom');
+ await waitFor(this.archiveChannelOption).toExist().withTimeout(timeouts.TWO_SEC);
+ await this.archiveChannelOption.tap({x: 1, y: 1});
+ const {
+ noButton,
+ yesButton,
+ } = Alert;
+ await expect(alertArchiveChannelTitle).toBeVisible();
+ await expect(noButton).toBeVisible();
+ await expect(yesButton).toBeVisible();
+ if (confirm) {
+ await yesButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).not.toExist();
+ } else {
+ await noButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).toExist();
+ }
+ };
+
+ archivePrivateChannel = async ({confirm = true} = {}) => {
+ await this.archiveChannel(Alert.archivePrivateChannelTitle, {confirm});
+ };
+
+ archivePublicChannel = async ({confirm = true} = {}) => {
+ await this.archiveChannel(Alert.archivePublicChannelTitle, {confirm});
+ };
+
+ leaveChannel = async ({confirm = true} = {}) => {
+ await this.scrollView.scrollTo('bottom');
+ await waitFor(this.leaveChannelOption).toExist().withTimeout(timeouts.TWO_SEC);
+ await this.leaveChannelOption.tap({x: 1, y: 1});
+ const {
+ leaveChannelTitle,
+ cancelButton,
+ leaveButton,
+ } = Alert;
+ await expect(leaveChannelTitle).toBeVisible();
+ await expect(cancelButton).toBeVisible();
+ await expect(leaveButton).toBeVisible();
+ if (confirm) {
+ await leaveButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).not.toExist();
+ } else {
+ await cancelButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).toExist();
+ }
+ };
+
toggleIgnoreMentionsOptionOn = async () => {
await this.ignoreMentionsOptionToggledOff.tap();
await expect(this.ignoreMentionsOptionToggledOn).toBeVisible();
@@ -104,6 +166,36 @@ class ChannelInfoScreen {
await this.ignoreMentionsOptionToggledOn.tap();
await expect(this.ignoreMentionsOptionToggledOff).toBeVisible();
};
+
+ unarchiveChannel = async (alertUnarchiveChannelTitle: Detox.NativeElement, {confirm = true} = {}) => {
+ await this.scrollView.scrollTo('bottom');
+ await waitFor(this.unarchiveChannelOption).toExist().withTimeout(timeouts.TWO_SEC);
+ await this.unarchiveChannelOption.tap({x: 1, y: 1});
+ const {
+ noButton,
+ yesButton,
+ } = Alert;
+ await expect(alertUnarchiveChannelTitle).toBeVisible();
+ await expect(noButton).toBeVisible();
+ await expect(yesButton).toBeVisible();
+ if (confirm) {
+ await yesButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).not.toExist();
+ } else {
+ await noButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await expect(this.channelInfoScreen).toExist();
+ }
+ };
+
+ unarchivePrivateChannel = async ({confirm = true} = {}) => {
+ await this.unarchiveChannel(Alert.unarchivePrivateChannelTitle, {confirm});
+ };
+
+ unarchivePublicChannel = async ({confirm = true} = {}) => {
+ await this.unarchiveChannel(Alert.unarchivePublicChannelTitle, {confirm});
+ };
}
const channelInfoScreen = new ChannelInfoScreen();
diff --git a/detox/e2e/support/ui/screen/create_or_edit_channel.ts b/detox/e2e/support/ui/screen/create_or_edit_channel.ts
index b03ea3f7f9..874751786c 100644
--- a/detox/e2e/support/ui/screen/create_or_edit_channel.ts
+++ b/detox/e2e/support/ui/screen/create_or_edit_channel.ts
@@ -68,7 +68,7 @@ class CreateOrEditChannelScreen {
if (fromChannelInfo) {
await ChannelInfoScreen.setHeaderAction.tap();
} else {
- await ChannelScreen.introSetHeaderOption.tap();
+ await ChannelScreen.introSetHeaderAction.tap();
}
return this.toBeVisible();
diff --git a/detox/e2e/test/autocomplete/channel_mention.e2e.ts b/detox/e2e/test/autocomplete/channel_mention.e2e.ts
index 6a1f4b6f5b..cf70cfe935 100644
--- a/detox/e2e/test/autocomplete/channel_mention.e2e.ts
+++ b/detox/e2e/test/autocomplete/channel_mention.e2e.ts
@@ -10,7 +10,6 @@
import {
Channel,
Setup,
- System,
Team,
} from '@support/server_api';
import {
@@ -38,12 +37,6 @@ describe('Autocomplete - Channel Mention', () => {
let otherChannelMentionAutocomplete: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- EnableAPIChannelDeletion: true,
- },
- });
-
const {channel, team, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
testTeam = team;
@@ -197,7 +190,7 @@ describe('Autocomplete - Channel Mention', () => {
await expect(Autocomplete.sectionChannelMentionList).toBeVisible();
});
- it('MM-T4879_8 - should not be able to autocomplete archived channel', async () => {
+ it('MM-T4879_8 - should be able to autocomplete archived channel', async () => {
// # Archive another team channel and type in "~" to activate channel mention autocomplete
await Channel.apiDeleteChannel(siteOneUrl, testOtherChannel.id);
await ChannelScreen.postInput.typeText('~');
@@ -209,8 +202,8 @@ describe('Autocomplete - Channel Mention', () => {
// # Type in channel name of archived channel
await ChannelScreen.postInput.typeText(testOtherChannel.name);
- // * Verify channel mention autocomplete does not contain associated channel suggestion
- await expect(otherChannelMentionAutocomplete).not.toBeVisible();
+ // * Verify channel mention autocomplete contains associated channel suggestion
+ await expect(otherChannelMentionAutocomplete).toBeVisible();
// # Unarchive channel, clear post input, and type in "~" to activate channel mention list
await Channel.apiRestoreChannel(siteOneUrl, testOtherChannel.id);
diff --git a/detox/e2e/test/channels/archive_channel.e2e.ts b/detox/e2e/test/channels/archive_channel.e2e.ts
new file mode 100644
index 0000000000..c14d26fab2
--- /dev/null
+++ b/detox/e2e/test/channels/archive_channel.e2e.ts
@@ -0,0 +1,128 @@
+// 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 {
+ Channel,
+ Setup,
+} from '@support/server_api';
+import {
+ serverOneUrl,
+ siteOneUrl,
+} from '@support/test_config';
+import {
+ BrowseChannelsScreen,
+ ChannelDropdownMenuScreen,
+ ChannelScreen,
+ ChannelListScreen,
+ HomeScreen,
+ LoginScreen,
+ ServerScreen,
+ ChannelInfoScreen,
+} from '@support/ui/screen';
+import {expect} from 'detox';
+
+describe('Channels - Archive Channel', () => {
+ const serverOneDisplayName = 'Server 1';
+ const channelsCategory = 'channels';
+ let testTeam: any;
+ let testUser: any;
+
+ beforeAll(async () => {
+ const {team, user} = await Setup.apiInit(siteOneUrl);
+ 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-T4932_1 - should be able to archive a public channel and confirm', async () => {
+ // # Open a public channel screen, open channel info screen, and tap on archive channel option and confirm
+ const {channel: publicChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'O', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, publicChannel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, publicChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.archivePublicChannel({confirm: true});
+
+ // * Verify on channel screen and post draft archived message is displayed
+ await ChannelScreen.toBeVisible();
+ await expect(ChannelScreen.postDraftArchived).toBeVisible();
+ await expect(element(by.text('You are viewing an archived channel. New messages cannot be posted.'))).toBeVisible();
+
+ // # Tap on close channel button, open browse channels screen, tap on channel dropdown, tap on archived channels menu item, and search for the archived public channel
+ await ChannelScreen.postDraftArchivedCloseChannelButton.tap();
+ await BrowseChannelsScreen.open();
+ await BrowseChannelsScreen.channelDropdownTextPublic.tap();
+ await ChannelDropdownMenuScreen.archivedChannelsItem.tap();
+ await BrowseChannelsScreen.searchInput.replaceText(publicChannel.name);
+
+ // * Verify search returns the archived public channel item
+ await expect(BrowseChannelsScreen.getChannelItemDisplayName(publicChannel.name)).toHaveText(publicChannel.display_name);
+
+ // # Go back to channel list screen
+ await BrowseChannelsScreen.close();
+ });
+
+ it('MM-T4932_2 - should be able to archive a public channel and cancel', async () => {
+ // # Open a public channel screen, open channel info screen, and tap on archive channel option and cancel
+ const {channel: publicChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'O', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, publicChannel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, publicChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.archivePublicChannel({confirm: false});
+
+ // * Verify still on channel info screen
+ await ChannelInfoScreen.toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4932_3 - should be able to archive a private channel and confirm', async () => {
+ // # Open a private channel screen, open channel info screen, and tap on archive channel option and confirm
+ const {channel: privateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, privateChannel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, privateChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.archivePrivateChannel({confirm: true});
+
+ // * Verify on channel screen and post draft archived message is displayed
+ await ChannelScreen.toBeVisible();
+ await expect(ChannelScreen.postDraftArchived).toBeVisible();
+ await expect(element(by.text('You are viewing an archived channel. New messages cannot be posted.'))).toBeVisible();
+
+ // # Tap on close channel button, open browse channels screen, tap on channel dropdown, tap on archived channels menu item, and search for the archived private channel
+ await ChannelScreen.postDraftArchivedCloseChannelButton.tap();
+ await BrowseChannelsScreen.open();
+ await BrowseChannelsScreen.channelDropdownTextPublic.tap();
+ await ChannelDropdownMenuScreen.archivedChannelsItem.tap();
+ await BrowseChannelsScreen.searchInput.replaceText(privateChannel.name);
+
+ // * Verify search returns the archived private channel item
+ await expect(BrowseChannelsScreen.getChannelItemDisplayName(privateChannel.name)).toHaveText(privateChannel.display_name);
+
+ // # Go back to channel list screen
+ await BrowseChannelsScreen.close();
+ });
+});
diff --git a/detox/e2e/test/channels/browse_channels.e2e.ts b/detox/e2e/test/channels/browse_channels.e2e.ts
index 50b2ec84ee..54c05bd001 100644
--- a/detox/e2e/test/channels/browse_channels.e2e.ts
+++ b/detox/e2e/test/channels/browse_channels.e2e.ts
@@ -10,7 +10,6 @@
import {
Channel,
Setup,
- System,
Team,
User,
} from '@support/server_api';
@@ -36,15 +35,6 @@ describe('Channels - Browse Channels', () => {
let testUser: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- EnableAPIChannelDeletion: true,
- },
- TeamSettings: {
- ExperimentalViewArchivedChannels: true,
- },
- });
-
const {team, user} = await Setup.apiInit(siteOneUrl);
testTeam = team;
testUser = user;
@@ -77,24 +67,24 @@ describe('Channels - Browse Channels', () => {
await BrowseChannelsScreen.close();
});
- it('MM-T4729_2 - should be able to browse and join a channel', async () => {
- // # As admin, create a new channel so that user can join
+ it('MM-T4729_2 - should be able to browse and join an unjoined public channel', async () => {
+ // # As admin, create a new public channel so that user can join
const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
- // * Verify new channel does not appear on channel list screen
+ // * Verify new public channel does not appear on channel list screen
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, channel.display_name)).not.toExist();
- // # Open browse channels screen and search for the new channel name to join
+ // # Open browse channels screen and search for the new public channel name to join
await BrowseChannelsScreen.open();
await BrowseChannelsScreen.searchInput.replaceText(channel.name);
- // * Verify search returns the new channel item
+ // * Verify search returns the new public channel item
await expect(BrowseChannelsScreen.getChannelItemDisplayName(channel.name)).toHaveText(channel.display_name);
- // # Tap on the new channel item
+ // # Tap on the new public channel item
await BrowseChannelsScreen.getChannelItem(channel.name).multiTap(2);
- // * Verify on newly joined channel screen
+ // * Verify on newly joined public channel screen
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText(channel.display_name);
await expect(ChannelScreen.introDisplayName).toHaveText(channel.display_name);
@@ -103,7 +93,7 @@ describe('Channels - Browse Channels', () => {
await ChannelScreen.back();
await ChannelListScreen.toBeVisible();
- // * Verify newly joined channel is added to channel list
+ // * Verify newly joined public channel is added to channel list
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, channel.name)).toBeVisible();
});
@@ -114,7 +104,7 @@ describe('Channels - Browse Channels', () => {
await BrowseChannelsScreen.searchInput.replaceText(searchTerm);
// * Verify empty search state for browse channels
- await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${searchTerm}”`))).toBeVisible();
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
// # Go back to channel list screen
@@ -133,13 +123,13 @@ describe('Channels - Browse Channels', () => {
await BrowseChannelsScreen.searchInput.replaceText(testOtherUser1.username);
// * Verify empty search state for browse channels
- await expect(element(by.text(`No results for “${testOtherUser1.username}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${testOtherUser1.username}”`))).toBeVisible();
// # Search for the group message channel
await BrowseChannelsScreen.searchInput.replaceText(testOtherUser2.username);
// * Verify empty search state for browse channels
- await expect(element(by.text(`No results for “${testOtherUser2.username}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${testOtherUser2.username}”`))).toBeVisible();
// # Go back to channel list screen
await BrowseChannelsScreen.close();
@@ -161,4 +151,39 @@ describe('Channels - Browse Channels', () => {
// # Go back to channel list screen
await BrowseChannelsScreen.close();
});
+
+ it('MM-T4729_6 - should not be able to browse a joined public channel', async () => {
+ // # Open browse channels screen and search for a joined public channel
+ const {channel: joinedPublicChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'O', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, joinedPublicChannel.id);
+ await BrowseChannelsScreen.open();
+ await BrowseChannelsScreen.searchInput.replaceText(joinedPublicChannel.name);
+
+ // * Verify empty search state for browse channels
+ await expect(element(by.text(`No matches found for “${joinedPublicChannel.name}”`))).toBeVisible();
+
+ // # Go back to channel list screen
+ await BrowseChannelsScreen.close();
+ });
+
+ it('MM-T4729_7 - should not be able to browse joined and unjoined private channel', async () => {
+ // # As admin, create joined and unjoined private channels, open browse channels screen, and search for the joined private channel
+ const {channel: joinedPrivateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
+ const {channel: unjoinedPrivateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, joinedPrivateChannel.id);
+ await BrowseChannelsScreen.open();
+ await BrowseChannelsScreen.searchInput.replaceText(joinedPrivateChannel.name);
+
+ // * Verify empty search state for browse channels
+ await expect(element(by.text(`No matches found for “${joinedPrivateChannel.name}”`))).toBeVisible();
+
+ // # Search for the unjoined private channel
+ await BrowseChannelsScreen.searchInput.replaceText(unjoinedPrivateChannel.name);
+
+ // * Verify empty search state for browse channels
+ await expect(element(by.text(`No matches found for “${unjoinedPrivateChannel.name}”`))).toBeVisible();
+
+ // # Go back to channel list screen
+ await BrowseChannelsScreen.close();
+ });
});
diff --git a/detox/e2e/test/channels/channel_info.e2e.ts b/detox/e2e/test/channels/channel_info.e2e.ts
new file mode 100644
index 0000000000..e09ce7b77b
--- /dev/null
+++ b/detox/e2e/test/channels/channel_info.e2e.ts
@@ -0,0 +1,102 @@
+// 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 {Setup} from '@support/server_api';
+import {
+ serverOneUrl,
+ siteOneUrl,
+} from '@support/test_config';
+import {
+ ChannelScreen,
+ ChannelListScreen,
+ HomeScreen,
+ LoginScreen,
+ ServerScreen,
+ ChannelInfoScreen,
+} from '@support/ui/screen';
+import {expect} from 'detox';
+
+describe('Channels - Channel Info', () => {
+ const serverOneDisplayName = 'Server 1';
+ const channelsCategory = 'channels';
+ let testChannel: any;
+
+ beforeAll(async () => {
+ const {channel, user} = await Setup.apiInit(siteOneUrl);
+ testChannel = channel;
+
+ // # 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-T4928_1 - should match elements on channel info screen', async () => {
+ // # Open a channel screen and open channel info screen
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelInfoScreen.open();
+
+ // * Verify basic elements on channel info screen
+ await expect(ChannelInfoScreen.closeButton).toBeVisible();
+ await expect(ChannelInfoScreen.publicPrivateTitleDisplayName).toHaveText(testChannel.display_name);
+ await expect(ChannelInfoScreen.publicPrivateTitlePurpose).toHaveText(`Channel purpose: ${testChannel.display_name.toLowerCase()}`);
+ await expect(element(by.text(`Channel header: ${testChannel.display_name.toLowerCase()}`))).toBeVisible();
+ await expect(ChannelInfoScreen.favoriteAction).toBeVisible();
+ await expect(ChannelInfoScreen.muteAction).toBeVisible();
+ await expect(ChannelInfoScreen.addPeopleAction).toBeVisible();
+ await expect(ChannelInfoScreen.copyChannelLinkAction).toBeVisible();
+ await expect(ChannelInfoScreen.ignoreMentionsOptionToggledOff).toBeVisible();
+ await expect(ChannelInfoScreen.notificationPreferenceOption).toBeVisible();
+ await expect(ChannelInfoScreen.pinnedMessagesOption).toBeVisible();
+ await expect(ChannelInfoScreen.membersOption).toBeVisible();
+ await expect(ChannelInfoScreen.editChannelOption).toBeVisible();
+ await expect(ChannelInfoScreen.leaveChannelOption).toBeVisible();
+ await expect(ChannelInfoScreen.archiveChannelOption).toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4928_2 - should be able to view channel info by tapping intro channel info action', async () => {
+ // # Open a channel screen and tap on intro channel info action
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelScreen.introChannelInfoAction.tap();
+
+ // * Verify on channel info screen
+ await ChannelInfoScreen.toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4928_3 - should be able to view channel info from channel quick actions', async () => {
+ // # Open a channel screen, tap on channel quick actions button, and tap on channel info action
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.channelInfoQuickAction.tap();
+
+ // * Verify on channel info screen
+ await ChannelInfoScreen.toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+});
diff --git a/detox/e2e/test/channels/channel_list.e2e.ts b/detox/e2e/test/channels/channel_list.e2e.ts
index 143048cc01..6b33c6bb26 100644
--- a/detox/e2e/test/channels/channel_list.e2e.ts
+++ b/detox/e2e/test/channels/channel_list.e2e.ts
@@ -9,7 +9,6 @@
import {
Setup,
- System,
Team,
} from '@support/server_api';
import {
@@ -41,12 +40,6 @@ describe('Channels - Channel List', () => {
let testUser: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, team, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
testTeam = team;
diff --git a/detox/e2e/test/channels/channel_post_list.e2e.ts b/detox/e2e/test/channels/channel_post_list.e2e.ts
index 1f13931ab4..9b0758b83c 100644
--- a/detox/e2e/test/channels/channel_post_list.e2e.ts
+++ b/detox/e2e/test/channels/channel_post_list.e2e.ts
@@ -57,9 +57,9 @@ describe('Channels - Channel Post List', () => {
await expect(ChannelScreen.backButton).toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText(testChannel.display_name);
await expect(ChannelScreen.introDisplayName).toHaveText(testChannel.display_name);
- await expect(ChannelScreen.introAddPeopleOption).toBeVisible();
- await expect(ChannelScreen.introSetHeaderOption).toBeVisible();
- await expect(ChannelScreen.introChannelDetailsOption).toBeVisible();
+ await expect(ChannelScreen.introAddPeopleAction).toBeVisible();
+ await expect(ChannelScreen.introSetHeaderAction).toBeVisible();
+ await expect(ChannelScreen.introChannelInfoAction).toBeVisible();
await expect(ChannelScreen.postList.getFlatList()).toBeVisible();
await expect(ChannelScreen.postDraft).toBeVisible();
await expect(ChannelScreen.postInput).toBeVisible();
diff --git a/detox/e2e/test/channels/create_channel_and_edit_channel_header.e2e.ts b/detox/e2e/test/channels/create_channel_and_edit_channel_header.e2e.ts
index 18e424f3b4..ab0a2c4a74 100644
--- a/detox/e2e/test/channels/create_channel_and_edit_channel_header.e2e.ts
+++ b/detox/e2e/test/channels/create_channel_and_edit_channel_header.e2e.ts
@@ -81,8 +81,8 @@ describe('Channels - Create Channel and Edit Channel Header', () => {
await expect(ChannelScreen.headerTitle).toHaveText(displayName);
await expect(ChannelScreen.introDisplayName).toHaveText(displayName);
- // # Tap on set header option to edit the channel header
- await ChannelScreen.introSetHeaderOption.tap();
+ // # Tap on set header action to edit the channel header
+ await ChannelScreen.introSetHeaderAction.tap();
// * Verify channel header is correct
await expect(CreateOrEditChannelScreen.headerInput).toHaveValue(header);
@@ -118,8 +118,8 @@ describe('Channels - Create Channel and Edit Channel Header', () => {
await expect(ChannelScreen.headerTitle).toHaveText(displayName);
await expect(ChannelScreen.introDisplayName).toHaveText(displayName);
- // # Tap on set header option to edit the channel header
- await ChannelScreen.introSetHeaderOption.tap();
+ // # Tap on set header action to edit the channel header
+ await ChannelScreen.introSetHeaderAction.tap();
// * Verify channel header is correct
await expect(CreateOrEditChannelScreen.headerInput).toHaveValue(header);
diff --git a/detox/e2e/test/channels/create_direct_message.e2e.ts b/detox/e2e/test/channels/create_direct_message.e2e.ts
index b71d2a4f26..ebfd04b0f5 100644
--- a/detox/e2e/test/channels/create_direct_message.e2e.ts
+++ b/detox/e2e/test/channels/create_direct_message.e2e.ts
@@ -160,7 +160,7 @@ describe('Channels - Create Direct Message', () => {
await CreateDirectMessageScreen.searchInput.replaceText(searchTerm);
// * Verify empty search state for create direct message
- await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${searchTerm}”`))).toBeVisible();
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
// # Go back to channel list screen
diff --git a/detox/e2e/test/channels/favorite_and_unfavorite_channel.e2e.ts b/detox/e2e/test/channels/favorite_and_unfavorite_channel.e2e.ts
new file mode 100644
index 0000000000..1cba9997b4
--- /dev/null
+++ b/detox/e2e/test/channels/favorite_and_unfavorite_channel.e2e.ts
@@ -0,0 +1,136 @@
+// 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 {
+ Channel,
+ Setup,
+ Team,
+ User,
+} from '@support/server_api';
+import {
+ serverOneUrl,
+ siteOneUrl,
+} from '@support/test_config';
+import {
+ ChannelScreen,
+ ChannelListScreen,
+ HomeScreen,
+ LoginScreen,
+ ServerScreen,
+ ChannelInfoScreen,
+} from '@support/ui/screen';
+import {expect} from 'detox';
+
+describe('Channels - Favorite and Unfavorite Channel', () => {
+ const serverOneDisplayName = 'Server 1';
+ const channelsCategory = 'channels';
+ const favoritesCategory = 'favorites';
+ const directMessagesCategory = 'direct_messages';
+ 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-T4929_1 - should be able to favorite/unfavorite a channel from channel quick actions', async () => {
+ // # Open a channel screen, tap on channel quick actions button, and tap on favorite quick action to favorite the channel
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.favoriteQuickAction.tap();
+
+ // * Verify favorited toast message appears
+ await expect(ChannelScreen.toastMessage).toHaveText('This channel was favorited');
+
+ // # Go back to channel list screen
+ await ChannelScreen.back();
+
+ // * Verify channel is listed under favorites category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, testChannel.name)).toBeVisible();
+
+ // # Go back to the favorited channel, tap on channel quick actions button, and tap on favorited quick action to unfavorite the channel
+ await ChannelScreen.open(favoritesCategory, testChannel.name);
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.unfavoriteQuickAction.tap();
+
+ // * Verify unfavorited toast message appears
+ await expect(ChannelScreen.toastMessage).toHaveText('This channel was unfavorited');
+
+ // # Go back to channel list screen
+ await ChannelScreen.back();
+
+ // * Verify channel is not listed anymore under favorites category and is back under channels category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, testChannel.name)).not.toBeVisible();
+ await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name)).toBeVisible();
+ });
+
+ it('MM-T4929_2 - should be able to favorite/unfavorite a channel from channel info screen', async () => {
+ // # Open a channel screen, open channel info screen, tap on favorite action to favorite the channel, and go back to channel list screen
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.favoriteAction.tap();
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+
+ // * Verify channel is listed under favorites category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, testChannel.name)).toBeVisible();
+
+ // # Go back to the favorited channel, open channel info screen, tap on favorited action to unfavorite the channel, and go back to channel list screen
+ await ChannelScreen.open(favoritesCategory, testChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.unfavoriteAction.tap();
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+
+ // * Verify channel is not listed anymore under favorites category and is back under channels category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, testChannel.name)).not.toBeVisible();
+ await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name)).toBeVisible();
+ });
+
+ it('MM-T4929_3 - should be able to favorite/unfavorite a direct message channel from channel intro', async () => {
+ // # Open a direct message channel screen, tap on intro favorite action to favorite the channel, and go back to channel list screen
+ const {user: newUser} = await User.apiCreateUser(siteOneUrl);
+ await Team.apiAddUserToTeam(siteOneUrl, newUser.id, testTeam.id);
+ const {channel: directMessageChannel} = await Channel.apiCreateDirectChannel(siteOneUrl, [testUser.id, newUser.id]);
+ await device.reloadReactNative();
+ await ChannelScreen.open(directMessagesCategory, directMessageChannel.name);
+ await ChannelScreen.introFavoriteAction.tap();
+ await ChannelScreen.back();
+
+ // * Verify direct message channel is listed under favorites category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, directMessageChannel.name)).toBeVisible();
+
+ // # Go back to the favorited direct message channel, tap on intro favorited action to unfavorite the direct message channel, and go back to channel list screen
+ await ChannelScreen.open(favoritesCategory, directMessageChannel.name);
+ await ChannelScreen.introUnfavoriteAction.tap();
+ await ChannelScreen.back();
+
+ // * Verify direct message channel is not listed anymore under favorites category and is back under direct messages category
+ await expect(ChannelListScreen.getChannelItemDisplayName(favoritesCategory, directMessageChannel.name)).not.toBeVisible();
+ await expect(ChannelListScreen.getChannelItemDisplayName(directMessagesCategory, directMessageChannel.name)).toBeVisible();
+ });
+});
diff --git a/detox/e2e/test/channels/find_channels.e2e.ts b/detox/e2e/test/channels/find_channels.e2e.ts
index 8dd1609f71..a1bcc7c786 100644
--- a/detox/e2e/test/channels/find_channels.e2e.ts
+++ b/detox/e2e/test/channels/find_channels.e2e.ts
@@ -10,7 +10,6 @@
import {
Channel,
Setup,
- System,
Team,
User,
} from '@support/server_api';
@@ -35,15 +34,6 @@ describe('Channels - Find Channels', () => {
let testUser: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- EnableAPIChannelDeletion: true,
- },
- TeamSettings: {
- ExperimentalViewArchivedChannels: true,
- },
- });
-
const {channel, team, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
testTeam = team;
@@ -77,18 +67,18 @@ describe('Channels - Find Channels', () => {
await FindChannelsScreen.close();
});
- it('MM-T4907_2 - should be able to find and navigate to a channel', async () => {
- // # Open find channels screen and search for the channel to navigate to
+ it('MM-T4907_2 - should be able to find and navigate to a public channel', async () => {
+ // # Open find channels screen and search for a public channel to navigate to
await FindChannelsScreen.open();
await FindChannelsScreen.searchInput.replaceText(testChannel.name);
- // * Verify search returns the target channel item
+ // * Verify search returns the target public channel item
await expect(FindChannelsScreen.getFilteredChannelItemDisplayName(testChannel.name)).toHaveText(testChannel.display_name);
- // # Tap on the target channel item
+ // # Tap on the target public channel item
await FindChannelsScreen.getFilteredChannelItem(testChannel.name).tap();
- // * Verify on target channel screen
+ // * Verify on target public channel screen
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText(testChannel.display_name);
await expect(ChannelScreen.introDisplayName).toHaveText(testChannel.display_name);
@@ -104,7 +94,7 @@ describe('Channels - Find Channels', () => {
await FindChannelsScreen.searchInput.replaceText(searchTerm);
// * Verify empty search state for find channels
- await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${searchTerm}”`))).toBeVisible();
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
// # Go back to channel list screen
@@ -135,7 +125,7 @@ describe('Channels - Find Channels', () => {
await FindChannelsScreen.close();
});
- it('MM-T4907_5 - should be able to find archived channel', async () => {
+ it('MM-T4907_5 - should be able to find an archived channel', async () => {
// # Archive a channel, open find channels screen, and search for the archived channel
const {channel: archivedChannel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, archivedChannel.id);
@@ -149,4 +139,25 @@ describe('Channels - Find Channels', () => {
// # Go back to channel list screen
await FindChannelsScreen.close();
});
+
+ it('MM-T4907_6 - should be able to find a joined private channel and not find an unjoined private channel', async () => {
+ // # Open find channels screen and search for a joined private channel
+ const {channel: joinedPrivateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
+ const {channel: unjoinedPrivateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, joinedPrivateChannel.id);
+ await FindChannelsScreen.open();
+ await FindChannelsScreen.searchInput.replaceText(joinedPrivateChannel.name);
+
+ // * Verify search returns the target joined private channel item
+ await expect(FindChannelsScreen.getFilteredChannelItemDisplayName(joinedPrivateChannel.name)).toHaveText(joinedPrivateChannel.display_name);
+
+ // # Search for an unjoined private channel
+ await FindChannelsScreen.searchInput.replaceText(unjoinedPrivateChannel.name);
+
+ // * Verify empty search state for find channels
+ await expect(element(by.text(`No matches found for “${unjoinedPrivateChannel.name}”`))).toBeVisible();
+
+ // # Go back to channel list screen
+ await FindChannelsScreen.close();
+ });
});
diff --git a/detox/e2e/test/channels/leave_channel.e2e.ts b/detox/e2e/test/channels/leave_channel.e2e.ts
new file mode 100644
index 0000000000..741fc19505
--- /dev/null
+++ b/detox/e2e/test/channels/leave_channel.e2e.ts
@@ -0,0 +1,98 @@
+// 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 {
+ Channel,
+ Setup,
+} from '@support/server_api';
+import {
+ serverOneUrl,
+ siteOneUrl,
+} from '@support/test_config';
+import {
+ ChannelScreen,
+ ChannelListScreen,
+ HomeScreen,
+ LoginScreen,
+ ServerScreen,
+ ChannelInfoScreen,
+} from '@support/ui/screen';
+import {expect} from 'detox';
+
+describe('Channels - Leave Channel', () => {
+ const serverOneDisplayName = 'Server 1';
+ const channelsCategory = 'channels';
+ let testTeam: any;
+ let testUser: any;
+
+ beforeAll(async () => {
+ const {team, user} = await Setup.apiInit(siteOneUrl);
+ 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-T4931_1 - should be able to leave a channel from channel info screen and confirm', async () => {
+ // # Open a channel screen, open channel info screen, and tap on leave channel option and confirm
+ const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, channel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, channel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.leaveChannel({confirm: true});
+
+ // * Verify on channel list screen and the channel left by the user does not appear on the list
+ await ChannelListScreen.toBeVisible();
+ await expect(ChannelListScreen.getChannelItem(channelsCategory, channel.name)).not.toExist();
+ });
+
+ it('MM-T4931_2 - should be able to leave a channel from channel info screen and cancel', async () => {
+ // # Open a channel screen, open channel info screen, and tap on leave channel option and cancel
+ const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, channel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, channel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.leaveChannel({confirm: false});
+
+ // * Verify still on channel info screen
+ await ChannelInfoScreen.toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4931_3 - should be able to leave a channel from channel quick actions', async () => {
+ // # Open a channel screen, tap on channel quick actions button, and tap on leave channel option and confirm
+ const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, channel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, channel.name);
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.leaveChannel({confirm: true});
+
+ // * Verify on channel list screen and the channel left by the user does not appear on the list
+ await ChannelListScreen.toBeVisible();
+ await expect(ChannelListScreen.getChannelItem(channelsCategory, channel.name)).not.toExist();
+ });
+});
diff --git a/detox/e2e/test/channels/mute_and_unmute_channel.e2e.ts b/detox/e2e/test/channels/mute_and_unmute_channel.e2e.ts
new file mode 100644
index 0000000000..95e5e4853c
--- /dev/null
+++ b/detox/e2e/test/channels/mute_and_unmute_channel.e2e.ts
@@ -0,0 +1,88 @@
+// 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 {Setup} from '@support/server_api';
+import {
+ serverOneUrl,
+ siteOneUrl,
+} from '@support/test_config';
+import {
+ ChannelScreen,
+ ChannelListScreen,
+ HomeScreen,
+ LoginScreen,
+ ServerScreen,
+ ChannelInfoScreen,
+} from '@support/ui/screen';
+import {expect} from 'detox';
+
+describe('Channels - Mute and Unmute Channel', () => {
+ const serverOneDisplayName = 'Server 1';
+ const channelsCategory = 'channels';
+ let testChannel: any;
+
+ beforeAll(async () => {
+ const {channel, user} = await Setup.apiInit(siteOneUrl);
+ testChannel = channel;
+
+ // # 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-T4930_1 - should be able to mute/unmute a channel from channel quick actions', async () => {
+ // # Open a channel screen, tap on channel quick actions button, and tap on mute quick action to mute the channel
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.muteQuickAction.tap();
+
+ // * Verify muted toast message appears
+ await expect(ChannelScreen.toastMessage).toHaveText('This channel was muted');
+
+ // # Tap on channel quick actions button and tap on muted quick action to unmute the channel
+ await ChannelScreen.channelQuickActionsButton.tap();
+ await ChannelScreen.unmuteQuickAction.tap();
+
+ // * Verify unmuted toast message appears
+ await expect(ChannelScreen.toastMessage).toHaveText('This channel was unmuted');
+
+ // # Go back to channel list screen
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4930_2 - should be able to mute/unmute a channel from channel info screen', async () => {
+ // # Open a channel screen, open channel info screen, and tap on mute action to mute the channel
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.muteAction.tap();
+
+ // * Verify channel is muted
+ await expect(ChannelInfoScreen.unmuteAction).toBeVisible();
+
+ // # Tap on muted action to unmute the channel
+ await ChannelInfoScreen.unmuteAction.tap();
+
+ // * Verify channel is unmuted
+ await expect(ChannelInfoScreen.muteAction).toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+});
diff --git a/detox/e2e/test/messaging/emojis_and_reactions.e2e.ts b/detox/e2e/test/messaging/emojis_and_reactions.e2e.ts
index c0f9f4f89f..49fd45015a 100644
--- a/detox/e2e/test/messaging/emojis_and_reactions.e2e.ts
+++ b/detox/e2e/test/messaging/emojis_and_reactions.e2e.ts
@@ -171,7 +171,7 @@ describe('Messaging - Emojis and Reactions', () => {
await EmojiPickerScreen.searchInput.replaceText(searchTerm);
// * Verify empty search state for emoji picker
- await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
+ await expect(element(by.text(`No matches found for “${searchTerm}”`))).toBeVisible();
await expect(element(by.text('Check the spelling or try another search.'))).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 d519d18333..0d3cc6e9f1 100644
--- a/detox/e2e/test/messaging/markdown_latex.e2e.ts
+++ b/detox/e2e/test/messaging/markdown_latex.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -31,13 +30,6 @@ describe('Messaging - Markdown Latex', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- EnableLatex: true,
- EnableInlineLatex: true,
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
diff --git a/detox/e2e/test/server_login/server_list.e2e.ts b/detox/e2e/test/server_login/server_list.e2e.ts
index 39129d1817..d5599bbec1 100644
--- a/detox/e2e/test/server_login/server_list.e2e.ts
+++ b/detox/e2e/test/server_login/server_list.e2e.ts
@@ -212,25 +212,23 @@ describe('Server Login - Server List', () => {
// * Verify on channel list screen of the first server
await expect(ChannelListScreen.headerServerDisplayName).toHaveText(serverOneDisplayName);
- // # Open server list screen, swipe left on first server and tap on logout option
+ // # Open server list screen, swipe left on third server and tap on logout option
await ServerListScreen.open();
- await ServerListScreen.getServerItemActive(serverOneDisplayName).swipe('left');
- await ServerListScreen.getServerItemLogoutOption(serverOneDisplayName).tap();
+ await ServerListScreen.getServerItemInactive(serverThreeDisplayName).swipe('left');
+ await ServerListScreen.getServerItemLogoutOption(serverThreeDisplayName).tap();
// * Verify logout server alert is displayed
- await expect(Alert.logoutTitle(serverOneDisplayName)).toBeVisible();
+ await expect(Alert.logoutTitle(serverThreeDisplayName)).toBeVisible();
- // # Tap on logout button and go back to server list screen
+ // # Tap on logout button
await Alert.logoutButton.tap();
- await ServerListScreen.open();
- // * Verify first server is logged out
- await ServerListScreen.getServerItemInactive(serverOneDisplayName).swipe('left');
- await expect(ServerListScreen.getServerItemLoginOption(serverOneDisplayName)).toBeVisible();
+ // * Verify third server is logged out
+ await ServerListScreen.getServerItemInactive(serverThreeDisplayName).swipe('left');
+ await expect(ServerListScreen.getServerItemLoginOption(serverThreeDisplayName)).toBeVisible();
- // # Log back in to first server
- await ServerListScreen.getServerItemLoginOption(serverOneDisplayName).tap();
- await LoginScreen.login(serverOneUser);
+ // # Go back to first server
+ await ServerListScreen.getServerItemActive(serverOneDisplayName).tap();
});
it('MM-T4691_7 - should not be able to add server for an already existing server', async () => {
@@ -257,7 +255,12 @@ describe('Server Login - Server List', () => {
// * Verify same name server error
await expect(ServerScreen.serverDisplayNameInputError).toHaveText(sameNameServerError);
- // # Close server screen to go back to first server
+ // # Close server screen, open server list screen, log out of second server, and go back to first server
await ServerScreen.close();
+ await ServerListScreen.open();
+ await ServerListScreen.getServerItemInactive(serverTwoDisplayName).swipe('left');
+ await ServerListScreen.getServerItemLogoutOption(serverTwoDisplayName).tap();
+ await Alert.logoutButton.tap();
+ await ServerListScreen.getServerItemActive(serverOneDisplayName).tap();
});
});
diff --git a/detox/e2e/test/smoke_test/channels.e2e.ts b/detox/e2e/test/smoke_test/channels.e2e.ts
index d04434eee2..3d94f99ec8 100644
--- a/detox/e2e/test/smoke_test/channels.e2e.ts
+++ b/detox/e2e/test/smoke_test/channels.e2e.ts
@@ -38,15 +38,17 @@ describe('Smoke Test - Channels', () => {
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(user);
+ await LoginScreen.login(testUser);
});
beforeEach(async () => {
@@ -158,4 +160,51 @@ describe('Smoke Test - Channels', () => {
await ChannelInfoScreen.close();
await ChannelScreen.back();
});
+
+ it('MM-T4774_5 - should be able to favorite and mute a channel', async () => {
+ // # Open a channel screen, open channel info screen, tap on favorite action to favorite the channel, and tap on mute action to mute the channel
+ await ChannelScreen.open(channelsCategory, testChannel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.favoriteAction.tap();
+ await ChannelInfoScreen.muteAction.tap();
+
+ // * Verify channel is favorited and muted
+ await expect(ChannelInfoScreen.unfavoriteAction).toBeVisible();
+ await expect(ChannelInfoScreen.unmuteAction).toBeVisible();
+
+ // # Tap on favorited action to unfavorite the channel and tap on muted action to unmute the channel
+ await ChannelInfoScreen.unfavoriteAction.tap();
+ await ChannelInfoScreen.unmuteAction.tap();
+
+ // * Verify channel is unfavorited and unmuted
+ await expect(ChannelInfoScreen.favoriteAction).toBeVisible();
+ await expect(ChannelInfoScreen.muteAction).toBeVisible();
+
+ // # Go back to channel list screen
+ await ChannelInfoScreen.close();
+ await ChannelScreen.back();
+ });
+
+ it('MM-T4774_6 - should be able to archive and leave a channel', async () => {
+ // # Open a channel screen, open channel info screen, and tap on archive channel option and confirm
+ const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
+ await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, channel.id);
+ await device.reloadReactNative();
+ await ChannelScreen.open(channelsCategory, channel.name);
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.archivePublicChannel({confirm: true});
+
+ // * Verify on channel screen and post draft archived message is displayed
+ await ChannelScreen.toBeVisible();
+ await expect(ChannelScreen.postDraftArchived).toBeVisible();
+ await expect(element(by.text('You are viewing an archived channel. New messages cannot be posted.'))).toBeVisible();
+
+ // # Open channel info screen, and tap on leave channel option and confirm
+ await ChannelInfoScreen.open();
+ await ChannelInfoScreen.leaveChannel({confirm: true});
+
+ // * Verify on channel list screen and the channel left by the user does not appear on the list
+ await ChannelListScreen.toBeVisible();
+ await expect(ChannelListScreen.getChannelItem(channelsCategory, channel.name)).not.toExist();
+ });
});
diff --git a/detox/e2e/test/smoke_test/server_login.e2e.ts b/detox/e2e/test/smoke_test/server_login.e2e.ts
index dbefff3b7d..c01d31b386 100644
--- a/detox/e2e/test/smoke_test/server_login.e2e.ts
+++ b/detox/e2e/test/smoke_test/server_login.e2e.ts
@@ -17,6 +17,7 @@ import {
serverTwoUrl,
siteTwoUrl,
} from '@support/test_config';
+import {Alert} from '@support/ui/component';
import {
ChannelListScreen,
HomeScreen,
@@ -55,7 +56,7 @@ describe('Smoke Test - Server Login', () => {
await expect(ChannelListScreen.headerServerDisplayName).toHaveText(serverOneDisplayName);
});
- it('MM-T4675_2 - should be able to add a new server and log in to the new server', async () => {
+ it('MM-T4675_2 - should be able to add a new server and log-in-to/log-out-from the new server', async () => {
// # Open server list screen
await ServerListScreen.open();
@@ -75,8 +76,24 @@ describe('Smoke Test - Server Login', () => {
await device.reloadReactNative();
await expect(ChannelListScreen.headerServerDisplayName).toHaveText(serverTwoDisplayName);
- // # Go back to first server
+ // # Go back to first server, open server list screen, swipe left on second server and tap on logout option
await ServerListScreen.open();
await ServerListScreen.getServerItemInactive(serverOneDisplayName).tap();
+ await ServerListScreen.open();
+ await ServerListScreen.getServerItemInactive(serverTwoDisplayName).swipe('left');
+ await ServerListScreen.getServerItemLogoutOption(serverTwoDisplayName).tap();
+
+ // * Verify logout server alert is displayed
+ await expect(Alert.logoutTitle(serverTwoDisplayName)).toBeVisible();
+
+ // # Tap on logout button
+ await Alert.logoutButton.tap();
+
+ // * Verify second server is logged out
+ await ServerListScreen.getServerItemInactive(serverTwoDisplayName).swipe('left');
+ await expect(ServerListScreen.getServerItemLoginOption(serverTwoDisplayName)).toBeVisible();
+
+ // # Go back to first server
+ await ServerListScreen.getServerItemActive(serverOneDisplayName).tap();
});
});
diff --git a/detox/e2e/test/smoke_test/threads.e2e.ts b/detox/e2e/test/smoke_test/threads.e2e.ts
index 0f7fd453f1..c5ecfa63e1 100644
--- a/detox/e2e/test/smoke_test/threads.e2e.ts
+++ b/detox/e2e/test/smoke_test/threads.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -37,12 +36,6 @@ describe('Smoke Test - Threads', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
diff --git a/detox/e2e/test/threads/follow_and_unfollow_thread.e2e.ts b/detox/e2e/test/threads/follow_and_unfollow_thread.e2e.ts
index bcf735017b..5a8b8172e4 100644
--- a/detox/e2e/test/threads/follow_and_unfollow_thread.e2e.ts
+++ b/detox/e2e/test/threads/follow_and_unfollow_thread.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -36,12 +35,6 @@ describe('Threads - Follow and Unfollow Thread', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
diff --git a/detox/e2e/test/threads/global_threads.e2e.ts b/detox/e2e/test/threads/global_threads.e2e.ts
index 42d013457c..5b3460cf87 100644
--- a/detox/e2e/test/threads/global_threads.e2e.ts
+++ b/detox/e2e/test/threads/global_threads.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -35,12 +34,6 @@ describe('Threads - Global Threads', () => {
let testUser: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
testUser = user;
@@ -75,7 +68,7 @@ describe('Threads - Global Threads', () => {
});
it('MM-T4805_2 - should be able to go to a thread a user started and followed', async () => {
- // # Create a thread started by the current user
+ // # Create a thread started by the current user which current user replied to
const parentMessage = `Message ${getRandomId()}`;
await ChannelScreen.open(channelsCategory, testChannel.name);
await ChannelScreen.postMessage(parentMessage);
@@ -100,7 +93,7 @@ describe('Threads - Global Threads', () => {
await expect(GlobalThreadsScreen.getThreadItem(parentPost.id)).toBeVisible();
await expect(GlobalThreadsScreen.getThreadItemThreadStarterUserDisplayName(parentPost.id)).toHaveText(testUser.username);
await expect(GlobalThreadsScreen.getThreadItemThreadStarterChannelDisplayName(parentPost.id)).toHaveText(testChannel.display_name.toUpperCase());
- await expect(GlobalThreadsScreen.getThreadItemFooterUnreadReplies(parentPost.id)).toHaveText('1 new reply');
+ await expect(GlobalThreadsScreen.getThreadItemFooterReplyCount(parentPost.id)).toHaveText('1 reply');
// # Tap on the thread
await GlobalThreadsScreen.getThreadItem(parentPost.id).tap();
@@ -168,7 +161,7 @@ describe('Threads - Global Threads', () => {
await expect(GlobalThreadsScreen.getThreadItem(parentPost.id)).toBeVisible();
await expect(GlobalThreadsScreen.getThreadItemThreadStarterUserDisplayName(parentPost.id)).toHaveText('sysadmin');
await expect(GlobalThreadsScreen.getThreadItemThreadStarterChannelDisplayName(parentPost.id)).toHaveText(testChannel.display_name.toUpperCase());
- await expect(GlobalThreadsScreen.getThreadItemFooterUnreadReplies(parentPost.id)).toHaveText('1 new reply');
+ await expect(GlobalThreadsScreen.getThreadItemFooterReplyCount(parentPost.id)).toHaveText('1 reply');
// # Tap on the thread
await GlobalThreadsScreen.getThreadItem(parentPost.id).tap();
diff --git a/detox/e2e/test/threads/mark_thread_as_read_and_unread.e2e.ts b/detox/e2e/test/threads/mark_thread_as_read_and_unread.e2e.ts
index b5454f8385..e58b232ff3 100644
--- a/detox/e2e/test/threads/mark_thread_as_read_and_unread.e2e.ts
+++ b/detox/e2e/test/threads/mark_thread_as_read_and_unread.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -36,12 +35,6 @@ describe('Threads - Mark Thread as Read and Unread', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
@@ -61,15 +54,16 @@ describe('Threads - Mark Thread as Read and Unread', () => {
});
it('MM-T4807_1 - should be able to mark a thread as read by opening thread', async () => {
- // # Create a thread, go back to channel list screen, then go to global threads screen, and tap on unread threads button
+ // # Create a thread started by the current user which another user replied to, go back to channel list screen, then go to global threads screen, and tap on unread threads button
const parentMessage = `Message ${getRandomId()}`;
await ChannelScreen.open(channelsCategory, testChannel.name);
await ChannelScreen.postMessage(parentMessage);
const {post: parentPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
- await ChannelScreen.openReplyThreadFor(parentPost.id, parentMessage);
- const replyMessage = `${parentMessage} reply`;
- await ThreadScreen.postMessage(replyMessage);
- await ThreadScreen.back();
+ await Post.apiCreatePost(siteOneUrl, {
+ channelId: testChannel.id,
+ message: `${parentMessage} reply`,
+ rootId: parentPost.id,
+ });
await ChannelScreen.back();
await device.reloadReactNative();
await GlobalThreadsScreen.open();
@@ -100,15 +94,16 @@ describe('Threads - Mark Thread as Read and Unread', () => {
});
it('MM-T4807_2 - should be able to mark a thread as read/unread via thread options', async () => {
- // # Create a thread, go back to channel list screen, then go to global threads screen, and tap on unread threads button
+ // # Create a thread started by the current user which another user replied to, go back to channel list screen, then go to global threads screen, and tap on unread threads button
const parentMessage = `Message ${getRandomId()}`;
await ChannelScreen.open(channelsCategory, testChannel.name);
await ChannelScreen.postMessage(parentMessage);
const {post: parentPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
- await ChannelScreen.openReplyThreadFor(parentPost.id, parentMessage);
- const replyMessage = `${parentMessage} reply`;
- await ThreadScreen.postMessage(replyMessage);
- await ThreadScreen.back();
+ await Post.apiCreatePost(siteOneUrl, {
+ channelId: testChannel.id,
+ message: `${parentMessage} reply`,
+ rootId: parentPost.id,
+ });
await ChannelScreen.back();
await device.reloadReactNative();
await GlobalThreadsScreen.open();
@@ -148,15 +143,16 @@ describe('Threads - Mark Thread as Read and Unread', () => {
});
it('MM-T4807_3 - should be able to mark all threads as read', async () => {
- // # Create a thread, go back to channel list screen, then go to global threads screen, and tap on unread threads button
+ // # Create a thread started by the current user which another user replied to, go back to channel list screen, then go to global threads screen, and tap on unread threads button
const parentMessage = `Message ${getRandomId()}`;
await ChannelScreen.open(channelsCategory, testChannel.name);
await ChannelScreen.postMessage(parentMessage);
const {post: parentPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
- await ChannelScreen.openReplyThreadFor(parentPost.id, parentMessage);
- const replyMessage = `${parentMessage} reply`;
- await ThreadScreen.postMessage(replyMessage);
- await ThreadScreen.back();
+ await Post.apiCreatePost(siteOneUrl, {
+ channelId: testChannel.id,
+ message: `${parentMessage} reply`,
+ rootId: parentPost.id,
+ });
await ChannelScreen.back();
await device.reloadReactNative();
await GlobalThreadsScreen.open();
diff --git a/detox/e2e/test/threads/open_thread_in_channel.e2e.ts b/detox/e2e/test/threads/open_thread_in_channel.e2e.ts
index 22af7da78b..86467ea62f 100644
--- a/detox/e2e/test/threads/open_thread_in_channel.e2e.ts
+++ b/detox/e2e/test/threads/open_thread_in_channel.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -36,12 +35,6 @@ describe('Threads - Open Thread in Channel', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
diff --git a/detox/e2e/test/threads/reply_to_thread.e2e.ts b/detox/e2e/test/threads/reply_to_thread.e2e.ts
index d60a6bb74f..60d547a8ab 100644
--- a/detox/e2e/test/threads/reply_to_thread.e2e.ts
+++ b/detox/e2e/test/threads/reply_to_thread.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -35,12 +34,6 @@ describe('Threads - Reply to Thread', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;
diff --git a/detox/e2e/test/threads/save_and_unsave_thread.e2e.ts b/detox/e2e/test/threads/save_and_unsave_thread.e2e.ts
index c529573afb..4ef5ce1878 100644
--- a/detox/e2e/test/threads/save_and_unsave_thread.e2e.ts
+++ b/detox/e2e/test/threads/save_and_unsave_thread.e2e.ts
@@ -10,7 +10,6 @@
import {
Post,
Setup,
- System,
} from '@support/server_api';
import {
serverOneUrl,
@@ -36,12 +35,6 @@ describe('Threads - Save and Unsave Thread', () => {
let testChannel: any;
beforeAll(async () => {
- System.apiUpdateConfig(siteOneUrl, {
- ServiceSettings: {
- CollapsedThreads: 'default_on',
- },
- });
-
const {channel, user} = await Setup.apiInit(siteOneUrl);
testChannel = channel;