MM-30428 Detox/E2E: Add e2e for MM-T3199, MM-T3223, MM-T3224 (#5240)

* MM-30428 Detox/E2E: Add e2e for MM-T3199, MM-T3223, MM-T3224

* Updated variables to better names
This commit is contained in:
Joseph Baylon 2021-03-24 07:13:10 -07:00 committed by GitHub
parent e75d3673cc
commit 48d4775907
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 235 additions and 18 deletions

View file

@ -51,8 +51,14 @@ export default class Reaction extends PureComponent {
textStyle={{color: 'black', fontWeight: 'bold'}}
customEmojiStyle={{marginHorizontal: 3}}
padding={5}
testID={`reaction.emoji.${emojiName}`}
/>
<Text style={styles.count}>{count}</Text>
<Text
style={styles.count}
testID={`reaction.emoji.${emojiName}.count`}
>
{count}
</Text>
</TouchableWithFeedback>
);
}

View file

@ -12,6 +12,7 @@ exports[`AddReaction should match snapshot 1`] = `
<Connect(EmojiPicker)
deviceWidth={750}
onEmojiPress={[Function]}
testID="add_reaction.emoji_picker"
/>
</View>
`;

View file

@ -68,6 +68,7 @@ const AddReaction = (props) => {
<EmojiPicker
deviceWidth={width}
onEmojiPress={handleEmojiPress}
testID='add_reaction.emoji_picker'
/>
</View>
);

View file

@ -120,6 +120,7 @@ exports[`channel_info_header should match snapshot 1`] = `
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -182,6 +183,7 @@ exports[`channel_info_header should match snapshot 1`] = `
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {
@ -453,6 +455,7 @@ exports[`channel_info_header should match snapshot when DM and hasGuests and is
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -515,6 +518,7 @@ exports[`channel_info_header should match snapshot when DM and hasGuests and is
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {
@ -758,6 +762,7 @@ exports[`channel_info_header should match snapshot when DM and hasGuests but its
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -820,6 +825,7 @@ exports[`channel_info_header should match snapshot when DM and hasGuests but its
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {
@ -1091,6 +1097,7 @@ exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = `
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -1153,6 +1160,7 @@ exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = `
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {
@ -1396,6 +1404,7 @@ exports[`channel_info_header should match snapshot when is group constrained 1`]
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -1458,6 +1467,7 @@ exports[`channel_info_header should match snapshot when is group constrained 1`]
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {
@ -1750,6 +1760,7 @@ exports[`channel_info_header should match snapshot when public channel and hasGu
"lineHeight": 20,
}
}
testID="channel_info.header.purpose"
>
Purpose string
</Text>
@ -1812,6 +1823,7 @@ exports[`channel_info_header should match snapshot when public channel and hasGu
disableGallery={true}
onChannelLinkPress={[MockFunction]}
onPermalinkPress={[MockFunction]}
testID="channel_info.header.header"
textStyles={
Object {
"code": Object {

View file

@ -188,7 +188,10 @@ export default class ChannelInfoHeader extends React.PureComponent {
id='channel_info.purpose'
defaultMessage='Purpose'
/>
<Text style={baseTextStyle}>
<Text
style={baseTextStyle}
testID={`${testID}.purpose`}
>
{purpose}
</Text>
</View>
@ -216,6 +219,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
value={header}
onChannelLinkPress={popToRoot}
disableAtChannelMentionHighlight={true}
testID={`${testID}.header`}
/>
</View>
</TouchableHighlight>

View file

@ -37,7 +37,7 @@ class PostOptions {
slideUpPanel = element(by.id(this.testID.slideUpPanel));
toBeVisible = async () => {
await expect(this.postOptions).toBeVisible();
await expect(this.postOptions).toExist();
return postOptions;
}

View file

@ -1,17 +1,27 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {PostOptions} from '@support/ui/component';
import {
PostOptions,
SearchBar,
} from '@support/ui/component';
class AddReactionScreen {
testID = {
addReactionScreen: 'add_reaction.screen',
addReactionEmojiPickerPrefix: 'add_reaction.emoji_picker.',
closeAddReactionButton: 'close.add_reaction.button',
}
addReactionScreen = element(by.id(this.testID.addReactionScreen));
closeAddReactionButton = element(by.id(this.testID.closeAddReactionButton));
// convenience props
searchBar = SearchBar.getSearchBar(this.testID.addReactionEmojiPickerPrefix);
searchInput = SearchBar.getSearchInput(this.testID.addReactionEmojiPickerPrefix);
cancelButton = SearchBar.getCancelButton(this.testID.addReactionEmojiPickerPrefix);
clearButton = SearchBar.getClearButton(this.testID.addReactionEmojiPickerPrefix);
toBeVisible = async () => {
await expect(this.addReactionScreen).toBeVisible();

View file

@ -10,8 +10,10 @@ class ChannelInfoScreen {
channelInfoScreen: 'channel_info.screen',
channelInfoScrollView: 'channel_info.scroll_view',
closeChannelInfoButton: 'close.channel_info.button',
headerChannelIconGMMemberCount: 'channel_info.header.channel_icon.gm_member_count',
headerDisplayName: 'channel_info.header.display_name',
channelIconGMMemberCount: 'channel_info.header.channel_icon.gm_member_count',
channelDisplayName: 'channel_info.header.display_name',
channelHeader: 'channel_info.header.header',
channelPurpose: 'channel_info.header.purpose',
favoritePreferenceAction: 'channel_info.favorite.action',
favoriteSwitchFalse: 'channel_info.favorite.action.switch.false',
favoriteSwitchTrue: 'channel_info.favorite.action.switch.true',
@ -34,8 +36,10 @@ class ChannelInfoScreen {
channelInfoScreen = element(by.id(this.testID.channelInfoScreen));
channelInfoScrollView = element(by.id(this.testID.channelInfoScrollView));
closeChannelInfoButton = element(by.id(this.testID.closeChannelInfoButton));
headerChannelIconGMMemberCount = element(by.id(this.testID.headerChannelIconGMMemberCount));
headerDisplayName = element(by.id(this.testID.headerDisplayName));
channelIconGMMemberCount = element(by.id(this.testID.channelIconGMMemberCount));
channelDisplayName = element(by.id(this.testID.channelDisplayName));
channelHeader = element(by.id('markdown_text').withAncestor(by.id(this.testID.channelHeader)));
channelPurpose = element(by.id(this.testID.channelPurpose));
favoritePreferenceAction = element(by.id(this.testID.favoritePreferenceAction));
favoriteSwitchFalse = element(by.id(this.testID.favoriteSwitchFalse));
favoriteSwitchTrue = element(by.id(this.testID.favoriteSwitchTrue));

View file

@ -52,7 +52,7 @@ describe('Channel Info Header', () => {
await ChannelInfoScreen.open();
// * Verify GM member count is 3
await expect(ChannelInfoScreen.headerChannelIconGMMemberCount).toHaveText('3');
await expect(ChannelInfoScreen.channelIconGMMemberCount).toHaveText('3');
// # Close channel info screen
await ChannelInfoScreen.close();

View file

@ -50,7 +50,7 @@ describe('Guest Experience', () => {
await expect(postListPostItemHeaderGuestTag).not.toBeVisible();
});
it('MM-T1397 Guest tag in search in:', async () => {
xit('MM-T1397 Guest tag in search in:', async () => { // Disabled due to https://mattermost.atlassian.net/browse/MM-33854
const {
getSearchResultPostItem,
searchInSection,

View file

@ -7,8 +7,20 @@
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {ChannelScreen, PermalinkScreen} from '@support/ui/screen';
import {User, Setup, Channel, Post} from '@support/server_api';
import {
ChannelScreen,
PermalinkScreen,
} from '@support/ui/screen';
import {
timeouts,
wait,
} from '@support/utils';
import {
Channel,
Post,
Setup,
User,
} from '@support/server_api';
describe('Permalink', () => {
let testUser;
@ -43,6 +55,7 @@ describe('Permalink', () => {
// # Tap the channel permalink
await element(by.text(permalinkLabel)).tap({x: 5, y: 10});
await wait(timeouts.ONE_SEC);
// * Verify permalink post list has the expected target message
await PermalinkScreen.toBeVisible();

View file

@ -30,6 +30,8 @@ import {
import {
getAdminAccount,
getRandomId,
timeouts,
wait,
} from '@support/utils';
describe('Messaging', () => {
@ -63,7 +65,7 @@ describe('Messaging', () => {
const channelPermalink = `${serverUrl}/${testTeam.name}/channels/${testChannel.name}`;
// # Post the channel permalink to the test channel in Town Square
await postMessage(channelPermalink, {quickReplace: true});
await postMessage(channelPermalink);
await expect(element(by.text(channelPermalink))).toBeVisible();
// # Create another user in the same team, log in and go to town square
@ -114,7 +116,7 @@ describe('Messaging', () => {
// # Post Private Channel 2's POST Permalink
const message2 = `${serverUrl}/${testTeam.name}/pl/${post.id}`;
await postMessage(message2, {quickReplace: true});
await postMessage(message2);
// * Check that message is successfully posted
await expect(element(by.text(message2))).toExist();
@ -186,4 +188,5 @@ async function joinPrivateChannel() {
async function tapLink(message) {
const permalinkPost = element(by.text(message));
await permalinkPost.tap({x: 5, y: 10});
await wait(timeouts.ONE_SEC);
}

View file

@ -0,0 +1,96 @@
// 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 {
AddReactionScreen,
ChannelScreen,
} from '@support/ui/screen';
import {
Channel,
Post,
Setup,
Team,
User,
} from '@support/server_api';
describe('Add Reaction', () => {
let testChannel;
let testOtherUser;
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: testChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({user: testOtherUser} = await User.apiCreateUser());
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T3223 should be able to add a reaction to a post using long press and +:', async () => {
const {
openPostOptionsFor,
postMessage,
} = ChannelScreen;
const {searchInput} = AddReactionScreen;
// # Post a message
const message = Date.now().toString();
await postMessage(message);
// # Add a reaction to the post using long press
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
await openPostOptionsFor(post.id, message);
await AddReactionScreen.open();
await searchInput.typeText(':fox_face:');
await element(by.text('🦊')).tap();
// # Add a reaction to the post using +:
await postMessage('+:dog:');
// * Verify emojis are added to post
await expect(element(by.text('🦊').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toExist();
await expect(element(by.text('🐶').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toExist();
// * Verify emoji exists in recently used section
await openPostOptionsFor(post.id, message);
await AddReactionScreen.open();
await expect(element(by.text('🦊').withAncestor(by.id('RECENTLY USED')))).toExist();
await expect(element(by.text('🐶').withAncestor(by.id('RECENTLY USED')))).toExist();
// # Close add reaction screen
await AddReactionScreen.close();
});
it('MM-T3224 should be able to remove own reaction and add to another user reaction', async () => {
// # Tap on own reaction to remove
await element(by.text('🦊')).tap();
// * Verify own reaction is removed
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
await expect(element(by.text('🦊').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).not.toExist();
// # Login as new user
await ChannelScreen.logout();
await ChannelScreen.open(testOtherUser);
// # Add the same existing reaction
await expect(element(by.id('reaction.emoji.dog.count'))).toHaveText('1');
await element(by.text('🐶')).tap();
// * Verify count incremented
await expect(element(by.id('reaction.emoji.dog.count'))).toHaveText('2');
});
});

View file

@ -63,6 +63,7 @@ describe('Channels', () => {
({channel: nonJoinedChannel} = await Channel.apiCreateChannel({type: 'O', prefix: '1-non-joined-channel', teamId: team.id}));
({user: dmOtherUser} = await User.apiCreateUser({prefix: 'testchannel-1'}));
await Team.apiAddUserToTeam(dmOtherUser.id, team.id);
({channel: directMessageChannel} = await Channel.apiCreateDirectChannel([user.id, dmOtherUser.id]));
await Post.apiCreatePost({
channelId: directMessageChannel.id,

View file

@ -66,7 +66,7 @@ describe('Direct Messages', () => {
// * Verify DM channel is created
await ChannelInfoScreen.open();
await expect(ChannelInfoScreen.headerDisplayName).toHaveText(testOtherUser.username);
await expect(ChannelInfoScreen.channelDisplayName).toHaveText(testOtherUser.username);
await ChannelInfoScreen.close();
await goToChannel(testOtherUser.username);

View file

@ -0,0 +1,65 @@
// 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,
ChannelInfoScreen,
EditChannelScreen,
} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Edit Channel', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T3199 should be able to edit public channel', async () => {
const {
editChannelScreen,
headerInput,
nameInput,
purposeInput,
saveButton,
} = EditChannelScreen;
const {
channelDisplayName,
channelPurpose,
} = ChannelInfoScreen;
// # Open edit channel screen
await ChannelInfoScreen.open();
await EditChannelScreen.open();
// # Edit channel info
await nameInput.typeText(' name');
await purposeInput.typeText('purpose');
await editChannelScreen.scrollTo('bottom');
await headerInput.typeText('header1');
await headerInput.tapReturnKey();
await headerInput.typeText('header2');
// # Save changes
await saveButton.tap();
// * Verify changes have been saved
await expect(channelDisplayName).toHaveText('Town Square name');
await expect(channelPurpose).toHaveText('purpose');
await expect(element(by.text('header1\nheader2'))).toBeVisible();
// # Close channel info screen
await ChannelInfoScreen.close();
});
});

View file

@ -79,7 +79,7 @@ describe('Group Messages', () => {
// * Verify GM channel is created
await ChannelInfoScreen.open();
await expect(ChannelInfoScreen.headerDisplayName).toHaveText(`${testOtherUser1.username}, ${testOtherUser2.username}`);
await expect(ChannelInfoScreen.channelDisplayName).toHaveText(`${testOtherUser1.username}, ${testOtherUser2.username}`);
await ChannelInfoScreen.close();
// * Verify current user can post message to GM channel

View file

@ -82,11 +82,11 @@ describe('Message Posting', () => {
it('MM-T3225 should be able to post a jumbo emoji', async () => {
// # Post a jumbo emoji
const message = ':fox_face:';
await postMessage(message, {quickReplace: true});
await postMessage(message);
// * Verify message is posted
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
const {postListPostItem} = await getPostListPostItem(post.id);
const {postListPostItem} = await getPostListPostItem(post.id, '🦊');
await expect(postListPostItem).toBeVisible();
});
});

View file

@ -41,6 +41,7 @@ describe('Select Team', () => {
it('MM-T3619 should be able to select a team', async () => {
// # Tap on team to join
await waitFor(SelectTeamScreen.getTeamByDisplayName(testTeam.display_name)).toBeVisible().whileElement(by.id(SelectTeamScreen.testID.teamsList)).scroll(500, 'down');
const team = await SelectTeamScreen.getTeamByDisplayName(testTeam.display_name);
await team.tap();