MM-29046 Add unit and e2e tests for autocomplete popover (#4855)

* WIP: Adding autocomplete E2E tests

* Fixing search.e2e tests

* Updated testIDs, added 2 test suites, added comments

* Added comments to search E2E test

* Updating testIDs & reverting changes to common.js

* Updating snapshots

* Added TM4J ticket numbers

* Adding assertion commends to search E2E

* Updated testID values
This commit is contained in:
Andre Vasconcelos 2020-10-12 21:07:23 +09:00 committed by GitHub
parent 335a25b516
commit c6c0d33f6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 197 additions and 1 deletions

View file

@ -265,6 +265,7 @@ export default class AtMention extends PureComponent {
return (
<SectionList
testID='autocomplete.at_mention.list'
keyboardShouldPersistTaps='always'
keyExtractor={this.keyExtractor}
style={[style.listView, {maxHeight: maxListHeight}]}

View file

@ -220,6 +220,7 @@ export default class ChannelMention extends PureComponent {
return (
<SectionList
testID='autocomplete.channel_mention.list'
keyboardShouldPersistTaps='always'
keyExtractor={this.keyExtractor}
style={[style.listView, {maxHeight: maxListHeight}]}

View file

@ -158,6 +158,7 @@ export default class DateSuggestion extends PureComponent {
>
{Boolean(calendarWidth) &&
<CalendarList
testID='autocomplete.date_suggestion'
current={currentDate}
maxDate={currentDate}
pastScrollRange={24}

View file

@ -3051,6 +3051,7 @@ exports[`components/autocomplete/emoji_suggestion should match snapshot 2`] = `
},
]
}
testID="autocomplete.emoji_suggestion.list"
updateCellsBatchingPeriod={50}
windowSize={21}
/>

View file

@ -226,6 +226,7 @@ export default class EmojiSuggestion extends PureComponent {
return (
<FlatList
testID='autocomplete.emoji_suggestion.list'
keyboardShouldPersistTaps='always'
style={[style.listView, {maxHeight: maxListHeight}]}
extraData={this.state}

View file

@ -204,6 +204,7 @@ export default class SlashSuggestion extends PureComponent {
return (
<FlatList
testID='autocomplete.slash_suggestion'
keyboardShouldPersistTaps='always'
style={[style.listView, {maxHeight: maxListHeight}]}
extraData={this.state}

View file

@ -276,6 +276,7 @@ exports[`EditChannelInfo should match snapshot 1`] = `
},
]
}
testID="edit_channel.header.input"
textAlignVertical="top"
underlineColorAndroid="transparent"
value="header"

View file

@ -336,6 +336,7 @@ export default class EditChannelInfo extends PureComponent {
</View>
<View style={[style.inputContainer, padding(isLandscape)]}>
<TextInputWithLocalizedPlaceholder
testID={'edit_channel.header.input'}
ref={this.headerInput}
value={header}
onChangeText={this.onHeaderChangeText}

View file

@ -311,6 +311,7 @@ export default class Search extends PureComponent {
]}
>
<SearchBar
testID='search.bar'
autoCapitalize={this.props.autoCapitalize}
autoCorrect={false}
autoFocus={this.props.autoFocus}

View file

@ -19,6 +19,7 @@ exports[`ChannelSearchButton should match, full snapshot 1`] = `
"flex": 1,
}
}
testID="channel.search.button"
>
<View
style={

View file

@ -62,6 +62,7 @@ export default class ChannelSearchButton extends PureComponent {
return (
<View style={style.container}>
<TouchableOpacity
testID={'channel.search.button'}
accessible={true}
accessibilityHint={accessibilityHint}
accessibilityLabel={accessibilityLabel}

View file

@ -7,6 +7,7 @@ exports[`ChannelTitle should match snapshot 1`] = `
"flex": 1,
}
}
testID="channel.title.button"
>
<View
style={
@ -57,6 +58,7 @@ exports[`ChannelTitle should match snapshot when is DM and has guests and the te
"flex": 1,
}
}
testID="channel.title.button"
>
<View
style={
@ -132,6 +134,7 @@ exports[`ChannelTitle should match snapshot when is DM and has guests but the te
"flex": 1,
}
}
testID="channel.title.button"
>
<View
style={
@ -182,6 +185,7 @@ exports[`ChannelTitle should match snapshot when isSelfDMChannel is true 1`] = `
"flex": 1,
}
}
testID="channel.title.button"
>
<View
style={

View file

@ -151,6 +151,7 @@ export default class ChannelTitle extends PureComponent {
return (
<TouchableOpacity
testID={'channel.title.button'}
style={style.container}
onPress={onPress}
>

View file

@ -65,6 +65,7 @@ exports[`EditPost should match snapshot 1`] = `
},
]
}
testID="edit_post.input"
underlineColorAndroid="transparent"
/>
</View>

View file

@ -255,6 +255,7 @@ export default class EditPost extends PureComponent {
{displayError}
<View style={[inputContainerStyle, padding(isLandscape), {height}]}>
<TextInputWithLocalizedPlaceholder
testID='edit_post.input'
ref={this.messageRef}
value={message}
blurOnSubmit={false}

View file

@ -39,7 +39,10 @@ export default class Modifier extends PureComponent {
underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)}
onPress={this.handlePress}
>
<View style={style.modifierItemContainer}>
<View
testID={item.testID}
style={style.modifierItemContainer}
>
<View style={[style.modifierItemWrapper, padding(isLandscape)]}>
<View style={style.modifierItemLabelContainer}>
<View style={style.modifierLabelIconContainer}>

View file

@ -597,6 +597,7 @@ export default class Search extends PureComponent {
const sectionsData = [{
value: 'from:',
testID: 'search_from.section',
modifier: `from:${intl.formatMessage({id: 'mobile.search.from_modifier_title', defaultMessage: 'username'})}`,
description: intl.formatMessage({
id: 'mobile.search.from_modifier_description',
@ -604,6 +605,7 @@ export default class Search extends PureComponent {
}),
}, {
value: 'in:',
testID: 'search_in.section',
modifier: `in:${intl.formatMessage({id: 'mobile.search.in_modifier_title', defaultMessage: 'channel-name'})}`,
description: intl.formatMessage({
id: 'mobile.search.in_modifier_description',
@ -615,6 +617,7 @@ export default class Search extends PureComponent {
if (this.props.enableDateSuggestion) {
sectionsData.push({
value: 'on:',
testID: 'search_on.section',
modifier: 'on: YYYY-MM-DD',
description: intl.formatMessage({
id: 'mobile.search.on_modifier_description',
@ -623,6 +626,7 @@ export default class Search extends PureComponent {
});
sectionsData.push({
value: 'after:',
testID: 'search_after.section',
modifier: 'after: YYYY-MM-DD',
description: intl.formatMessage({
id: 'mobile.search.after_modifier_description',
@ -631,6 +635,7 @@ export default class Search extends PureComponent {
});
sectionsData.push({
value: 'before:',
testID: 'search_before.section',
modifier: 'before: YYYY-MM-DD',
description: intl.formatMessage({
id: 'mobile.search.before_modifier_description',

View file

@ -0,0 +1,27 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {toChannelScreen} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Autocomplete', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
await toChannelScreen(user);
});
it('MM-T3390 should render autocomplete in channel header edit screen', async () => {
// # Open channel info modal
await element(by.id('channel.title.button')).tap();
// # Open edit channel menu
await element(by.text('Edit Channel')).tap();
// # Activate at_mention autocomplete
await element(by.id('edit_channel.header.input')).typeText('@');
// * Expect autocomplete to render
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
});
});

View file

@ -0,0 +1,36 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {toChannelScreen} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Autocomplete', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
await toChannelScreen(user);
});
it('MM-T3391 should render autocomplete in post edit screen', async () => {
const message = Date.now().toString();
// # Type a message
const postInput = await element(by.id('post_input'));
await postInput.tap();
await postInput.typeText(message);
// # Tap the send button
await element(by.id('send_button')).tap();
// # Open edit screen
await element(by.text(message)).longPress();
await element(by.text('Edit')).tap();
// # Open autocomplete
await expect(element(by.id('autocomplete.at_mention.list'))).not.toExist();
await element(by.id('edit_post.input')).typeText(' @');
// * Expect at_mention autocomplete to render
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
});
});

View file

@ -0,0 +1,57 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {toChannelScreen} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Autocomplete', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
await toChannelScreen(user);
});
beforeEach(async () => {
await device.reloadReactNative();
// # Select post draft
await expect(element(by.id('channel_screen'))).toBeVisible();
await element(by.id('post_input')).tap();
});
it('MM-T3392_1 should render emoji_suggestion component', async () => {
// # Type ":" to activate emoji suggestions
await expect(element(by.id('autocomplete.emoji_suggestion.list'))).not.toExist();
await element(by.id('post_input')).typeText(':');
// * Expect emoji suggestions to render
await expect(element(by.id('autocomplete.emoji_suggestion.list'))).toExist();
});
it('MM-T3392_2 should render at_mention component', async () => {
// # Type "@" to activate at mention autocomplete
await expect(element(by.id('autocomplete.at_mention.list'))).not.toExist();
await element(by.id('post_input')).typeText('@');
// * Expect at mention autocomplete to render
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
});
it('MM-T3392_3 should render channel_mention component', async () => {
// # Type "~" to activate channel mention autocomplete
await expect(element(by.id('autocomplete.channel_mention.list'))).not.toExist();
await element(by.id('post_input')).typeText('~');
// * Expect channel mention to render
await expect(element(by.id('autocomplete.channel_mention.list'))).toExist();
});
it('MM-T3392_4 should render slash_suggestion component', async () => {
// # Type "/" to activate slash command suggestions
await expect(element(by.id('autocomplete.slash_suggestion'))).not.toExist();
await element(by.id('post_input')).typeText('/');
// * Expect slash suggestions to render
await expect(element(by.id('autocomplete.slash_suggestion'))).toExist();
});
});

View file

@ -0,0 +1,50 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {toChannelScreen} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Autocomplete', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
await toChannelScreen(user);
});
beforeEach(async () => {
await device.reloadReactNative();
// # Enter search screen
await element(by.id('channel.search.button')).tap();
});
it('MM-T3393_1 should render at_mention component', async () => {
await expect(element(by.id('autocomplete.at_mention.list'))).not.toExist();
// # Tap "from:" modifier
await element(by.id('search_from.section')).tap();
// * Expect at mention to render
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
});
it('MM-T3393_2 should render channel_mention component', async () => {
await expect(element(by.id('autocomplete.channel_mention.list'))).not.toExist();
// # Tap "in:" modifier
await element(by.id('search_in.section')).tap();
// * Expect channel mention to render
await expect(element(by.id('autocomplete.channel_mention.list'))).toExist();
});
it('MM-T3393_3 should render date_suggestion component', async () => {
await expect(element(by.id('autocomplete.date_suggestion'))).not.toExist();
// # Tap "before:" modifier
await element(by.id('search_before.section')).tap();
// * Expect date suggestion to render
await expect(element(by.id('autocomplete.date_suggestion'))).toExist();
});
});