Detox/E2E: Messaging post options e2e tests in Gekidou (#6405)
* Detox/E2E: Messaging post options e2e tests in Gekidou * Simplify find channels search bar
This commit is contained in:
parent
07df681193
commit
7a71d864e2
61 changed files with 953 additions and 70 deletions
|
|
@ -443,7 +443,7 @@ const AtMention = ({
|
|||
renderSectionHeader={renderSectionHeader}
|
||||
style={[style.listView, {maxHeight: maxListHeight}]}
|
||||
sections={sections}
|
||||
testID='at_mention_suggestion.list'
|
||||
testID='autocomplete.at_mention.section_list'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ const AtMentionItem = ({
|
|||
>
|
||||
<UserItem
|
||||
user={user}
|
||||
testID='at_mention'
|
||||
testID='at_mention.user_item'
|
||||
/>
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ const ChannelMention = ({
|
|||
renderSectionHeader={renderSectionHeader}
|
||||
style={listStyle}
|
||||
sections={sections}
|
||||
testID='channel_mention_suggestion.list'
|
||||
testID='autocomplete.channel_mention.section_list'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const InfoBox = ({channelId, containerStyle, showAsLabel = false, testID}: Props
|
|||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
icon: closeButton,
|
||||
testID: closeButtonId,
|
||||
testID: 'close.channel_info.button',
|
||||
}],
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ exports[`components/channel_list/categories/body/channel_item should match snaps
|
|||
},
|
||||
]
|
||||
}
|
||||
testID="channel_list_item.hello.collapsed.true"
|
||||
testID="channel_item.hello"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -103,7 +103,7 @@ exports[`components/channel_list/categories/body/channel_item should match snaps
|
|||
false,
|
||||
]
|
||||
}
|
||||
testID="channel_list_item.hello.display_name"
|
||||
testID="channel_item.hello.display_name"
|
||||
>
|
||||
Hello!
|
||||
</Text>
|
||||
|
|
@ -147,7 +147,7 @@ exports[`components/channel_list/categories/body/channel_item should match snaps
|
|||
},
|
||||
]
|
||||
}
|
||||
testID="channel_list_item.hello.collapsed.true"
|
||||
testID="channel_item.hello"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -216,7 +216,7 @@ exports[`components/channel_list/categories/body/channel_item should match snaps
|
|||
false,
|
||||
]
|
||||
}
|
||||
testID="channel_list_item.hello.display_name"
|
||||
testID="channel_item.hello.display_name"
|
||||
>
|
||||
Hello!
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ describe('components/channel_list/categories/body/channel_item', () => {
|
|||
membersCount={0}
|
||||
isMuted={false}
|
||||
currentUserId={'id'}
|
||||
testID='channel_list_item'
|
||||
testID='channel_item'
|
||||
onPress={() => undefined}
|
||||
isUnread={myChannel.isUnread}
|
||||
mentionsCount={myChannel.mentionsCount}
|
||||
|
|
@ -57,7 +57,7 @@ describe('components/channel_list/categories/body/channel_item', () => {
|
|||
membersCount={3}
|
||||
isMuted={false}
|
||||
currentUserId={'id'}
|
||||
testID='channel_list_item'
|
||||
testID='channel_item'
|
||||
onPress={() => undefined}
|
||||
isUnread={myChannel.isUnread}
|
||||
mentionsCount={myChannel.mentionsCount}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ const ChannelListItem = ({
|
|||
<>
|
||||
<View
|
||||
style={containerStyle}
|
||||
testID={`${testID}.${channel.name}.collapsed.${!isActive}`}
|
||||
testID={`${testID}.${channel.name}`}
|
||||
>
|
||||
<View style={styles.wrapper}>
|
||||
<ChannelIcon
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const CustomStatus = ({customStatus, customStatusExpired, isCustomStatusEnabled,
|
|||
<CustomStatusEmoji
|
||||
customStatus={customStatus!}
|
||||
style={[style.customStatusEmoji, isInfo && style.info]}
|
||||
testID={`channel_list_item.custom_status.${customStatus!.emoji}-${customStatus!.text}`}
|
||||
testID={`channel_item.custom_status.${customStatus!.emoji}-${customStatus!.text}`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,11 +100,9 @@ const EmojiPicker = ({customEmojis, customEmojisEnabled, onEmojiPress, recentEmo
|
|||
<SafeAreaView
|
||||
style={styles.flex}
|
||||
edges={edges}
|
||||
testID={`${testID}.screen`}
|
||||
>
|
||||
<View
|
||||
style={styles.searchBar}
|
||||
testID={testID}
|
||||
>
|
||||
<View style={styles.searchBar}>
|
||||
<SearchBar
|
||||
autoCapitalize='none'
|
||||
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ const EmojiSectionBar = ({currentIndex, sections, scrollToIndex}: Props) => {
|
|||
scrollViewNativeID={SCROLLVIEW_NATIVE_ID}
|
||||
normalList={true}
|
||||
style={styles.container}
|
||||
testID='emoji_picker.emoji_sections.section_bar'
|
||||
>
|
||||
<View style={styles.background}>
|
||||
<View style={styles.pane}>
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ const EmojiSections = ({customEmojis, customEmojisEnabled, onEmojiPress, recentE
|
|||
sections={sections}
|
||||
contentContainerStyle={{paddingBottom: 50}}
|
||||
windowSize={100}
|
||||
testID='emoji_picker.emoji_sections.section_list'
|
||||
/>
|
||||
<EmojiSectionBar
|
||||
currentIndex={sectionIndex}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ const Avatar = ({author, enablePostIconOverride, isAutoReponse, location, post}:
|
|||
size={ViewConstant.PROFILE_PICTURE_SIZE}
|
||||
iconSize={24}
|
||||
showStatus={!isAutoReponse || author.isBot}
|
||||
testID='post_profile_picture.profile_picture'
|
||||
testID={`post_profile_picture.${author.id}.profile_picture`}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ const ProfilePicture = ({
|
|||
return (
|
||||
<View
|
||||
style={containerStyle}
|
||||
testID={`${testID}.${author?.id}`}
|
||||
testID={testID}
|
||||
>
|
||||
<Image
|
||||
author={author}
|
||||
|
|
|
|||
|
|
@ -108,14 +108,19 @@ const UserItem = ({
|
|||
const name = getName(user, showFullName, isCurrentUser, intl);
|
||||
const customStatus = getUserCustomStatus(user);
|
||||
|
||||
const userItemTestId = `${testID}.${user?.id}`;
|
||||
|
||||
return (
|
||||
<View style={[style.row, containerStyle]}>
|
||||
<View
|
||||
style={[style.row, containerStyle]}
|
||||
testID={userItemTestId}
|
||||
>
|
||||
<View style={style.rowPicture}>
|
||||
<ProfilePicture
|
||||
author={user}
|
||||
size={24}
|
||||
showStatus={false}
|
||||
testID={`${testID}.profile_picture`}
|
||||
testID={`${userItemTestId}.profile_picture`}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
|
|
@ -127,7 +132,7 @@ const UserItem = ({
|
|||
<Text
|
||||
style={style.rowFullname}
|
||||
numberOfLines={1}
|
||||
testID={`${testID}.name`}
|
||||
testID={`${userItemTestId}.display_name`}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
|
|
@ -143,7 +148,7 @@ const UserItem = ({
|
|||
<Text
|
||||
style={style.rowUsername}
|
||||
numberOfLines={1}
|
||||
testID='at_mention_item.username'
|
||||
testID={`${userItemTestId}.username`}
|
||||
>
|
||||
{` @${user!.username}`}
|
||||
</Text>
|
||||
|
|
@ -153,6 +158,7 @@ const UserItem = ({
|
|||
<CustomStatusEmoji
|
||||
customStatus={customStatus!}
|
||||
style={style.icon}
|
||||
testID={testID}
|
||||
/>
|
||||
)}
|
||||
{shared && (
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const Member = ({channelId, containerStyle, size = 72, showStatus = true, theme,
|
|||
iconSize={48}
|
||||
showStatus={showStatus}
|
||||
statusSize={24}
|
||||
testID='channel_intro.profile_picture'
|
||||
testID={`channel_intro.${user.id}.profile_picture`}
|
||||
/>
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ const ChannelHeader = ({
|
|||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
icon: closeButton,
|
||||
testID: closeButtonId,
|
||||
testID: 'close.channel_info.button',
|
||||
}],
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const EmojiPickerScreen = ({closeButton, componentId, onEmojiPress}: Props) => {
|
|||
{
|
||||
icon: closeButton,
|
||||
id: 'close-add-reaction',
|
||||
testID: 'close.add_reaction.button',
|
||||
testID: 'close.emoji_picker.button',
|
||||
},
|
||||
],
|
||||
rightButtons: [],
|
||||
|
|
@ -50,7 +50,12 @@ const EmojiPickerScreen = ({closeButton, componentId, onEmojiPress}: Props) => {
|
|||
close();
|
||||
}, []);
|
||||
|
||||
return <EmojiPicker onEmojiPress={handleEmojiPress}/>;
|
||||
return (
|
||||
<EmojiPicker
|
||||
onEmojiPress={handleEmojiPress}
|
||||
testID='emoji_picker'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmojiPickerScreen;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type Props = {
|
|||
term: string;
|
||||
usersMatch: UserModel[];
|
||||
usersMatchStart: UserModel[];
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
const style = StyleSheet.create({
|
||||
|
|
@ -77,7 +78,7 @@ const sortByUserOrChannel = <T extends Channel |UserModel>(locale: string, teamm
|
|||
const FilteredList = ({
|
||||
archivedChannels, close, channelsMatch, channelsMatchStart, currentTeamId,
|
||||
keyboardHeight, loading, onLoading, restrictDirectMessage, showTeamName,
|
||||
teamIds, teammateDisplayNameSetting, term, usersMatch, usersMatchStart,
|
||||
teamIds, teammateDisplayNameSetting, term, usersMatch, usersMatchStart, testID,
|
||||
}: Props) => {
|
||||
const bounce = useRef<DebouncedFunc<() => void>>();
|
||||
const mounted = useRef(false);
|
||||
|
|
@ -211,6 +212,7 @@ const FilteredList = ({
|
|||
isInfo={true}
|
||||
onPress={onSwitchToChannel}
|
||||
showTeamName={showTeamName}
|
||||
testID='find_channels.filtered_list.channel_item'
|
||||
/>
|
||||
);
|
||||
} else if ('username' in item) {
|
||||
|
|
@ -304,6 +306,7 @@ const FilteredList = ({
|
|||
renderItem={renderItem}
|
||||
data={data}
|
||||
showsVerticalScrollIndicator={false}
|
||||
testID={`${testID}.flat_list`}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,10 @@ const FindChannels = ({closeButtonId, componentId}: Props) => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View
|
||||
style={styles.container}
|
||||
testID='find_channels.screen'
|
||||
>
|
||||
<SearchBar
|
||||
autoCapitalize='none'
|
||||
autoFocus={true}
|
||||
|
|
@ -99,6 +102,7 @@ const FindChannels = ({closeButtonId, componentId}: Props) => {
|
|||
selectionColor={color}
|
||||
showLoading={loading}
|
||||
value={term}
|
||||
testID='find_channels.search_bar'
|
||||
/>
|
||||
{term === '' && <QuickOptions close={close}/>}
|
||||
<View style={styles.listContainer}>
|
||||
|
|
@ -106,6 +110,7 @@ const FindChannels = ({closeButtonId, componentId}: Props) => {
|
|||
<UnfilteredList
|
||||
close={close}
|
||||
keyboardHeight={keyboardHeight}
|
||||
testID='find_channels.unfiltered_list'
|
||||
/>
|
||||
}
|
||||
{Boolean(term) &&
|
||||
|
|
@ -115,6 +120,7 @@ const FindChannels = ({closeButtonId, componentId}: Props) => {
|
|||
loading={loading}
|
||||
onLoading={setLoading}
|
||||
term={term}
|
||||
testID='find_channels.filtered_list'
|
||||
/>
|
||||
}
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => {
|
|||
iconName='globe'
|
||||
onPress={browseChannels}
|
||||
text={intl.formatMessage({id: 'find_channels.directory', defaultMessage: 'Directory'})}
|
||||
testID='find_channels.quick_options.directory.option'
|
||||
/>
|
||||
<View style={styles.separator}/>
|
||||
</>
|
||||
|
|
@ -84,6 +85,7 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => {
|
|||
iconName='account-outline'
|
||||
onPress={openDirectMessage}
|
||||
text={intl.formatMessage({id: 'find_channels.open_dm', defaultMessage: 'Open a DM'})}
|
||||
testID='find_channels.quick_options.open_dm.option'
|
||||
/>
|
||||
{canCreateChannels &&
|
||||
<>
|
||||
|
|
@ -92,6 +94,7 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => {
|
|||
iconName='plus'
|
||||
onPress={createNewChannel}
|
||||
text={intl.formatMessage({id: 'find_channels.new_channel', defaultMessage: 'New Channel'})}
|
||||
testID='find_channels.quick_options.new_channel.option'
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ type Props = {
|
|||
recentChannels: ChannelModel[];
|
||||
showTeamName: boolean;
|
||||
unreadChannels: ChannelModel[];
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
const sectionNames = {
|
||||
|
|
@ -57,7 +58,7 @@ const buildSections = (unreadChannels: ChannelModel[], recentChannels: ChannelMo
|
|||
return sections;
|
||||
};
|
||||
|
||||
const UnfilteredList = ({close, keyboardHeight, recentChannels, showTeamName, unreadChannels}: Props) => {
|
||||
const UnfilteredList = ({close, keyboardHeight, recentChannels, showTeamName, unreadChannels, testID}: Props) => {
|
||||
const intl = useIntl();
|
||||
const serverUrl = useServerUrl();
|
||||
const [sections, setSections] = useState(buildSections(unreadChannels, recentChannels));
|
||||
|
|
@ -79,6 +80,7 @@ const UnfilteredList = ({close, keyboardHeight, recentChannels, showTeamName, un
|
|||
isInfo={true}
|
||||
onPress={onPress}
|
||||
showTeamName={showTeamName}
|
||||
testID='find_channels.unfiltered_list.channel_item'
|
||||
/>
|
||||
);
|
||||
}, [onPress, showTeamName]);
|
||||
|
|
@ -102,6 +104,7 @@ const UnfilteredList = ({close, keyboardHeight, recentChannels, showTeamName, un
|
|||
sections={sections}
|
||||
showsVerticalScrollIndicator={false}
|
||||
stickySectionHeadersEnabled={true}
|
||||
testID={`${testID}.section_list`}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ const AccountUserInfo = ({user, showFullName, theme}: Props) => {
|
|||
iconSize={28}
|
||||
showStatus={true}
|
||||
author={user}
|
||||
testID={'account.profile_picture'}
|
||||
statusStyle={styles.statusStyle}
|
||||
statusSize={24}
|
||||
testID={`account.${user.id}.profile_picture`}
|
||||
/>
|
||||
{showFullName && <Text style={styles.textFullName}>{title}</Text>}
|
||||
<Text style={showFullName ? styles.textUserName : styles.textFullName}>{`${userName}`}</Text>
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ exports[`components/categories_list should render team error 1`] = `
|
|||
"padding": 8,
|
||||
}
|
||||
}
|
||||
testID="channel_list_subheader.search_field.button"
|
||||
>
|
||||
<Icon
|
||||
name="magnify"
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ const CategoryBody = ({sortedChannels, unreadIds, unreadsOnTop, category, limit,
|
|||
return (
|
||||
<ChannelItem
|
||||
channel={item}
|
||||
testID={`category.${category.displayName.replace(/ /g, '_').toLocaleLowerCase()}.channel_list_item`}
|
||||
onPress={onChannelSwitch}
|
||||
key={item.id}
|
||||
testID={`channel_list.category.${category.displayName.replace(/ /g, '_').toLocaleLowerCase()}.channel_item`}
|
||||
/>
|
||||
);
|
||||
}, [onChannelSwitch]);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ exports[`components/channel_list/categories/header should match snapshot 1`] = `
|
|||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
testID="category_header.custom.collapsed.false"
|
||||
testID="channel_list.category_header.custom.collapsed.false"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -75,7 +75,7 @@ exports[`components/channel_list/categories/header should match snapshot 1`] = `
|
|||
"textTransform": "uppercase",
|
||||
}
|
||||
}
|
||||
testID="category_header.custom.display_name"
|
||||
testID="channel_list.category_header.custom.display_name"
|
||||
>
|
||||
Test Category
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ const CategoryHeader = ({category, hasChannels}: Props) => {
|
|||
return (
|
||||
<TouchableOpacity
|
||||
onPress={toggleCollapse}
|
||||
testID={`category_header.${category.type}.collapsed.${category.collapsed}`}
|
||||
testID={`channel_list.category_header.${category.type}.collapsed.${category.collapsed}`}
|
||||
>
|
||||
<View style={[styles.container, category.muted ? styles.muted : null]}>
|
||||
<AnimatedCompassIcon
|
||||
|
|
@ -107,7 +107,7 @@ const CategoryHeader = ({category, hasChannels}: Props) => {
|
|||
/>
|
||||
<Text
|
||||
style={styles.heading}
|
||||
testID={`category_header.${category.type}.display_name`}
|
||||
testID={`channel_list.category_header.${category.type}.display_name`}
|
||||
>
|
||||
{displayName}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ const UnreadCategories = ({onChannelSwitch, onlyUnreads, unreadChannels, unreadT
|
|||
<ChannelItem
|
||||
channel={item}
|
||||
onPress={onChannelSwitch}
|
||||
testID='channel_list.category.unreads.channel_item'
|
||||
/>
|
||||
);
|
||||
}, [onChannelSwitch]);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ exports[`Search Field should match snapshot 1`] = `
|
|||
"padding": 8,
|
||||
}
|
||||
}
|
||||
testID="channel_list_subheader.search_field.button"
|
||||
>
|
||||
<Icon
|
||||
name="magnify"
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ const SearchField = () => {
|
|||
style={styles.container}
|
||||
onPress={onPress}
|
||||
underlayColor={changeOpacity(theme.sidebarText, 0.32)}
|
||||
testID='channel_list_subheader.search_field.button'
|
||||
>
|
||||
<>
|
||||
<CompassIcon
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ export const loginAnimationOptions = () => {
|
|||
export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) => {
|
||||
if (closeButtonId) {
|
||||
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.centerChannelColor);
|
||||
const closeButtonTestId = `${closeButtonId.replace('close-', 'close.').replace(/-/g, '_')}.button`;
|
||||
return {
|
||||
modalPresentationStyle: OptionsModalPresentationStyle.formSheet,
|
||||
modal: {
|
||||
|
|
@ -90,7 +91,7 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) =>
|
|||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
icon: closeButton,
|
||||
testID: closeButtonId,
|
||||
testID: closeButtonTestId,
|
||||
}],
|
||||
leftButtonColor: changeOpacity(theme.centerChannelColor, 0.56),
|
||||
background: {
|
||||
|
|
@ -724,7 +725,7 @@ export async function findChannels(title: string, theme: Theme) {
|
|||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
icon: closeButton,
|
||||
testID: closeButtonId,
|
||||
testID: 'close.find_channels.button',
|
||||
}],
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const PickReaction = ({openEmojiPicker, width, height}: PickReactionProps) => {
|
|||
style={[styles.container, {
|
||||
width, height,
|
||||
}]}
|
||||
testID='post_options.reaction_bar.pick_reaction'
|
||||
testID='post_options.reaction_bar.pick_reaction.button'
|
||||
>
|
||||
<CompassIcon
|
||||
onPress={openEmojiPicker}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ const EmojiAliases = ({emoji}: Props) => {
|
|||
ellipsizeMode='tail'
|
||||
numberOfLines={1}
|
||||
style={style.title}
|
||||
testID={`emoji_aliases.${emoji}`}
|
||||
>
|
||||
{aliases}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ const ReactorsList = ({location, reactions}: Props) => {
|
|||
scrollEnabled={enabled}
|
||||
scrollEventThrottle={60}
|
||||
{...panResponder.panHandlers}
|
||||
testID='reactors_list.flat_list'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ const Reactor = ({channelId, location, user}: Props) => {
|
|||
<UserItem
|
||||
containerStyle={style.container}
|
||||
user={user}
|
||||
testID='reactors_list.user_item'
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ function unsupportedServerAlert(intl: IntlShape) {
|
|||
|
||||
function buildServerModalOptions(theme: Theme, closeButtonId: string) {
|
||||
const closeButton = CompassIcon.getImageSourceSync('close', 24, changeOpacity(theme.centerChannelColor, 0.56));
|
||||
const closeButtonTestId = `${closeButtonId.replace('close-', 'close.').replace(/-/g, '_')}.button`;
|
||||
return {
|
||||
layout: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
|
|
@ -251,7 +252,7 @@ function buildServerModalOptions(theme: Theme, closeButtonId: string) {
|
|||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
icon: closeButton,
|
||||
testID: closeButtonId,
|
||||
testID: closeButtonTestId,
|
||||
}],
|
||||
leftButtonColor: undefined,
|
||||
title: {color: theme.sidebarHeaderTextColor},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import Post from './post';
|
|||
import PostDraft from './post_draft';
|
||||
import PostList from './post_list';
|
||||
import ProfilePicture from './profile_picture';
|
||||
import SearchBar from './search_bar';
|
||||
import SendButton from './send_button';
|
||||
import TeamSidebar from './team_sidebar';
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ export {
|
|||
PostDraft,
|
||||
PostList,
|
||||
ProfilePicture,
|
||||
SearchBar,
|
||||
SendButton,
|
||||
TeamSidebar,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import ProfilePicture from './profile_picture';
|
|||
|
||||
class Post {
|
||||
testID = {
|
||||
postProfilePicturePrefix: 'post_profile_picture.profile_picture.',
|
||||
postProfilePicturePrefix: 'post_profile_picture.',
|
||||
blockQuote: 'markdown_block_quote',
|
||||
editedIndicator: 'edited_indicator',
|
||||
emoji: 'markdown_emoji',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ class ProfilePicture {
|
|||
};
|
||||
|
||||
getProfilePictureItemMatcher = (profilePictureSourcePrefix: string, userId: string) => {
|
||||
const profilePictureTestID = `${profilePictureSourcePrefix}${userId}`;
|
||||
const profilePictureTestID = `${profilePictureSourcePrefix}${userId}.profile_picture`;
|
||||
return by.id(profilePictureTestID);
|
||||
};
|
||||
|
||||
|
|
|
|||
35
detox/e2e/support/ui/component/search_bar.ts
Normal file
35
detox/e2e/support/ui/component/search_bar.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {isAndroid} from '@support/utils';
|
||||
|
||||
class SearchBar {
|
||||
testID = {
|
||||
searchBarSuffix: 'search_bar',
|
||||
searchInputSuffix: 'search_bar.search.input',
|
||||
cancelButtonSuffix: 'search_bar.search.cancel.button',
|
||||
clearButtonSuffix: 'search_bar.search.clear.button',
|
||||
};
|
||||
|
||||
getSearchBar = (screenPrefix: string) => {
|
||||
return element(by.id(`${screenPrefix}${this.testID.searchBarSuffix}`));
|
||||
};
|
||||
|
||||
getSearchInput = (screenPrefix: string) => {
|
||||
return element(by.id(`${screenPrefix}${this.testID.searchInputSuffix}`)).atIndex(0);
|
||||
};
|
||||
|
||||
getCancelButton = (screenPrefix: string) => {
|
||||
if (isAndroid()) {
|
||||
return element(by.id(`${screenPrefix}${this.testID.cancelButtonSuffix}`)).atIndex(0);
|
||||
}
|
||||
return element(by.text('Cancel').withAncestor(by.id(`${screenPrefix}${this.testID.searchBarSuffix}`))).atIndex(0);
|
||||
};
|
||||
|
||||
getClearButton = (screenPrefix: string) => {
|
||||
return element(by.id(`${screenPrefix}${this.testID.clearButtonSuffix}`)).atIndex(0);
|
||||
};
|
||||
}
|
||||
|
||||
const searchBar = new SearchBar();
|
||||
export default searchBar;
|
||||
|
|
@ -87,7 +87,7 @@ class ChannelScreen {
|
|||
|
||||
open = async (categoryKey: string, channelName: string) => {
|
||||
// # Open channel screen
|
||||
await ChannelListScreen.getChannelListItemDisplayName(categoryKey, channelName).tap();
|
||||
await ChannelListScreen.getChannelItemDisplayName(categoryKey, channelName).tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class ChannelListScreen {
|
|||
headerServerDisplayName: 'channel_list_header.server_display_name',
|
||||
headerChevronButton: 'channel_list_header.chevron.button',
|
||||
headerPlusButton: 'channel_list_header.plus.button',
|
||||
subheaderSearchFieldButton: 'channel_list_subheader.search_field.button',
|
||||
findChannelsInput: 'channel_list.search_field.find_channels.input',
|
||||
threadsButton: 'channel_list.threads.button',
|
||||
};
|
||||
|
|
@ -26,6 +27,7 @@ class ChannelListScreen {
|
|||
headerServerDisplayName = element(by.id(this.testID.headerServerDisplayName));
|
||||
headerChevronButton = element(by.id(this.testID.headerChevronButton));
|
||||
headerPlusButton = element(by.id(this.testID.headerPlusButton));
|
||||
subheaderSearchFieldButton = element(by.id(this.testID.subheaderSearchFieldButton));
|
||||
findChannelsInput = element(by.id(this.testID.findChannelsInput));
|
||||
threadsButton = element(by.id(this.testID.threadsButton));
|
||||
|
||||
|
|
@ -36,19 +38,23 @@ class ChannelListScreen {
|
|||
openDirectMessageItem = PlusMenu.openDirectMessageItem;
|
||||
|
||||
getCategoryCollapsed = (categoryKey: string) => {
|
||||
return element(by.id(`category_header.${categoryKey}.collapsed.true`));
|
||||
return element(by.id(`channel_list.category_header.${categoryKey}.collapsed.true`));
|
||||
};
|
||||
|
||||
getCategoryExpanded = (categoryKey: string) => {
|
||||
return element(by.id(`category_header.${categoryKey}.collapsed.false`));
|
||||
return element(by.id(`channel_list.category_header.${categoryKey}.collapsed.false`));
|
||||
};
|
||||
|
||||
getCategoryHeaderDisplayName = (categoryKey: string) => {
|
||||
return element(by.id(`category_header.${categoryKey}.display_name`));
|
||||
return element(by.id(`channel_list.category_header.${categoryKey}.display_name`));
|
||||
};
|
||||
|
||||
getChannelListItemDisplayName = (categoryKey: string, channelName: string) => {
|
||||
return element(by.id(`category.${categoryKey}.channel_list_item.${channelName}.display_name`));
|
||||
getChannelItem = (categoryKey: string, channelName: string) => {
|
||||
return element(by.id(`channel_list.category.${categoryKey}.channel_item.${channelName}`));
|
||||
};
|
||||
|
||||
getChannelItemDisplayName = (categoryKey: string, channelName: string) => {
|
||||
return element(by.id(`channel_list.category.${categoryKey}.channel_item.${channelName}.display_name`));
|
||||
};
|
||||
|
||||
getTeamItemSelected = (teamId: string) => {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {timeouts} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class EditServerScreen {
|
||||
testID = {
|
||||
editServerScreen: 'edit_server.screen',
|
||||
closeButton: 'close-server-edit',
|
||||
closeButton: 'close.server_edit.button',
|
||||
headerTitle: 'edit_server_header.title',
|
||||
headerDescription: 'edit_server_header.description',
|
||||
serverDisplayNameInput: 'edit_server_form.server_display_name.input',
|
||||
|
|
@ -32,6 +33,11 @@ class EditServerScreen {
|
|||
|
||||
return this.editServerScreen;
|
||||
};
|
||||
|
||||
close = async () => {
|
||||
await this.closeButton.tap();
|
||||
await expect(this.editServerScreen).not.toBeVisible();
|
||||
};
|
||||
}
|
||||
|
||||
const editServerScreen = new EditServerScreen();
|
||||
|
|
|
|||
44
detox/e2e/support/ui/screen/emoji_picker.ts
Normal file
44
detox/e2e/support/ui/screen/emoji_picker.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SearchBar} from '@support/ui/component';
|
||||
import {PostOptionsScreen} from '@support/ui/screen';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class EmojiPickerScreen {
|
||||
testID = {
|
||||
emojiPickerScreen: 'emoji_picker.screen',
|
||||
emojiPickerPrefix: 'emoji_picker.',
|
||||
closeButton: 'close.emoji_picker.button',
|
||||
};
|
||||
|
||||
emojiPickerScreen = element(by.id(this.testID.emojiPickerScreen));
|
||||
closeButton = element(by.id(this.testID.closeButton));
|
||||
|
||||
// convenience props
|
||||
searchBar = SearchBar.getSearchBar(this.testID.emojiPickerPrefix);
|
||||
searchInput = SearchBar.getSearchInput(this.testID.emojiPickerPrefix);
|
||||
cancelButton = SearchBar.getCancelButton(this.testID.emojiPickerPrefix);
|
||||
clearButton = SearchBar.getClearButton(this.testID.emojiPickerPrefix);
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.emojiPickerScreen).toBeVisible();
|
||||
|
||||
return this.emojiPickerScreen;
|
||||
};
|
||||
|
||||
open = async () => {
|
||||
// # Open add reaction screen
|
||||
await PostOptionsScreen.pickReactionButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
};
|
||||
|
||||
close = async () => {
|
||||
await this.closeButton.tap();
|
||||
await expect(this.emojiPickerScreen).not.toBeVisible();
|
||||
};
|
||||
}
|
||||
|
||||
const emojiPickerScreen = new EmojiPickerScreen();
|
||||
export default emojiPickerScreen;
|
||||
71
detox/e2e/support/ui/screen/find_channels.ts
Normal file
71
detox/e2e/support/ui/screen/find_channels.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SearchBar} from '@support/ui/component';
|
||||
import {ChannelListScreen} from '@support/ui/screen';
|
||||
import {timeouts} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class FindChannelsScreen {
|
||||
testID = {
|
||||
findChannelsScreen: 'find_channels.screen',
|
||||
findChannelsPrefix: 'find_channels.',
|
||||
closeButton: 'close.find_channels.button',
|
||||
directoryQuickOption: 'find_channels.quick_options.directory.option',
|
||||
openDirectMessageQuickOption: 'find_channels.quick_options.open_dm.option',
|
||||
newChannelQuickOption: 'find_channels.quick_options.new_channel.option',
|
||||
sectionUnfilteredChannelList: 'find_channels.unfiltered_list.section_list',
|
||||
flatFilteredChannelList: 'find_channels.filtered_list.flat_list',
|
||||
};
|
||||
|
||||
findChannelsScreen = element(by.id(this.testID.findChannelsScreen));
|
||||
closeButton = element(by.id(this.testID.closeButton));
|
||||
directoryQuickOption = element(by.id(this.testID.directoryQuickOption));
|
||||
openDirectMessageQuickOption = element(by.id(this.testID.openDirectMessageQuickOption));
|
||||
newChannelQuickOption = element(by.id(this.testID.newChannelQuickOption));
|
||||
sectionUnfilteredChannelList = element(by.id(this.testID.sectionUnfilteredChannelList));
|
||||
flatFilteredChannelList = element(by.id(this.testID.flatFilteredChannelList));
|
||||
|
||||
// convenience props
|
||||
searchBar = SearchBar.getSearchBar(this.testID.findChannelsPrefix);
|
||||
searchInput = SearchBar.getSearchInput(this.testID.findChannelsPrefix);
|
||||
cancelButton = SearchBar.getCancelButton(this.testID.findChannelsPrefix);
|
||||
clearButton = SearchBar.getClearButton(this.testID.findChannelsPrefix);
|
||||
|
||||
getUnfilteredChannelItem = (channelName: string) => {
|
||||
return element(by.id(`find_channels.unfiltered_list.channel_item.${channelName}`));
|
||||
};
|
||||
|
||||
getUnfilteredChannelItemDisplayName = (channelName: string) => {
|
||||
return element(by.id(`find_channels.unfiltered_list.channel_item.${channelName}.display_name`));
|
||||
};
|
||||
|
||||
getFilteredChannelItem = (channelName: string) => {
|
||||
return element(by.id(`find_channels.filtered_list.channel_item.${channelName}`));
|
||||
};
|
||||
|
||||
getFilteredChannelItemDisplayName = (channelName: string) => {
|
||||
return element(by.id(`find_channels.filtered_list.channel_item.${channelName}.display_name`));
|
||||
};
|
||||
|
||||
toBeVisible = async () => {
|
||||
await waitFor(this.findChannelsScreen).toExist().withTimeout(timeouts.TEN_SEC);
|
||||
|
||||
return this.findChannelsScreen;
|
||||
};
|
||||
|
||||
open = async () => {
|
||||
// # Open find channels screen
|
||||
await ChannelListScreen.subheaderSearchFieldButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
};
|
||||
|
||||
close = async () => {
|
||||
await this.closeButton.tap();
|
||||
await expect(this.findChannelsScreen).not.toBeVisible();
|
||||
};
|
||||
}
|
||||
|
||||
const findChannelsScreen = new FindChannelsScreen();
|
||||
export default findChannelsScreen;
|
||||
|
|
@ -10,11 +10,14 @@ import CreateDirectMessageScreen from './create_direct_message';
|
|||
import CreateOrEditChannelScreen from './create_or_edit_channel';
|
||||
import EditPostScreen from './edit_post';
|
||||
import EditServerScreen from './edit_server';
|
||||
import EmojiPickerScreen from './emoji_picker';
|
||||
import FindChannelsScreen from './find_channels';
|
||||
import GlobalThreadsScreen from './global_threads';
|
||||
import HomeScreen from './home';
|
||||
import LoginScreen from './login';
|
||||
import PermalinkScreen from './permalink';
|
||||
import PostOptionsScreen from './post_options';
|
||||
import ReactionsScreen from './reactions';
|
||||
import ServerScreen from './server';
|
||||
import ServerListScreen from './server_list';
|
||||
import ThreadScreen from './thread';
|
||||
|
|
@ -30,11 +33,14 @@ export {
|
|||
CreateOrEditChannelScreen,
|
||||
EditPostScreen,
|
||||
EditServerScreen,
|
||||
EmojiPickerScreen,
|
||||
FindChannelsScreen,
|
||||
GlobalThreadsScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PermalinkScreen,
|
||||
PostOptionsScreen,
|
||||
ReactionsScreen,
|
||||
ServerScreen,
|
||||
ServerListScreen,
|
||||
ThreadScreen,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class PostOptionsScreen {
|
|||
reactionEmojiPrefix: 'post_options.reaction_bar.reaction.',
|
||||
postOptionsScreen: 'post_options.screen',
|
||||
postOptionsBackdrop: 'post_options.backdrop',
|
||||
pickReaction: 'post_options.reaction_bar.pick_reaction',
|
||||
pickReactionButton: 'post_options.reaction_bar.pick_reaction.button',
|
||||
replyPostOption: 'post_options.reply_post.option',
|
||||
followThreadOption: 'post_options.follow_thread.option',
|
||||
followingThreadOption: 'post_options.following_thread.option',
|
||||
|
|
@ -27,7 +27,7 @@ class PostOptionsScreen {
|
|||
|
||||
postOptionsScreen = element(by.id(this.testID.postOptionsScreen));
|
||||
postOptionsBackdrop = element(by.id(this.testID.postOptionsBackdrop));
|
||||
pickReaction = element(by.id(this.testID.pickReaction));
|
||||
pickReactionButton = element(by.id(this.testID.pickReactionButton));
|
||||
replyPostOption = element(by.id(this.testID.replyPostOption));
|
||||
followThreadOption = element(by.id(this.testID.followThreadOption));
|
||||
followingThreadOption = element(by.id(this.testID.followingThreadOption));
|
||||
|
|
|
|||
48
detox/e2e/support/ui/screen/reactions.ts
Normal file
48
detox/e2e/support/ui/screen/reactions.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect} from 'detox';
|
||||
|
||||
class ReactionsScreen {
|
||||
testID = {
|
||||
reactorItemPrefix: 'reactors_list.user_item.',
|
||||
reactionsScreen: 'reactions.screen',
|
||||
reactionsBackdrop: 'reactions.backdrop',
|
||||
flatReactorsList: 'reactors_list.flat_list',
|
||||
};
|
||||
|
||||
reactionsScreen = element(by.id(this.testID.reactionsScreen));
|
||||
reactionsBackdrop = element(by.id(this.testID.reactionsBackdrop));
|
||||
flatReactorsList = element(by.id(this.testID.flatReactorsList));
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.reactionsScreen).toExist();
|
||||
|
||||
return reactionsScreen;
|
||||
};
|
||||
|
||||
close = async () => {
|
||||
await this.reactionsBackdrop.tap({x: 5, y: 10});
|
||||
await expect(this.reactionsScreen).not.toBeVisible();
|
||||
};
|
||||
|
||||
getReactorItem = (userId: string, emojiName: string) => {
|
||||
const reactorItemEmojiAliasesMatcher = by.id(`emoji_aliases.${emojiName}`);
|
||||
const reactorItemUserTestId = `${this.testID.reactorItemPrefix}${userId}`;
|
||||
const reactorItemUserMatcher = by.id(reactorItemUserTestId);
|
||||
const reactorItemUserProfilePictureMatcher = by.id(`${reactorItemUserTestId}.profile_picture`);
|
||||
const reactorItemUserDisplayNameMatcher = by.id(`${reactorItemUserTestId}.display_name`);
|
||||
const reactorItemUserUsernameMatcher = by.id(`${reactorItemUserTestId}.username`);
|
||||
|
||||
return {
|
||||
reactorItemEmojiAliases: element(reactorItemEmojiAliasesMatcher),
|
||||
reactorItemUser: element(reactorItemUserMatcher),
|
||||
reactorItemUserProfilePicture: element(reactorItemUserProfilePictureMatcher),
|
||||
reactorItemUserDisplayName: element(reactorItemUserDisplayNameMatcher),
|
||||
reactorItemUserUsername: element(reactorItemUserUsernameMatcher),
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const reactionsScreen = new ReactionsScreen();
|
||||
export default reactionsScreen;
|
||||
|
|
@ -7,7 +7,7 @@ import {expect} from 'detox';
|
|||
class ServerScreen {
|
||||
testID = {
|
||||
serverScreen: 'server.screen',
|
||||
closeButton: 'close-server',
|
||||
closeButton: 'close.server.button',
|
||||
headerTitleAddServer: 'server_header.title.add_server',
|
||||
headerTitleConnectToServer: 'server_header.title.connect_to_server',
|
||||
headerWelcome: 'server_header.welcome',
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ describe('Channels - Browse Channels', () => {
|
|||
const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
|
||||
|
||||
// * Verify new channel does not appear on channel list screen
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, channel.display_name)).not.toExist();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, channel.display_name)).not.toExist();
|
||||
|
||||
// # Open browse channels screen and search for the new channel name to join
|
||||
await BrowseChannelsScreen.open();
|
||||
|
|
@ -89,6 +89,20 @@ describe('Channels - Browse Channels', () => {
|
|||
await ChannelListScreen.toBeVisible();
|
||||
|
||||
// * Verify newly joined channel is added to channel list
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, channel.name)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, channel.name)).toBeVisible();
|
||||
});
|
||||
|
||||
it('MM-T4729_3 - should display empty search state for browse channels', async () => {
|
||||
// # Open browse channels screen and search for a non-existent channel
|
||||
const searchTerm = 'blahblahblahblah';
|
||||
await BrowseChannelsScreen.open();
|
||||
await BrowseChannelsScreen.searchInput.replaceText(searchTerm);
|
||||
|
||||
// * Verify empty search state for browse channels
|
||||
await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
|
||||
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await BrowseChannelsScreen.close();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import {
|
|||
ChannelListScreen,
|
||||
CreateDirectMessageScreen,
|
||||
CreateOrEditChannelScreen,
|
||||
FindChannelsScreen,
|
||||
GlobalThreadsScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
|
|
@ -75,15 +76,15 @@ describe('Channels - Channel List', () => {
|
|||
await expect(ChannelListScreen.headerPlusButton).toBeVisible();
|
||||
await expect(ChannelListScreen.threadsButton).toBeVisible();
|
||||
await expect(ChannelListScreen.getCategoryHeaderDisplayName(channelsCategory)).toHaveText('CHANNELS');
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, testChannel.name)).toHaveText(testChannel.display_name);
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, offTopicChannelName)).toHaveText('Off-Topic');
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, townSquareChannelName)).toHaveText('Town Square');
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name)).toHaveText(testChannel.display_name);
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, offTopicChannelName)).toHaveText('Off-Topic');
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, townSquareChannelName)).toHaveText('Town Square');
|
||||
await expect(ChannelListScreen.getCategoryHeaderDisplayName(directMessagesCategory)).toHaveText('DIRECT MESSAGES');
|
||||
});
|
||||
|
||||
it('MM-T4728_2 - should be able to switch between channels', async () => {
|
||||
// # Tap on a first channel
|
||||
await ChannelListScreen.getChannelListItemDisplayName(channelsCategory, testChannel.name).tap();
|
||||
await ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name).tap();
|
||||
|
||||
// * Verify on first channel
|
||||
await ChannelScreen.toBeVisible();
|
||||
|
|
@ -93,7 +94,7 @@ describe('Channels - Channel List', () => {
|
|||
// # Go back to channel list screen and tap on a second channel
|
||||
await ChannelScreen.back();
|
||||
await ChannelListScreen.toBeVisible();
|
||||
await ChannelListScreen.getChannelListItemDisplayName(channelsCategory, offTopicChannelName).tap();
|
||||
await ChannelListScreen.getChannelItemDisplayName(channelsCategory, offTopicChannelName).tap();
|
||||
|
||||
// * Verify on second channel
|
||||
await ChannelScreen.toBeVisible();
|
||||
|
|
@ -117,18 +118,18 @@ describe('Channels - Channel List', () => {
|
|||
|
||||
// * Verify category is collapsed and channels are not listed
|
||||
await expect(ChannelListScreen.getCategoryCollapsed(channelsCategory)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, testChannel.name)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, offTopicChannelName)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, townSquareChannelName)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, offTopicChannelName)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, townSquareChannelName)).not.toBeVisible();
|
||||
|
||||
// # Toggle channels category to expand
|
||||
await ChannelListScreen.getCategoryCollapsed(channelsCategory).tap();
|
||||
|
||||
// * Verify category is expanded and all channels are listed
|
||||
await expect(ChannelListScreen.getCategoryExpanded(channelsCategory)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, testChannel.name)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, offTopicChannelName)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(channelsCategory, townSquareChannelName)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, testChannel.name)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, offTopicChannelName)).toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(channelsCategory, townSquareChannelName)).toBeVisible();
|
||||
});
|
||||
|
||||
it('MM-T4728_4 - should be able to go to browse channels screen', async () => {
|
||||
|
|
@ -179,8 +180,15 @@ describe('Channels - Channel List', () => {
|
|||
await GlobalThreadsScreen.back();
|
||||
});
|
||||
|
||||
xit('MM-T4728_8 - should be able to find channels', async () => {
|
||||
// NOT YET IMPLEMENTED
|
||||
it('MM-T4728_8 - should be able to go to find channels screen', async () => {
|
||||
// # Tap on search field button
|
||||
await ChannelListScreen.subheaderSearchFieldButton.tap();
|
||||
|
||||
// * Verify on find channels screen
|
||||
await FindChannelsScreen.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await FindChannelsScreen.close();
|
||||
});
|
||||
|
||||
it('MM-T4728_9 - should be able to switch between teams', async () => {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ describe('Channels - Create Direct Message', () => {
|
|||
|
||||
// * Verify no direct message channel for the new user appears on channel list screen
|
||||
const newUserDisplayName = newUser.username;
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(directMessagesCategory, newUserDisplayName)).not.toBeVisible();
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(directMessagesCategory, newUserDisplayName)).not.toBeVisible();
|
||||
|
||||
// # Open create direct message screen and search for the new user
|
||||
await CreateDirectMessageScreen.open();
|
||||
|
|
@ -105,7 +105,7 @@ describe('Channels - Create Direct Message', () => {
|
|||
|
||||
// * Verify direct message channel for the new user is added to direct message list
|
||||
const {channel: directMessageChannel} = await Channel.apiCreateDirectChannel(siteOneUrl, [testUser.id, newUser.id]);
|
||||
await expect(ChannelListScreen.getChannelListItemDisplayName(directMessagesCategory, directMessageChannel.name)).toHaveText(newUserDisplayName);
|
||||
await expect(ChannelListScreen.getChannelItemDisplayName(directMessagesCategory, directMessageChannel.name)).toHaveText(newUserDisplayName);
|
||||
});
|
||||
|
||||
it('MM-T4730_3 - should be able to create a group message', async () => {
|
||||
|
|
@ -152,4 +152,18 @@ describe('Channels - Create Direct Message', () => {
|
|||
// * Verify group message channel for the other two new users is added to direct message list
|
||||
await expect(element(by.text(groupDisplayName))).toBeVisible();
|
||||
});
|
||||
|
||||
it('MM-T4730_4 - should display empty search state for create direct message', async () => {
|
||||
// # Open create direct message screen and search for a non-existent user
|
||||
const searchTerm = 'blahblahblahblah';
|
||||
await CreateDirectMessageScreen.open();
|
||||
await CreateDirectMessageScreen.searchInput.replaceText(searchTerm);
|
||||
|
||||
// * Verify empty search state for create direct message
|
||||
await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
|
||||
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await CreateDirectMessageScreen.close();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
181
detox/e2e/test/messaging/emojis_and_reactions.e2e.ts
Normal file
181
detox/e2e/test/messaging/emojis_and_reactions.e2e.ts
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
// 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 {
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
serverOneUrl,
|
||||
siteOneUrl,
|
||||
} from '@support/test_config';
|
||||
import {
|
||||
ChannelListScreen,
|
||||
ChannelScreen,
|
||||
EmojiPickerScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PostOptionsScreen,
|
||||
ReactionsScreen,
|
||||
ServerScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
describe('Messaging - Emojis and Reactions', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
let testChannel: any;
|
||||
let testUser: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, user} = await Setup.apiInit(siteOneUrl);
|
||||
testChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
// # Log in to server
|
||||
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
|
||||
await LoginScreen.login(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// * Verify on channel list screen
|
||||
await ChannelListScreen.toBeVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// # Log out
|
||||
await HomeScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T4862_1 - should be able to view recent reactions and add new reaction via post options', async () => {
|
||||
// # Open a channel screen, post a message, and open post options for message
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
|
||||
// * Verify six default reactions are displayed
|
||||
await expect(PostOptionsScreen.getReactionEmoji('+1')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('smiley')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('white_check_mark')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('heart')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('eyes')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('raised_hands')).toBeVisible();
|
||||
|
||||
// # Open emoji picker screen and add a new reaction
|
||||
await EmojiPickerScreen.open();
|
||||
await EmojiPickerScreen.searchInput.typeText('clown_face');
|
||||
await element(by.text('🤡')).tap();
|
||||
|
||||
// * Verify new reaction is added to the message
|
||||
await expect(element(by.text('🤡').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toBeVisible();
|
||||
|
||||
// # Open post options for message
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
|
||||
// * Verify recent reactions are displayed, newest reaction first and then the first five default reactions
|
||||
await expect(PostOptionsScreen.getReactionEmoji('clown_face')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('+1')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('smiley')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('white_check_mark')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('heart')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('eyes')).toBeVisible();
|
||||
await expect(PostOptionsScreen.getReactionEmoji('raised_hands')).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await PostOptionsScreen.close();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4862_2 - should be able to long press on a reaction to view the list of users who reacted', async () => {
|
||||
// # Open a channel screen, post a message, open post options for message, open emoji picker screen, and add a reaction
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await EmojiPickerScreen.open();
|
||||
await EmojiPickerScreen.searchInput.typeText('fire');
|
||||
await element(by.text('🔥')).tap();
|
||||
|
||||
// * Verify reaction is added to the message
|
||||
const reaction = element(by.text('🔥').withAncestor(by.id(`channel.post_list.post.${post.id}`)));
|
||||
await expect(reaction).toBeVisible();
|
||||
|
||||
// # Long press on the reaction
|
||||
await reaction.longPress();
|
||||
|
||||
// * Verify user who reacted with the emoji
|
||||
await ReactionsScreen.toBeVisible();
|
||||
const {reactorItemEmojiAliases, reactorItemUserProfilePicture, reactorItemUserDisplayName, reactorItemUserUsername} = ReactionsScreen.getReactorItem(testUser.id, 'fire');
|
||||
await expect(reactorItemEmojiAliases).toHaveText(':fire:');
|
||||
await expect(reactorItemUserProfilePicture).toBeVisible();
|
||||
await expect(reactorItemUserDisplayName).toHaveText(`${testUser.first_name} ${testUser.last_name}`);
|
||||
await expect(reactorItemUserUsername).toHaveText(` @${testUser.username}`);
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ReactionsScreen.close();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4862_3 - should be able to include emojis in a message and be able to find them in emoji bar and recently used section', async () => {
|
||||
// # Open a channel screen and post a message that includes emojis
|
||||
const message = 'The quick brown fox :fox_face: jumps over the lazy dog :dog:';
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
|
||||
// * Verify message is posted with emojis
|
||||
const resolvedMessage = 'The quick brown fox 🦊 jumps over the lazy dog 🐶';
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, resolvedMessage);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options for message
|
||||
await ChannelScreen.openPostOptionsFor(post.id, resolvedMessage);
|
||||
await PostOptionsScreen.toBeVisible();
|
||||
|
||||
// * Verify emojis exist in emoji bar
|
||||
await expect(element(by.text('🦊'))).toExist();
|
||||
await expect(element(by.text('🐶'))).toExist();
|
||||
|
||||
// # Open emoji picker screen
|
||||
await EmojiPickerScreen.open();
|
||||
|
||||
// * Verify emojis exist in recently used section
|
||||
await expect(element(by.text('Recently Used'))).toExist();
|
||||
await expect(element(by.text('🦊'))).toExist();
|
||||
await expect(element(by.text('🐶'))).toExist();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await EmojiPickerScreen.close();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4862_4 - should display empty search state for emoji picker', async () => {
|
||||
// # Open a channel screen, post a message, open post options for message, open emoji picker screen, and search for a non-existent emoji
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const searchTerm = 'blahblahblahblah';
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await EmojiPickerScreen.open();
|
||||
await EmojiPickerScreen.searchInput.typeText(searchTerm);
|
||||
|
||||
// * Verify empty search state for emoji picker
|
||||
await expect(element(by.text(`No results for “${searchTerm}”`))).toBeVisible();
|
||||
await expect(element(by.text('Check the spelling or try another search.'))).toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await EmojiPickerScreen.close();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
});
|
||||
105
detox/e2e/test/messaging/follow_and_unfollow_messsage.e2e.ts
Normal file
105
detox/e2e/test/messaging/follow_and_unfollow_messsage.e2e.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// 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 {
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
serverOneUrl,
|
||||
siteOneUrl,
|
||||
} from '@support/test_config';
|
||||
import {
|
||||
ChannelListScreen,
|
||||
ChannelScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PostOptionsScreen,
|
||||
ServerScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
describe('Messaging - Follow and Unfollow Message', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
let testChannel: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, user} = await Setup.apiInit(siteOneUrl);
|
||||
testChannel = channel;
|
||||
|
||||
// # Log in to server
|
||||
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
|
||||
await LoginScreen.login(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// * Verify on channel list screen
|
||||
await ChannelListScreen.toBeVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// # Log out
|
||||
await HomeScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T4863_1 - should be able to follow/unfollow a message via post options', async () => {
|
||||
// # Open a channel screen and post a message
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
|
||||
// * Verify message is posted
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on follow message option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.followThreadOption.tap();
|
||||
|
||||
// * Verify message is followed by user via post footer
|
||||
const {postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemFooterFollowingButton).toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on unfollow message option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.followingThreadOption.tap();
|
||||
|
||||
// * Verify message is not followed by user via post footer
|
||||
await expect(postListPostItemFooterFollowingButton).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4863_2 - should be able to unfollow a message via post footer', async () => {
|
||||
// # Open a channel screen, post a message, open post options for message, and tap on follow message option
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.followThreadOption.tap();
|
||||
|
||||
// * Verify message is followed by user via post footer
|
||||
const {postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemFooterFollowingButton).toBeVisible();
|
||||
|
||||
// # Tap on following button via post footer
|
||||
await postListPostItemFooterFollowingButton.tap();
|
||||
|
||||
// * Verify message is not followed by user via post footer
|
||||
await expect(postListPostItemFooterFollowingButton).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
});
|
||||
|
|
@ -85,7 +85,7 @@ describe('Messaging - Message Reply', () => {
|
|||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4785_2 - should be able to open reply thread by tapping the post', async () => {
|
||||
it('MM-T4785_2 - should be able to open reply thread by tapping on the post', async () => {
|
||||
// # Open a channel screen and post a message
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
|
|
@ -96,7 +96,7 @@ describe('Messaging - Message Reply', () => {
|
|||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toExist();
|
||||
|
||||
// # Tap the post
|
||||
// # Tap on post to open thread
|
||||
await postListPostItem.tap();
|
||||
|
||||
// * Verify on reply thread screen
|
||||
|
|
|
|||
111
detox/e2e/test/messaging/pin_and_unpin_message.e2e.ts
Normal file
111
detox/e2e/test/messaging/pin_and_unpin_message.e2e.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// 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 {
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
serverOneUrl,
|
||||
siteOneUrl,
|
||||
} from '@support/test_config';
|
||||
import {
|
||||
ChannelListScreen,
|
||||
ChannelScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PostOptionsScreen,
|
||||
ServerScreen,
|
||||
ThreadScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
describe('Messaging - Pin and Unpin Message', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
const pinnedText = 'Pinned';
|
||||
let testChannel: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, user} = await Setup.apiInit(siteOneUrl);
|
||||
testChannel = channel;
|
||||
|
||||
// # Log in to server
|
||||
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
|
||||
await LoginScreen.login(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// * Verify on channel list screen
|
||||
await ChannelListScreen.toBeVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// # Log out
|
||||
await HomeScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T4865_1 - should be able to pin/unpin a message via post options on channel screen', async () => {
|
||||
// # Open a channel screen and post a message
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
|
||||
// * Verify message is posted
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on pin to channel option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.pinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemPreHeaderText).toHaveText(pinnedText);
|
||||
|
||||
// # Open post options for message and tap on unpin from channel option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.unpinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is not displayed on the post pre-header
|
||||
await expect(postListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4865_2 - should be able to pin/unpin a message via post options on thread screen', async () => {
|
||||
// # Open a channel screen, post a message, tap on post to open thread, open post options for message, and tap on pin to channel option
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await postListPostItem.tap();
|
||||
await ThreadScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.pinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText} = ThreadScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemPreHeaderText).toHaveText(pinnedText);
|
||||
|
||||
// # Open post options for message and tap on unpin from channel option
|
||||
await ThreadScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.unpinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is not displayed on the post pre-header
|
||||
await expect(postListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ThreadScreen.back();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
});
|
||||
111
detox/e2e/test/messaging/save_and_unsave_message.e2e.ts
Normal file
111
detox/e2e/test/messaging/save_and_unsave_message.e2e.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// 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 {
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
serverOneUrl,
|
||||
siteOneUrl,
|
||||
} from '@support/test_config';
|
||||
import {
|
||||
ChannelListScreen,
|
||||
ChannelScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PostOptionsScreen,
|
||||
ServerScreen,
|
||||
ThreadScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {getRandomId} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
describe('Messaging - Save and Unsave Message', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
const savedText = 'Saved';
|
||||
let testChannel: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, user} = await Setup.apiInit(siteOneUrl);
|
||||
testChannel = channel;
|
||||
|
||||
// # Log in to server
|
||||
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
|
||||
await LoginScreen.login(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// * Verify on channel list screen
|
||||
await ChannelListScreen.toBeVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// # Log out
|
||||
await HomeScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T4864_1 - should be able to save/unsave a message via post options on channel screen', async () => {
|
||||
// # Open a channel screen and post a message
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
|
||||
// * Verify message is posted
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on save option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.savePostOption.tap();
|
||||
|
||||
// * Verify saved text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemPreHeaderText).toHaveText(savedText);
|
||||
|
||||
// # Open post options for message and tap on unsave option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.unsavePostOption.tap();
|
||||
|
||||
// * Verify saved text is not displayed on the post pre-header
|
||||
await expect(postListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4864_2 - should be able to save/unsave a message via post options on thread screen', async () => {
|
||||
// # Open a channel screen, post a message, tap on post to open thread, open post options for message, and tap on save option
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await postListPostItem.tap();
|
||||
await ThreadScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.savePostOption.tap();
|
||||
|
||||
// * Verify saved text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText} = ThreadScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemPreHeaderText).toHaveText(savedText);
|
||||
|
||||
// # Open post options for message and tap on unsave option
|
||||
await ThreadScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.unsavePostOption.tap();
|
||||
|
||||
// * Verify saved text is not displayed on the post pre-header
|
||||
await expect(postListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ThreadScreen.back();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
});
|
||||
|
|
@ -85,6 +85,7 @@ describe('Server Login - Connect to Server', () => {
|
|||
await expect(serverUrlInputError).toHaveText(connectionError);
|
||||
|
||||
// # Connect with invalid host and valid server display name
|
||||
await device.reloadReactNative();
|
||||
await serverUrlInput.replaceText('wrong.host.badssl.com');
|
||||
await serverDisplayNameInput.replaceText('Server 1');
|
||||
await connectButton.tap();
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ describe('Server Login - Server List', () => {
|
|||
|
||||
// * Verify on channel list screen of the second server
|
||||
await ChannelListScreen.toBeVisible();
|
||||
await device.reloadReactNative();
|
||||
await expect(ChannelListScreen.headerServerDisplayName).toHaveText(serverTwoDisplayName);
|
||||
|
||||
// # Open server list screen
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
ChannelScreen,
|
||||
ChannelListScreen,
|
||||
EditPostScreen,
|
||||
EmojiPickerScreen,
|
||||
HomeScreen,
|
||||
LoginScreen,
|
||||
PostOptionsScreen,
|
||||
|
|
@ -31,6 +32,8 @@ import {expect} from 'detox';
|
|||
describe('Smoke Test - Messaging', () => {
|
||||
const serverOneDisplayName = 'Server 1';
|
||||
const channelsCategory = 'channels';
|
||||
const savedText = 'Saved';
|
||||
const pinnedText = 'Pinned';
|
||||
let testChannel: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
|
|
@ -116,4 +119,83 @@ describe('Smoke Test - Messaging', () => {
|
|||
await ThreadScreen.back();
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4786_3 - should be able to include emojis in a message and add reaction to a message', async () => {
|
||||
// # Open a channel screen and post a message that includes emojis
|
||||
const message = 'The quick brown fox :fox_face: jumps over the lazy dog :dog:';
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
|
||||
// * Verify message is posted with emojis
|
||||
const resolvedMessage = 'The quick brown fox 🦊 jumps over the lazy dog 🐶';
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
const {postListPostItem} = ChannelScreen.getPostListPostItem(post.id, resolvedMessage);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open post options for message, open emoji picker screen, and add a reaction
|
||||
await ChannelScreen.openPostOptionsFor(post.id, resolvedMessage);
|
||||
await EmojiPickerScreen.open();
|
||||
await EmojiPickerScreen.searchInput.typeText('clown_face');
|
||||
await element(by.text('🤡')).tap();
|
||||
|
||||
// * Verify reaction is added to the message
|
||||
await expect(element(by.text('🤡').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
|
||||
it('MM-T4786_4 - should be able to follow/unfollow a message, save/unsave a message, and pin/unpin a message', async () => {
|
||||
// # Open a channel screen, post a message, open post options for message, and tap on follow message option
|
||||
const message = `Message ${getRandomId()}`;
|
||||
await ChannelScreen.open(channelsCategory, testChannel.name);
|
||||
await ChannelScreen.postMessage(message);
|
||||
const {post} = await Post.apiGetLastPostInChannel(siteOneUrl, testChannel.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.followThreadOption.tap();
|
||||
|
||||
// * Verify message is followed by user via post footer
|
||||
const {postListPostItem, postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(postListPostItemFooterFollowingButton).toBeVisible();
|
||||
|
||||
// # Tap on following button via post footer
|
||||
await postListPostItemFooterFollowingButton.tap();
|
||||
|
||||
// * Verify message is not followed by user via post footer
|
||||
await expect(postListPostItemFooterFollowingButton).not.toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on save option
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.savePostOption.tap();
|
||||
|
||||
// * Verify saved text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText: channelPostListPostItemPreHeaderText} = ChannelScreen.getPostListPostItem(post.id, message);
|
||||
await expect(channelPostListPostItemPreHeaderText).toHaveText(savedText);
|
||||
|
||||
// # Tap on post to open thread and tap on thread overview unsave button
|
||||
await postListPostItem.tap();
|
||||
await ThreadScreen.getThreadOverviewUnsaveButton().tap();
|
||||
|
||||
// * Verify saved text is not displayed on the post pre-header
|
||||
await expect(channelPostListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Open post options for message and tap on pin to channel option
|
||||
await ThreadScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.pinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is displayed on the post pre-header
|
||||
const {postListPostItemPreHeaderText: threadPostListPostItemPreHeaderText} = ThreadScreen.getPostListPostItem(post.id, message);
|
||||
await expect(threadPostListPostItemPreHeaderText).toHaveText(pinnedText);
|
||||
|
||||
// # Go back to channel, open post options for message, and tap on unpin from channel option
|
||||
await ThreadScreen.back();
|
||||
await ChannelScreen.openPostOptionsFor(post.id, message);
|
||||
await PostOptionsScreen.unpinPostOption.tap();
|
||||
|
||||
// * Verify pinned text is not displayed on the post pre-header
|
||||
await expect(channelPostListPostItemPreHeaderText).not.toBeVisible();
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ describe('Smoke Test - Server Login', () => {
|
|||
|
||||
// * Verify on channel list screen of the second server
|
||||
await ChannelListScreen.toBeVisible();
|
||||
await device.reloadReactNative();
|
||||
await expect(ChannelListScreen.headerServerDisplayName).toHaveText(serverTwoDisplayName);
|
||||
|
||||
// # Go back to first server
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ describe('Smoke Test - Threads', () => {
|
|||
// # Go back to channel list screen, then go to global threads screen, tap on all your threads button, open thread options for thread, tap on mark as unread option, and tap on unread threads button
|
||||
await ThreadScreen.back();
|
||||
await ChannelScreen.back();
|
||||
await device.reloadReactNative();
|
||||
await GlobalThreadsScreen.open();
|
||||
await GlobalThreadsScreen.headerAllThreadsButton.tap();
|
||||
await GlobalThreadsScreen.openThreadOptionsFor(parentPost.id);
|
||||
|
|
|
|||
Loading…
Reference in a new issue