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:
parent
335a25b516
commit
c6c0d33f6a
21 changed files with 197 additions and 1 deletions
|
|
@ -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}]}
|
||||
|
|
|
|||
|
|
@ -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}]}
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ export default class DateSuggestion extends PureComponent {
|
|||
>
|
||||
{Boolean(calendarWidth) &&
|
||||
<CalendarList
|
||||
testID='autocomplete.date_suggestion'
|
||||
current={currentDate}
|
||||
maxDate={currentDate}
|
||||
pastScrollRange={24}
|
||||
|
|
|
|||
|
|
@ -3051,6 +3051,7 @@ exports[`components/autocomplete/emoji_suggestion should match snapshot 2`] = `
|
|||
},
|
||||
]
|
||||
}
|
||||
testID="autocomplete.emoji_suggestion.list"
|
||||
updateCellsBatchingPeriod={50}
|
||||
windowSize={21}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ exports[`EditChannelInfo should match snapshot 1`] = `
|
|||
},
|
||||
]
|
||||
}
|
||||
testID="edit_channel.header.input"
|
||||
textAlignVertical="top"
|
||||
underlineColorAndroid="transparent"
|
||||
value="header"
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ export default class Search extends PureComponent {
|
|||
]}
|
||||
>
|
||||
<SearchBar
|
||||
testID='search.bar'
|
||||
autoCapitalize={this.props.autoCapitalize}
|
||||
autoCorrect={false}
|
||||
autoFocus={this.props.autoFocus}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ exports[`ChannelSearchButton should match, full snapshot 1`] = `
|
|||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="channel.search.button"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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={
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ export default class ChannelTitle extends PureComponent {
|
|||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
testID={'channel.title.button'}
|
||||
style={style.container}
|
||||
onPress={onPress}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ exports[`EditPost should match snapshot 1`] = `
|
|||
},
|
||||
]
|
||||
}
|
||||
testID="edit_post.input"
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
27
detox/e2e/test/autocomplete/edit_channel.e2e.js
Normal file
27
detox/e2e/test/autocomplete/edit_channel.e2e.js
Normal 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();
|
||||
});
|
||||
});
|
||||
36
detox/e2e/test/autocomplete/edit_post.e2e.js
Normal file
36
detox/e2e/test/autocomplete/edit_post.e2e.js
Normal 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();
|
||||
});
|
||||
});
|
||||
57
detox/e2e/test/autocomplete/post_draft.e2e.js
Normal file
57
detox/e2e/test/autocomplete/post_draft.e2e.js
Normal 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();
|
||||
});
|
||||
});
|
||||
50
detox/e2e/test/autocomplete/search.e2e.js
Normal file
50
detox/e2e/test/autocomplete/search.e2e.js
Normal 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();
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue