MM-35681 Detox/E2E: Add e2e for bot account, mention badges, at mention (#5539)
* MM-35681 Detox/E2E: Add e2e for bot account, mention badges, at mention * Fix return for apiUpdateUserActiveStatus * Fix param comment for apiCreateBot * Move it blocks to the top
This commit is contained in:
parent
2cd2ddbf5f
commit
8c8348ea0b
15 changed files with 364 additions and 25 deletions
|
|
@ -31,6 +31,7 @@ const HeaderTag = ({
|
|||
return (
|
||||
<BotTag
|
||||
style={style.tag}
|
||||
testID='post_header.bot_tag'
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
58
detox/e2e/support/server_api/bot.js
Normal file
58
detox/e2e/support/server_api/bot.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {capitalize, getRandomId} from '@support/utils';
|
||||
|
||||
import client from './client';
|
||||
import {getResponseFromError} from './common';
|
||||
|
||||
// ****************************************************************
|
||||
// Bots
|
||||
// See https://api.mattermost.com/#tag/bots
|
||||
//
|
||||
// Exported API function should have the following:
|
||||
// - documented using JSDoc
|
||||
// - meaningful description
|
||||
// - match the referenced API endpoints
|
||||
// - parameter/s defined by `@param`
|
||||
// - return value defined by `@return`
|
||||
// ****************************************************************
|
||||
|
||||
/**
|
||||
* Create a bot.
|
||||
* See https://api.mattermost.com/#operation/CreateBot
|
||||
* @param {string} option.prefix - prefix to username and display name
|
||||
* @param {Object} option.bot - bot object to be created
|
||||
* @return {Object} returns {bot} on success or {error, status} on error
|
||||
*/
|
||||
export const apiCreateBot = async ({prefix = 'bot', bot = null} = {}) => {
|
||||
try {
|
||||
const newBot = bot || generateRandomBot({prefix});
|
||||
|
||||
const response = await client.post(
|
||||
'/api/v4/bots',
|
||||
newBot,
|
||||
);
|
||||
|
||||
return {bot: response.data};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const generateRandomBot = ({prefix = 'bot', randomIdLength = 6} = {}) => {
|
||||
const randomId = getRandomId(randomIdLength);
|
||||
|
||||
return {
|
||||
username: `${prefix}-${randomId}`,
|
||||
display_name: `${capitalize(prefix)} ${randomId}`,
|
||||
description: `Test bot description ${randomId}`,
|
||||
};
|
||||
};
|
||||
|
||||
export const Bot = {
|
||||
apiCreateBot,
|
||||
generateRandomBot,
|
||||
};
|
||||
|
||||
export default Bot;
|
||||
|
|
@ -43,8 +43,8 @@ export const apiAddUserToChannel = async (userId, channelId) => {
|
|||
* See https://api.mattermost.com/#operation/CreateChannel
|
||||
* @param {string} option.teamId - The team ID of the team to create the channel on
|
||||
* @param {string} option.type - 'O' (default) for a public channel, 'P' for a private channel
|
||||
* @param {string} option.prefix - option to add prefix to name and display name
|
||||
* @param {Object} option.channel - fix channel object to be created
|
||||
* @param {string} option.prefix - prefix to name, display name, purpose, and header
|
||||
* @param {Object} option.channel - channel object to be created
|
||||
* @return {Object} returns {channel} on success or {error, status} on error
|
||||
*/
|
||||
export const apiCreateChannel = async ({teamId = null, type = 'O', prefix = 'channel', channel = null} = {}) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Bot from './bot';
|
||||
import Channel from './channel';
|
||||
import Ldap from './ldap';
|
||||
import Plugin from './plugin';
|
||||
|
|
@ -13,6 +14,7 @@ import Team from './team';
|
|||
import User from './user';
|
||||
|
||||
export {
|
||||
Bot,
|
||||
Channel,
|
||||
Ldap,
|
||||
Plugin,
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ export const apiAddUserToTeam = async (userId, teamId) => {
|
|||
* Create a team.
|
||||
* See https://api.mattermost.com/#operation/CreateTeam
|
||||
* @param {string} option.type - 'O' (default) for open, 'I' for invite only
|
||||
* @param {string} option.prefix - option to add prefix to name and display name
|
||||
* @param {Object} team - fix team object to be created
|
||||
* @param {string} option.prefix - prefix to name and display name
|
||||
* @param {Object} option.team - team object to be created
|
||||
* @return {Object} returns {team} on success or {error, status} on error
|
||||
*/
|
||||
export const apiCreateTeam = async ({type = 'O', prefix = 'team', team = null} = {}) => {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ export const apiAdminLogin = () => {
|
|||
/**
|
||||
* Create a user.
|
||||
* See https://api.mattermost.com/#operation/CreateUser
|
||||
* @param {Object} user - user object to be created
|
||||
* @param {string} option.prefix - prefix to email and username
|
||||
* @param {Object} option.user - user object to be created
|
||||
* @return {Object} returns {user} on success or {error, status} on error
|
||||
*/
|
||||
export const apiCreateUser = async ({prefix = 'user', user = null} = {}) => {
|
||||
|
|
@ -194,6 +195,26 @@ export const apiPatchUser = async (userId, userData) => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update user active status.
|
||||
* See https://api.mattermost.com/#operation/UpdateUserActive
|
||||
* @param {string} userId - the user ID
|
||||
* @param {boolean} active - use true to set the user active, false for inactive
|
||||
* @return {Object} returns {status} on success or {error, status} on error
|
||||
*/
|
||||
export const apiUpdateUserActiveStatus = async (userId, active) => {
|
||||
try {
|
||||
const response = await client.put(
|
||||
`/api/v4/users/${userId}/active`,
|
||||
{active},
|
||||
);
|
||||
|
||||
return {status: response.status};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const generateRandomUser = ({prefix = 'user', randomIdLength = 6} = {}) => {
|
||||
const randomId = getRandomId(randomIdLength);
|
||||
|
||||
|
|
@ -220,6 +241,7 @@ export const User = {
|
|||
apiLogout,
|
||||
apiPatchMe,
|
||||
apiPatchUser,
|
||||
apiUpdateUserActiveStatus,
|
||||
generateRandomUser,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import ProfilePicture from './profile_picture';
|
||||
|
||||
class Autocomplete {
|
||||
testID = {
|
||||
atMentionItemPrefix: 'autocomplete.at_mention.item.',
|
||||
atMentionItemProfilePicturePrefix: 'at_mention_item.profile_picture.',
|
||||
channelMentionItemPrefix: 'autocomplete.channel_mention.item.',
|
||||
autocomplete: 'autocomplete',
|
||||
atMentionItemName: 'at_mention_item.name',
|
||||
atMentionItemProfilePicture: 'at_mention_item.profile_picture',
|
||||
atMentionItemUsername: 'at_mention_item.username',
|
||||
atMentionSuggestionList: 'at_mention_suggestion.list',
|
||||
channelMentionSuggestionList: 'channel_mention_suggestion.list',
|
||||
|
|
@ -26,7 +28,7 @@ class Autocomplete {
|
|||
getAtMentionItem = (userId) => {
|
||||
const atMentionItemMatcher = by.id(`${this.testID.atMentionItemPrefix}${userId}`);
|
||||
const atMentionItemNameMatcher = by.id(this.testID.atMentionItemName).withAncestor(atMentionItemMatcher);
|
||||
const atMentionItemProfilePictureMatcher = by.id(this.testID.atMentionItemProfilePicture).withAncestor(atMentionItemMatcher);
|
||||
const atMentionItemProfilePictureMatcher = ProfilePicture.getProfilePictureItemMatcher(this.testID.atMentionItemProfilePicturePrefix, userId).withAncestor(atMentionItemMatcher);
|
||||
const atMentionItemUsernameMatcher = by.id(this.testID.atMentionItemUsername).withAncestor(atMentionItemMatcher);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class Post {
|
|||
postHeaderCommentedOn: 'post_header.commented_on',
|
||||
postHeaderDateTime: 'post_header.date_time',
|
||||
postHeaderDisplayName: 'post_header.display_name',
|
||||
postHeaderBotTag: 'post_header.bot_tag',
|
||||
postHeaderGuestTag: 'post_header.guest_tag',
|
||||
postHeaderReply: 'post_header.reply',
|
||||
postHeaderReplyCount: 'post_header.reply.count',
|
||||
|
|
@ -58,6 +59,7 @@ class Post {
|
|||
const postItemHeaderCommentedOnMatcher = by.id(this.testID.postHeaderCommentedOn).withAncestor(postItemMatcher);
|
||||
const postItemHeaderDateTimeMatcher = by.id(this.testID.postHeaderDateTime).withAncestor(postItemMatcher);
|
||||
const postItemHeaderDisplayNameMatcher = by.id(this.testID.postHeaderDisplayName).withAncestor(postItemMatcher);
|
||||
const postItemHeaderBotTagMatcher = by.id(this.testID.postHeaderBotTag).withAncestor(postItemMatcher);
|
||||
const postItemHeaderGuestTagMatcher = by.id(this.testID.postHeaderGuestTag).withAncestor(postItemMatcher);
|
||||
const postItemHeaderReplyMatcher = by.id(this.testID.postHeaderReply).withAncestor(postItemMatcher);
|
||||
const postItemHeaderReplyCountMatcher = by.id(this.testID.postHeaderReplyCount).withAncestor(postItemMatcher);
|
||||
|
|
@ -66,6 +68,7 @@ class Post {
|
|||
postItemHeaderCommentedOn: element(postItemHeaderCommentedOnMatcher),
|
||||
postItemHeaderDateTime: element(postItemHeaderDateTimeMatcher),
|
||||
postItemHeaderDisplayName: element(postItemHeaderDisplayNameMatcher),
|
||||
postItemHeaderBotTag: element(postItemHeaderBotTagMatcher),
|
||||
postItemHeaderGuestTag: element(postItemHeaderGuestTagMatcher),
|
||||
postItemHeaderReply: element(postItemHeaderReplyMatcher),
|
||||
postItemHeaderReplyCount: element(postItemHeaderReplyCountMatcher),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class PostList {
|
|||
postItemHeaderCommentedOn,
|
||||
postItemHeaderDateTime,
|
||||
postItemHeaderDisplayName,
|
||||
postItemHeaderBotTag,
|
||||
postItemHeaderGuestTag,
|
||||
postItemHeaderReply,
|
||||
postItemHeaderReplyCount,
|
||||
|
|
@ -50,6 +51,7 @@ class PostList {
|
|||
postListPostItemHeaderCommentedOn: postItemHeaderCommentedOn,
|
||||
postListPostItemHeaderDateTime: postItemHeaderDateTime,
|
||||
postListPostItemHeaderDisplayName: postItemHeaderDisplayName,
|
||||
postListPostItemHeaderBotTag: postItemHeaderBotTag,
|
||||
postListPostItemHeaderGuestTag: postItemHeaderGuestTag,
|
||||
postListPostItemHeaderReply: postItemHeaderReply,
|
||||
postListPostItemHeaderReplyCount: postItemHeaderReplyCount,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
PostDraft,
|
||||
PostList,
|
||||
PostOptions,
|
||||
ProfilePicture,
|
||||
SendButton,
|
||||
SettingsSidebar,
|
||||
} from '@support/ui/component';
|
||||
|
|
@ -23,6 +24,7 @@ import {isAndroid} from '@support/utils';
|
|||
class ChannelScreen {
|
||||
testID = {
|
||||
channelScreenPrefix: 'channel.',
|
||||
channelIntroProfilePicturePrefix: 'channel_intro.profile_picture.',
|
||||
channelScreen: 'channel.screen',
|
||||
channelPostList: 'channel.post_list',
|
||||
mainSidebarDrawerButton: 'main_sidebar_drawer.button',
|
||||
|
|
@ -68,6 +70,11 @@ class ChannelScreen {
|
|||
|
||||
postList = new PostList(this.testID.channelScreenPrefix);
|
||||
|
||||
getChannelIntroProfilePicture = (userId) => {
|
||||
const profilePictureItemMatcher = ProfilePicture.getProfilePictureItemMatcher(this.testID.channelIntroProfilePicturePrefix, userId);
|
||||
return element(profilePictureItemMatcher);
|
||||
}
|
||||
|
||||
getMoreMessagesButton = () => {
|
||||
return this.postList.getMoreMessagesButton();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class SearchResultPostScreen {
|
|||
postItemEmoji,
|
||||
postItemHeaderDateTime,
|
||||
postItemHeaderDisplayName,
|
||||
postItemHeaderBotTag,
|
||||
postItemHeaderGuestTag,
|
||||
postItemHeaderReply,
|
||||
postItemImage,
|
||||
|
|
@ -34,6 +35,7 @@ class SearchResultPostScreen {
|
|||
searchResultPostItemEmoji: postItemEmoji,
|
||||
searchResultPostItemHeaderDateTime: postItemHeaderDateTime,
|
||||
searchResultPostItemHeaderDisplayName: postItemHeaderDisplayName,
|
||||
searchResultPostItemHeaderBotTag: postItemHeaderBotTag,
|
||||
searchResultPostItemHeaderGuestTag: postItemHeaderGuestTag,
|
||||
searchResultPostItemHeaderReply: postItemHeaderReply,
|
||||
searchResultPostItemImage: postItemImage,
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@ class UserProfileScreen {
|
|||
userProfilePicturePrefix: 'user_profile.profile_picture.',
|
||||
userProfileScreen: 'user_profile.screen',
|
||||
customStatus: 'user_profile.custom_status',
|
||||
profilePicture: 'user_profile.profile_picture',
|
||||
userProfileScrollView: 'user_profile.scroll_view',
|
||||
closeSettingsButton: 'close.settings.button',
|
||||
editButton: 'user_profile.edit.button',
|
||||
userProfileBotTag: 'user_profile.bot_tag',
|
||||
userProfileDisplayName: 'user_profile.display_name',
|
||||
userProfileGuestTag: 'user_profile.bot_tag',
|
||||
userProfileGuestTag: 'user_profile.guest_tag',
|
||||
userProfileUsername: 'user_profile.username',
|
||||
emailLabel: 'user_profile.display_block.email.label',
|
||||
emailValue: 'user_profile.display_block.email.value',
|
||||
|
|
@ -38,7 +37,6 @@ class UserProfileScreen {
|
|||
userProfileScreen = element(by.id(this.testID.userProfileScreen));
|
||||
userProfileScrollView = element(by.id(this.testID.userProfileScrollView));
|
||||
customStatus = element(by.id(this.testID.customStatus));
|
||||
profilePicture = element(by.id(this.testID.profilePicture))
|
||||
closeSettingsButton = element(by.id(this.testID.closeSettingsButton));
|
||||
editButton = element(by.id(this.testID.editButton));
|
||||
userProfileBotTag = element(by.id(this.testID.userProfileBotTag));
|
||||
|
|
|
|||
|
|
@ -9,20 +9,31 @@
|
|||
|
||||
import {Autocomplete} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {Setup} from '@support/server_api';
|
||||
import {
|
||||
Setup,
|
||||
Team,
|
||||
User,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Autocomplete', () => {
|
||||
let user;
|
||||
const {postInput} = ChannelScreen;
|
||||
const {atMentionSuggestionList} = Autocomplete;
|
||||
let testUser;
|
||||
let testOtherUser;
|
||||
let userAtMentionAutocomplete;
|
||||
let otherUserAtMentionAutocomplete;
|
||||
|
||||
beforeAll(async () => {
|
||||
({user} = await Setup.apiInit());
|
||||
({atMentionItem: userAtMentionAutocomplete} = Autocomplete.getAtMentionItem(user.id));
|
||||
const {team, user} = await Setup.apiInit();
|
||||
testUser = user;
|
||||
({atMentionItem: userAtMentionAutocomplete} = Autocomplete.getAtMentionItem(testUser.id));
|
||||
|
||||
({user: testOtherUser} = await User.apiCreateUser());
|
||||
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
|
||||
({atMentionItem: otherUserAtMentionAutocomplete} = Autocomplete.getAtMentionItem(testOtherUser.id));
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
await ChannelScreen.open(testUser);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
|
|
@ -42,7 +53,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type username
|
||||
await postInput.typeText(user.username);
|
||||
await postInput.typeText(testUser.username);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -55,7 +66,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type nickname
|
||||
await postInput.typeText(user.nickname);
|
||||
await postInput.typeText(testUser.nickname);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -68,7 +79,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type first name
|
||||
await postInput.typeText(user.first_name);
|
||||
await postInput.typeText(testUser.first_name);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -81,7 +92,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type last name
|
||||
await postInput.typeText(user.last_name);
|
||||
await postInput.typeText(testUser.last_name);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -94,7 +105,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type lowercase first name
|
||||
await postInput.typeText(user.first_name.toLowerCase());
|
||||
await postInput.typeText(testUser.first_name.toLowerCase());
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -107,7 +118,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type lowercase last name
|
||||
await postInput.typeText(user.last_name.toLowerCase());
|
||||
await postInput.typeText(testUser.last_name.toLowerCase());
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -120,7 +131,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type full name
|
||||
await postInput.typeText(`${user.first_name} ${user.last_name}`);
|
||||
await postInput.typeText(`${testUser.first_name} ${testUser.last_name}`);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -133,7 +144,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type partial full name
|
||||
await postInput.typeText(`${user.first_name} ${user.last_name.substring(0, user.last_name.length - 6)}`);
|
||||
await postInput.typeText(`${testUser.first_name} ${testUser.last_name.substring(0, testUser.last_name.length - 6)}`);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -146,7 +157,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type full name
|
||||
await postInput.typeText(`${user.first_name} ${user.last_name}`);
|
||||
await postInput.typeText(`${testUser.first_name} ${testUser.last_name}`);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(userAtMentionAutocomplete).toExist();
|
||||
|
|
@ -178,7 +189,7 @@ describe('Autocomplete', () => {
|
|||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type username
|
||||
await postInput.typeText(user.username);
|
||||
await postInput.typeText(testUser.username);
|
||||
|
||||
// # Tap user
|
||||
await userAtMentionAutocomplete.tap();
|
||||
|
|
@ -190,4 +201,36 @@ describe('Autocomplete', () => {
|
|||
await postInput.typeText('@');
|
||||
await expect(atMentionSuggestionList).toExist();
|
||||
});
|
||||
|
||||
it('MM-T511 should not be able to autocomplete deactivated user', async () => {
|
||||
// # Deactivate user
|
||||
await User.apiDeactivateUser(testOtherUser.id);
|
||||
|
||||
// # Type "@" to activate at mention autocomplete
|
||||
await postInput.typeText('@');
|
||||
await Autocomplete.toBeVisible();
|
||||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type username
|
||||
await postInput.typeText(testOtherUser.username);
|
||||
|
||||
// * Expect at mention autocomplete to not contain associated user suggestion
|
||||
await expect(otherUserAtMentionAutocomplete).not.toExist();
|
||||
|
||||
// # Reactivate user
|
||||
await User.apiUpdateUserActiveStatus(testOtherUser.id, true);
|
||||
|
||||
// # Type "@" to activate at mention autocomplete
|
||||
await postInput.clearText();
|
||||
await Autocomplete.toBeVisible(false);
|
||||
await postInput.typeText('@');
|
||||
await Autocomplete.toBeVisible();
|
||||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type username
|
||||
await postInput.typeText(testOtherUser.username);
|
||||
|
||||
// * Expect at mention autocomplete to contain associated user suggestion
|
||||
await expect(otherUserAtMentionAutocomplete).toExist();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
78
detox/e2e/test/bot_account/bot_account.e2e.js
Normal file
78
detox/e2e/test/bot_account/bot_account.e2e.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// 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 {
|
||||
ChannelScreen,
|
||||
MoreDirectMessagesScreen,
|
||||
UserProfileScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {
|
||||
Bot,
|
||||
Setup,
|
||||
Team,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Bot Account', () => {
|
||||
const {
|
||||
getChannelIntroProfilePicture,
|
||||
openMainSidebar,
|
||||
} = ChannelScreen;
|
||||
let testBot;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {team, user} = await Setup.apiInit();
|
||||
|
||||
({bot: testBot} = await Bot.apiCreateBot());
|
||||
await Team.apiAddUserToTeam(testBot.user_id, team.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T1824 should be able to show bot profile', async () => {
|
||||
const {
|
||||
getUserAtIndex,
|
||||
searchInput,
|
||||
startButton,
|
||||
} = MoreDirectMessagesScreen;
|
||||
const {
|
||||
additionalOptionsAction,
|
||||
getProfilePicture,
|
||||
localTimeLabel,
|
||||
sendMessageAction,
|
||||
userProfileBotTag,
|
||||
} = UserProfileScreen;
|
||||
|
||||
// # Create a DM with the other user
|
||||
await openMainSidebar();
|
||||
await MoreDirectMessagesScreen.open();
|
||||
await searchInput.typeText(testBot.username);
|
||||
await getUserAtIndex(0).tap();
|
||||
await startButton.tap();
|
||||
|
||||
// # Open bot profile from channel intro
|
||||
await getChannelIntroProfilePicture(testBot.user_id).tap();
|
||||
|
||||
// * Verify bot profile
|
||||
await UserProfileScreen.toBeVisible();
|
||||
await expect(element(by.text(`@${testBot.username}`))).toBeVisible();
|
||||
await expect(getProfilePicture(testBot.user_id)).toBeVisible();
|
||||
await expect(userProfileBotTag).toBeVisible();
|
||||
await expect(sendMessageAction.atIndex(0)).toBeVisible();
|
||||
await expect(additionalOptionsAction).not.toBeVisible();
|
||||
await expect(localTimeLabel).not.toBeVisible();
|
||||
|
||||
// # Go back to channel
|
||||
await UserProfileScreen.close();
|
||||
});
|
||||
});
|
||||
121
detox/e2e/test/notifications/mention_badges.e2e.js
Normal file
121
detox/e2e/test/notifications/mention_badges.e2e.js
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// 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 {MainSidebar} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Team,
|
||||
User,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Mention Badges', () => {
|
||||
const {
|
||||
channelNavBarTitle,
|
||||
closeMainSidebar,
|
||||
goToChannel,
|
||||
mainSidebarDrawerButtonBadgeUnreadCount,
|
||||
openTeamSidebar,
|
||||
} = ChannelScreen;
|
||||
const {
|
||||
closeTeamSidebar,
|
||||
getTeamByDisplayName,
|
||||
switchTeamsButtonBadgeUnreadCount,
|
||||
} = MainSidebar;
|
||||
let testChannel;
|
||||
let testPrivateChannel;
|
||||
let testPublicChannel;
|
||||
let testTeam1;
|
||||
let testTeam2;
|
||||
let testUser1;
|
||||
let testUser2;
|
||||
|
||||
beforeAll(async () => {
|
||||
({user: testUser1} = await User.apiCreateUser());
|
||||
({team: testTeam1} = await Team.apiCreateTeam({prefix: 'team-a'}));
|
||||
({channel: testChannel} = await Channel.apiGetChannelByName(testTeam1.id, 'town-square'));
|
||||
|
||||
({user: testUser2} = await User.apiCreateUser());
|
||||
({team: testTeam2} = await Team.apiCreateTeam({prefix: 'team-b'}));
|
||||
({channel: testPublicChannel} = await Channel.apiGetChannelByName(testTeam2.id, 'town-square'));
|
||||
|
||||
await Team.apiAddUserToTeam(testUser1.id, testTeam1.id);
|
||||
await Team.apiAddUserToTeam(testUser1.id, testTeam2.id);
|
||||
await Team.apiAddUserToTeam(testUser2.id, testTeam1.id);
|
||||
await Team.apiAddUserToTeam(testUser2.id, testTeam2.id);
|
||||
|
||||
({channel: testPrivateChannel} = await Channel.apiCreateChannel({type: 'P', teamId: testTeam2.id}));
|
||||
|
||||
await Channel.apiAddUserToChannel(testUser1.id, testPrivateChannel.id);
|
||||
await Channel.apiAddUserToChannel(testUser2.id, testPrivateChannel.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(testUser1);
|
||||
|
||||
// # Clear unreads and go back to original team and channel
|
||||
await openTeamSidebar();
|
||||
await getTeamByDisplayName(testTeam2.display_name).tap();
|
||||
await goToChannel(testPrivateChannel.display_name);
|
||||
await openTeamSidebar();
|
||||
await getTeamByDisplayName(testTeam1.display_name).tap();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T520_1 should display mention badges for public channel', async () => {
|
||||
await expectMentionBadges(testPublicChannel);
|
||||
});
|
||||
|
||||
it('MM-T520_2 should display mention badges for private channel', async () => {
|
||||
await expectMentionBadges(testPrivateChannel);
|
||||
});
|
||||
|
||||
const expectMentionBadges = async (messagePostedChannel) => {
|
||||
// * Verify team 1 main sidebar drawer button badge does not exist
|
||||
await expect(mainSidebarDrawerButtonBadgeUnreadCount).not.toExist();
|
||||
|
||||
// # Post an at-mention message to user 1 by user 2 on a channel
|
||||
const testMessage = `Mention @${testUser1.username}`;
|
||||
await User.apiLogin(testUser2);
|
||||
await Post.apiCreatePost({
|
||||
channelId: messagePostedChannel.id,
|
||||
message: testMessage,
|
||||
});
|
||||
|
||||
// * Verify team 1 main sidebar drawer button badge count is 1
|
||||
await expect(channelNavBarTitle).toHaveText(testChannel.display_name);
|
||||
await expect(mainSidebarDrawerButtonBadgeUnreadCount).toHaveText('1');
|
||||
|
||||
// * Verify team 2 item badge count is 1
|
||||
await openTeamSidebar();
|
||||
const {teamItemBadgeUnreadCount: team2ItemBadgeUnreadCount} = await MainSidebar.getTeam(testTeam2.id);
|
||||
await expect(team2ItemBadgeUnreadCount).toHaveText('1');
|
||||
|
||||
// * Verify team 1 item badge count does not exist
|
||||
const {teamItemBadgeUnreadCount: team1ItemBadgeUnreadCount} = await MainSidebar.getTeam(testTeam1.id);
|
||||
await expect(team1ItemBadgeUnreadCount).not.toExist();
|
||||
|
||||
// * Verify switch teams sidebar button badge count is 1
|
||||
await closeTeamSidebar();
|
||||
await expect(switchTeamsButtonBadgeUnreadCount).toHaveText('1');
|
||||
|
||||
// # Close main sidebar
|
||||
await closeMainSidebar();
|
||||
|
||||
// # Clear unreads and go back to original team and channel
|
||||
await openTeamSidebar();
|
||||
await getTeamByDisplayName(testTeam2.display_name).tap();
|
||||
await goToChannel(messagePostedChannel.display_name);
|
||||
await openTeamSidebar();
|
||||
await getTeamByDisplayName(testTeam1.display_name).tap();
|
||||
};
|
||||
});
|
||||
Loading…
Reference in a new issue