forked from Ivasoft/mattermost-mobile
Detox/E2E: Search Messages e2e tests in Gekidou (#6756)
* Detox/E2E: Search Messages e2e tests in Gekidou * Migrate to Detox 20 * Fix detoxrc * Fix assertion for search messages
This commit is contained in:
@@ -87,6 +87,7 @@ const NavigationSearch = forwardRef<SearchRef, Props>(({
|
||||
searchIconColor={theme.sidebarText}
|
||||
selectionColor={theme.sidebarText}
|
||||
ref={ref}
|
||||
testID='navigation.header.search_bar'
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
|
||||
@@ -211,6 +211,7 @@ const OptionItem = ({
|
||||
onPress={onRemove}
|
||||
style={[styles.iconContainer]}
|
||||
type='opacity'
|
||||
testID={`${testID}.remove.button`}
|
||||
>
|
||||
<CompassIcon
|
||||
name={'close'}
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function AddTeamSlideUp({otherTeams, title, showTitle = true}: Pr
|
||||
onPress={onPressCreate}
|
||||
showButton={false}
|
||||
showTitle={showTitle}
|
||||
testID={'team_sidebar.add_team_slide_up'}
|
||||
testID='team_sidebar.add_team_slide_up'
|
||||
title={title}
|
||||
>
|
||||
{hasOtherTeams &&
|
||||
@@ -90,13 +90,13 @@ export default function AddTeamSlideUp({otherTeams, title, showTitle = true}: Pr
|
||||
id='team_list.no_other_teams.title'
|
||||
defaultMessage='No additional teams to join'
|
||||
style={styles.title}
|
||||
testID={'team_sidebar.add_team_slide_up.no_other_teams.title'}
|
||||
testID='team_sidebar.add_team_slide_up.no_other_teams.title'
|
||||
/>
|
||||
<FormattedText
|
||||
id='team_list.no_other_teams.description'
|
||||
defaultMessage='To join another team, ask a Team Admin for an invitation, or create your own team.'
|
||||
style={styles.description}
|
||||
testID={'team_sidebar.add_team_slide_up.no_other_teams.description'}
|
||||
testID='team_sidebar.add_team_slide_up.no_other_teams.description'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export default function TeamListItem({team, textColor, iconTextColor, iconBackgr
|
||||
<Text
|
||||
style={[styles.text, textColor && {color: textColor}]}
|
||||
numberOfLines={1}
|
||||
testID={`${teamListItemTestId}.team_display_name`}
|
||||
>
|
||||
{displayName}
|
||||
</Text>
|
||||
|
||||
@@ -43,35 +43,35 @@ const getModifiersSectionsData = (intl: IntlShape): ModifierItem[] => {
|
||||
const sectionsData = [
|
||||
{
|
||||
term: 'From:',
|
||||
testID: 'search.from_section',
|
||||
testID: 'search.modifier.from',
|
||||
description: formatMessage({id: 'mobile.search.modifier.from', defaultMessage: ' a specific user'}),
|
||||
}, {
|
||||
term: 'In:',
|
||||
testID: 'search.in_section',
|
||||
testID: 'search.modifier.in',
|
||||
description: formatMessage({id: 'mobile.search.modifier.in', defaultMessage: ' a specific channel'}),
|
||||
},
|
||||
|
||||
// {
|
||||
// term: 'On:',
|
||||
// testID: 'search.on_section',
|
||||
// testID: 'search.modifier.on',
|
||||
// description: formatMessage({id: 'mobile.search.modifier.on', defaultMessage: ' a specific date'}),
|
||||
// },
|
||||
// {
|
||||
// term: 'After:',
|
||||
// testID: 'search.after_section',
|
||||
// testID: 'search.modifier.after',
|
||||
// description: formatMessage({id: 'mobile.search.modifier.after', defaultMessage: ' after a date'}),
|
||||
// }, {
|
||||
// term: 'Before:',
|
||||
// testID: 'search.before_section',
|
||||
// testID: 'search.modifier.before',
|
||||
// description: formatMessage({id: 'mobile.search.modifier.before', defaultMessage: ' before a date'}),
|
||||
// },
|
||||
{
|
||||
term: '-',
|
||||
testID: 'search.exclude_section',
|
||||
testID: 'search.modifier.exclude',
|
||||
description: formatMessage({id: 'mobile.search.modifier.exclude', defaultMessage: ' exclude search terms'}),
|
||||
}, {
|
||||
term: '""',
|
||||
testID: 'search.phrases_section',
|
||||
testID: 'search.modifier.phrases',
|
||||
description: formatMessage({id: 'mobile.search.modifier.phrases', defaultMessage: ' messages with phrases'}),
|
||||
},
|
||||
];
|
||||
@@ -143,6 +143,7 @@ const Modifiers = ({scrollEnabled, searchValue, setSearchValue, setTeamId, teamI
|
||||
style={styles.title}
|
||||
id={'screen.search.modifier.header'}
|
||||
defaultMessage='Search options'
|
||||
testID='search.modifier.header'
|
||||
/>
|
||||
{teams.length > 1 &&
|
||||
<TeamPickerIcon
|
||||
|
||||
@@ -39,7 +39,7 @@ const RecentItem = ({item, setRecentValue}: Props) => {
|
||||
inline={true}
|
||||
label={item.term}
|
||||
onRemove={handleRemove}
|
||||
testID={'search.recent_item'}
|
||||
testID={`search.recent_item.${item.term}`}
|
||||
type='remove'
|
||||
containerStyle={styles.container}
|
||||
/>
|
||||
|
||||
@@ -335,6 +335,7 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
||||
style={styles.flex}
|
||||
edges={EDGES}
|
||||
onLayout={onLayout}
|
||||
testID='search_messages.screen'
|
||||
>
|
||||
<Animated.View style={animated}>
|
||||
<Animated.View style={headerTopStyle}>
|
||||
|
||||
@@ -30,14 +30,14 @@ export default function SelectTeamSlideUp({teams, title, setTeamId, teamId}: Pro
|
||||
<BottomSheetContent
|
||||
showButton={false}
|
||||
showTitle={showTitle}
|
||||
testID={'search.search_team_slide_up'}
|
||||
testID='search.select_team_slide_up'
|
||||
title={title}
|
||||
>
|
||||
<TeamList
|
||||
selectedTeamId={teamId}
|
||||
teams={teams}
|
||||
onPress={onPress}
|
||||
testID='search.search_team_slide_up.team_list'
|
||||
testID='search.select_team_slide_up.team_list'
|
||||
/>
|
||||
</BottomSheetContent>
|
||||
);
|
||||
|
||||
@@ -88,7 +88,7 @@ const TeamPickerIcon = ({size = 24, divider = false, setTeamId, teams, teamId}:
|
||||
<TouchableWithFeedback
|
||||
onPress={handleTeamChange}
|
||||
type='opacity'
|
||||
testID={selectedTeam.id}
|
||||
testID='team_picker.button'
|
||||
>
|
||||
<View style={[styles.teamContainer, divider && styles.border]}>
|
||||
<View style={[styles.teamIcon, {width: size, height: size}]}>
|
||||
@@ -99,7 +99,7 @@ const TeamPickerIcon = ({size = 24, divider = false, setTeamId, teams, teamId}:
|
||||
textColor={theme.centerChannelColor}
|
||||
backgroundColor={changeOpacity(theme.centerChannelColor, 0.16)}
|
||||
selected={false}
|
||||
testID={`${selectedTeam}.team_icon`}
|
||||
testID={`team_picker.${selectedTeam.id}.team_icon`}
|
||||
smallText={true}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -1,37 +1,61 @@
|
||||
{
|
||||
"testRunner": "jest --forceExit --detectOpenHandles",
|
||||
"runnerConfig": "e2e/config.js",
|
||||
"testRunner": {
|
||||
"$0": "jest",
|
||||
"args": {
|
||||
"config": "e2e/config.js"
|
||||
}
|
||||
},
|
||||
"apps": {
|
||||
"ios.debug": {
|
||||
"type": "ios.app",
|
||||
"binaryPath": "../ios/Build/Products/Debug-iphonesimulator/Mattermost.app"
|
||||
},
|
||||
"ios.release": {
|
||||
"type": "ios.app",
|
||||
"binaryPath": "../ios/Build/Products/Release-iphonesimulator/Mattermost.app",
|
||||
"build": "cd ../fastlane && NODE_ENV=production bundle exec fastlane ios simulator && cd ../detox"
|
||||
},
|
||||
"android.debug": {
|
||||
"type": "android.apk",
|
||||
"binaryPath": "../android/app/build/outputs/apk/debug/app-debug.apk",
|
||||
"build": "cd .. && ./node_modules/.bin/jetify && cd android && ./gradlew clean && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ../detox"
|
||||
},
|
||||
"android.release": {
|
||||
"type": "android.apk",
|
||||
"binaryPath": "../android/app/build/outputs/apk/release/app-release.apk",
|
||||
"build": "cd .. && ./node_modules/.bin/jetify && cd android && ./gradlew clean && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ../detox"
|
||||
}
|
||||
},
|
||||
"devices": {
|
||||
"ios.simulator": {
|
||||
"type": "ios.simulator",
|
||||
"device": {
|
||||
"type": "iPhone 13"
|
||||
}
|
||||
},
|
||||
"android.emulator": {
|
||||
"type": "android.emulator",
|
||||
"device": {
|
||||
"avdName": "detox_pixel_4_xl_api_30"
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"ios.sim.debug": {
|
||||
"binaryPath": "../ios/Build/Products/Debug-iphonesimulator/Mattermost.app",
|
||||
"type": "ios.simulator",
|
||||
"device": {
|
||||
"type": "iPhone 13"
|
||||
}
|
||||
"device": "ios.simulator",
|
||||
"app": "ios.debug"
|
||||
},
|
||||
"ios.sim.release": {
|
||||
"type": "ios.simulator",
|
||||
"binaryPath": "../ios/Build/Products/Release-iphonesimulator/Mattermost.app",
|
||||
"build": "cd ../fastlane && NODE_ENV=production bundle exec fastlane ios simulator && cd ../detox",
|
||||
"device": {
|
||||
"type": "iPhone 13"
|
||||
}
|
||||
"device": "ios.simulator",
|
||||
"app": "ios.release"
|
||||
},
|
||||
"android.emu.debug": {
|
||||
"type": "android.emulator",
|
||||
"binaryPath": "../android/app/build/outputs/apk/debug/app-debug.apk",
|
||||
"build": "cd .. && ./node_modules/.bin/jetify && cd android && ./gradlew clean && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ../detox",
|
||||
"device": {
|
||||
"avdName": "detox_pixel_4_xl_api_30"
|
||||
}
|
||||
"device": "android.emulator",
|
||||
"app": "android.debug"
|
||||
},
|
||||
"android.emu.release": {
|
||||
"type": "android.emulator",
|
||||
"binaryPath": "../android/app/build/outputs/apk/release/app-release.apk",
|
||||
"build": "cd .. && ./node_modules/.bin/jetify && cd android && ./gradlew clean && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ../detox",
|
||||
"device": {
|
||||
"avdName": "detox_pixel_4_xl_api_30"
|
||||
}
|
||||
"device": "android.emulator",
|
||||
"app": "android.release"
|
||||
}
|
||||
},
|
||||
"artifacts": {
|
||||
|
||||
@@ -7,16 +7,15 @@ const shard = process.env.CI_NODE_INDEX ? process.env.CI_NODE_INDEX : '';
|
||||
module.exports = {
|
||||
setupFilesAfterEnv: ['./test/setup.ts'],
|
||||
maxWorkers: 1,
|
||||
testEnvironment: './environment',
|
||||
testRunner: 'jest-circus/runner',
|
||||
testSequencer: './custom_sequencer.js',
|
||||
testTimeout: 120000,
|
||||
testRegex: '\\.e2e\\.ts$',
|
||||
rootDir: '.',
|
||||
testMatch: ['<rootDir>/test/**/*.e2e.ts'],
|
||||
transform: {
|
||||
'\\.ts?$': 'ts-jest',
|
||||
},
|
||||
reporters: [
|
||||
'detox/runners/jest/streamlineReporter',
|
||||
'detox/runners/jest/reporter',
|
||||
['jest-junit', {
|
||||
suiteName: 'Mobile App E2E with Detox and Jest',
|
||||
outputDirectory: './artifacts',
|
||||
@@ -36,6 +35,9 @@ module.exports = {
|
||||
resultHtml: `${platform}-main${shard}.html`,
|
||||
}],
|
||||
],
|
||||
globalSetup: 'detox/runners/jest/globalSetup',
|
||||
globalTeardown: 'detox/runners/jest/globalTeardown',
|
||||
testEnvironment: 'detox/runners/jest/testEnvironment',
|
||||
verbose: true,
|
||||
moduleNameMapper: {
|
||||
'^@support/(.*)': '<rootDir>/support/$1',
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const {
|
||||
DetoxCircusEnvironment,
|
||||
SpecReporter,
|
||||
WorkerAssignReporter,
|
||||
} = require('detox/runners/jest-circus');
|
||||
|
||||
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
|
||||
constructor(config, context) {
|
||||
super(config, context);
|
||||
|
||||
this.initTimeout = 300000;
|
||||
|
||||
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
|
||||
// This is strictly optional.
|
||||
this.registerListeners({
|
||||
SpecReporter,
|
||||
WorkerAssignReporter,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CustomDetoxEnvironment;
|
||||
@@ -8,6 +8,9 @@ class NavigationHeader {
|
||||
headerSubtitle: 'navigation.header.subtitle',
|
||||
largeHeaderTitle: 'navigation.large_header.title',
|
||||
largeHeaderSubtitle: 'navigation.large_header.subtitle',
|
||||
searchInput: 'navigation.header.search_bar.search.input',
|
||||
searchClearButton: 'navigation.header.search_bar.search.clear.button',
|
||||
searchCancelButton: 'navigation.header.search_bar.search.cancel.button',
|
||||
};
|
||||
|
||||
backButton = element(by.id(this.testID.backButton));
|
||||
@@ -15,6 +18,9 @@ class NavigationHeader {
|
||||
headerSubtitle = element(by.id(this.testID.headerSubtitle));
|
||||
largeHeaderTitle = element(by.id(this.testID.largeHeaderTitle));
|
||||
largeHeaderSubtitle = element(by.id(this.testID.largeHeaderSubtitle));
|
||||
searchInput = element(by.id(this.testID.searchInput));
|
||||
searchClearButton = element(by.id(this.testID.searchClearButton));
|
||||
searchCancelButton = element(by.id(this.testID.searchCancelButton));
|
||||
}
|
||||
|
||||
const navigationHeader = new NavigationHeader();
|
||||
|
||||
@@ -33,11 +33,13 @@ import PushNotificationSettingsScreen from './push_notification_settings';
|
||||
import ReactionsScreen from './reactions';
|
||||
import RecentMentionsScreen from './recent_mentions';
|
||||
import SavedMessagesScreen from './saved_messages';
|
||||
import SearchMessagesScreen from './search_messages';
|
||||
import SelectTimezoneScreen from './select_timezone';
|
||||
import ServerScreen from './server';
|
||||
import ServerListScreen from './server_list';
|
||||
import SettingsScreen from './settings';
|
||||
import TableScreen from './table';
|
||||
import TeamDropdownMenuScreen from './team_dropdown_menu';
|
||||
import ThemeDisplaySettingsScreen from './theme_display_settings';
|
||||
import ThreadScreen from './thread';
|
||||
import ThreadOptionsScreen from './thread_options';
|
||||
@@ -77,11 +79,13 @@ export {
|
||||
ReactionsScreen,
|
||||
RecentMentionsScreen,
|
||||
SavedMessagesScreen,
|
||||
SearchMessagesScreen,
|
||||
SelectTimezoneScreen,
|
||||
ServerScreen,
|
||||
ServerListScreen,
|
||||
SettingsScreen,
|
||||
TableScreen,
|
||||
TeamDropdownMenuScreen,
|
||||
ThemeDisplaySettingsScreen,
|
||||
ThreadScreen,
|
||||
ThreadOptionsScreen,
|
||||
|
||||
110
detox/e2e/support/ui/screen/search_messages.ts
Normal file
110
detox/e2e/support/ui/screen/search_messages.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {
|
||||
NavigationHeader,
|
||||
PostList,
|
||||
} from '@support/ui/component';
|
||||
import {
|
||||
HomeScreen,
|
||||
PostOptionsScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {timeouts, wait} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class SearchMessagesScreen {
|
||||
testID = {
|
||||
searchResultsScreenPrefix: 'search_results.',
|
||||
searchMessagesScreen: 'search_messages.screen',
|
||||
searchModifierHeader: 'search.modifier.header',
|
||||
searchModifierFrom: 'search.modifier.from',
|
||||
searchModifierIn: 'search.modifier.in',
|
||||
searchModifierOn: 'search.modifier.on',
|
||||
searchModifierAfter: 'search.modifier.after',
|
||||
searchModifierBefore: 'search.modifier.before',
|
||||
searchModifierExclude: 'search.modifier.exclude',
|
||||
searchModifierPhrases: 'search.modifier.phrases',
|
||||
teamPickerButton: 'team_picker.button',
|
||||
};
|
||||
|
||||
searchMessagesScreen = element(by.id(this.testID.searchMessagesScreen));
|
||||
searchModifierHeader = element(by.id(this.testID.searchModifierHeader));
|
||||
searchModifierFrom = element(by.id(this.testID.searchModifierFrom));
|
||||
searchModifierIn = element(by.id(this.testID.searchModifierIn));
|
||||
searchModifierOn = element(by.id(this.testID.searchModifierOn));
|
||||
searchModifierAfter = element(by.id(this.testID.searchModifierAfter));
|
||||
searchModifierBefore = element(by.id(this.testID.searchModifierBefore));
|
||||
searchModifierExclude = element(by.id(this.testID.searchModifierExclude));
|
||||
searchModifierPhrases = element(by.id(this.testID.searchModifierPhrases));
|
||||
teamPickerButton = element(by.id(this.testID.teamPickerButton));
|
||||
|
||||
// convenience props
|
||||
largeHeaderTitle = NavigationHeader.largeHeaderTitle;
|
||||
largeHeaderSubtitle = NavigationHeader.largeHeaderSubtitle;
|
||||
searchInput = NavigationHeader.searchInput;
|
||||
searchClearButton = NavigationHeader.searchClearButton;
|
||||
searchCancelButton = NavigationHeader.searchCancelButton;
|
||||
|
||||
postList = new PostList(this.testID.searchResultsScreenPrefix);
|
||||
|
||||
getFlatPostList = () => {
|
||||
return this.postList.getFlatList();
|
||||
};
|
||||
|
||||
getPostListPostItem = (postId: string, text = '', postProfileOptions: any = {}) => {
|
||||
return this.postList.getPost(postId, text, postProfileOptions);
|
||||
};
|
||||
|
||||
getPostMessageAtIndex = (index: number) => {
|
||||
return this.postList.getPostMessageAtIndex(index);
|
||||
};
|
||||
|
||||
getTeamPickerIcon = (teamId: string) => {
|
||||
return element(by.id(`team_picker.${teamId}.team_icon`));
|
||||
};
|
||||
|
||||
getRecentSearchItem = (searchTerm: string) => {
|
||||
return element(by.id(`search.recent_item.${searchTerm}`));
|
||||
};
|
||||
|
||||
getRecentSearchItemRemoveButton = (searchTerm: string) => {
|
||||
return element(by.id(`search.recent_item.${searchTerm}.remove.button`));
|
||||
};
|
||||
|
||||
toBeVisible = async () => {
|
||||
await waitFor(this.searchMessagesScreen).toExist().withTimeout(timeouts.TEN_SEC);
|
||||
|
||||
return this.searchMessagesScreen;
|
||||
};
|
||||
|
||||
open = async () => {
|
||||
// # Open search messages screen
|
||||
await HomeScreen.searchTab.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
};
|
||||
|
||||
openPostOptionsFor = async (postId: string, text: string) => {
|
||||
const {postListPostItem} = this.getPostListPostItem(postId, text);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options
|
||||
await postListPostItem.longPress();
|
||||
await PostOptionsScreen.toBeVisible();
|
||||
await wait(timeouts.TWO_SEC);
|
||||
};
|
||||
|
||||
hasPostMessage = async (postId: string, postMessage: string) => {
|
||||
const {postListPostItem} = this.getPostListPostItem(postId, postMessage);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
};
|
||||
|
||||
hasPostMessageAtIndex = async (index: number, postMessage: string) => {
|
||||
await expect(
|
||||
this.getPostMessageAtIndex(index),
|
||||
).toHaveText(postMessage);
|
||||
};
|
||||
}
|
||||
|
||||
const searchMessagesScreen = new SearchMessagesScreen();
|
||||
export default searchMessagesScreen;
|
||||
43
detox/e2e/support/ui/screen/team_dropdown_menu.ts
Normal file
43
detox/e2e/support/ui/screen/team_dropdown_menu.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SearchMessagesScreen} from '@support/ui/screen';
|
||||
import {timeouts} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class TeamDropdownMenuScreen {
|
||||
testID = {
|
||||
teamDropdownMenuScreen: 'search.select_team_slide_up.screen',
|
||||
};
|
||||
|
||||
teamDropdownMenuScreen = element(by.id(this.testID.teamDropdownMenuScreen));
|
||||
|
||||
getTeamIcon = (teamId: string) => {
|
||||
return element(by.id(`team_sidebar.team_list.team_list_item.${teamId}.team_icon`));
|
||||
};
|
||||
|
||||
getTeamDisplayName = (teamId: string) => {
|
||||
return element(by.id(`team_sidebar.team_list.team_list_item.${teamId}.team_display_name`));
|
||||
};
|
||||
|
||||
toBeVisible = async () => {
|
||||
await waitFor(this.teamDropdownMenuScreen).toExist().withTimeout(timeouts.TEN_SEC);
|
||||
|
||||
return this.teamDropdownMenuScreen;
|
||||
};
|
||||
|
||||
open = async () => {
|
||||
// # Open team dropdown menu screen
|
||||
await SearchMessagesScreen.teamPickerButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
};
|
||||
|
||||
close = async () => {
|
||||
await this.teamDropdownMenuScreen.tap({x: 5, y: 10});
|
||||
await expect(this.teamDropdownMenuScreen).not.toBeVisible();
|
||||
};
|
||||
}
|
||||
|
||||
const teamDropdownMenuScreen = new TeamDropdownMenuScreen();
|
||||
export default teamDropdownMenuScreen;
|
||||
519
detox/e2e/test/search/search_messages.e2e.ts
Normal file
519
detox/e2e/test/search/search_messages.e2e.ts
Normal file
@@ -0,0 +1,519 @@
|
||||
// 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 {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
Team,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
serverOneUrl,
|
||||
siteOneUrl,
|
||||
} from '@support/test_config';
|
||||
import {Autocomplete} from '@support/ui/component';
|
||||
import {
|
||||
ChannelInfoScreen,
|
||||
ChannelListScreen,
|
||||
ChannelScreen,
|
||||
EditPostScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PinnedMessagesScreen,
|
||||
PostOptionsScreen,
|
||||
SavedMessagesScreen,
|
||||
SearchMessagesScreen,
|
||||
ServerScreen,
|
||||
TeamDropdownMenuScreen,
|
||||
ThreadScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
describe('Search - Search Messages', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
let testChannel: any;
|
||||
let testTeam: any;
|
||||
let testUser: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, team, user} = await Setup.apiInit(siteOneUrl);
|
||||
testChannel = channel;
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
|
||||
// # Log in to server
|
||||
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
|
||||
await LoginScreen.login(testUser);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// * Verify on channel list screen
|
||||
await ChannelListScreen.toBeVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// # Log out
|
||||
await HomeScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T5294_1 - should match elements on search messages screen', async () => {
|
||||
// # Open search messages screen
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify basic elements on search messages screen
|
||||
await expect(SearchMessagesScreen.largeHeaderTitle).toHaveText('Search');
|
||||
await expect(SearchMessagesScreen.searchInput).toBeVisible();
|
||||
await expect(SearchMessagesScreen.searchModifierHeader).toHaveText('Search options');
|
||||
await expect(SearchMessagesScreen.searchModifierFrom).toBeVisible();
|
||||
await expect(SearchMessagesScreen.searchModifierIn).toBeVisible();
|
||||
await expect(SearchMessagesScreen.searchModifierExclude).toBeVisible();
|
||||
await expect(SearchMessagesScreen.searchModifierPhrases).toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_2 - should be able to search messages from a specific user', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Tap on from-search-modifier, type in username, tap on user at-mention autocomplete, and tap on search key
|
||||
await SearchMessagesScreen.searchModifierFrom.tap();
|
||||
await SearchMessagesScreen.searchInput.typeText(testUser.username);
|
||||
const {atMentionItem} = Autocomplete.getAtMentionItem(testUser.id);
|
||||
await atMentionItem.tap();
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results contain messages from user
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(`from: ${testUser.username}`).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_3 - should be able to search messages in a specific channel', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Tap on in-search-modifier, type in channel name, tap on channel mention autocomplete, and tap on search key
|
||||
await SearchMessagesScreen.searchModifierIn.tap();
|
||||
await SearchMessagesScreen.searchInput.typeText(testChannel.name);
|
||||
const {channelMentionItem} = Autocomplete.getChannelMentionItem(testChannel.name);
|
||||
await channelMentionItem.tap();
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results contain messages in channel
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(`channel: ${testChannel.name}`).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_4 - should be able to search messages excluding search terms', async () => {
|
||||
// # Open a channel screen, post a message prefix plus non-excluded term, post another message prefix plus excluded term, go back to channel list screen, and open search messages screen
|
||||
const excludedTerm = getRandomId();
|
||||
const messagePrefix = 'Message';
|
||||
const messageWithNonExcludedTerm = `${messagePrefix} ${getRandomId()}`;
|
||||
const messageWithExcludedTerm = `${messagePrefix} ${excludedTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(messageWithNonExcludedTerm);
|
||||
const {post: nonExcludedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem: nonExcludedPostListPostItem} = SearchMessagesScreen.getPostListPostItem(nonExcludedPost.id, messageWithNonExcludedTerm);
|
||||
await ChannelScreen.postMessage(messageWithExcludedTerm);
|
||||
const {post: excludedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem: excludedPostListPostItem} = SearchMessagesScreen.getPostListPostItem(excludedPost.id, messageWithExcludedTerm);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in the message prefix, tap on excluded-search modifier, type in the excluded term, and tap on search key
|
||||
await SearchMessagesScreen.searchInput.typeText(messagePrefix);
|
||||
await SearchMessagesScreen.searchModifierExclude.tap();
|
||||
await SearchMessagesScreen.searchInput.typeText(excludedTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results do not contain messages with excluded term
|
||||
await expect(nonExcludedPostListPostItem).toBeVisible();
|
||||
await expect(excludedPostListPostItem).not.toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(`${messagePrefix} -${excludedTerm}`).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_5 - should be able to search messages with phrases', async () => {
|
||||
// # Open a channel screen, post a message prefix plus non-included term, post another message prefix plus included term, go back to channel list screen, and open search messages screen
|
||||
const includedTerm = getRandomId();
|
||||
const messagePrefix = 'How are';
|
||||
const messageWithNonIncludedTerm = `${messagePrefix} ${getRandomId()}`;
|
||||
const messageWithIncludedTerm = `${messagePrefix} ${includedTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(messageWithNonIncludedTerm);
|
||||
const {post: nonIncludedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem: nonIncludedPostListPostItem} = SearchMessagesScreen.getPostListPostItem(nonIncludedPost.id, messageWithNonIncludedTerm);
|
||||
await ChannelScreen.postMessage(messageWithIncludedTerm);
|
||||
const {post: includedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem: includedPostListPostItem} = SearchMessagesScreen.getPostListPostItem(includedPost.id, messageWithIncludedTerm);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in the message prefix plus included term inside double quotes and tap on search key
|
||||
await SearchMessagesScreen.searchModifierPhrases.tap();
|
||||
await SearchMessagesScreen.searchInput.tapBackspaceKey();
|
||||
await SearchMessagesScreen.searchInput.typeText(messageWithIncludedTerm);
|
||||
await SearchMessagesScreen.searchModifierPhrases.tap();
|
||||
await SearchMessagesScreen.searchInput.tapBackspaceKey();
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results only contain messages with included term
|
||||
await expect(nonIncludedPostListPostItem).not.toBeVisible();
|
||||
await expect(includedPostListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(`"${messageWithIncludedTerm} "`).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_6 - should be able to search messages using combination of modifiers', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Tap on from-search-modifier, type in username, tap on user at-mention autocomplete, tap on in-search-modifier, type in channel, tap on channel mention autocomplete, and tap on search key
|
||||
await SearchMessagesScreen.searchModifierFrom.tap();
|
||||
await SearchMessagesScreen.searchInput.typeText(testUser.username);
|
||||
const {atMentionItem} = Autocomplete.getAtMentionItem(testUser.id);
|
||||
await atMentionItem.tap();
|
||||
await SearchMessagesScreen.searchModifierIn.tap();
|
||||
await SearchMessagesScreen.searchInput.typeText(testChannel.name);
|
||||
const {channelMentionItem} = Autocomplete.getChannelMentionItem(testChannel.name);
|
||||
await channelMentionItem.tap();
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results only contain messages from user in channel
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(`from: ${testUser.username} channel: ${testChannel.name}`).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_7 - should be able to search messages using recent searches', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield results and tap on search key
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results contain searched message
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input and tap on recent search item
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItem(searchTerm).tap();
|
||||
|
||||
// * Verify search results contain searched message
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_8 - should be able to search messages on a another joined team', async () => {
|
||||
// # As admin, create a second team, add user to the second team, create a new channel on second team, and add user to new channel; as user, terminate app and relaunch app
|
||||
const {team: testTeamTwo} = await Team.apiCreateTeam(siteOneUrl, {prefix: 'a'});
|
||||
await Team.apiAddUserToTeam(siteOneUrl, testUser.id, testTeamTwo.id);
|
||||
const {channel: testChannelTwo} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeamTwo.id});
|
||||
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, testChannelTwo.id);
|
||||
await device.reloadReactNative();
|
||||
|
||||
// * Verify on first team
|
||||
await expect(ChannelListScreen.headerTeamDisplayName).toHaveText(testTeam.display_name);
|
||||
|
||||
// # Post a message to the new channel on second team and open search messages screen
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
const {post} = await Post.apiCreatePost(siteOneUrl, {
|
||||
channelId: testChannelTwo.id,
|
||||
message,
|
||||
});
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Tap on team picker button and tap on second team option
|
||||
await SearchMessagesScreen.teamPickerButton.tap();
|
||||
await TeamDropdownMenuScreen.getTeamIcon(testTeamTwo.id).tap();
|
||||
|
||||
// * Verify team picker button displays second team icon
|
||||
await expect(SearchMessagesScreen.getTeamPickerIcon(testTeamTwo.id)).toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield results for second team and tap on search key
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results contain searched message
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Tap on team picker button and tap on first team option
|
||||
await SearchMessagesScreen.teamPickerButton.tap();
|
||||
await TeamDropdownMenuScreen.getTeamIcon(testTeam.id).tap();
|
||||
|
||||
// * Verify team picker button displays first team icon and search results do not contain searched message
|
||||
await expect(SearchMessagesScreen.getTeamPickerIcon(testTeam.id)).toBeVisible();
|
||||
await expect(postListPostItem).not.toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_9 - should show empty search results screen when search result is empty', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield no results and tap on search key
|
||||
const searchTerm = getRandomId();
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify empty search state for search messages
|
||||
await expect(element(by.text(`No matches found for “${searchTerm}”`))).toBeVisible();
|
||||
await expect(element(by.text('Check the spelling or try another search.'))).toExist();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_10 - should be able to edit, reply to, and delete a searched message from search results screen', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield results, tap on search key, open post options for searched message, and tap on edit option
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
const {post: searchedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, message);
|
||||
await PostOptionsScreen.editPostOption.tap();
|
||||
|
||||
// * Verify on edit post screen
|
||||
await EditPostScreen.toBeVisible();
|
||||
|
||||
// # Edit post message and tap save button
|
||||
const updatedMessage = `${message} edit`;
|
||||
await EditPostScreen.messageInput.replaceText(updatedMessage);
|
||||
await EditPostScreen.saveButton.tap();
|
||||
|
||||
// * Verify post message is updated and displays edited indicator '(edited)'
|
||||
const {postListPostItem: updatedPostListPostItem, postListPostItemEditedIndicator} = SearchMessagesScreen.getPostListPostItem(searchedPost.id, updatedMessage);
|
||||
await expect(updatedPostListPostItem).toBeVisible();
|
||||
await expect(postListPostItemEditedIndicator).toHaveText('(edited)');
|
||||
|
||||
// # Open post options for searched message and tap on reply option
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, updatedMessage);
|
||||
await PostOptionsScreen.replyPostOption.tap();
|
||||
|
||||
// * Verify on thread screen
|
||||
await ThreadScreen.toBeVisible();
|
||||
|
||||
// # Post a reply
|
||||
const replyMessage = `${message} reply`;
|
||||
await ThreadScreen.postMessage(replyMessage);
|
||||
|
||||
// * Verify reply is posted
|
||||
const {post: replyPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ThreadScreen.getPostListPostItem(replyPost.id, replyMessage);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Go back to search results screen
|
||||
await ThreadScreen.back();
|
||||
|
||||
// * Verify reply count and following button
|
||||
const {postListPostItemFooterReplyCount, postListPostItemFooterFollowingButton} = SearchMessagesScreen.getPostListPostItem(searchedPost.id, updatedMessage);
|
||||
await expect(postListPostItemFooterReplyCount).toHaveText('1 reply');
|
||||
await expect(postListPostItemFooterFollowingButton).toBeVisible();
|
||||
|
||||
// # Open post options for updated searched message and delete post
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, updatedMessage);
|
||||
await PostOptionsScreen.deletePost({confirm: true});
|
||||
|
||||
// * Verify updated searched message is deleted
|
||||
await expect(postListPostItem).not.toExist();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_11 - should be able to save/unsave a searched message from search results screen', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield results, tap on search key, open post options for searched message, tap on save option, and open saved messages screen
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
const {post: searchedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, message);
|
||||
await PostOptionsScreen.savePostOption.tap();
|
||||
await SavedMessagesScreen.open();
|
||||
|
||||
// * Verify searched message is displayed on saved messages screen
|
||||
const {postListPostItem} = SavedMessagesScreen.getPostListPostItem(searchedPost.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Go back to searched messages screen, open post options for searched message, tap on usave option, and open saved messages screen
|
||||
await SearchMessagesScreen.open();
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, message);
|
||||
await PostOptionsScreen.unsavePostOption.tap();
|
||||
await SavedMessagesScreen.open();
|
||||
|
||||
// * Verify searched message is not displayed anymore on saved messages screen
|
||||
await expect(postListPostItem).not.toExist();
|
||||
|
||||
// # Go back to searched messages screen, clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.open();
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
|
||||
it('MM-T5294_12 - should be able to pin/unpin a searched message from search results screen', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, and open search messages screen
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
|
||||
// * Verify on search messages screen
|
||||
await SearchMessagesScreen.toBeVisible();
|
||||
|
||||
// # Type in a search term that will yield results, tap on search key, open post options for searched message, tap on pin to channel option, go back to channel list screen, open the channel screen where searched message is posted, open channel info screen, and open pinned messages screen
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
const {post: searchedPost} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, message);
|
||||
await PostOptionsScreen.pinPostOption.tap();
|
||||
await ChannelListScreen.open();
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelInfoScreen.open();
|
||||
await PinnedMessagesScreen.open();
|
||||
|
||||
// * Verify searched message is displayed on pinned messages screen
|
||||
const {postListPostItem} = PinnedMessagesScreen.getPostListPostItem(searchedPost.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Go back to searched messages screen, open post options for searched message, tap on unpin from channel option, go back to channel list screen, open the channel screen where searched message is posted, open channel info screen, and open pinned messages screen
|
||||
await PinnedMessagesScreen.back();
|
||||
await ChannelInfoScreen.close();
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
await SearchMessagesScreen.openPostOptionsFor(searchedPost.id, message);
|
||||
await PostOptionsScreen.unpinPostOption.tap();
|
||||
await ChannelListScreen.open();
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelInfoScreen.open();
|
||||
await PinnedMessagesScreen.open();
|
||||
|
||||
// * Verify searched message is not displayed anymore on pinned messages screen
|
||||
await expect(postListPostItem).not.toExist();
|
||||
|
||||
// # Go back to searched messages screen, clear search input, remove recent search item, and go back to channel list screen
|
||||
await PinnedMessagesScreen.back();
|
||||
await ChannelInfoScreen.close();
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
});
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
PostOptionsScreen,
|
||||
RecentMentionsScreen,
|
||||
SavedMessagesScreen,
|
||||
SearchMessagesScreen,
|
||||
ServerScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
@@ -115,4 +116,26 @@ describe('Smoke Test - Search', () => {
|
||||
await ChannelInfoScreen.close();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4911_4 - should be able to search for a message and display on search results screen', async () => {
|
||||
// # Open a channel screen, post a message, go back to channel list screen, open search messages screen, type in a search term that will yield results, and tap on search key
|
||||
const searchTerm = getRandomId();
|
||||
const message = `Message ${searchTerm}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
await ChannelScreen.back();
|
||||
await SearchMessagesScreen.open();
|
||||
await SearchMessagesScreen.searchInput.typeText(searchTerm);
|
||||
await SearchMessagesScreen.searchInput.tapReturnKey();
|
||||
|
||||
// * Verify search results contain searched message
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = SearchMessagesScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Clear search input, remove recent search item, and go back to channel list screen
|
||||
await SearchMessagesScreen.searchClearButton.tap();
|
||||
await SearchMessagesScreen.getRecentSearchItemRemoveButton(searchTerm).tap();
|
||||
await ChannelListScreen.open();
|
||||
});
|
||||
});
|
||||
|
||||
2452
detox/package-lock.json
generated
2452
detox/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,37 +5,37 @@
|
||||
"author": "Mattermost, Inc.",
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.18.6",
|
||||
"@babel/plugin-transform-runtime": "7.19.1",
|
||||
"@babel/preset-env": "7.19.4",
|
||||
"@jest/test-sequencer": "29.2.0",
|
||||
"@types/jest": "29.1.2",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.19.6",
|
||||
"@babel/plugin-transform-runtime": "7.19.6",
|
||||
"@babel/preset-env": "7.20.2",
|
||||
"@jest/test-sequencer": "29.3.1",
|
||||
"@types/jest": "29.2.3",
|
||||
"@types/tough-cookie": "4.0.2",
|
||||
"@types/uuid": "8.3.4",
|
||||
"aws-sdk": "2.1233.0",
|
||||
"axios": "1.1.2",
|
||||
"aws-sdk": "2.1255.0",
|
||||
"axios": "1.1.3",
|
||||
"axios-cookiejar-support": "4.0.3",
|
||||
"babel-jest": "29.2.0",
|
||||
"babel-jest": "29.3.1",
|
||||
"babel-plugin-module-resolver": "4.1.0",
|
||||
"client-oauth2": "4.3.3",
|
||||
"deepmerge": "4.2.2",
|
||||
"detox": "19.12.6",
|
||||
"detox": "20.0.1",
|
||||
"form-data": "4.0.0",
|
||||
"jest": "29.2.0",
|
||||
"jest-circus": "29.2.0",
|
||||
"jest-cli": "29.2.0",
|
||||
"jest": "29.3.1",
|
||||
"jest-circus": "29.3.1",
|
||||
"jest-cli": "29.3.1",
|
||||
"jest-html-reporters": "3.0.11",
|
||||
"jest-junit": "14.0.1",
|
||||
"jest-stare": "2.4.1",
|
||||
"junit-report-merger": "4.0.0",
|
||||
"moment-timezone": "0.5.38",
|
||||
"recursive-readdir": "2.2.2",
|
||||
"moment-timezone": "0.5.39",
|
||||
"recursive-readdir": "2.2.3",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"shelljs": "0.8.5",
|
||||
"tough-cookie": "4.1.2",
|
||||
"ts-jest": "29.0.3",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.8.4",
|
||||
"tslib": "2.4.1",
|
||||
"typescript": "4.9.3",
|
||||
"uuid": "9.0.0",
|
||||
"xml2js": "0.4.23"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user