MM-30286 Detox/E2E: Add e2e test for MM-T3222 and some cleanup (#4959)
* MM-30286 Detox/E2E: Add e2e test for MM-T3222 and some cleanup * Fix merge issues * Fix more issues * Fixed new line * Remove redundant check * Updated instance to getElement Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
402c312f8f
commit
4f668f0fdf
89 changed files with 961 additions and 361 deletions
|
|
@ -5,7 +5,6 @@ exports[`PasteableTextInput should render pasteable text input 1`] = `
|
|||
allowFontScaling={true}
|
||||
onPaste={[Function]}
|
||||
rejectResponderTermination={true}
|
||||
testID="post.input"
|
||||
underlineColorAndroid="transparent"
|
||||
>
|
||||
My Text
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ export class PasteableTextInput extends React.PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {forwardRef, ...props} = this.props;
|
||||
const {testID, forwardRef, ...props} = this.props;
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
testID='post.input'
|
||||
testID={testID}
|
||||
{...props}
|
||||
onPaste={this.onPaste}
|
||||
ref={forwardRef}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
|||
|
||||
export default class Post extends PureComponent {
|
||||
static propTypes = {
|
||||
testID: PropTypes.string,
|
||||
actions: PropTypes.shape({
|
||||
createPost: PropTypes.func.isRequired,
|
||||
insertToDraft: PropTypes.func.isRequired,
|
||||
|
|
@ -240,6 +241,7 @@ export default class Post extends PureComponent {
|
|||
|
||||
render() {
|
||||
const {
|
||||
testID,
|
||||
channelIsReadOnly,
|
||||
commentedOnPost,
|
||||
highlight,
|
||||
|
|
@ -323,7 +325,10 @@ export default class Post extends PureComponent {
|
|||
const rightColumnStyle = [style.rightColumn, (commentedOnPost && isLastReply && style.rightColumnPadding)];
|
||||
|
||||
return (
|
||||
<View style={[style.postStyle, highlighted, padding(isLandscape)]}>
|
||||
<View
|
||||
testID={testID}
|
||||
style={[style.postStyle, highlighted, padding(isLandscape)]}
|
||||
>
|
||||
<TouchableWithFeedback
|
||||
onPress={this.handlePress}
|
||||
onLongPress={this.showPostOptions}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ exports[`PostDraft Should render the Archived for channelIsArchived 1`] = `
|
|||
"paddingTop": 10,
|
||||
}
|
||||
}
|
||||
testID="post_draft.archived"
|
||||
>
|
||||
<Text>
|
||||
<Text
|
||||
|
|
@ -116,6 +117,7 @@ exports[`PostDraft Should render the Archived for deactivatedChannel 1`] = `
|
|||
"paddingTop": 10,
|
||||
}
|
||||
}
|
||||
testID="post_draft.archived"
|
||||
>
|
||||
<Text>
|
||||
<Text
|
||||
|
|
@ -266,6 +268,7 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
null,
|
||||
]
|
||||
}
|
||||
testID="post_draft"
|
||||
>
|
||||
<RCTScrollView
|
||||
contentContainerStyle={
|
||||
|
|
@ -316,7 +319,7 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
"paddingTop": 6,
|
||||
}
|
||||
}
|
||||
testID="post.input"
|
||||
testID="post_draft.post.input"
|
||||
textContentType="none"
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
|
|
@ -534,7 +537,7 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
"paddingRight": 8,
|
||||
}
|
||||
}
|
||||
testID="disabled_send.button"
|
||||
testID="post_draft.send.button.disabled"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -587,6 +590,7 @@ exports[`PostDraft Should render the ReadOnly for canPost 1`] = `
|
|||
"paddingHorizontal": 12,
|
||||
}
|
||||
}
|
||||
testID="post_draft.read_only"
|
||||
>
|
||||
<Icon
|
||||
color="#3d3c40"
|
||||
|
|
@ -636,6 +640,7 @@ exports[`PostDraft Should render the ReadOnly for channelIsReadOnly 1`] = `
|
|||
"paddingHorizontal": 12,
|
||||
}
|
||||
}
|
||||
testID="post_draft.read_only"
|
||||
>
|
||||
<Icon
|
||||
color="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ export default class Archived extends PureComponent {
|
|||
const style = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<View style={style.archivedWrapper}>
|
||||
<View
|
||||
testID='post_draft.archived'
|
||||
style={style.archivedWrapper}
|
||||
>
|
||||
<FormattedMarkdownText
|
||||
{...this.message()}
|
||||
theme={theme}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const HW_EVENT_IN_SCREEN = ['Channel', 'Thread'];
|
|||
|
||||
export default class DraftInput extends PureComponent {
|
||||
static propTypes = {
|
||||
testID: PropTypes.string,
|
||||
registerTypingAnimation: PropTypes.func.isRequired,
|
||||
addReactionToLatestPost: PropTypes.func.isRequired,
|
||||
getChannelMemberCountsByGroup: PropTypes.func.isRequired,
|
||||
|
|
@ -395,6 +396,7 @@ export default class DraftInput extends PureComponent {
|
|||
|
||||
render() {
|
||||
const {
|
||||
testID,
|
||||
channelDisplayName,
|
||||
channelId,
|
||||
cursorPositionEvent,
|
||||
|
|
@ -416,6 +418,7 @@ export default class DraftInput extends PureComponent {
|
|||
registerTypingAnimation={registerTypingAnimation}
|
||||
/>
|
||||
<View
|
||||
testID={testID}
|
||||
style={[style.inputWrapper, padding(isLandscape)]}
|
||||
onLayout={this.handleLayout}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ export default class PostDraft extends PureComponent {
|
|||
|
||||
const draftInput = (
|
||||
<DraftInput
|
||||
testID='post_draft'
|
||||
ref={this.draftInput}
|
||||
channelId={channelId}
|
||||
cursorPositionEvent={cursorPositionEvent}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ describe('PostDraft', () => {
|
|||
);
|
||||
|
||||
expect(toJSON()).toMatchSnapshot();
|
||||
expect(getByTestId('post.input')).toBeTruthy();
|
||||
expect(getByTestId('post_draft.post.input')).toBeTruthy();
|
||||
expect(queryByText('Close Channel')).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ describe('PostDraft', () => {
|
|||
expect(toJSON()).toMatchSnapshot();
|
||||
|
||||
// Should not render text input
|
||||
expect(queryByTestId('post.input')).toBeNull();
|
||||
expect(queryByTestId('post_draft.post.input')).toBeNull();
|
||||
|
||||
// Should match text description
|
||||
expect(getByText('You are viewing an ')).toBeTruthy();
|
||||
|
|
@ -100,7 +100,7 @@ describe('PostDraft', () => {
|
|||
expect(toJSON()).toMatchSnapshot();
|
||||
|
||||
// Should not render text input
|
||||
expect(queryByTestId('post.input')).toBeNull();
|
||||
expect(queryByTestId('post_draft.post.input')).toBeNull();
|
||||
|
||||
// Should match text description
|
||||
expect(getByText('You are viewing an ')).toBeTruthy();
|
||||
|
|
@ -121,7 +121,7 @@ describe('PostDraft', () => {
|
|||
expect(toJSON()).toMatchSnapshot();
|
||||
|
||||
// Should not render text input
|
||||
expect(queryByTestId('post.input')).toBeNull();
|
||||
expect(queryByTestId('post_draft.post.input')).toBeNull();
|
||||
|
||||
// Should match text description
|
||||
expect(getByText('This channel is read-only.')).toBeTruthy();
|
||||
|
|
@ -140,7 +140,7 @@ describe('PostDraft', () => {
|
|||
expect(toJSON()).toMatchSnapshot();
|
||||
|
||||
// Should not render text input
|
||||
expect(queryByTestId('post.input')).toBeNull();
|
||||
expect(queryByTestId('post_draft.post.input')).toBeNull();
|
||||
|
||||
// Should match text description
|
||||
expect(getByText('This channel is read-only.')).toBeTruthy();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ exports[`PostInput should match, full snapshot 1`] = `
|
|||
"paddingTop": 6,
|
||||
}
|
||||
}
|
||||
testID="post_draft.post.input"
|
||||
textContentType="none"
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ export default class PostInput extends PureComponent {
|
|||
|
||||
return (
|
||||
<PasteableTextInput
|
||||
testID='post_draft.post.input'
|
||||
ref={this.input}
|
||||
style={{...style.input, maxHeight}}
|
||||
onChangeText={this.handleTextChange}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ exports[`PostDraft ReadOnly Should match snapshot 1`] = `
|
|||
"paddingHorizontal": 12,
|
||||
}
|
||||
}
|
||||
testID="post_draft.read_only"
|
||||
>
|
||||
<CompassIcon
|
||||
color="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ const ReadOnlyChannnel = ({theme}: ReadOnlyProps): ReactNode => {
|
|||
const style = getStyle(theme);
|
||||
return (
|
||||
<SafeAreaView style={style.background}>
|
||||
<View style={style.container}>
|
||||
<View
|
||||
testID='post_draft.read_only'
|
||||
style={style.container}
|
||||
>
|
||||
<CompassIcon
|
||||
name='glasses'
|
||||
style={style.icon}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ exports[`SendAction should change theme backgroundColor to 0.3 opacity 1`] = `
|
|||
"paddingRight": 8,
|
||||
}
|
||||
}
|
||||
testID="disabled_send.button"
|
||||
testID="post_draft.send.button.disabled"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -45,7 +45,7 @@ exports[`SendAction should match snapshot 1`] = `
|
|||
"paddingRight": 8,
|
||||
}
|
||||
}
|
||||
testID="send.button"
|
||||
testID="post_draft.send.button"
|
||||
type="opacity"
|
||||
>
|
||||
<View
|
||||
|
|
@ -78,7 +78,7 @@ exports[`SendAction should render theme backgroundColor 1`] = `
|
|||
"paddingRight": 8,
|
||||
}
|
||||
}
|
||||
testID="send.button"
|
||||
testID="post_draft.send.button"
|
||||
type="opacity"
|
||||
>
|
||||
<View
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function SendButton(props) {
|
|||
if (props.disabled) {
|
||||
return (
|
||||
<View
|
||||
testID='disabled_send.button'
|
||||
testID='post_draft.send.button.disabled'
|
||||
style={style.sendButtonContainer}
|
||||
>
|
||||
<View style={[style.sendButton, style.disableButton]}>
|
||||
|
|
@ -32,7 +32,7 @@ function SendButton(props) {
|
|||
|
||||
return (
|
||||
<TouchableWithFeedback
|
||||
testID='send.button'
|
||||
testID='post_draft.send.button'
|
||||
onPress={props.handleSendMessage}
|
||||
style={style.sendButtonContainer}
|
||||
type={'opacity'}
|
||||
|
|
|
|||
|
|
@ -546,8 +546,11 @@ export default class PostList extends PureComponent {
|
|||
}
|
||||
|
||||
function PostComponent({postId, highlightPostId, lastPostIndex, index, ...postProps}) {
|
||||
const testID = `post_list.post.${postId}`;
|
||||
|
||||
return (
|
||||
<Post
|
||||
testID={testID}
|
||||
postId={postId}
|
||||
highlight={highlightPostId === postId}
|
||||
isLastPost={lastPostIndex === index}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ exports[`Reactions Should match snapshot with default emojis 1`] = `
|
|||
/>
|
||||
<TouchableWithoutFeedback
|
||||
onPress={[MockFunction]}
|
||||
testID="open.reaction_picker"
|
||||
testID="open.add_reaction.button"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -492,7 +492,7 @@ exports[`Reactions Should match snapshot with default emojis 2`] = `
|
|||
/>
|
||||
<TouchableWithoutFeedback
|
||||
onPress={[MockFunction]}
|
||||
testID="open.reaction_picker"
|
||||
testID="open.add_reaction.button"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
|
|||
|
|
@ -52,9 +52,11 @@ export default class ReactionButton extends PureComponent {
|
|||
containerSize,
|
||||
} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
const testID = `reaction_picker.reaction_button.${emoji}`;
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
testID={testID}
|
||||
key={emoji}
|
||||
onPress={this.handlePress}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export default class ReactionPicker extends PureComponent {
|
|||
{list}
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.props.openReactionScreen}
|
||||
testID='open.reaction_picker'
|
||||
testID='open.add_reaction.button'
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
|
|
|
|||
|
|
@ -198,11 +198,13 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
contentContainerStyle={style.wrapper}
|
||||
>
|
||||
<UserInfo
|
||||
testID='settings.sidebar.user_info.action'
|
||||
onPress={this.goToUserProfile}
|
||||
user={currentUser}
|
||||
/>
|
||||
<View style={style.block}>
|
||||
<DrawerItem
|
||||
testID='settings.sidebar.status.action'
|
||||
labelComponent={this.renderUserStatusLabel(currentUser.id)}
|
||||
leftComponent={this.renderUserStatusIcon(currentUser.id)}
|
||||
separator={false}
|
||||
|
|
@ -213,6 +215,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
<View style={style.separator}/>
|
||||
<View style={style.block}>
|
||||
<DrawerItem
|
||||
testID='settings.sidebar.recent_mentions.action'
|
||||
defaultMessage='Recent Mentions'
|
||||
i18nId='search_header.title2'
|
||||
iconName='at'
|
||||
|
|
@ -221,6 +224,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
theme={theme}
|
||||
/>
|
||||
<DrawerItem
|
||||
testID='settings.sidebar.saved_messages.action'
|
||||
defaultMessage='Saved Messages'
|
||||
i18nId='search_header.title3'
|
||||
iconName='bookmark-outline'
|
||||
|
|
@ -232,6 +236,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
<View style={style.separator}/>
|
||||
<View style={style.block}>
|
||||
<DrawerItem
|
||||
testID='settings.sidebar.edit_profile.action'
|
||||
defaultMessage='Edit Profile'
|
||||
i18nId='mobile.routes.edit_profile'
|
||||
iconName='pencil-outline'
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import ProfilePicture from 'app/components/profile_picture';
|
|||
|
||||
export default class UserInfo extends PureComponent {
|
||||
static propTypes = {
|
||||
testID: PropTypes.string,
|
||||
user: PropTypes.object.isRequired,
|
||||
onPress: PropTypes.func,
|
||||
theme: PropTypes.object.isRequired,
|
||||
|
|
@ -22,7 +23,7 @@ export default class UserInfo extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {user, onPress, theme} = this.props;
|
||||
const {testID, user, onPress, theme} = this.props;
|
||||
const {first_name: firstName, last_name: lastName} = user;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
|
|
@ -36,7 +37,10 @@ export default class UserInfo extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<TouchableOpacity
|
||||
testID={testID}
|
||||
onPress={onPress}
|
||||
>
|
||||
<View style={style.container}>
|
||||
<ProfilePicture
|
||||
size={48}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
<Connect(Favorite)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.favorite.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -143,6 +144,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
<Connect(Mute)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.mute.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -208,6 +210,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
<Connect(IgnoreMentions)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.ignore_mentions.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -338,6 +341,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
<Connect(Pinned)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.pinned.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -370,6 +374,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
/>
|
||||
<Connect(ManageMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.manage_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -402,6 +407,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
/>
|
||||
<Connect(AddMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.add_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -434,6 +440,7 @@ exports[`channelInfo should match snapshot 1`] = `
|
|||
/>
|
||||
<Connect(ConvertPrivate)
|
||||
isLandscape={false}
|
||||
testID="channel_info.convert_private.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -582,6 +589,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Favorite)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.favorite.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -646,6 +654,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Mute)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.mute.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -711,6 +720,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(IgnoreMentions)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.ignore_mentions.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -841,6 +851,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Pinned)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.pinned.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -873,6 +884,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(ManageMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.manage_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -905,6 +917,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(AddMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.add_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -937,6 +950,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(ConvertPrivate)
|
||||
isLandscape={false}
|
||||
testID="channel_info.convert_private.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1008,6 +1022,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Favorite)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.favorite.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1072,6 +1087,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Mute)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.mute.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1137,6 +1153,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(IgnoreMentions)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.ignore_mentions.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1201,6 +1218,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
<Connect(Pinned)
|
||||
channelId="1234"
|
||||
isLandscape={false}
|
||||
testID="channel_info.pinned.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1233,6 +1251,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(ManageMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.manage_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1265,6 +1284,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(AddMembers)
|
||||
isLandscape={false}
|
||||
testID="channel_info.add_members.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
@ -1297,6 +1317,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
|
|||
/>
|
||||
<Connect(ConvertPrivate)
|
||||
isLandscape={false}
|
||||
testID="channel_info.convert_private.action"
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface AddMembersProps {
|
||||
testID?: string;
|
||||
canManageUsers: boolean;
|
||||
groupConstrained: boolean;
|
||||
isLandscape: boolean;
|
||||
|
|
@ -32,13 +33,14 @@ export default class AddMembers extends PureComponent<AddMembersProps> {
|
|||
});
|
||||
|
||||
render() {
|
||||
const {canManageUsers, groupConstrained, isLandscape, theme} = this.props;
|
||||
const {testID, canManageUsers, groupConstrained, isLandscape, theme} = this.props;
|
||||
|
||||
if (canManageUsers && !groupConstrained) {
|
||||
return (
|
||||
<>
|
||||
<Separator theme={theme}/>
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={this.goToChannelAddMembers}
|
||||
defaultMessage='Add Members'
|
||||
icon='account-plus-outline'
|
||||
|
|
|
|||
|
|
@ -110,12 +110,14 @@ export default class ChannelInfo extends PureComponent {
|
|||
return (
|
||||
<>
|
||||
<Favorite
|
||||
testID='channel_info.favorite.action'
|
||||
channelId={currentChannel.id}
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
/>
|
||||
<Separator theme={theme}/>
|
||||
<Mute
|
||||
testID='channel_info.mute.action'
|
||||
channelId={currentChannel.id}
|
||||
isLandscape={isLandscape}
|
||||
userId={currentUserId}
|
||||
|
|
@ -123,6 +125,7 @@ export default class ChannelInfo extends PureComponent {
|
|||
/>
|
||||
<Separator theme={theme}/>
|
||||
<IgnoreMentions
|
||||
testID='channel_info.ignore_mentions.action'
|
||||
channelId={currentChannel.id}
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
|
|
@ -139,19 +142,23 @@ export default class ChannelInfo extends PureComponent {
|
|||
</>
|
||||
}
|
||||
<Pinned
|
||||
testID='channel_info.pinned.action'
|
||||
channelId={currentChannel.id}
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
/>
|
||||
<ManageMembers
|
||||
testID='channel_info.manage_members.action'
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
/>
|
||||
<AddMembers
|
||||
testID='channel_info.add_members.action'
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
/>
|
||||
<ConvertPrivate
|
||||
testID='channel_info.convert_private.action'
|
||||
isLandscape={isLandscape}
|
||||
theme={theme}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface ConvertPrivateProps {
|
||||
testID?: string;
|
||||
canConvert: boolean;
|
||||
channelId: string;
|
||||
convertChannelToPrivate: (channelId: string) => Promise<ActionResult>;
|
||||
|
|
@ -79,7 +80,7 @@ export default class ConvertPrivate extends PureComponent<ConvertPrivateProps> {
|
|||
});
|
||||
|
||||
render() {
|
||||
const {canConvert, isLandscape, theme} = this.props;
|
||||
const {testID, canConvert, isLandscape, theme} = this.props;
|
||||
|
||||
if (!canConvert) {
|
||||
return null;
|
||||
|
|
@ -89,6 +90,7 @@ export default class ConvertPrivate extends PureComponent<ConvertPrivateProps> {
|
|||
<>
|
||||
<Separator theme={theme}/>
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={this.handleConvertToPrivate}
|
||||
defaultMessage='Convert to Private Channel'
|
||||
icon='lock'
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface FavoriteProps {
|
||||
testID?: string;
|
||||
channelId: string;
|
||||
favoriteChannel: (channelId: string) => void;
|
||||
isFavorite: boolean;
|
||||
|
|
@ -17,7 +18,7 @@ interface FavoriteProps {
|
|||
theme: Theme;
|
||||
}
|
||||
|
||||
const Favorite = ({channelId, favoriteChannel, isLandscape, isFavorite, unfavoriteChannel, theme}: FavoriteProps) => {
|
||||
const Favorite = ({testID, channelId, favoriteChannel, isLandscape, isFavorite, unfavoriteChannel, theme}: FavoriteProps) => {
|
||||
const [favorite, setFavorite] = useState(isFavorite);
|
||||
|
||||
const handleFavorite = preventDoubleTap(() => {
|
||||
|
|
@ -28,6 +29,7 @@ const Favorite = ({channelId, favoriteChannel, isLandscape, isFavorite, unfavori
|
|||
|
||||
return (
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={handleFavorite}
|
||||
defaultMessage='Favorite'
|
||||
detail={favorite}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface IgnoreMentionsProps {
|
||||
testID?: string;
|
||||
channelId: string;
|
||||
ignore: boolean;
|
||||
isLandscape: boolean;
|
||||
|
|
@ -18,7 +19,7 @@ interface IgnoreMentionsProps {
|
|||
userId: string;
|
||||
}
|
||||
|
||||
const IgnoreMentions = ({channelId, ignore, isLandscape, updateChannelNotifyProps, userId, theme}: IgnoreMentionsProps) => {
|
||||
const IgnoreMentions = ({testID, channelId, ignore, isLandscape, updateChannelNotifyProps, userId, theme}: IgnoreMentionsProps) => {
|
||||
const [mentions, setMentions] = useState(ignore);
|
||||
|
||||
const handleIgnoreChannelMentions = preventDoubleTap(() => {
|
||||
|
|
@ -32,6 +33,7 @@ const IgnoreMentions = ({channelId, ignore, isLandscape, updateChannelNotifyProp
|
|||
|
||||
return (
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={handleIgnoreChannelMentions}
|
||||
defaultMessage='Ignore @channel, @here, @all'
|
||||
detail={ignore}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface ManageMembersProps {
|
||||
testID?: string;
|
||||
canManageUsers: boolean;
|
||||
isDirectMessage: boolean;
|
||||
isLandscape: boolean;
|
||||
|
|
@ -41,7 +42,7 @@ export default class ManageMembers extends PureComponent<ManageMembersProps> {
|
|||
});
|
||||
|
||||
render() {
|
||||
const {isDirectMessage, canManageUsers, isLandscape, membersCount, separator, theme} = this.props;
|
||||
const {testID, isDirectMessage, canManageUsers, isLandscape, membersCount, separator, theme} = this.props;
|
||||
|
||||
if (isDirectMessage) {
|
||||
return null;
|
||||
|
|
@ -51,6 +52,7 @@ export default class ManageMembers extends PureComponent<ManageMembersProps> {
|
|||
<>
|
||||
{separator && <Separator theme={theme}/>}
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={this.goToChannelMembers}
|
||||
defaultMessage={canManageUsers ? 'Manage Members' : 'View Members'}
|
||||
detail={membersCount}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface MuteProps {
|
||||
testID?: string;
|
||||
channelId: string;
|
||||
isChannelMuted: boolean;
|
||||
isLandscape: boolean;
|
||||
|
|
@ -17,7 +18,7 @@ interface MuteProps {
|
|||
userId: string;
|
||||
}
|
||||
|
||||
const Mute = ({channelId, isChannelMuted, isLandscape, updateChannelNotifyProps, userId, theme}: MuteProps) => {
|
||||
const Mute = ({testID, channelId, isChannelMuted, isLandscape, updateChannelNotifyProps, userId, theme}: MuteProps) => {
|
||||
const [muted, setMuted] = useState(isChannelMuted);
|
||||
|
||||
const handleMuteChannel = preventDoubleTap(() => {
|
||||
|
|
@ -31,6 +32,7 @@ const Mute = ({channelId, isChannelMuted, isLandscape, updateChannelNotifyProps,
|
|||
|
||||
return (
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={handleMuteChannel}
|
||||
defaultMessage='Mute channel'
|
||||
detail={muted}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {t} from '@utils/i18n';
|
|||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
interface PinnedProps {
|
||||
testID?: string;
|
||||
channelId: string;
|
||||
pinnedCount: number;
|
||||
isLandscape: boolean;
|
||||
|
|
@ -38,9 +39,10 @@ export default class Pinned extends PureComponent<PinnedProps> {
|
|||
});
|
||||
|
||||
render() {
|
||||
const {pinnedCount, isLandscape, theme} = this.props;
|
||||
const {testID, pinnedCount, isLandscape, theme} = this.props;
|
||||
return (
|
||||
<ChannelInfoRow
|
||||
testID={testID}
|
||||
action={this.goToPinnedPosts}
|
||||
defaultMessage='Pinned Messages'
|
||||
detail={pinnedCount}
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ LongPost {
|
|||
shouldRenderReplyButton={false}
|
||||
showAddReaction={false}
|
||||
showLongPost={true}
|
||||
testID="long_post.post.post-id"
|
||||
/>
|
||||
</ScrollView>
|
||||
<View
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ export default class LongPost extends PureComponent {
|
|||
isLandscape,
|
||||
} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
const testID = `long_post.post.${postId}`;
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
|
|
@ -158,6 +159,7 @@ export default class LongPost extends PureComponent {
|
|||
</View>
|
||||
<ScrollView style={style.postList}>
|
||||
<Post
|
||||
testID={testID}
|
||||
postId={postId}
|
||||
shouldRenderReplyButton={false}
|
||||
onPress={this.handlePress}
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ export default class MoreDirectMessages extends PureComponent {
|
|||
text: formatMessage({id: 'mobile.more_dms.start', defaultMessage: 'Start'}),
|
||||
showAsAction: 'always',
|
||||
enabled: startEnabled,
|
||||
testID: START_BUTTON,
|
||||
testID: 'more_direct_messages.start.button',
|
||||
}],
|
||||
});
|
||||
};
|
||||
|
|
@ -366,7 +366,7 @@ export default class MoreDirectMessages extends PureComponent {
|
|||
selectable={true}
|
||||
selected={selected}
|
||||
enabled={true}
|
||||
testID='more_dms.user'
|
||||
testID='more_direct_messages.user'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -477,7 +477,7 @@ export default class MoreDirectMessages extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<KeyboardLayout testID='direct_channels.screen'>
|
||||
<KeyboardLayout testID='more_direct_messages.screen'>
|
||||
<StatusBar/>
|
||||
<View style={style.searchBar}>
|
||||
<View style={padding(isLandscape)}>
|
||||
|
|
@ -519,7 +519,7 @@ export default class MoreDirectMessages extends PureComponent {
|
|||
onLoadMore={this.getProfiles}
|
||||
onRowPress={this.handleSelectProfile}
|
||||
renderItem={this.renderItem}
|
||||
testID='more_dms.list'
|
||||
testID='more_direct_messages.list'
|
||||
theme={theme}
|
||||
/>
|
||||
</KeyboardLayout>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ const Notification = ({componentId, notification}: NotificationProps) => {
|
|||
style={styles.container}
|
||||
useNativeDriver={true}
|
||||
animation={animation}
|
||||
testID='in_app_notification'
|
||||
testID='in_app_notification.screen'
|
||||
>
|
||||
<View style={styles.flex}>
|
||||
<TouchableOpacity
|
||||
|
|
|
|||
|
|
@ -47,12 +47,14 @@ exports[`PostOptions should match snapshot, no option for system message to user
|
|||
<Connect(ReactionPicker)
|
||||
addReaction={[Function]}
|
||||
openReactionScreen={[Function]}
|
||||
testID="post_options.reaction_picker.action"
|
||||
/>
|
||||
<PostOption
|
||||
destructive={false}
|
||||
icon="reply-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.reply.action"
|
||||
text="Reply"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -88,6 +90,7 @@ exports[`PostOptions should match snapshot, no option for system message to user
|
|||
icon="mark-as-unread"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.markUnread.action"
|
||||
text="Mark as Unread"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -124,6 +127,7 @@ exports[`PostOptions should match snapshot, no option for system message to user
|
|||
icon="pin-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.pin.action"
|
||||
text="Pin to Channel"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -160,6 +164,7 @@ exports[`PostOptions should match snapshot, no option for system message to user
|
|||
icon="pencil-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.edit.action"
|
||||
text="Edit"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -242,12 +247,14 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste
|
|||
<Connect(ReactionPicker)
|
||||
addReaction={[Function]}
|
||||
openReactionScreen={[Function]}
|
||||
testID="post_options.reaction_picker.action"
|
||||
/>
|
||||
<PostOption
|
||||
destructive={false}
|
||||
icon="reply-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.reply.action"
|
||||
text="Reply"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -283,6 +290,7 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste
|
|||
icon="mark-as-unread"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.markUnread.action"
|
||||
text="Mark as Unread"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -319,6 +327,7 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste
|
|||
icon="pin-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.pin.action"
|
||||
text="Pin to Channel"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -355,6 +364,7 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste
|
|||
icon="pencil-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.edit.action"
|
||||
text="Edit"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -391,6 +401,7 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste
|
|||
icon="trash-can-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.delete.action"
|
||||
text="Delete"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -473,12 +484,14 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = `
|
|||
<Connect(ReactionPicker)
|
||||
addReaction={[Function]}
|
||||
openReactionScreen={[Function]}
|
||||
testID="post_options.reaction_picker.action"
|
||||
/>
|
||||
<PostOption
|
||||
destructive={false}
|
||||
icon="reply-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.reply.action"
|
||||
text="Reply"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -514,6 +527,7 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = `
|
|||
icon="mark-as-unread"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.markUnread.action"
|
||||
text="Mark as Unread"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -550,6 +564,7 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = `
|
|||
icon="pin-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.pin.action"
|
||||
text="Pin to Channel"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -586,6 +601,7 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = `
|
|||
icon="pencil-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.edit.action"
|
||||
text="Edit"
|
||||
theme={
|
||||
Object {
|
||||
|
|
@ -622,6 +638,7 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = `
|
|||
icon="trash-can-outline"
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
testID="post.options.delete.action"
|
||||
text="Delete"
|
||||
theme={
|
||||
Object {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {preventDoubleTap} from '@utils/tap';
|
|||
|
||||
export default class PostOption extends PureComponent {
|
||||
static propTypes = {
|
||||
testID: PropTypes.string,
|
||||
destructive: PropTypes.bool,
|
||||
icon: PropTypes.string.isRequired,
|
||||
onPress: PropTypes.func.isRequired,
|
||||
|
|
@ -31,7 +32,7 @@ export default class PostOption extends PureComponent {
|
|||
}, 500);
|
||||
|
||||
render() {
|
||||
const {destructive, icon, text, isLandscape, theme} = this.props;
|
||||
const {testID, destructive, icon, text, isLandscape, theme} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
const Touchable = Platform.select({
|
||||
|
|
@ -52,7 +53,10 @@ export default class PostOption extends PureComponent {
|
|||
});
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
testID={testID}
|
||||
style={style.container}
|
||||
>
|
||||
<Touchable
|
||||
onPress={this.handleOnPress}
|
||||
{...touchableProps}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,11 @@ export default class PostOptions extends PureComponent {
|
|||
getOption = (key, icon, message, onPress, destructive = false) => {
|
||||
const {formatMessage} = this.context.intl;
|
||||
const {isLandscape, theme} = this.props;
|
||||
const testID = `post.options.${key}.action`;
|
||||
|
||||
return (
|
||||
<PostOption
|
||||
testID={testID}
|
||||
key={key}
|
||||
icon={icon}
|
||||
text={formatMessage(message)}
|
||||
|
|
@ -222,6 +224,7 @@ export default class PostOptions extends PureComponent {
|
|||
if (!isSystemMessage(post) && this.props.canMarkAsUnread) {
|
||||
return (
|
||||
<PostOption
|
||||
testID='post.options.markUnread.action'
|
||||
key='markUnread'
|
||||
icon='mark-as-unread'
|
||||
text={formatMessage({id: 'mobile.post_info.mark_unread', defaultMessage: 'Mark as Unread'})}
|
||||
|
|
@ -403,6 +406,7 @@ export default class PostOptions extends PureComponent {
|
|||
reactionHeight = REACTION_PICKER_HEIGHT;
|
||||
reactionPicker = (
|
||||
<ReactionPicker
|
||||
testID='post_options.reaction_picker.action'
|
||||
addReaction={this.handleAddReaction}
|
||||
openReactionScreen={this.handleAddReactionScreen}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ describe('PostOptions', () => {
|
|||
currentUserId: 'user1',
|
||||
deviceHeight: 600,
|
||||
hasBeenDeleted: false,
|
||||
isFlagged: false,
|
||||
isFlagged: true,
|
||||
isSystemMessage: false,
|
||||
managedConfig: {},
|
||||
post,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ exports[`RecentMentions should match snapshot 1`] = `
|
|||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="recent_mentions.screen"
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<Connect(ChannelLoader)
|
||||
|
|
@ -22,6 +23,7 @@ exports[`RecentMentions should match snapshot when component waiting for respons
|
|||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="recent_mentions.screen"
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<Connect(ChannelLoader)
|
||||
|
|
@ -37,6 +39,7 @@ exports[`RecentMentions should match snapshot when getRecentMentions failed 1`]
|
|||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="recent_mentions.screen"
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<Connect(FailedNetworkAction)
|
||||
|
|
|
|||
|
|
@ -222,7 +222,10 @@ export default class RecentMentions extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
testID='recent_mentions.screen'
|
||||
style={style.container}
|
||||
>
|
||||
<StatusBar/>
|
||||
{component}
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SearchResultPost should match snapshot 1`] = `
|
||||
<Connect(Post)
|
||||
highlightPinnedOrFlagged={false}
|
||||
isSearchResult={true}
|
||||
managedConfig={Object {}}
|
||||
onHashtagPress={[MockFunction]}
|
||||
onPermalinkPress={[MockFunction]}
|
||||
onPress={[MockFunction]}
|
||||
onReply={[MockFunction]}
|
||||
postId="post-id"
|
||||
shouldRenderReplyButton={true}
|
||||
showAddReaction={false}
|
||||
showFullDate={false}
|
||||
skipFlaggedHeader={false}
|
||||
skipPinnedHeader={false}
|
||||
testID="search_result_post.post.post-id"
|
||||
/>
|
||||
`;
|
||||
|
|
@ -42,8 +42,11 @@ export default class SearchResultPost extends PureComponent {
|
|||
postComponentProps.skipPinnedHeader = this.props.skipPinnedHeader;
|
||||
}
|
||||
|
||||
const testID = `search_result_post.post.${this.props.postId}`;
|
||||
|
||||
return (
|
||||
<Post
|
||||
testID={testID}
|
||||
postId={this.props.postId}
|
||||
{...postComponentProps}
|
||||
isSearchResult={true}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import SearchResultPost from './search_result_post';
|
||||
|
||||
describe('SearchResultPost', () => {
|
||||
const baseProps = {
|
||||
goToThread: jest.fn(),
|
||||
onHashtagPress: jest.fn(),
|
||||
onPermalinkPress: jest.fn(),
|
||||
previewPost: jest.fn(),
|
||||
postId: 'post-id',
|
||||
isDeleted: false,
|
||||
highlightPinnedOrFlagged: false,
|
||||
managedConfig: {},
|
||||
showFullDate: false,
|
||||
skipFlaggedHeader: false,
|
||||
skipPinnedHeader: false,
|
||||
};
|
||||
|
||||
test('should match snapshot', async () => {
|
||||
const wrapper = shallowWithIntl(<SearchResultPost {...baseProps}/>);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -211,6 +211,7 @@ class Settings extends PureComponent {
|
|||
isLandscape={isLandscape}
|
||||
/>
|
||||
<SettingsItem
|
||||
testID='general_settings.display.action'
|
||||
defaultMessage='Display'
|
||||
i18nId={t('user.settings.modal.display')}
|
||||
iconName='layers-outline'
|
||||
|
|
@ -223,6 +224,7 @@ class Settings extends PureComponent {
|
|||
{showTeams &&
|
||||
<React.Fragment>
|
||||
<SettingsItem
|
||||
testID='general_settings.select_team.action'
|
||||
defaultMessage='Open teams you can join'
|
||||
i18nId={t('mobile.select_team.join_open')}
|
||||
iconName='menu'
|
||||
|
|
@ -235,6 +237,7 @@ class Settings extends PureComponent {
|
|||
</React.Fragment>
|
||||
}
|
||||
<SettingsItem
|
||||
testID='general_settings.advanced.action'
|
||||
defaultMessage='Advanced Settings'
|
||||
i18nId={t('mobile.advanced_settings.title')}
|
||||
iconName='tune'
|
||||
|
|
@ -247,6 +250,7 @@ class Settings extends PureComponent {
|
|||
{LocalConfig.EnableMobileClientUpgrade && LocalConfig.EnableMobileClientUpgradeUserSetting &&
|
||||
<React.Fragment>
|
||||
<SettingsItem
|
||||
testID='general_settings.check_for_upgrade.action'
|
||||
defaultMessage='Check for Upgrade'
|
||||
i18nId={t('mobile.settings.modal.check_for_upgrade')}
|
||||
iconName='update'
|
||||
|
|
@ -259,6 +263,7 @@ class Settings extends PureComponent {
|
|||
</React.Fragment>
|
||||
}
|
||||
<SettingsItem
|
||||
testID='general_settings.about.action'
|
||||
defaultMessage='About {appTitle}'
|
||||
messageValues={{appTitle: config.SiteName || 'Mattermost'}}
|
||||
i18nId={t('about.title')}
|
||||
|
|
@ -273,6 +278,7 @@ class Settings extends PureComponent {
|
|||
{showHelp &&
|
||||
<React.Fragment>
|
||||
<SettingsItem
|
||||
testID='general_settings.help.action'
|
||||
defaultMessage='Help'
|
||||
i18nId={t('mobile.help.title')}
|
||||
onPress={this.openHelp}
|
||||
|
|
@ -285,6 +291,7 @@ class Settings extends PureComponent {
|
|||
</React.Fragment>
|
||||
}
|
||||
<SettingsItem
|
||||
testID='general_settings.report.action'
|
||||
defaultMessage='Report a Problem'
|
||||
i18nId={t('sidebar_right_menu.report')}
|
||||
onPress={this.openErrorEmail}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,34 @@ import {getResponseFromError} from './common';
|
|||
// - return value defined by `@return`
|
||||
// ****************************************************************
|
||||
|
||||
/**
|
||||
* Create a new post in a channel. To create the post as a comment on another post, provide root_id.
|
||||
* See https://api.mattermost.com/#tag/posts/paths/~1posts/post
|
||||
* @param {string} option.channelId - The channel ID to post in
|
||||
* @param {string} option.message - The message contents, can be formatted with Markdown
|
||||
* @param {string} option.rootId - The post ID to comment on
|
||||
* @param {Object} option.props - A general object property bag to attach to the post
|
||||
* @param {Date} option.createAt - The date the post is created at
|
||||
* @return {Object} returns {post} on success or {error, status} on error
|
||||
*/
|
||||
export const apiCreatePost = async ({channelId, message, rootId, props = {}, createAt = 0}) => {
|
||||
try {
|
||||
const payload = {
|
||||
channel_id: channelId,
|
||||
message,
|
||||
parent_id: rootId,
|
||||
root_id: rootId,
|
||||
props,
|
||||
create_at: createAt,
|
||||
};
|
||||
const response = await client.post('/api/v4/posts', payload);
|
||||
|
||||
return {post: response.data};
|
||||
} catch (err) {
|
||||
return getResponseFromError(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get posts for a channel.
|
||||
* See https://api.mattermost.com/#tag/posts/paths/~1channels~1{channel_id}~1posts/get
|
||||
|
|
@ -47,6 +75,7 @@ export const apiGetLastPostInChannel = async (channelId) => {
|
|||
};
|
||||
|
||||
export const Post = {
|
||||
apiCreatePost,
|
||||
apiGetLastPostInChannel,
|
||||
apiGetPostsInChannel,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import CameraQuickAction from './camera_quick_action';
|
|||
import FileQuickAction from './file_quick_action';
|
||||
import ImageQuickAction from './image_quick_action';
|
||||
import MainSidebar from './main_sidebar';
|
||||
import Post from './post';
|
||||
import PostDraft from './post_draft';
|
||||
import PostOptions from './post_options';
|
||||
import SendButton from './send_button';
|
||||
import SettingsSidebar from './settings_sidebar';
|
||||
|
||||
export {
|
||||
|
|
@ -15,6 +18,9 @@ export {
|
|||
FileQuickAction,
|
||||
ImageQuickAction,
|
||||
MainSidebar,
|
||||
Post,
|
||||
PostDraft,
|
||||
PostOptions,
|
||||
SendButton,
|
||||
SettingsSidebar,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ class MainSidebar {
|
|||
mainSidebar: 'main.sidebar',
|
||||
channelItemDisplayName: 'channel_item.display_name',
|
||||
channelsList: 'channels.list',
|
||||
addChannel: 'action_button_sidebar.channels',
|
||||
addDirectChannel: 'action_button_sidebar.direct',
|
||||
openMoreChannelsButton: 'action_button_sidebar.channels',
|
||||
openCreatePrivateChannelButton: 'action_button_sidebar.pg',
|
||||
openMoreDirectMessagesButton: 'action_button_sidebar.direct',
|
||||
}
|
||||
|
||||
mainSidebar = element(by.id(this.testID.mainSidebar));
|
||||
channelItemDisplayName = element(by.id(this.testID.channelItemDisplayName));
|
||||
channelsList = element(by.id(this.testID.channelsList));
|
||||
addChannel = element(by.id(this.testID.addChannel));
|
||||
addDirectChannel = element(by.id(this.testID.addDirectChannel));
|
||||
openMoreChannelsButton = element(by.id(this.testID.openMoreChannelsButton));
|
||||
openCreatePrivateChannelButton = element(by.id(this.testID.openCreatePrivateChannelButton));
|
||||
openMoreDirectMessagesButton = element(by.id(this.testID.openMoreDirectMessagesButton));
|
||||
|
||||
getChannelByDisplayName = (displayName) => {
|
||||
return element(by.text(displayName).withAncestor(by.id(this.testID.channelsList)));
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.mainSidebar).toBeVisible();
|
||||
|
|
@ -22,10 +28,6 @@ class MainSidebar {
|
|||
return this.mainSidebar;
|
||||
}
|
||||
|
||||
getChannelByDisplayName = (displayName) => {
|
||||
return element(by.text(displayName).withAncestor(by.id(this.testID.channelsList)));
|
||||
}
|
||||
|
||||
hasChannelAtIndex = async (index, channelDisplayName) => {
|
||||
await expect(
|
||||
element(by.id(this.testID.channelItemDisplayName).withAncestor(by.id(this.testID.channelsList))).atIndex(index),
|
||||
|
|
|
|||
18
detox/e2e/support/ui/component/post.js
Normal file
18
detox/e2e/support/ui/component/post.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
class Post {
|
||||
testID = {
|
||||
postPrefix: 'post.',
|
||||
}
|
||||
|
||||
getPost = (postTypePrefix, postId, text) => {
|
||||
if (text) {
|
||||
return element(by.id(`${postTypePrefix}${this.testID.postPrefix}${postId}`).withDescendant(by.text(text)));
|
||||
}
|
||||
return element(by.id(`${postTypePrefix}${this.testID.postPrefix}${postId}`));
|
||||
}
|
||||
}
|
||||
|
||||
const post = new Post();
|
||||
export default post;
|
||||
34
detox/e2e/support/ui/component/post_draft.js
Normal file
34
detox/e2e/support/ui/component/post_draft.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
class PostDraft {
|
||||
testID = {
|
||||
postDraft: 'post_draft',
|
||||
postDraftArchived: 'post_draft.archived',
|
||||
postDraftReadOnly: 'post_draft.archived',
|
||||
postInput: 'post_draft.post.input',
|
||||
}
|
||||
|
||||
postDraft = element(by.id(this.testID.postDraft));
|
||||
postDraftArchived = element(by.id(this.testID.postDraftArchived));
|
||||
postDraftReadOnly = element(by.id(this.testID.postDraftReadOnly));
|
||||
postInput = element(by.id(this.testID.postInput));
|
||||
|
||||
toBeVisible = async (options = {archived: false, readOnly: false}) => {
|
||||
if (options.archived) {
|
||||
await expect(this.postDraftArchived).toBeVisible();
|
||||
return this.postDraftArchived;
|
||||
}
|
||||
|
||||
if (options.readOnly) {
|
||||
await expect(this.postDraftReadOnly).toBeVisible();
|
||||
return this.postDraftReadOnly;
|
||||
}
|
||||
|
||||
await expect(this.postDraft).toBeVisible();
|
||||
return this.postDraft;
|
||||
}
|
||||
}
|
||||
|
||||
const postDraft = new PostDraft();
|
||||
export default postDraft;
|
||||
|
|
@ -4,17 +4,45 @@
|
|||
class PostOptions {
|
||||
testID = {
|
||||
postOptions: 'post.options',
|
||||
openReactionPicker: 'open.reaction_picker',
|
||||
reactionPickerAction: 'post.options.reaction_picker.action',
|
||||
replyAction: 'post.options.reply.action',
|
||||
permalinkAction: 'post.options.permalink.action',
|
||||
copyAction: 'post.options.copy.action',
|
||||
deleteAction: 'post.options.delete.action',
|
||||
editAction: 'post.options.edit.action',
|
||||
saveAction: 'post.options.flagged.action',
|
||||
unsaveAction: 'post.options.unflag.action',
|
||||
pinAction: 'post.options.pin.action',
|
||||
unpinAction: 'post.options.unpin.action',
|
||||
markUnreadAction: 'post.options.markUnread.action',
|
||||
openAddReactionButton: 'open.add_reaction.button',
|
||||
slideUpPanel: 'slide_up_panel',
|
||||
}
|
||||
|
||||
postOptions = element(by.id(this.testID.postOptions));
|
||||
openReactionPicker = element(by.id(this.testID.openReactionPicker));
|
||||
reactionPickerAction = element(by.id(this.testID.reactionPickerAction));
|
||||
replyAction = element(by.id(this.testID.replyAction));
|
||||
permalinkAction = element(by.id(this.testID.permalinkAction));
|
||||
deleteAction = element(by.id(this.testID.deleteAction));
|
||||
editAction = element(by.id(this.testID.editAction));
|
||||
saveAction = element(by.id(this.testID.saveAction));
|
||||
unsaveAction = element(by.id(this.testID.unsaveAction));
|
||||
pinAction = element(by.id(this.testID.pinAction));
|
||||
unpinAction = element(by.id(this.testID.unpinAction));
|
||||
markUnreadAction = element(by.id(this.testID.markUnreadAction));
|
||||
openAddReactionButton = element(by.id(this.testID.openAddReactionButton));
|
||||
slideUpPanel = element(by.id(this.testID.slideUpPanel));
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.postOptions).toBeVisible();
|
||||
|
||||
return postOptions;
|
||||
}
|
||||
|
||||
close = async () => {
|
||||
await this.postOptions.tap();
|
||||
await expect(this.postOptions).not.toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
const postOptions = new PostOptions();
|
||||
|
|
|
|||
25
detox/e2e/support/ui/component/send_button.js
Normal file
25
detox/e2e/support/ui/component/send_button.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
class SendButton {
|
||||
testID = {
|
||||
sendButton: 'post_draft.send.button',
|
||||
sendButtonDisabled: 'post_draft.send.button.disabled',
|
||||
}
|
||||
|
||||
sendButton = element(by.id(this.testID.sendButton));
|
||||
sendButtonDisabled = element(by.id(this.testID.sendButtonDisabled));
|
||||
|
||||
toBeVisible = async (options = {disabled: false}) => {
|
||||
if (options.disabled) {
|
||||
await expect(this.sendButtonDisabled).toBeVisible();
|
||||
return this.sendButtonDisabled;
|
||||
}
|
||||
|
||||
await expect(this.sendButton).toBeVisible();
|
||||
return this.sendButton;
|
||||
}
|
||||
}
|
||||
|
||||
const sendButton = new SendButton();
|
||||
export default sendButton;
|
||||
|
|
@ -4,11 +4,21 @@
|
|||
class SettingsSidebar {
|
||||
testID = {
|
||||
settingsSidebar: 'settings.sidebar',
|
||||
userInfoAction: 'settings.sidebar.user_info.action',
|
||||
statusAction: 'settings.sidebar.status.action',
|
||||
recentMentionsAction: 'settings.sidebar.recent_mentions.action',
|
||||
savedMessagesAction: 'settings.sidebar.saved_messages.action',
|
||||
editProfileAction: 'settings.sidebar.edit_profile.action',
|
||||
settingsAction: 'settings.sidebar.settings.action',
|
||||
logoutAction: 'settings.sidebar.logout.action',
|
||||
}
|
||||
|
||||
settingsSidebar = element(by.id(this.testID.settingsSidebar));
|
||||
userInfoAction = element(by.id(this.testID.userInfoAction));
|
||||
statusAction = element(by.id(this.testID.statusAction));
|
||||
recentMentionsAction = element(by.id(this.testID.recentMentionsAction));
|
||||
savedMessagesAction = element(by.id(this.testID.savedMessagesAction));
|
||||
editProfileAction = element(by.id(this.testID.editProfileAction));
|
||||
settingsAction = element(by.id(this.testID.settingsAction));
|
||||
logoutAction = element(by.id(this.testID.logoutAction));
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,9 @@ class AddReactionScreen {
|
|||
return this.addReactionScreen;
|
||||
}
|
||||
|
||||
open = async (message) => {
|
||||
await element(by.text(message)).longPress();
|
||||
await PostOptions.toBeVisible();
|
||||
await PostOptions.openReactionPicker.tap();
|
||||
open = async () => {
|
||||
// # Open add reaction screen
|
||||
await PostOptions.openAddReactionButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,22 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SettingsSidebar} from '@support/ui/component';
|
||||
import {LoginScreen, SelectServerScreen} from '@support/ui/screen';
|
||||
import {
|
||||
CameraQuickAction,
|
||||
FileQuickAction,
|
||||
ImageQuickAction,
|
||||
MainSidebar,
|
||||
PostDraft,
|
||||
PostOptions,
|
||||
SendButton,
|
||||
SettingsSidebar,
|
||||
} from '@support/ui/component';
|
||||
import {
|
||||
LoginScreen,
|
||||
LongPostScreen,
|
||||
PostListScreen,
|
||||
SelectServerScreen,
|
||||
} from '@support/ui/screen';
|
||||
|
||||
class ChannelScreen {
|
||||
testID = {
|
||||
|
|
@ -12,9 +26,6 @@ class ChannelScreen {
|
|||
channelNavBarTitle: 'channel.nav_bar.title',
|
||||
channelSearchButton: 'channel.search.button',
|
||||
channelTitleButton: 'channel.title.button',
|
||||
disabledSendButton: 'disabled_send.button',
|
||||
postInput: 'post.input',
|
||||
sendButton: 'send.button',
|
||||
settingsSidebarDrawerButton: 'settings_sidebar_drawer.button',
|
||||
}
|
||||
|
||||
|
|
@ -24,11 +35,30 @@ class ChannelScreen {
|
|||
channelNavBarTitle = element(by.id(this.testID.channelNavBarTitle));
|
||||
channelSearchButton = element(by.id(this.testID.channelSearchButton));
|
||||
channelTitleButton = element(by.id(this.testID.channelTitleButton));
|
||||
disabledSendButton = element(by.id(this.testID.disabledSendButton));
|
||||
postInput = element(by.id(this.testID.postInput));
|
||||
sendButton = element(by.id(this.testID.sendButton));
|
||||
settingsSidebarDrawerButton = element(by.id(this.testID.settingsSidebarDrawerButton));
|
||||
|
||||
// convenience props
|
||||
cameraQuickAction = CameraQuickAction.cameraQuickAction;
|
||||
cameraQuickActionDisabled = CameraQuickAction.cameraQuickActionDisabled;
|
||||
imageQuickAction = ImageQuickAction.imageQuickAction;
|
||||
imageQuickActionDisabled = ImageQuickAction.imageQuickActionDisabled;
|
||||
fileQuickAction = FileQuickAction.fileQuickAction;
|
||||
fileQuickActionDisabled = FileQuickAction.fileQuickActionDisabled;
|
||||
postDraft = PostDraft.postDraft;
|
||||
postDraftArchived = PostDraft.postDraftArchived;
|
||||
postDraftReadOnly = PostDraft.postDraftReadOnly;
|
||||
postInput = PostDraft.postInput;
|
||||
sendButton = SendButton.sendButton;
|
||||
sendButtonDisabled = SendButton.sendButtonDisabled;
|
||||
|
||||
getLongPostPostItem = (postId, text) => {
|
||||
return LongPostScreen.getPost(postId, text);
|
||||
}
|
||||
|
||||
getPostListPostItem = (postId, text) => {
|
||||
return PostListScreen.getPost(postId, text);
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.channelScreen).toBeVisible();
|
||||
|
||||
|
|
@ -36,6 +66,7 @@ class ChannelScreen {
|
|||
}
|
||||
|
||||
open = async (user) => {
|
||||
// # Open channel screen
|
||||
await SelectServerScreen.connectToServer();
|
||||
await LoginScreen.login(user);
|
||||
|
||||
|
|
@ -43,10 +74,38 @@ class ChannelScreen {
|
|||
}
|
||||
|
||||
logout = async () => {
|
||||
await this.settingsSidebarDrawerButton.tap();
|
||||
await this.openSettingsSidebar();
|
||||
await SettingsSidebar.logoutAction.tap();
|
||||
await SelectServerScreen.toBeVisible();
|
||||
}
|
||||
|
||||
openMainSidebar = async () => {
|
||||
// # Open main sidebar
|
||||
await this.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.toBeVisible();
|
||||
}
|
||||
|
||||
openSettingsSidebar = async () => {
|
||||
// # Open settings sidebar
|
||||
await this.settingsSidebarDrawerButton.tap();
|
||||
await SettingsSidebar.toBeVisible();
|
||||
}
|
||||
|
||||
openPostOptionsFor = async (postId, text) => {
|
||||
const post = await this.getPostListPostItem(postId, text);
|
||||
await expect(post).toBeVisible();
|
||||
|
||||
// # Open post options
|
||||
await post.longPress();
|
||||
await PostOptions.toBeVisible();
|
||||
}
|
||||
|
||||
tapSendButton = async () => {
|
||||
// # Tap send button
|
||||
await this.sendButton.tap();
|
||||
await expect(this.sendButton).not.toExist();
|
||||
await expect(this.sendButtonDisabled).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
const channelScreen = new ChannelScreen();
|
||||
|
|
|
|||
|
|
@ -9,14 +9,28 @@ class ChannelInfoScreen {
|
|||
channelInfoScreen: 'channel_info.screen',
|
||||
closeChannelInfoButton: 'close.channel_info.button',
|
||||
channelIconGMMemberCount: 'channel_icon.gm_member_count',
|
||||
favoritePreferenceAction: 'channel_info.favorite.action',
|
||||
mutePreferenceAction: 'channel_info.mute.action',
|
||||
ignoreMentionsPreferenceAction: 'channel_info.ignore_mentions.action',
|
||||
notificationPreferenceAction: 'channel_info.notification_preference.action',
|
||||
pinnedAction: 'channel_info.pinned.action',
|
||||
manageMembersAction: 'channel_info.manage_members.action',
|
||||
addMembersAction: 'channel_info.add_members.action',
|
||||
convertPrivateAction: 'channel_info.convert_private.action',
|
||||
editChannelAction: 'channel_info.edit_channel.action',
|
||||
}
|
||||
|
||||
channelInfoScreen = element(by.id(this.testID.channelInfoScreen));
|
||||
closeChannelInfoButton = element(by.id(this.testID.closeChannelInfoButton));
|
||||
channelIconGMMemberCount = element(by.id(this.testID.channelIconGMMemberCount));
|
||||
favoritePreferenceAction = element(by.id(this.testID.favoritePreferenceAction));
|
||||
mutePreferenceAction = element(by.id(this.testID.mutePreferenceAction));
|
||||
ignoreMentionsPreferenceAction = element(by.id(this.testID.ignoreMentionsPreferenceAction));
|
||||
notificationPreferenceAction = element(by.id(this.testID.notificationPreferenceAction));
|
||||
pinnedAction = element(by.id(this.testID.pinnedAction));
|
||||
manageMembersAction = element(by.id(this.testID.manageMembersAction));
|
||||
addMembersAction = element(by.id(this.testID.addMembersAction));
|
||||
convertPrivateAction = element(by.id(this.testID.convertPrivateAction));
|
||||
editChannelAction = element(by.id(this.testID.editChannelAction));
|
||||
|
||||
toBeVisible = async () => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChannelInfoScreen} from '@support/ui/screen';
|
||||
|
||||
class CreateChannelScreen {
|
||||
testID = {
|
||||
createChannelScreen: 'create_channel.screen',
|
||||
|
|
@ -26,16 +24,6 @@ class CreateChannelScreen {
|
|||
return this.createChannelScreen;
|
||||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open channel info screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Edit Channel
|
||||
await ChannelInfoScreen.editChannelAction.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
||||
back = async () => {
|
||||
await this.backButton.tap();
|
||||
await expect(this.createChannelScreen).not.toBeVisible();
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChannelScreen} from '@support/ui/component';
|
||||
import {MainSidebar} from '@support/ui/screen';
|
||||
|
||||
class DirectChannelsScreen {
|
||||
testID = {
|
||||
directChannelsScreen: 'direct_channels.screen',
|
||||
startButton: 'start-conversation',
|
||||
}
|
||||
|
||||
directChannelsScreen = element(by.id(this.testID.directChannelsScreen));
|
||||
startButton = element(by.id(this.testID.startButton));
|
||||
|
||||
getUserAtIndex = (index) => {
|
||||
return element(by.id('more_dms.user').withAncestor(by.id('more_dms.list'))).atIndex(index);
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.directChannelsScreen).toBeVisible();
|
||||
|
||||
return this.directChannelsScreen;
|
||||
}
|
||||
|
||||
open = async () => {
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.addDirectChannel.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
const directChannelsScreen = new DirectChannelsScreen();
|
||||
export default directChannelsScreen;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {ChannelInfoScreen} from '@support/ui/screen';
|
||||
|
||||
class EditChannelScreen {
|
||||
testID = {
|
||||
|
|
@ -21,9 +21,8 @@ class EditChannelScreen {
|
|||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open channel menu then tap 'Edit Channel'
|
||||
await ChannelScreen.channelTitleButton.tap();
|
||||
await element(by.text('Edit Channel')).tap();
|
||||
// # Open edit channel screen
|
||||
await ChannelInfoScreen.editChannelAction.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {PostOptions} from '@support/ui/component';
|
||||
import {isAndroid} from '@support/utils';
|
||||
|
||||
class EditPostScreen {
|
||||
|
|
@ -10,26 +11,30 @@ class EditPostScreen {
|
|||
editPostClose: 'edit_post.close',
|
||||
}
|
||||
|
||||
editPostScreen = element(by.id(this.testID.editPostScreen));
|
||||
editPostInput = element(by.id(this.testID.editPostInput));
|
||||
editPostClose = element(by.id(this.testID.editPostClose));
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.editPostScreen).toBeVisible();
|
||||
if (isAndroid()) {
|
||||
await expect(this.editPostScreen).toBeVisible();
|
||||
} else {
|
||||
await expect(this.editPostScreen).toExist();
|
||||
}
|
||||
|
||||
return this.editPostScreen;
|
||||
}
|
||||
|
||||
open = async (message) => {
|
||||
// # Open edit post screen
|
||||
await element(by.text(message)).longPress();
|
||||
|
||||
open = async () => {
|
||||
// # Swipe up panel on Android
|
||||
if (isAndroid()) {
|
||||
const slide = element(by.id('slide_up_panel'));
|
||||
await slide.swipe('up');
|
||||
await PostOptions.slideUpPanel.swipe('up');
|
||||
}
|
||||
|
||||
await element(by.text('Edit')).tap();
|
||||
// # Open edit post screen
|
||||
await PostOptions.editAction.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
||||
back = async () => {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,25 @@ class GeneralSettingsScreen {
|
|||
generalSettingsScreen: 'general_settings.screen',
|
||||
closeSettingsButton: 'close.settings.button',
|
||||
notificationsAction: 'general_settings.notifications.action',
|
||||
displayAction: 'general_settings.display.action',
|
||||
selectTeamAction: 'general_settings.select_team.action',
|
||||
advancedAction: 'general_settings.advanced.action',
|
||||
checkForUpgradeAction: 'general_settings.checkForUpgrade.action',
|
||||
aboutAction: 'general_settings.about.action',
|
||||
helpAction: 'general_settings.help.action',
|
||||
reportAction: 'general_settings.report.action',
|
||||
}
|
||||
|
||||
generalSettingsScreen = element(by.id(this.testID.generalSettingsScreen));
|
||||
closeSettingsButton = element(by.id(this.testID.closeSettingsButton));
|
||||
notificationsAction = element(by.id(this.testID.notificationsAction));
|
||||
displayAction = element(by.id(this.testID.displayAction));
|
||||
selectTeamAction = element(by.id(this.testID.selectTeamAction));
|
||||
advancedAction = element(by.id(this.testID.advancedAction));
|
||||
checkForUpgradeAction = element(by.id(this.testID.checkForUpgradeAction));
|
||||
aboutAction = element(by.id(this.testID.aboutAction));
|
||||
helpAction = element(by.id(this.testID.helpAction));
|
||||
reportAction = element(by.id(this.testID.reportAction));
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.generalSettingsScreen).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -6,15 +6,19 @@ import ChannelInfoScreen from './channel_info';
|
|||
import ChannelNotificationPreferenceScreen from './channel_notification_preference';
|
||||
import ChannelScreen from './channel';
|
||||
import CreateChannelScreen from './create_channel';
|
||||
import DirectChannelsScreen from './direct_channels';
|
||||
import EditChannelScreen from './edit_channel';
|
||||
import EditPostScreen from './edit_post';
|
||||
import GeneralSettingsScreen from './general_settings';
|
||||
import LoginScreen from './login';
|
||||
import LongPostScreen from './long_post';
|
||||
import MoreChannelsScreen from './more_channels';
|
||||
import MoreDirectMessagesScreen from './more_direct_messages';
|
||||
import NotificationScreen from './notification';
|
||||
import NotificationSettingsMobileScreen from './notification_settings_mobile';
|
||||
import NotificationSettingsScreen from './notification_settings';
|
||||
import PostListScreen from './post_list';
|
||||
import RecentMentionsScreen from './recent_mentions';
|
||||
import SearchResultPostScreen from './search_result_post';
|
||||
import SearchScreen from './search';
|
||||
import SelectServerScreen from './select_server';
|
||||
|
||||
|
|
@ -24,15 +28,19 @@ export {
|
|||
ChannelNotificationPreferenceScreen,
|
||||
ChannelScreen,
|
||||
CreateChannelScreen,
|
||||
DirectChannelsScreen,
|
||||
EditChannelScreen,
|
||||
EditPostScreen,
|
||||
GeneralSettingsScreen,
|
||||
LoginScreen,
|
||||
LongPostScreen,
|
||||
MoreChannelsScreen,
|
||||
MoreDirectMessagesScreen,
|
||||
NotificationScreen,
|
||||
NotificationSettingsMobileScreen,
|
||||
NotificationSettingsScreen,
|
||||
PostListScreen,
|
||||
RecentMentionsScreen,
|
||||
SearchResultPostScreen,
|
||||
SearchScreen,
|
||||
SelectServerScreen,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class LoginScreen {
|
|||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open login screen
|
||||
await SelectServerScreen.connectToServer();
|
||||
|
||||
return this.toBeVisible();
|
||||
|
|
|
|||
17
detox/e2e/support/ui/screen/long_post.js
Normal file
17
detox/e2e/support/ui/screen/long_post.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Post} from '@support/ui/component';
|
||||
|
||||
class LongPostScreen {
|
||||
testID = {
|
||||
longPostScreenPrefix: 'long_post.',
|
||||
}
|
||||
|
||||
getPost = (postId, text) => {
|
||||
return Post.getPost(this.testID.longPostScreenPrefix, postId, text);
|
||||
}
|
||||
}
|
||||
|
||||
const longPostScreen = new LongPostScreen();
|
||||
export default longPostScreen;
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChannelScreen} from '@support/ui/component';
|
||||
import {MainSidebar} from '@support/ui/screen';
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
|
||||
class MoreChannelsScreen {
|
||||
testID = {
|
||||
|
|
@ -20,8 +19,8 @@ class MoreChannelsScreen {
|
|||
}
|
||||
|
||||
open = async () => {
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.addChannel.tap();
|
||||
// # Open more channels screen
|
||||
await MainSidebar.openMoreChannelsButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
|
|
|||
36
detox/e2e/support/ui/screen/more_direct_messages.js
Normal file
36
detox/e2e/support/ui/screen/more_direct_messages.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
|
||||
class MoreDirectMessagesScreen {
|
||||
testID = {
|
||||
moreDirectMessagesScreen: 'more_direct_messages.screen',
|
||||
startButton: 'more_direct_messages.start.button',
|
||||
list: 'more_direct_messages.list',
|
||||
user: 'more_direct_messages.user',
|
||||
}
|
||||
|
||||
moreDirectMessagesScreen = element(by.id(this.testID.moreDirectMessagesScreen));
|
||||
startButton = element(by.id(this.testID.startButton));
|
||||
|
||||
getUserAtIndex = (index) => {
|
||||
return element(by.id(this.testID.user).withAncestor(by.id(this.testID.list))).atIndex(index);
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.moreDirectMessagesScreen).toBeVisible();
|
||||
|
||||
return this.moreDirectMessagesScreen;
|
||||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open more direct messages screen
|
||||
await MainSidebar.openMoreDirectMessagesButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
const moreDirectMessagesScreen = new MoreDirectMessagesScreen();
|
||||
export default moreDirectMessagesScreen;
|
||||
|
|
@ -3,21 +3,21 @@
|
|||
|
||||
class NotificationScreen {
|
||||
testID = {
|
||||
inAppNotification: 'in_app_notification',
|
||||
inAppNotificationScreen: 'in_app_notification.screen',
|
||||
inAppNotificationIcon: 'in_app_notification.icon',
|
||||
inAppNotificationTitle: 'in_app_notification.title',
|
||||
inAppNotificationMessage: 'in_app_notification.message',
|
||||
}
|
||||
|
||||
inAppNotification = element(by.id(this.testID.inAppNotification));
|
||||
inAppNotificationScreen = element(by.id(this.testID.inAppNotificationScreen));
|
||||
inAppNotificationIcon = element(by.id(this.testID.inAppNotificationIcon));
|
||||
inAppNotificationTitle = element(by.id(this.testID.inAppNotificationTitle));
|
||||
inAppNotificationMessage = element(by.id(this.testID.inAppNotificationMessage));
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.inAppNotification).toBeVisible();
|
||||
await expect(this.inAppNotificationScreen).toBeVisible();
|
||||
|
||||
return this.inAppNotification;
|
||||
return this.inAppNotificationScreen;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class NotificationSettingsScreen {
|
|||
|
||||
open = async () => {
|
||||
// # Open notification settings screen
|
||||
await GeneralSettingsScreen.notificationAction.tap();
|
||||
await GeneralSettingsScreen.notificationsAction.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,19 @@ class NotificationSettingsMobileScreen {
|
|||
pushModalCancelButton = element(by.id(this.testID.pushModalCancelButton));
|
||||
pushModalSaveButton = element(by.id(this.testID.pushModalSaveButton));
|
||||
|
||||
getPushActionFor = (pushKey) => {
|
||||
switch (pushKey) {
|
||||
case 'all':
|
||||
return this.allAction;
|
||||
case 'mentions':
|
||||
return this.mentionsAction;
|
||||
case 'never':
|
||||
return this.neverAction;
|
||||
default:
|
||||
throw new Error('Not a valid push option: ' + pushKey);
|
||||
}
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.notificationSettingsMobileScreen).toBeVisible();
|
||||
|
||||
|
|
@ -47,19 +60,6 @@ class NotificationSettingsMobileScreen {
|
|||
await this.backButton.tap();
|
||||
await expect(this.notificationSettingsMobileScreen).not.toBeVisible();
|
||||
}
|
||||
|
||||
getPushActionFor(pushKey) {
|
||||
switch (pushKey) {
|
||||
case 'all':
|
||||
return this.allAction;
|
||||
case 'mentions':
|
||||
return this.mentionsAction;
|
||||
case 'never':
|
||||
return this.neverAction;
|
||||
default:
|
||||
throw new Error('Not a valid push option: ' + pushKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const notificationSettingsMobileScreen = new NotificationSettingsMobileScreen();
|
||||
|
|
|
|||
17
detox/e2e/support/ui/screen/post_list.js
Normal file
17
detox/e2e/support/ui/screen/post_list.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Post} from '@support/ui/component';
|
||||
|
||||
class PostListScreen {
|
||||
testID = {
|
||||
postListScreenPrefix: 'post_list.',
|
||||
}
|
||||
|
||||
getPost = (postId, text) => {
|
||||
return Post.getPost(this.testID.postListScreenPrefix, postId, text);
|
||||
}
|
||||
}
|
||||
|
||||
const postListScreen = new PostListScreen();
|
||||
export default postListScreen;
|
||||
52
detox/e2e/support/ui/screen/recent_mentions.js
Normal file
52
detox/e2e/support/ui/screen/recent_mentions.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {
|
||||
PostOptions,
|
||||
SettingsSidebar,
|
||||
} from '@support/ui/component';
|
||||
import {SearchResultPostScreen} from '@support/ui/screen';
|
||||
|
||||
class RecentMentionsScreen {
|
||||
testID = {
|
||||
recentMentionsScreen: 'recent_mentions.screen',
|
||||
closeSettingsButton: 'close.settings.button',
|
||||
}
|
||||
|
||||
recentMentionsScreen = element(by.id(this.testID.recentMentionsScreen));
|
||||
closeSettingsButton = element(by.id(this.testID.closeSettingsButton));
|
||||
|
||||
getSearchResultPostItem = (postId, text) => {
|
||||
return SearchResultPostScreen.getPost(postId, text);
|
||||
}
|
||||
|
||||
toBeVisible = async () => {
|
||||
await expect(this.recentMentionsScreen).toBeVisible();
|
||||
|
||||
return this.recentMentionsScreen;
|
||||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open recent mentions screen
|
||||
await SettingsSidebar.recentMentionsAction.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
}
|
||||
|
||||
close = async () => {
|
||||
await this.closeSettingsButton.tap();
|
||||
await expect(this.recentMentionsScreen).not.toBeVisible();
|
||||
}
|
||||
|
||||
openPostOptionsFor = async (postId, text) => {
|
||||
const post = await this.getSearchResultPostItem(postId, text);
|
||||
await expect(post).toBeVisible();
|
||||
|
||||
// # Open post options
|
||||
await post.longPress();
|
||||
await PostOptions.toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
const recentMentionsScreen = new RecentMentionsScreen();
|
||||
export default recentMentionsScreen;
|
||||
|
|
@ -26,6 +26,7 @@ class SearchScreen {
|
|||
}
|
||||
|
||||
open = async () => {
|
||||
// # Open search screen
|
||||
await ChannelScreen.channelSearchButton.tap();
|
||||
|
||||
return this.toBeVisible();
|
||||
|
|
|
|||
17
detox/e2e/support/ui/screen/search_result_post.js
Normal file
17
detox/e2e/support/ui/screen/search_result_post.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Post} from '@support/ui/component';
|
||||
|
||||
class SearchResultPostScreen {
|
||||
testID = {
|
||||
searchResultPostScreenPrefix: 'search_result_post.',
|
||||
}
|
||||
|
||||
getPost = (postId, text) => {
|
||||
return Post.getPost(this.testID.searchResultPostScreenPrefix, postId, text);
|
||||
}
|
||||
}
|
||||
|
||||
const searchResultPostScreen = new SearchResultPostScreen();
|
||||
export default searchResultPostScreen;
|
||||
|
|
@ -20,6 +20,8 @@ describe('Autocomplete', () => {
|
|||
beforeAll(async () => {
|
||||
({user} = await Setup.apiInit());
|
||||
userAtMentionAutocomplete = Autocomplete.getAtMentionItem(user.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -171,21 +173,21 @@ describe('Autocomplete', () => {
|
|||
|
||||
it('MM-T3409_11 should be able to select at mention multiple times', async () => {
|
||||
// # Type "@" to activate at mention autocomplete
|
||||
await expect(element(by.id('autocomplete.at_mention.list'))).not.toExist();
|
||||
await expect(atMentionSuggestionList).not.toExist();
|
||||
await postInput.typeText('@');
|
||||
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
|
||||
await expect(atMentionSuggestionList).toExist();
|
||||
|
||||
// # Type username
|
||||
await postInput.typeText(user.username);
|
||||
|
||||
// # Tap user
|
||||
await element(by.id(`autocomplete.at_mention.item.${user.id}`)).tap();
|
||||
await userAtMentionAutocomplete.tap();
|
||||
|
||||
// * expect mention autocomplete to dissappear
|
||||
await expect(element(by.id('autocomplete.at_mention.list'))).not.toExist();
|
||||
await expect(atMentionSuggestionList).not.toExist();
|
||||
|
||||
// # Type "@" again to re-activate mention autocomplete
|
||||
await postInput.typeText('@');
|
||||
await expect(element(by.id('autocomplete.at_mention.list'))).toExist();
|
||||
await expect(atMentionSuggestionList).toExist();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import {Setup} from '@support/server_api';
|
|||
describe('Autocomplete', () => {
|
||||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -26,7 +28,8 @@ describe('Autocomplete', () => {
|
|||
});
|
||||
|
||||
it('MM-T3390 should render autocomplete in channel header edit screen', async () => {
|
||||
// # Open edit channel modal
|
||||
// # Open edit channel screen
|
||||
await ChannelInfoScreen.open();
|
||||
await EditChannelScreen.open();
|
||||
|
||||
// # Activate at_mention autocomplete
|
||||
|
|
|
|||
|
|
@ -8,13 +8,25 @@
|
|||
// *******************************************************************
|
||||
|
||||
import {Autocomplete} from '@support/ui/component';
|
||||
import {ChannelScreen, EditPostScreen} from '@support/ui/screen';
|
||||
import {isAndroid, timeouts, wait} from '@support/utils';
|
||||
import {Setup} from '@support/server_api';
|
||||
import {
|
||||
ChannelScreen,
|
||||
EditPostScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Autocomplete', () => {
|
||||
let testChannel;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
const {team, user} = await Setup.apiInit();
|
||||
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
|
||||
testChannel = channel;
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -23,23 +35,20 @@ describe('Autocomplete', () => {
|
|||
});
|
||||
|
||||
it('MM-T3391 should render autocomplete in post edit screen', async () => {
|
||||
const message = Date.now().toString();
|
||||
const {postInput, sendButton} = ChannelScreen;
|
||||
const testMessage = Date.now().toString();
|
||||
const {postInput} = ChannelScreen;
|
||||
|
||||
// # Type a message
|
||||
await postInput.tap();
|
||||
await postInput.typeText(message);
|
||||
await postInput.typeText(testMessage);
|
||||
|
||||
// # Tap the send button
|
||||
await sendButton.tap();
|
||||
// # Tap send button
|
||||
await ChannelScreen.tapSendButton();
|
||||
|
||||
// # Explicitly wait on Android before verifying error message
|
||||
if (isAndroid()) {
|
||||
await wait(timeouts.ONE_SEC);
|
||||
}
|
||||
|
||||
// # Open edit screen
|
||||
await EditPostScreen.open(message);
|
||||
// # Open edit post screen
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, testMessage);
|
||||
await EditPostScreen.open();
|
||||
|
||||
const {atMentionSuggestionList} = Autocomplete;
|
||||
const {editPostInput, editPostClose} = EditPostScreen;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ describe('Autocomplete', () => {
|
|||
|
||||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ describe('Autocomplete', () => {
|
|||
|
||||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
await ChannelScreen.open(user);
|
||||
|
||||
// # Open search screen
|
||||
await ChannelScreen.open(user);
|
||||
await SearchScreen.open();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
import {
|
||||
ChannelInfoScreen,
|
||||
ChannelScreen,
|
||||
DirectChannelsScreen,
|
||||
MoreDirectMessagesScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {timeouts, wait} from '@support/utils';
|
||||
import {Setup} from '@support/server_api';
|
||||
|
|
@ -19,6 +18,8 @@ import {Setup} from '@support/server_api';
|
|||
describe('Channel Info Header', () => {
|
||||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -27,13 +28,9 @@ describe('Channel Info Header', () => {
|
|||
});
|
||||
|
||||
it('MM-T3406 should render correct GM member count in channel info header', async () => {
|
||||
// # Open main sidebar
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.toBeVisible();
|
||||
|
||||
// # Open Direct Channels screen
|
||||
await MainSidebar.addDirectChannel.tap();
|
||||
await DirectChannelsScreen.toBeVisible();
|
||||
// # Open more direct messages screen
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MoreDirectMessagesScreen.open();
|
||||
|
||||
// # Wait for some profiles to load
|
||||
await wait(timeouts.ONE_SEC);
|
||||
|
|
@ -41,7 +38,7 @@ describe('Channel Info Header', () => {
|
|||
const {
|
||||
getUserAtIndex,
|
||||
startButton,
|
||||
} = DirectChannelsScreen;
|
||||
} = MoreDirectMessagesScreen;
|
||||
|
||||
// # Select 3 profiles
|
||||
await getUserAtIndex(0).tap();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import jestExpect from 'expect';
|
||||
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
import {
|
||||
ChannelScreen,
|
||||
ChannelInfoScreen,
|
||||
|
|
@ -22,6 +21,7 @@ describe('Channels', () => {
|
|||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -30,14 +30,11 @@ describe('Channels', () => {
|
|||
});
|
||||
|
||||
it('MM-T3201 Create public channel', async () => {
|
||||
// # Go to channel sidebar list
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
|
||||
// # Tap on + public channels
|
||||
await MainSidebar.addChannel.tap();
|
||||
// # Open more channels screen
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MoreChannelsScreen.open();
|
||||
|
||||
// * Expect a list of public channels, initially empty
|
||||
await MoreChannelsScreen.toBeVisible();
|
||||
await expect(element(by.text('No more channels to join'))).toBeVisible();
|
||||
|
||||
// # Tap to create new channel
|
||||
|
|
|
|||
|
|
@ -7,11 +7,6 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {
|
||||
CameraQuickAction,
|
||||
FileQuickAction,
|
||||
ImageQuickAction,
|
||||
} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Setup,
|
||||
|
|
@ -35,9 +30,15 @@ describe('Disable Upload', () => {
|
|||
});
|
||||
|
||||
it('MM-T3453 should disable file, image, camera icons when mobile file upload is disabled', async () => {
|
||||
const {
|
||||
cameraQuickActionDisabled,
|
||||
fileQuickActionDisabled,
|
||||
imageQuickActionDisabled,
|
||||
} = ChannelScreen;
|
||||
|
||||
// * Verify disabled file, image, camera icons are visible
|
||||
await expect(CameraQuickAction.cameraQuickActionDisabled).toBeVisible();
|
||||
await expect(FileQuickAction.fileQuickActionDisabled).toBeVisible();
|
||||
await expect(ImageQuickAction.imageQuickActionDisabled).toBeVisible();
|
||||
await expect(cameraQuickActionDisabled).toBeVisible();
|
||||
await expect(fileQuickActionDisabled).toBeVisible();
|
||||
await expect(imageQuickActionDisabled).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,11 +7,6 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {
|
||||
CameraQuickAction,
|
||||
FileQuickAction,
|
||||
ImageQuickAction,
|
||||
} from '@support/ui/component';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Setup,
|
||||
|
|
@ -35,9 +30,15 @@ describe('Enable Upload', () => {
|
|||
});
|
||||
|
||||
it('MM-T3483 should enable file, image, camera icons when mobile file upload is enabled', async () => {
|
||||
const {
|
||||
cameraQuickAction,
|
||||
fileQuickAction,
|
||||
imageQuickAction,
|
||||
} = ChannelScreen;
|
||||
|
||||
// * Verify enabled file, image, camera icons are visible
|
||||
await expect(CameraQuickAction.cameraQuickAction).toBeVisible();
|
||||
await expect(FileQuickAction.fileQuickAction).toBeVisible();
|
||||
await expect(ImageQuickAction.imageQuickAction).toBeVisible();
|
||||
await expect(cameraQuickAction).toBeVisible();
|
||||
await expect(fileQuickAction).toBeVisible();
|
||||
await expect(imageQuickAction).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ describe('Select channel', () => {
|
|||
const {user, channel} = await Setup.apiInit();
|
||||
newChannel = channel;
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -27,13 +28,10 @@ describe('Select channel', () => {
|
|||
});
|
||||
|
||||
it('MM-T3412 should close the sidebar menu when selecting the same channel', async () => {
|
||||
const {mainSidebarDrawerButton, channelNavBarTitle} = ChannelScreen;
|
||||
const {channelNavBarTitle} = ChannelScreen;
|
||||
|
||||
// # Open main sidebar (with at least one unread channel)
|
||||
await mainSidebarDrawerButton.tap();
|
||||
|
||||
// * Main sidebar should be visible
|
||||
await MainSidebar.toBeVisible();
|
||||
await ChannelScreen.openMainSidebar();
|
||||
|
||||
// # Tap a channel to view it
|
||||
const channelItem = MainSidebar.getChannelByDisplayName(newChannel.display_name);
|
||||
|
|
@ -43,7 +41,7 @@ describe('Select channel', () => {
|
|||
await expect(channelNavBarTitle).toHaveText(newChannel.display_name);
|
||||
|
||||
// # Open main sidebar again and select the same channel
|
||||
await mainSidebarDrawerButton.tap();
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await channelItem.tap();
|
||||
|
||||
// * Drawer should not be visible on Android
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ describe('Messaging', () => {
|
|||
beforeAll(async () => {
|
||||
const {user} = await Setup.apiInit();
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -21,28 +22,34 @@ describe('Messaging', () => {
|
|||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('should post a message on tap to paper send button', async () => {
|
||||
it('MM-T3486 should post a message when send button is tapped', async () => {
|
||||
// * Verify channel screen is visible
|
||||
await ChannelScreen.toBeVisible();
|
||||
|
||||
const {postInput, sendButton} = ChannelScreen;
|
||||
const {
|
||||
postInput,
|
||||
sendButton,
|
||||
sendButtonDisabled,
|
||||
} = ChannelScreen;
|
||||
|
||||
// * Post input should exist while send button should not
|
||||
// * Verify post input is visible and send button is disabled
|
||||
await expect(postInput).toBeVisible();
|
||||
await expect(sendButton).not.toExist();
|
||||
await expect(sendButtonDisabled).toBeVisible();
|
||||
|
||||
// # Tap on post input
|
||||
await postInput.tap();
|
||||
|
||||
// # Type text on post input
|
||||
const text = Date.now().toString();
|
||||
await postInput.typeText(text);
|
||||
// # Type message on post input
|
||||
const message = Date.now().toString();
|
||||
await postInput.typeText(message);
|
||||
|
||||
// * Verify send button is enabled
|
||||
await expect(sendButton).toBeVisible();
|
||||
|
||||
// # Tap send button
|
||||
await expect(sendButton).toBeVisible();
|
||||
await sendButton.tap();
|
||||
|
||||
// * Verify text to exist
|
||||
await expect(element(by.text(text))).toBeVisible();
|
||||
// * Verify message is posted
|
||||
await expect(element(by.text(message))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ describe('Messaging', () => {
|
|||
beforeAll(async () => {
|
||||
({team, user} = await Setup.apiInit());
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -29,21 +30,21 @@ describe('Messaging', () => {
|
|||
it('MM-T109 User can\'t send the same message repeatedly', async () => {
|
||||
const message = Date.now().toString();
|
||||
|
||||
const {disabledSendButton, sendButton, postInput} = ChannelScreen;
|
||||
const {
|
||||
postInput,
|
||||
sendButtonDisabled,
|
||||
} = ChannelScreen;
|
||||
|
||||
// # Type a message
|
||||
await postInput.tap();
|
||||
await postInput.typeText(message);
|
||||
|
||||
// # Tap the send button
|
||||
await expect(sendButton).toBeVisible();
|
||||
await sendButton.tap();
|
||||
await expect(sendButton).not.toExist();
|
||||
// # Tap send button
|
||||
await ChannelScreen.tapSendButton();
|
||||
|
||||
// # Then tap send button repeatedly
|
||||
await expect(disabledSendButton).toBeVisible();
|
||||
await expect(disabledSendButton).toExist();
|
||||
await disabledSendButton.multiTap(3);
|
||||
await expect(sendButtonDisabled).toBeVisible();
|
||||
await sendButtonDisabled.multiTap(3);
|
||||
|
||||
// * Check that message is successfully posted
|
||||
await expect(element(by.text(message))).toExist();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {
|
||||
MainSidebar,
|
||||
SettingsSidebar,
|
||||
} from '@support/ui/component';
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
import {
|
||||
ChannelInfoScreen,
|
||||
ChannelNotificationPreferenceScreen,
|
||||
|
|
@ -28,15 +25,14 @@ describe('Channel Notification Preference - Default', () => {
|
|||
beforeAll(async () => {
|
||||
const {user, channel} = await Setup.apiInit();
|
||||
testChannel = channel;
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// # Open main sidebar
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.toBeVisible();
|
||||
|
||||
// # Go to channel
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MainSidebar.getChannelByDisplayName(testChannel.display_name).tap();
|
||||
});
|
||||
|
||||
|
|
@ -53,11 +49,9 @@ describe('Channel Notification Preference - Default', () => {
|
|||
// # Set global notifications to mentions
|
||||
await setGlobalNotificationsTo('mentions');
|
||||
|
||||
// # Open channel info screen
|
||||
// # Open on notification preference screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Mobile Notifications
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
|
||||
// # Tap on For all activity option
|
||||
await element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (Mentions)`)).tap();
|
||||
|
|
@ -76,7 +70,7 @@ describe('Channel Notification Preference - Default', () => {
|
|||
|
||||
// * Verify Global default (Never) is displayed
|
||||
await ChannelInfoScreen.open();
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
await expect(element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (Never)`))).toBeVisible();
|
||||
|
||||
// # Go back to channel info screen
|
||||
|
|
@ -88,7 +82,7 @@ describe('Channel Notification Preference - Default', () => {
|
|||
|
||||
// * Verify Global default (All) is displayed
|
||||
await ChannelInfoScreen.open();
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
await expect(element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (All)`))).toBeVisible();
|
||||
|
||||
// # Tap on back button
|
||||
|
|
@ -97,21 +91,11 @@ describe('Channel Notification Preference - Default', () => {
|
|||
});
|
||||
|
||||
async function setGlobalNotificationsTo(pushKey) {
|
||||
// # Open settings sidebar
|
||||
await ChannelScreen.settingsSidebarDrawerButton.tap();
|
||||
await SettingsSidebar.toBeVisible();
|
||||
|
||||
// # Open general settings screen
|
||||
await SettingsSidebar.settingsAction.tap();
|
||||
await GeneralSettingsScreen.toBeVisible();
|
||||
|
||||
// # Open notification settings screen
|
||||
await GeneralSettingsScreen.notificationsAction.tap();
|
||||
await NotificationSettingsScreen.toBeVisible();
|
||||
|
||||
// # Open notifications settings mobile screen
|
||||
await NotificationSettingsScreen.mobileAction.tap();
|
||||
await NotificationSettingsMobileScreen.toBeVisible();
|
||||
await ChannelScreen.openSettingsSidebar();
|
||||
await GeneralSettingsScreen.open();
|
||||
await NotificationSettingsScreen.open();
|
||||
await NotificationSettingsMobileScreen.open();
|
||||
|
||||
// # Tap on Send Notifications option if Android
|
||||
if (isAndroid()) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
ChannelInfoScreen,
|
||||
ChannelNotificationPreferenceScreen,
|
||||
ChannelScreen,
|
||||
DirectChannelsScreen,
|
||||
MoreDirectMessagesScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {Setup} from '@support/server_api';
|
||||
import {isAndroid} from '@support/utils';
|
||||
|
|
@ -23,15 +23,14 @@ describe('Channel Notification Preference', () => {
|
|||
beforeAll(async () => {
|
||||
const {user, channel} = await Setup.apiInit();
|
||||
testChannel = channel;
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// # Open main sidebar
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.toBeVisible();
|
||||
|
||||
// # Go to channel
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MainSidebar.getChannelByDisplayName(testChannel.display_name).tap();
|
||||
});
|
||||
|
||||
|
|
@ -45,11 +44,9 @@ describe('Channel Notification Preference', () => {
|
|||
});
|
||||
|
||||
it('MM-T3375_1 should display Mobile Notifications option for non-DM Channels', async () => {
|
||||
// # Open channel info screen
|
||||
// # Open on notification preference screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Mobile Notifications
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
|
||||
const {
|
||||
titleText,
|
||||
|
|
@ -73,18 +70,14 @@ describe('Channel Notification Preference', () => {
|
|||
});
|
||||
|
||||
it('MM-T3375_2 should not display Mobile Notifications option for DM Channel', async () => {
|
||||
// # Open main sidebar
|
||||
await ChannelScreen.mainSidebarDrawerButton.tap();
|
||||
await MainSidebar.toBeVisible();
|
||||
|
||||
// # Open Direct Channels screen
|
||||
await MainSidebar.addDirectChannel.tap();
|
||||
await DirectChannelsScreen.toBeVisible();
|
||||
// # Open more direct messages screen
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MoreDirectMessagesScreen.open();
|
||||
|
||||
const {
|
||||
getUserAtIndex,
|
||||
startButton,
|
||||
} = DirectChannelsScreen;
|
||||
} = MoreDirectMessagesScreen;
|
||||
|
||||
// # Select 1 profile
|
||||
await getUserAtIndex(0).tap();
|
||||
|
|
@ -100,11 +93,9 @@ describe('Channel Notification Preference', () => {
|
|||
});
|
||||
|
||||
it('MM-T3377 should be able to select For all activity option and display All next to Mobile Notifications', async () => {
|
||||
// # Open channel info screen
|
||||
// # Open on notification preference screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Mobile Notifications
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
|
||||
// # Tap on For all activity option
|
||||
await element(by.text(ChannelNotificationPreferenceScreen.optionAllText)).tap();
|
||||
|
|
@ -118,11 +109,9 @@ describe('Channel Notification Preference', () => {
|
|||
});
|
||||
|
||||
it('MM-T3378 should be able to select Only mentions and direct messages option and display Mentions next to Mobile Notifications', async () => {
|
||||
// # Open channel info screen
|
||||
// # Open on notification preference screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Mobile Notifications
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
|
||||
// # Tap on For all activity option
|
||||
await element(by.text(ChannelNotificationPreferenceScreen.optionMentionsText)).tap();
|
||||
|
|
@ -136,11 +125,9 @@ describe('Channel Notification Preference', () => {
|
|||
});
|
||||
|
||||
it('MM-T3379 should be able to select Never option and display Never next to Mobile Notifications', async () => {
|
||||
// # Open channel info screen
|
||||
// # Open on notification preference screen
|
||||
await ChannelInfoScreen.open();
|
||||
|
||||
// # Tap on Mobile Notifications
|
||||
await ChannelInfoScreen.notificationPreferenceAction.tap();
|
||||
await ChannelNotificationPreferenceScreen.open();
|
||||
|
||||
// # Tap on For all activity option
|
||||
await element(by.text(ChannelNotificationPreferenceScreen.optionNeverText)).tap();
|
||||
|
|
|
|||
|
|
@ -7,12 +7,94 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {AddReactionScreen, ChannelScreen, NotificationScreen} from '@support/ui/screen';
|
||||
import {isAndroid, timeouts, wait} from '@support/utils';
|
||||
import {Setup} from '@support/server_api';
|
||||
import {
|
||||
AddReactionScreen,
|
||||
ChannelScreen,
|
||||
NotificationScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
import {
|
||||
isAndroid,
|
||||
timeouts,
|
||||
wait,
|
||||
} from '@support/utils';
|
||||
|
||||
const DetoxConstants = require('detox').DetoxConstants;
|
||||
|
||||
describe('in-app Notification', () => {
|
||||
let testChannel1;
|
||||
let testChannel2;
|
||||
let testNotification;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, team, user} = await Setup.apiInit();
|
||||
testChannel1 = channel;
|
||||
testNotification = getNotification(testChannel1, team, user);
|
||||
|
||||
({channel: testChannel2} = await Channel.apiGetChannelByName(team.name, 'town-square'));
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T3440 should render an in-app notification', async () => {
|
||||
const testMessage = Date.now().toString();
|
||||
const {postInput} = ChannelScreen;
|
||||
|
||||
// # Type a message
|
||||
await postInput.tap();
|
||||
await postInput.typeText(testMessage);
|
||||
|
||||
// # Tap send button
|
||||
await ChannelScreen.tapSendButton();
|
||||
|
||||
// # Open add reaction screen
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel2.id);
|
||||
await ChannelScreen.openPostOptionsFor(post.id, testMessage);
|
||||
await AddReactionScreen.open();
|
||||
|
||||
// # Close add reaction screen
|
||||
await AddReactionScreen.close();
|
||||
|
||||
if (isAndroid()) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Skipping on Android until https://github.com/wix/Detox/issues/2141');
|
||||
return;
|
||||
}
|
||||
|
||||
// # When a push notification is received
|
||||
await device.sendUserNotification(testNotification);
|
||||
await wait(timeouts.HALF_SEC);
|
||||
|
||||
// * Verify in-app notification is shown
|
||||
const {
|
||||
inAppNotificationScreen,
|
||||
inAppNotificationIcon,
|
||||
inAppNotificationTitle,
|
||||
inAppNotificationMessage,
|
||||
} = NotificationScreen;
|
||||
|
||||
await NotificationScreen.toBeVisible();
|
||||
await expect(inAppNotificationIcon).toBeVisible();
|
||||
await expect(inAppNotificationTitle).toHaveText(testChannel1.name);
|
||||
await expect(inAppNotificationMessage).toHaveText('This is an e2e test message');
|
||||
|
||||
// # Wait for some profiles to load
|
||||
await wait(5 * timeouts.ONE_SEC);
|
||||
|
||||
// * Verify in-app notification is hidden
|
||||
await expect(inAppNotificationScreen).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
function getNotification(channel, team, user) {
|
||||
if (isAndroid()) {
|
||||
return {
|
||||
|
|
@ -52,66 +134,3 @@ function getNotification(channel, team, user) {
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('in-app Notification', () => {
|
||||
let testNotification;
|
||||
let testChannel;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {channel, team, user} = await Setup.apiInit();
|
||||
testChannel = channel;
|
||||
testNotification = getNotification(channel, team, user);
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T3440 should render an in-app notification', async () => {
|
||||
const message = Date.now().toString();
|
||||
|
||||
const {postInput, sendButton} = ChannelScreen;
|
||||
|
||||
// # Type a message
|
||||
await postInput.tap();
|
||||
await postInput.typeText(message);
|
||||
|
||||
// # Tap the send button
|
||||
await sendButton.tap();
|
||||
await wait(timeouts.HALF_SEC);
|
||||
|
||||
// # Open Add reaction screen
|
||||
await AddReactionScreen.open(message);
|
||||
await AddReactionScreen.closeAddReactionButton.tap();
|
||||
|
||||
if (isAndroid()) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Skipping on Android until https://github.com/wix/Detox/issues/2141');
|
||||
return;
|
||||
}
|
||||
|
||||
// # When a push notification is received
|
||||
await device.sendUserNotification(testNotification);
|
||||
await wait(timeouts.HALF_SEC);
|
||||
|
||||
// * Verify in-app notification is shown
|
||||
const {
|
||||
inAppNotification,
|
||||
inAppNotificationIcon,
|
||||
inAppNotificationTitle,
|
||||
inAppNotificationMessage,
|
||||
} = NotificationScreen;
|
||||
|
||||
await NotificationScreen.toBeVisible();
|
||||
await expect(inAppNotificationIcon).toBeVisible();
|
||||
await expect(inAppNotificationTitle).toHaveText(testChannel.name);
|
||||
await expect(inAppNotificationMessage).toHaveText('This is an e2e test message');
|
||||
|
||||
// # Wait for some profiles to load
|
||||
await wait(5 * timeouts.ONE_SEC);
|
||||
|
||||
// * Verify in-app notification is hidden
|
||||
await expect(inAppNotification).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ describe('Smoke Tests', () => {
|
|||
// * Check that LDAP server can connect and is synchronized with Mattermost server
|
||||
await Ldap.apiRequireLDAPServer();
|
||||
|
||||
// # Ensure user has team
|
||||
await ensureUserHasTeam(testOne);
|
||||
});
|
||||
|
||||
|
|
|
|||
79
detox/e2e/test/smoke_test/recent_mentions.e2e.js
Normal file
79
detox/e2e/test/smoke_test/recent_mentions.e2e.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// 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 {PostOptions} from '@support/ui/component';
|
||||
import {
|
||||
ChannelScreen,
|
||||
RecentMentionsScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
Team,
|
||||
User,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Recent Mentions', () => {
|
||||
let testUser1;
|
||||
let testUser2;
|
||||
let testChannel;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {team, user} = await Setup.apiInit();
|
||||
testUser1 = user;
|
||||
|
||||
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
|
||||
testChannel = channel;
|
||||
|
||||
({user: testUser2} = await User.apiCreateUser());
|
||||
await Team.apiAddUserToTeam(testUser2.id, team.id);
|
||||
await Channel.apiAddUserToChannel(testUser2.id, testChannel.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(testUser1);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T3222 should display recent mentions and no option to add a reaction', async () => {
|
||||
// # Post an at-mention message to user 1 by user 2
|
||||
const testMessage = `Mention @${testUser1.username}`;
|
||||
await User.apiLogin(testUser2);
|
||||
await Post.apiCreatePost({
|
||||
channelId: testChannel.id,
|
||||
message: testMessage,
|
||||
});
|
||||
|
||||
// * Verify most recent post has the message
|
||||
const lastPost = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
const postListPostItem = await ChannelScreen.getPostListPostItem(lastPost.post.id, testMessage);
|
||||
await expect(postListPostItem).toBeVisible();
|
||||
|
||||
// # Open recent mentions screen
|
||||
await ChannelScreen.openSettingsSidebar();
|
||||
await RecentMentionsScreen.open();
|
||||
|
||||
// * Verify most recent search result post has the at-mention message
|
||||
const lastSearchResultPost = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
const searchResultPostItem = await RecentMentionsScreen.getSearchResultPostItem(lastSearchResultPost.post.id, testMessage);
|
||||
await expect(searchResultPostItem).toBeVisible();
|
||||
|
||||
// * Verify recent mentions post item does not have option to add a reaction
|
||||
await searchResultPostItem.longPress();
|
||||
await PostOptions.toBeVisible();
|
||||
await expect(PostOptions.reactionPickerAction).not.toBeVisible();
|
||||
|
||||
// # Close recent mentions screen
|
||||
await PostOptions.close();
|
||||
await RecentMentionsScreen.close();
|
||||
});
|
||||
});
|
||||
|
|
@ -7,9 +7,12 @@
|
|||
// - Use element testID when selecting an element. Create one if none.
|
||||
// *******************************************************************
|
||||
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {MainSidebar} from '@support/ui/component';
|
||||
import {Setup, Channel} from '@support/server_api';
|
||||
import {ChannelScreen} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Setup,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Unread channels', () => {
|
||||
let newChannel;
|
||||
|
|
@ -26,6 +29,7 @@ describe('Unread channels', () => {
|
|||
({channel: zChannel} = await Channel.apiCreateChannel({type: 'O', prefix: 'z-channel', teamId: team.id}));
|
||||
await Channel.apiAddUserToChannel(user.id, zChannel.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(user);
|
||||
});
|
||||
|
||||
|
|
@ -34,13 +38,8 @@ describe('Unread channels', () => {
|
|||
});
|
||||
|
||||
it('MM-T3187 Unread channels sort at top', async () => {
|
||||
const {mainSidebarDrawerButton} = ChannelScreen;
|
||||
|
||||
// # Open main sidebar (with at least one unread channel)
|
||||
await mainSidebarDrawerButton.tap();
|
||||
|
||||
// * Channel should be visible
|
||||
await MainSidebar.toBeVisible();
|
||||
await ChannelScreen.openMainSidebar();
|
||||
|
||||
// * Verify unread channel(s) display at top of channel list (with mentions first, if any), in alphabetical order, with title "Unreads"
|
||||
await expect(element(by.text('UNREADS'))).toBeVisible();
|
||||
|
|
@ -50,15 +49,13 @@ describe('Unread channels', () => {
|
|||
|
||||
// # Tap an unread channel to view it
|
||||
await MainSidebar.getChannelByDisplayName(aChannel.display_name).tap();
|
||||
await mainSidebarDrawerButton.tap();
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MainSidebar.getChannelByDisplayName(newChannel.display_name).tap();
|
||||
await mainSidebarDrawerButton.tap();
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MainSidebar.getChannelByDisplayName(zChannel.display_name).tap();
|
||||
|
||||
// # Open main sidebar again
|
||||
await mainSidebarDrawerButton.tap();
|
||||
|
||||
// * Channel you just read is no longer listed in Unreads
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await expect(element(by.text('UNREADS'))).not.toBeVisible();
|
||||
await expect(element(by.text('PUBLIC CHANNELS'))).toBeVisible();
|
||||
await MainSidebar.hasChannelAtIndex(0, aChannel.display_name);
|
||||
Loading…
Reference in a new issue