MM-35670 Detox/E2E: Add e2e for mark post unread and read (#5396)
This commit is contained in:
parent
025b019840
commit
d464f102fb
15 changed files with 373 additions and 51 deletions
|
|
@ -53,6 +53,7 @@ export default class MoreMessageButton extends React.PureComponent {
|
|||
registerScrollEndIndexListener: PropTypes.func.isRequired,
|
||||
resetUnreadMessageCount: PropTypes.func.isRequired,
|
||||
deepLinkURL: PropTypes.string,
|
||||
testID: PropTypes.string,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
|
|
@ -295,7 +296,7 @@ export default class MoreMessageButton extends React.PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {theme, loadingPosts} = this.props;
|
||||
const {theme, loadingPosts, testID} = this.props;
|
||||
|
||||
const styles = getStyleSheet(theme);
|
||||
const {moreText} = this.state;
|
||||
|
|
@ -309,6 +310,7 @@ export default class MoreMessageButton extends React.PureComponent {
|
|||
onPress={this.onMoreMessagesPress}
|
||||
underlayColor={underlayColor}
|
||||
style={styles.roundBorder}
|
||||
testID={testID}
|
||||
>
|
||||
<View style={[styles.container, styles.roundBorder]}>
|
||||
<View style={styles.iconContainer}>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ function NewMessagesDivider(props) {
|
|||
id='posts_view.newMsg'
|
||||
defaultMessage='New Messages'
|
||||
style={style.text}
|
||||
testID={props.testID}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ function NewMessagesDivider(props) {
|
|||
id='mobile.posts_view.moreMsg'
|
||||
defaultMessage='More New Messages Above'
|
||||
style={style.text}
|
||||
testID={props.testID}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -47,6 +49,7 @@ NewMessagesDivider.propTypes = {
|
|||
moreMessages: PropTypes.bool,
|
||||
style: ViewPropTypes.style,
|
||||
theme: PropTypes.object,
|
||||
testID: PropTypes.string,
|
||||
};
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
|
|
|
|||
|
|
@ -317,6 +317,7 @@ export default class PostList extends PureComponent {
|
|||
index={index}
|
||||
theme={theme}
|
||||
moreMessages={moreNewMessages && checkForPostId}
|
||||
testID={`${testID}.new_messages_divider`}
|
||||
/>
|
||||
);
|
||||
} else if (PostListUtils.isDateLine(item)) {
|
||||
|
|
@ -544,6 +545,7 @@ export default class PostList extends PureComponent {
|
|||
scrollToIndex={this.scrollToIndex}
|
||||
registerViewableItemsListener={this.registerViewableItemsListener}
|
||||
registerScrollEndIndexListener={this.registerScrollEndIndexListener}
|
||||
testID={`${testID}.more_messages_button`}
|
||||
/>
|
||||
}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -98,25 +98,6 @@ export const apiCreateGroupChannel = async (userIds = []) => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove user from channel.
|
||||
* See https://api.mattermost.com/#operation/RemoveUserFromChannel
|
||||
* @param {string} channelId - The channel ID
|
||||
* @param {string} userId - The user ID to be removed from channel
|
||||
* @return {Object} returns {status} on success or {error, status} on error
|
||||
*/
|
||||
export const apiDeleteUserFromChannel = async (channelId, userId) => {
|
||||
try {
|
||||
const response = await client.delete(
|
||||
`/api/v4/channels/${channelId}/members/${userId}`,
|
||||
);
|
||||
|
||||
return {status: response.status};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a channel by name.
|
||||
* See https://api.mattermost.com/#operation/GetChannelByName
|
||||
|
|
@ -168,6 +149,60 @@ export const apiGetChannelsForUser = async (userId, teamId) => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get unread messages.
|
||||
* See https://api.mattermost.com/#operation/GetChannelUnread
|
||||
* @param {string} userId - The user ID to perform view actions for
|
||||
* @param {string} channelId - The channel ID that is being viewed
|
||||
* @return {Object} returns response on success or {error, status} on error
|
||||
*/
|
||||
export const apiGetUnreadMessages = async (userId, channelId) => {
|
||||
try {
|
||||
return await client.get(`/api/v4/users/${userId}/channels/${channelId}/unread`);
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove user from channel.
|
||||
* See https://api.mattermost.com/#operation/RemoveUserFromChannel
|
||||
* @param {string} channelId - The channel ID
|
||||
* @param {string} userId - The user ID to be removed from channel
|
||||
* @return {Object} returns {status} on success or {error, status} on error
|
||||
*/
|
||||
export const apiRemoveUserFromChannel = async (channelId, userId) => {
|
||||
try {
|
||||
const response = await client.delete(
|
||||
`/api/v4/channels/${channelId}/members/${userId}`,
|
||||
);
|
||||
|
||||
return {status: response.status};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* View channel.
|
||||
* See https://api.mattermost.com/#operation/ViewChannel
|
||||
* @param {string} userId - The user ID to perform view actions for
|
||||
* @param {string} channelId - The channel ID that is being viewed
|
||||
* @return {Object} returns {viewed} on success or {error, status} on error
|
||||
*/
|
||||
export const apiViewChannel = async (userId, channelId) => {
|
||||
try {
|
||||
const response = await client.post(
|
||||
`/api/v4/channels/members/${userId}/view`,
|
||||
{channel_id: channelId},
|
||||
);
|
||||
|
||||
return {viewed: response.data};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
function generateRandomChannel(teamId, type, prefix) {
|
||||
const randomId = getRandomId();
|
||||
|
||||
|
|
@ -186,9 +221,11 @@ export const Channel = {
|
|||
apiCreateChannel,
|
||||
apiCreateDirectChannel,
|
||||
apiCreateGroupChannel,
|
||||
apiDeleteUserFromChannel,
|
||||
apiGetChannelByName,
|
||||
apiGetChannelsForUser,
|
||||
apiGetUnreadMessages,
|
||||
apiRemoveUserFromChannel,
|
||||
apiViewChannel,
|
||||
};
|
||||
|
||||
export default Channel;
|
||||
|
|
|
|||
|
|
@ -34,13 +34,11 @@ export const apiUploadFile = async (name, absFilePath, requestOptions = {}) => {
|
|||
formData.append(name, fs.createReadStream(absFilePath));
|
||||
|
||||
try {
|
||||
const response = await client.request({
|
||||
return await client.request({
|
||||
...requestOptions,
|
||||
data: formData,
|
||||
headers: formData.getHeaders(),
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@ import {getResponseFromError} from './common';
|
|||
/**
|
||||
* Synchronize any user attribute changes in the configured AD/LDAP server with Mattermost.
|
||||
* See https://api.mattermost.com/#operation/SyncLdap
|
||||
* @return {string} returns {status} on success or {error, status} on error
|
||||
* @return {string} returns response on success or {error, status} on error
|
||||
*/
|
||||
export const apiLDAPSync = async () => {
|
||||
try {
|
||||
const response = await client.post('/api/v4/ldap/sync');
|
||||
|
||||
return response;
|
||||
return await client.post('/api/v4/ldap/sync');
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
@ -36,13 +34,13 @@ export const apiLDAPSync = async () => {
|
|||
/**
|
||||
* Test the current AD/LDAP configuration to see if the AD/LDAP server can be contacted successfully.
|
||||
* See https://api.mattermost.com/#operation/TestLdap
|
||||
* @return {string} returns {status} on success or {error, status} on error
|
||||
* @return {Object} returns {status} on success or {error, status} on error
|
||||
*/
|
||||
export const apiLDAPTest = async () => {
|
||||
try {
|
||||
const response = await client.post('/api/v4/ldap/test');
|
||||
|
||||
return response.data;
|
||||
return {status: response.status};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,9 +57,7 @@ export const apiDisableNonPrepackagedPlugins = async () => {
|
|||
*/
|
||||
export const apiDisablePluginById = async (pluginId) => {
|
||||
try {
|
||||
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/disable`);
|
||||
|
||||
return response;
|
||||
return await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/disable`);
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
@ -73,9 +71,7 @@ export const apiDisablePluginById = async (pluginId) => {
|
|||
*/
|
||||
export const apiEnablePluginById = async (pluginId) => {
|
||||
try {
|
||||
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/enable`);
|
||||
|
||||
return response;
|
||||
return await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/enable`);
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
@ -121,9 +117,7 @@ export const apiInstallPluginFromUrl = async (pluginDownloadUrl, force = false)
|
|||
*/
|
||||
export const apiRemovePluginById = async (pluginId) => {
|
||||
try {
|
||||
const response = await client.delete(`/api/v4/plugins/${encodeURIComponent(pluginId)}`);
|
||||
|
||||
return response;
|
||||
return await client.delete(`/api/v4/plugins/${encodeURIComponent(pluginId)}`);
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
@ -138,9 +132,7 @@ export const apiRemovePluginById = async (pluginId) => {
|
|||
export const apiUploadPlugin = async (filename) => {
|
||||
try {
|
||||
const absFilePath = path.resolve(__dirname, `../../support/fixtures/${filename}`);
|
||||
const response = await apiUploadFile('plugin', absFilePath, {url: '/api/v4/plugins', method: 'POST'});
|
||||
|
||||
return response;
|
||||
return await apiUploadFile('plugin', absFilePath, {url: '/api/v4/plugins', method: 'POST'});
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,10 +74,31 @@ export const apiGetLastPostInChannel = async (channelId) => {
|
|||
return {post: posts[0]};
|
||||
};
|
||||
|
||||
/**
|
||||
* Patch a post.
|
||||
* See https://api.mattermost.com/#operation/PatchPost
|
||||
* @param {string} postId - the post ID
|
||||
* @param {Object} postData - data to partially update a post
|
||||
* @return {Object} returns {post} on success or {error, status} on error
|
||||
*/
|
||||
export const apiPatchPost = async (postId, postData) => {
|
||||
try {
|
||||
const response = await client.put(
|
||||
`/api/v4/posts/${postId}/patch`,
|
||||
postData,
|
||||
);
|
||||
|
||||
return {post: response.data};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const Post = {
|
||||
apiCreatePost,
|
||||
apiGetLastPostInChannel,
|
||||
apiGetPostsInChannel,
|
||||
apiPatchPost,
|
||||
};
|
||||
|
||||
export default Post;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ export const apiCheckSystemHealth = async () => {
|
|||
*/
|
||||
export const apiEmailTest = async () => {
|
||||
try {
|
||||
const response = await client.post('/api/v4/email/test');
|
||||
return response;
|
||||
return await client.post('/api/v4/email/test');
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
|
|
@ -174,9 +173,7 @@ export const apiUpdateConfig = async (newConfig = {}) => {
|
|||
*/
|
||||
export const apiUploadLicense = async () => {
|
||||
const absFilePath = path.resolve(__dirname, '../../support/fixtures/mattermost-license.txt');
|
||||
const response = await apiUploadFile('license', absFilePath, {url: '/api/v4/license', method: 'POST'});
|
||||
|
||||
return response;
|
||||
return apiUploadFile('license', absFilePath, {url: '/api/v4/license', method: 'POST'});
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -155,14 +155,14 @@ export const apiLogin = async (user) => {
|
|||
/**
|
||||
* Logout from the Mattermost server.
|
||||
* See https://api.mattermost.com/#operation/Logout
|
||||
* @return {Object} returns data on success
|
||||
* @return {Object} returns {status} on success
|
||||
*/
|
||||
export const apiLogout = async () => {
|
||||
const response = await client.post('/api/v4/users/logout');
|
||||
|
||||
client.defaults.headers.Cookie = '';
|
||||
|
||||
return response.data;
|
||||
return {status: response.status};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,10 +6,20 @@ import Post from './post';
|
|||
class PostList {
|
||||
constructor(screenPrefix) {
|
||||
this.testID = {
|
||||
moreMessagesButton: `${screenPrefix}post_list.more_messages_button`,
|
||||
newMessagesDivider: `${screenPrefix}post_list.new_messages_divider`,
|
||||
postListPostItem: `${screenPrefix}post_list.post`,
|
||||
};
|
||||
}
|
||||
|
||||
getMoreMessagesButton = () => {
|
||||
return element(by.id(this.testID.moreMessagesButton));
|
||||
}
|
||||
|
||||
getNewMessagesDivider = () => {
|
||||
return element(by.id(this.testID.newMessagesDivider));
|
||||
}
|
||||
|
||||
getPost = (postId, postMessage, postProfileOptions = {}) => {
|
||||
const {
|
||||
postItem,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,14 @@ class ChannelScreen {
|
|||
|
||||
postList = new PostList(this.testID.channelScreenPrefix);
|
||||
|
||||
getMoreMessagesButton = () => {
|
||||
return this.postList.getMoreMessagesButton();
|
||||
}
|
||||
|
||||
getNewMessagesDivider = () => {
|
||||
return this.postList.getNewMessagesDivider();
|
||||
}
|
||||
|
||||
getLongPostItem = (postId, text, postProfileOptions = {}) => {
|
||||
return LongPostScreen.getPost(postId, text, postProfileOptions);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ describe('Channel Moderation', () => {
|
|||
await ChannelInfoScreen.close();
|
||||
|
||||
// # Remove user while on channel
|
||||
await Channel.apiDeleteUserFromChannel(testChannel.id, testUser.id);
|
||||
await Channel.apiRemoveUserFromChannel(testChannel.id, testUser.id);
|
||||
|
||||
// * Verify user is prompted removal alert
|
||||
const removeFromChannelTitleText = `Removed from ${testChannel.display_name}`;
|
||||
|
|
@ -112,7 +112,7 @@ describe('Channel Moderation', () => {
|
|||
await goToChannel(townSquareChannel.display_name);
|
||||
|
||||
// # Remove user while on channel
|
||||
await Channel.apiDeleteUserFromChannel(testChannel.id, testOtherUser.id);
|
||||
await Channel.apiRemoveUserFromChannel(testChannel.id, testOtherUser.id);
|
||||
|
||||
// * Verify channel is not in the channels list anymore
|
||||
await openMainSidebar();
|
||||
|
|
|
|||
87
detox/e2e/test/messaging/mark_as_read.e2e.js
Normal file
87
detox/e2e/test/messaging/mark_as_read.e2e.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// 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 jestExpect from 'expect';
|
||||
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Mark As Read', () => {
|
||||
const {
|
||||
closeMainSidebar,
|
||||
goToChannel,
|
||||
openMainSidebar,
|
||||
} = ChannelScreen;
|
||||
const {hasChannelDisplayNameAtIndex} = MainSidebar;
|
||||
let testChannel;
|
||||
let testUser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, user} = await Setup.apiInit();
|
||||
testChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(testUser);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T119 should mark message as read on mobile when message was read on webapp or api', async () => {
|
||||
// # Post a new message to channel by sysadmin
|
||||
await Post.apiCreatePost({
|
||||
channelId: testChannel.id,
|
||||
message: Date.now().toString(),
|
||||
});
|
||||
|
||||
// * Verify channel has unread message
|
||||
await openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).toBeVisible();
|
||||
await hasChannelDisplayNameAtIndex(0, testChannel.display_name);
|
||||
|
||||
// # View channel on webapp or api
|
||||
await closeMainSidebar();
|
||||
await Channel.apiViewChannel(testUser.id, testChannel.id);
|
||||
|
||||
// * Verify message is read
|
||||
await openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).not.toBeVisible();
|
||||
await expect(element(by.text('PUBLIC CHANNELS'))).toBeVisible();
|
||||
await hasChannelDisplayNameAtIndex(0, testChannel.display_name);
|
||||
|
||||
// # Go back to channel
|
||||
await closeMainSidebar();
|
||||
});
|
||||
|
||||
it('MM-T120 should mark message as read on webapp or api when message was read on mobile', async () => {
|
||||
// # Post a new message to channel by sysadmin
|
||||
await Post.apiCreatePost({
|
||||
channelId: testChannel.id,
|
||||
message: Date.now().toString(),
|
||||
});
|
||||
|
||||
// * Verify unread messages on webapp or api is 1
|
||||
const beforeVisit = await Channel.apiGetUnreadMessages(testUser.id, testChannel.id);
|
||||
jestExpect(beforeVisit.data.msg_count).toEqual(1);
|
||||
|
||||
// # Visit channel on mobile
|
||||
await goToChannel(testChannel.display_name);
|
||||
|
||||
// * Verify unread messages on webapp or api is 0
|
||||
const afterVisit = await Channel.apiGetUnreadMessages(testUser.id, testChannel.id);
|
||||
jestExpect(afterVisit.data.msg_count).toEqual(0);
|
||||
});
|
||||
});
|
||||
167
detox/e2e/test/messaging/mark_as_unread.e2e.js
Normal file
167
detox/e2e/test/messaging/mark_as_unread.e2e.js
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
// 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,
|
||||
PostOptions,
|
||||
} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
Team,
|
||||
User,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Mark as Unread', () => {
|
||||
const {
|
||||
closeMainSidebar,
|
||||
getNewMessagesDivider,
|
||||
goToChannel,
|
||||
mainSidebarDrawerButtonBadgeUnreadIndicator,
|
||||
openMainSidebar,
|
||||
openTeamSidebar,
|
||||
openPostOptionsFor,
|
||||
postMessage,
|
||||
} = ChannelScreen;
|
||||
const {
|
||||
getTeamByDisplayName,
|
||||
hasChannelDisplayNameAtIndex,
|
||||
switchTeamsButtonBadgeUnreadIndicator,
|
||||
} = MainSidebar;
|
||||
let testChannel;
|
||||
let townSquareChannel;
|
||||
let testTeam1;
|
||||
let testTeam2;
|
||||
let testUser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, team, user} = await Setup.apiInit({teamOptions: {prefix: 'team-a'}});
|
||||
testChannel = channel;
|
||||
testTeam1 = team;
|
||||
testUser = user;
|
||||
|
||||
({channel: townSquareChannel} = await Channel.apiGetChannelByName(testTeam1.id, 'town-square'));
|
||||
|
||||
({team: testTeam2} = await Team.apiCreateTeam({prefix: 'team-b'}));
|
||||
await Team.apiAddUserToTeam(testUser.id, testTeam2.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(testUser);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T245 should be able to mark a post as unread', async () => {
|
||||
// # Switch channels
|
||||
await goToChannel(testChannel.display_name);
|
||||
await goToChannel(townSquareChannel.display_name);
|
||||
|
||||
// # Post a message
|
||||
const message = Date.now().toString();
|
||||
await postMessage(message);
|
||||
|
||||
// # Mark post as unread
|
||||
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
|
||||
await openPostOptionsFor(post.id, message);
|
||||
await PostOptions.markUnreadAction.tap();
|
||||
|
||||
// * Verify new messages divider is visible
|
||||
await expect(getNewMessagesDivider()).toBeVisible();
|
||||
|
||||
// * Verify drawer button badge unread indicator
|
||||
await expect(mainSidebarDrawerButtonBadgeUnreadIndicator).toExist();
|
||||
|
||||
// * Verify team item badge unread indicator
|
||||
await openTeamSidebar();
|
||||
const {teamItemBadgeUnreadIndicator} = await MainSidebar.getTeam(testTeam1.id);
|
||||
await expect(teamItemBadgeUnreadIndicator).toExist();
|
||||
|
||||
// # Switch teams
|
||||
await getTeamByDisplayName(testTeam2.display_name).tap();
|
||||
|
||||
// * Verify switch teams button badge unread indicator
|
||||
await openMainSidebar();
|
||||
await expect(switchTeamsButtonBadgeUnreadIndicator).toExist();
|
||||
|
||||
// # Go back to channel
|
||||
await closeMainSidebar();
|
||||
});
|
||||
|
||||
it('MM-T258 should maintain unread state on app reopen', async () => {
|
||||
// # Go to team 1 test channel
|
||||
await openTeamSidebar();
|
||||
await getTeamByDisplayName(testTeam1.display_name).tap();
|
||||
await goToChannel(testChannel.display_name);
|
||||
|
||||
// # Post a message
|
||||
const message = Date.now().toString();
|
||||
await postMessage(message);
|
||||
|
||||
// # Mark post as unread and switch channels
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
await openPostOptionsFor(post.id, message);
|
||||
await PostOptions.markUnreadAction.tap();
|
||||
await goToChannel(townSquareChannel.display_name);
|
||||
|
||||
// * Verify channel has unread message
|
||||
await openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).toBeVisible();
|
||||
await hasChannelDisplayNameAtIndex(0, testChannel.display_name);
|
||||
|
||||
// # Send app to home and relaunch
|
||||
await closeMainSidebar();
|
||||
await device.sendToHome();
|
||||
await device.launchApp({newInstance: false});
|
||||
|
||||
// * Verify unread state is maintained
|
||||
await openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).toBeVisible();
|
||||
await hasChannelDisplayNameAtIndex(0, testChannel.display_name);
|
||||
|
||||
// # Go back to channel
|
||||
await closeMainSidebar();
|
||||
});
|
||||
|
||||
it('MM-T245 should be able to mark a DM post as unread', async () => {
|
||||
const {user: dmOtherUser} = await User.apiCreateUser();
|
||||
await Team.apiAddUserToTeam(dmOtherUser.id, testTeam1.id);
|
||||
const {channel: directMessageChannel} = await Channel.apiCreateDirectChannel([testUser.id, dmOtherUser.id]);
|
||||
|
||||
// # Post DM from other user
|
||||
const message = Date.now().toString();
|
||||
await User.apiLogin(dmOtherUser);
|
||||
const {post} = await Post.apiCreatePost({
|
||||
channelId: directMessageChannel.id,
|
||||
message,
|
||||
});
|
||||
|
||||
// # Switch channels
|
||||
await goToChannel(testChannel.display_name);
|
||||
await goToChannel(dmOtherUser.username);
|
||||
|
||||
// # Mark DM post as unread
|
||||
await openPostOptionsFor(post.id, message);
|
||||
await PostOptions.markUnreadAction.tap();
|
||||
|
||||
// * Verify new messages divider is visible
|
||||
await expect(getNewMessagesDivider()).toBeVisible();
|
||||
|
||||
// * Verify channel has unread message
|
||||
await openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).toBeVisible();
|
||||
await hasChannelDisplayNameAtIndex(0, dmOtherUser.username);
|
||||
|
||||
// # Go back to channel
|
||||
await closeMainSidebar();
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue