MM-30165 Detox/E2E: Add e2e tests for channel notification preference (#4949)

* Detox/E2E: Add e2e tests for channel notification preference

* Fixed unit snap files

* Moved e2e to notifications and updated formatting

* Added basic snapshot tests

* Update app/components/radio_button/radio_button_group.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/components/radio_button/radio_button_group.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/components/radio_button/radio_button_group.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/components/sidebars/settings/drawer_item.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/screens/channel_info/edit_channel/edit_channel.tsx

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/screens/channel_info/notification_preference/notification_preference.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/screens/channel_info/notification_preference/notification_preference.tsx

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/components/radio_button/radio_button_group.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Fix radio button group snap file

* Simplified element call

* Rename channel sidebar to main sidebar

* Rename drawer button files

* Update app/components/sidebars/settings/settings_sidebar.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update app/screens/channel_info/channel_info_row.test.js

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* Update comments

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
Joseph Baylon 2020-11-10 09:53:38 -08:00 committed by GitHub
parent ae56d73dba
commit 0dfb776290
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 1485 additions and 124 deletions

View file

@ -0,0 +1,82 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`RadioButtonGroup should match snapshot 1`] = `
<View>
<Connect(RadioButton)
checked={true}
disabled={false}
label="label-1"
name="name"
onCheck={[Function]}
testID="radio-1"
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value="value"
/>
<Connect(RadioButton)
checked={false}
disabled={true}
label="label-2"
name="name"
onCheck={[Function]}
testID="radio-2"
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value="value"
/>
</View>
`;

View file

@ -15,6 +15,7 @@ const DEFAULT_OPACITY = 1;
class RadioButton extends PureComponent {
static propTypes = {
testID: PropTypes.string,
label: PropTypes.string,
theme: PropTypes.object,
value: PropTypes.string,
@ -83,7 +84,7 @@ class RadioButton extends PureComponent {
render() {
const {scaleValue, opacityValue} = this.state;
const {theme, checked, disabled} = this.props;
const {testID, theme, checked, disabled} = this.props;
const styles = getStyleSheet(theme);
const color = checked ? theme.buttonBg : theme.centerChannelColor;
@ -91,6 +92,7 @@ class RadioButton extends PureComponent {
return (
<View
testID={testID}
style={styles.container}
{...this.responder}
>

View file

@ -29,6 +29,7 @@ export default class RadioButtonGroup extends PureComponent {
if (this.props.options.length) {
options = this.props.options.map((option) => {
const {
testID,
value,
label,
disabled,
@ -39,6 +40,7 @@ export default class RadioButtonGroup extends PureComponent {
return (
<RadioButton
testID={testID}
{...other}
name={name}
key={`${name}-${value}`}

View file

@ -0,0 +1,43 @@
// 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 Preferences from '@mm-redux/constants/preferences';
import RadioButtonGroup from './radio_button_group';
describe('RadioButtonGroup', () => {
const baseProps = {
onSelect: jest.fn(),
name: 'name',
};
test('should match snapshot', () => {
const options = [{
testID: 'radio-1',
label: 'label-1',
theme: Preferences.THEMES.default,
value: 'value',
checked: true,
disabled: false,
}, {
testID: 'radio-2',
label: 'label-2',
theme: Preferences.THEMES.default,
value: 'value',
checked: false,
disabled: true,
}];
const wrapper = shallowWithIntl(
<RadioButtonGroup
{...baseProps}
options={options}
/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
});

View file

@ -0,0 +1,94 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DrawerItem should match snapshot 1`] = `
<ForwardRef
onPress={[MockFunction]}
testID="test-id"
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"flexDirection": "row",
"height": 50,
}
}
>
<View
style={
Object {
"alignItems": "center",
"height": 50,
"justifyContent": "center",
"marginLeft": 5,
"width": 45,
}
}
>
<CompassIcon
name="icon-name"
style={
Array [
Object {
"color": "rgba(61,60,64,0.64)",
"fontSize": 24,
},
Object {
"color": "#fd5960",
},
]
}
/>
</View>
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
}
}
>
<FormattedText
defaultMessage="default message"
id="i18-id"
style={
Array [
Object {
"color": "rgba(61,60,64,0.5)",
"flex": 1,
"fontSize": 17,
"includeFontPadding": false,
"textAlignVertical": "center",
},
Object {
"color": "#fd5960",
},
Object {
"textAlign": "center",
"textAlignVertical": "center",
},
]
}
/>
</View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.2)",
"height": 1,
}
}
/>
</View>
</View>
</ForwardRef>
`;

View file

@ -0,0 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SettingsSidebar should match snapshot 1`] = `
<DrawerLayout
drawerPosition="right"
drawerWidth={710}
isTablet={false}
onDrawerClose={[Function]}
onDrawerOpen={[Function]}
renderNavigationView={[Function]}
useNativeAnimations={true}
/>
`;

View file

@ -11,6 +11,7 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
export default class DrawerItem extends PureComponent {
static propTypes = {
testID: PropTypes.string,
centered: PropTypes.bool,
defaultMessage: PropTypes.string,
i18nId: PropTypes.string,
@ -31,6 +32,7 @@ export default class DrawerItem extends PureComponent {
render() {
const {
testID,
centered,
defaultMessage,
i18nId,
@ -81,6 +83,7 @@ export default class DrawerItem extends PureComponent {
return (
<TouchableOpacity
testID={testID}
onPress={onPress}
>
<View style={style.container}>

View file

@ -0,0 +1,31 @@
// 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 Preferences from '@mm-redux/constants/preferences';
import DrawerItem from './drawer_item';
describe('DrawerItem', () => {
const baseProps = {
onPress: jest.fn(),
testID: 'test-id',
centered: true,
defaultMessage: 'default message',
i18nId: 'i18-id',
iconName: 'icon-name',
isDestructor: true,
separator: true,
theme: Preferences.THEMES.default,
};
test('should match snapshot', () => {
const wrapper = shallowWithIntl(
<DrawerItem {...baseProps}/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
});

View file

@ -0,0 +1,31 @@
// 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 Preferences from '@mm-redux/constants/preferences';
import SettingsSidebar from './settings_sidebar.ios';
describe('SettingsSidebar', () => {
const baseProps = {
actions: {
logout: jest.fn(),
setStatus: jest.fn(),
},
currentUser: {
id: 'user-id',
},
status: 'offline',
theme: Preferences.THEMES.default,
};
test('should match snapshot', () => {
const wrapper = shallowWithIntl(
<SettingsSidebar {...baseProps}/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
});

View file

@ -139,6 +139,7 @@ export default class SettingsSidebarBase extends PureComponent {
const options = {
topBar: {
leftButtons: [{
testID: 'close.settings.button',
id: 'close-settings',
icon: this.closeButton,
}],
@ -188,7 +189,10 @@ export default class SettingsSidebarBase extends PureComponent {
const {currentUser, theme} = this.props;
return (
<View style={style.container}>
<View
testID='settings.sidebar'
style={style.container}
>
<ScrollView
alwaysBounceVertical={false}
contentContainerStyle={style.wrapper}
@ -236,6 +240,7 @@ export default class SettingsSidebarBase extends PureComponent {
theme={theme}
/>
<DrawerItem
testID='settings.sidebar.settings.action'
defaultMessage='Settings'
i18nId='mobile.routes.settings'
iconName='settings-outline'
@ -247,13 +252,13 @@ export default class SettingsSidebarBase extends PureComponent {
<View style={style.separator}/>
<View style={style.block}>
<DrawerItem
testID='settings.sidebar.logout.action'
defaultMessage='Logout'
i18nId='sidebar_right_menu.logout'
iconName='exit-to-app'
isDestructor={true}
onPress={this.logout}
separator={false}
testID='sidebar.settings.logout'
theme={theme}
/>
</View>

View file

@ -184,7 +184,7 @@ export default class ChannelBase extends PureComponent {
leftButtons: [{
id: 'close-info',
icon: source,
testID: 'screen.channel_info.close',
testID: 'close.channel_info.button',
}],
},
};

View file

@ -18,7 +18,7 @@ exports[`ChannelNavBar should match, full snapshot 1`] = `
]
}
>
<Connect(ChannelDrawerButton)
<Connect(MainSidebarDrawerButton)
openSidebar={[MockFunction]}
visible={true}
/>
@ -57,7 +57,7 @@ exports[`ChannelNavBar should match, full snapshot 1`] = `
}
}
/>
<Connect(SettingDrawerButton)
<Connect(SettingsSidebarDrawerButton)
openSidebar={[MockFunction]}
/>
</View>

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SettingDrawerButton should match, full snapshot 1`] = `
exports[`SettingsSidebarDrawerButton should match, full snapshot 1`] = `
<ForwardRef
accessibilityHint="Opens the more options right hand sidebar"
accessibilityLabel="More Options"
@ -12,7 +12,7 @@ exports[`SettingDrawerButton should match, full snapshot 1`] = `
"width": 44,
}
}
testID="sidebar.settings.button"
testID="settings_sidebar_drawer.button"
>
<View
style={

View file

@ -12,10 +12,10 @@ import {DeviceTypes, ViewTypes} from 'app/constants';
import mattermostManaged from 'app/mattermost_managed';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
import ChannelDrawerButton from './channel_drawer_button';
import MainSidebarDrawerButton from './main_sidebar_drawer_button';
import ChannelSearchButton from './channel_search_button';
import ChannelTitle from './channel_title';
import SettingDrawerButton from './settings_drawer_button';
import SettingsSidebarDrawerButton from './settings_sidebar_drawer_button';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
const {
@ -112,7 +112,7 @@ export default class ChannelNavBar extends PureComponent {
return (
<View style={[style.header, padding(isLandscape), {height}]}>
<ChannelDrawerButton
<MainSidebarDrawerButton
openSidebar={openMainSidebar}
visible={this.drawerButtonVisible()}
/>
@ -123,7 +123,7 @@ export default class ChannelNavBar extends PureComponent {
<ChannelSearchButton
theme={theme}
/>
<SettingDrawerButton openSidebar={openSettingsSidebar}/>
<SettingsSidebarDrawerButton openSidebar={openSettingsSidebar}/>
</View>
);
}

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ChannelDrawerButton should match, full snapshot 1`] = `
exports[`MainSidebarDrawerButton should match, full snapshot 1`] = `
<ForwardRef
accessibilityHint="Opens the channels and teams drawer"
accessibilityLabel="Channels and teams"
@ -25,7 +25,7 @@ exports[`ChannelDrawerButton should match, full snapshot 1`] = `
},
]
}
testID="channel_drawer.button"
testID="main_sidebar_drawer.button"
>
<View>
<View
@ -40,7 +40,7 @@ exports[`ChannelDrawerButton should match, full snapshot 1`] = `
</ForwardRef>
`;
exports[`ChannelDrawerButton should match, full snapshot 2`] = `
exports[`MainSidebarDrawerButton should match, full snapshot 2`] = `
<ForwardRef
accessibilityHint="Opens the channels and teams drawer"
accessibilityLabel="Channels and teams"
@ -65,7 +65,7 @@ exports[`ChannelDrawerButton should match, full snapshot 2`] = `
},
]
}
testID="channel_drawer.button"
testID="main_sidebar_drawer.button"
>
<View>
<CompassIcon

View file

@ -6,7 +6,7 @@ import {connect} from 'react-redux';
import {getTheme} from '@mm-redux/selectors/entities/preferences';
import {getBadgeCount} from 'app/selectors/views';
import ChannelDrawerButton from './channel_drawer_button';
import MainSidebarDrawerButton from './main_sidebar_drawer_button';
function mapStateToProps(state) {
return {
@ -15,4 +15,4 @@ function mapStateToProps(state) {
};
}
export default connect(mapStateToProps)(ChannelDrawerButton);
export default connect(mapStateToProps)(MainSidebarDrawerButton);

View file

@ -19,7 +19,7 @@ import {t} from '@utils/i18n';
import telemetry from '@telemetry';
import {LARGE_BADGE_RIGHT_POSITION, SMALL_BADGE_RIGHT_POSITION, MAX_BADGE_RIGHT_POSITION} from '@constants/view';
export default class ChannelDrawerButton extends PureComponent {
export default class MainSidebarDrawerButton extends PureComponent {
static propTypes = {
openSidebar: PropTypes.func.isRequired,
badgeCount: PropTypes.number,
@ -133,7 +133,7 @@ export default class ChannelDrawerButton extends PureComponent {
>
<View
style={[style.wrapper]}
testID='channel_drawer.button'
testID='main_sidebar_drawer.button'
>
<View>
{icon}

View file

@ -10,7 +10,7 @@ import Badge from 'app/components/badge';
import PushNotification from 'app/push_notifications/push_notifications.ios';
import {shallowWithIntl} from 'test/intl-test-helper';
import ChannelDrawerButton from './channel_drawer_button';
import MainSidebarDrawerButton from './main_sidebar_drawer_button';
jest.mock('react-native-notifications', () => {
let badgesCount = 0;
@ -37,7 +37,7 @@ jest.mock('react-native-notifications', () => {
};
});
describe('ChannelDrawerButton', () => {
describe('MainSidebarDrawerButton', () => {
const baseProps = {
openSidebar: jest.fn(),
badgeCount: 0,
@ -49,7 +49,7 @@ describe('ChannelDrawerButton', () => {
test('should match, full snapshot', () => {
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...baseProps}/>,
<MainSidebarDrawerButton {...baseProps}/>,
);
// no badge to show
@ -70,7 +70,7 @@ describe('ChannelDrawerButton', () => {
};
shallowWithIntl(
<ChannelDrawerButton {...props}/>,
<MainSidebarDrawerButton {...props}/>,
);
expect(setApplicationIconBadgeNumber).not.toBeCalled();
NotificationsIOS.getBadgesCount((count) => expect(count).toBe(0));
@ -84,7 +84,7 @@ describe('ChannelDrawerButton', () => {
};
shallowWithIntl(
<ChannelDrawerButton {...props}/>,
<MainSidebarDrawerButton {...props}/>,
);
expect(setApplicationIconBadgeNumber).toHaveBeenCalledTimes(1);
NotificationsIOS.getBadgesCount((count) => expect(count).toBe(1));
@ -98,7 +98,7 @@ describe('ChannelDrawerButton', () => {
};
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...props}/>,
<MainSidebarDrawerButton {...props}/>,
);
NotificationsIOS.getBadgesCount((count) => expect(count).toBe(0));
@ -116,7 +116,7 @@ describe('ChannelDrawerButton', () => {
};
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...props}/>,
<MainSidebarDrawerButton {...props}/>,
);
wrapper.setProps({badgeCount: 2});
expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(2);
@ -129,21 +129,21 @@ describe('ChannelDrawerButton', () => {
test('Should be accessible', () => {
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...baseProps}/>,
<MainSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessible).toBeTruthy();
});
test('Should have the correct accessibilityHint', () => {
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...baseProps}/>,
<MainSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessibilityHint).toEqual('Opens the channels and teams drawer');
});
test('Should have the correct accessibilityLabel', () => {
const wrapper = shallowWithIntl(
<ChannelDrawerButton {...baseProps}/>,
<MainSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessibilityLabel).toEqual('Channels and teams');
});

View file

@ -17,7 +17,7 @@ import {preventDoubleTap} from '@utils/tap';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {t} from '@utils/i18n';
export class SettingDrawerButton extends PureComponent {
export class SettingsSidebarDrawerButton extends PureComponent {
static propTypes = {
openSidebar: PropTypes.func.isRequired,
theme: PropTypes.object,
@ -70,7 +70,7 @@ export class SettingDrawerButton extends PureComponent {
accessibilityHint={accessibilityHint}
accessibilityLabel={accessibilityLabel}
accessibilityRole='button'
testID='sidebar.settings.button'
testID='settings_sidebar_drawer.button'
onPress={this.handlePress}
style={style.container}
>
@ -107,4 +107,4 @@ function mapStateToProps(state) {
};
}
export default connect(mapStateToProps)(SettingDrawerButton);
export default connect(mapStateToProps)(SettingsSidebarDrawerButton);

View file

@ -4,11 +4,11 @@
import React from 'react';
import Preferences from '@mm-redux/constants/preferences';
import {SettingDrawerButton} from './settings_drawer_button';
import {SettingsSidebarDrawerButton} from './settings_sidebar_drawer_button';
import {shallowWithIntl} from 'test/intl-test-helper';
describe('SettingDrawerButton', () => {
describe('SettingsSidebarDrawerButton', () => {
const baseProps = {
openSidebar: jest.fn(),
theme: Preferences.THEMES.default,
@ -16,28 +16,28 @@ describe('SettingDrawerButton', () => {
test('should match, full snapshot', () => {
const wrapper = shallowWithIntl(
<SettingDrawerButton {...baseProps}/>,
<SettingsSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper).toMatchSnapshot();
});
test('Should be accessible', () => {
const wrapper = shallowWithIntl(
<SettingDrawerButton {...baseProps}/>,
<SettingsSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessible).toBeTruthy();
});
test('Should have the correct accessibilityHint', () => {
const wrapper = shallowWithIntl(
<SettingDrawerButton {...baseProps}/>,
<SettingsSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessibilityHint).toEqual('Opens the more options right hand sidebar');
});
test('Should have the correct accessibilityLabel', () => {
const wrapper = shallowWithIntl(
<SettingDrawerButton {...baseProps}/>,
<SettingsSidebarDrawerButton {...baseProps}/>,
);
expect(wrapper.props().accessibilityLabel).toEqual('More Options');
});

View file

@ -272,6 +272,7 @@ exports[`channelInfo should match snapshot 1`] = `
<React.Fragment>
<Connect(NotificationPreference)
isLandscape={false}
testID="channel_info.notification_preference.action"
theme={
Object {
"awayIndicator": "#ffbc42",
@ -465,6 +466,7 @@ exports[`channelInfo should match snapshot 1`] = `
/>
<Connect(EditChannel)
isLandscape={false}
testID="channel_info.edit_channel.action"
theme={
Object {
"awayIndicator": "#ffbc42",
@ -773,6 +775,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
<React.Fragment>
<Connect(NotificationPreference)
isLandscape={false}
testID="channel_info.notification_preference.action"
theme={
Object {
"awayIndicator": "#ffbc42",
@ -966,6 +969,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
/>
<Connect(EditChannel)
isLandscape={false}
testID="channel_info.edit_channel.action"
theme={
Object {
"awayIndicator": "#ffbc42",
@ -1325,6 +1329,7 @@ exports[`channelInfo should not include NotificationPreference for direct messag
/>
<Connect(EditChannel)
isLandscape={false}
testID="channel_info.edit_channel.action"
theme={
Object {
"awayIndicator": "#ffbc42",

View file

@ -0,0 +1,71 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ChannelInfoRow should match snapshot 1`] = `
<ForwardRef
onPress={[MockFunction]}
>
<View
style={
Array [
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"flexDirection": "row",
"paddingHorizontal": 15,
},
null,
]
}
testID="test-id"
>
<Image
source={1}
style={
Object {
"height": 15,
"tintColor": "#ffffff",
"width": 15,
}
}
/>
<FormattedText
defaultMessage="default-message"
id="text-id"
style={
Array [
Object {
"flex": 1,
"fontSize": 15,
"marginLeft": 15,
"paddingVertical": 15,
},
Object {
"color": "#000000",
},
]
}
/>
<Text
style={
Object {
"color": "rgba(61,60,64,0.5)",
"fontSize": 15,
"marginHorizontal": 7,
}
}
>
detail
</Text>
<CompassIcon
name="chevron-right"
size={24}
style={
Object {
"color": "rgba(61,60,64,0.32)",
"marginRight": -4,
}
}
/>
</View>
</ForwardRef>
`;

View file

@ -131,6 +131,7 @@ export default class ChannelInfo extends PureComponent {
{!isDirectMessage &&
<>
<NotificationPreference
testID='channel_info.notification_preference.action'
isLandscape={isLandscape}
theme={theme}
/>
@ -155,6 +156,7 @@ export default class ChannelInfo extends PureComponent {
theme={theme}
/>
<EditChannel
testID='channel_info.edit_channel.action'
isLandscape={isLandscape}
theme={theme}
/>

View file

@ -25,7 +25,7 @@ function createTouchableComponent(children, action) {
}
function channelInfoRow(props) {
const {action, defaultMessage, detail, icon, iconColor, image, imageTintColor, rightArrow, textColor, textId, togglable, theme, shouldRender, isLandscape} = props;
const {testID, action, defaultMessage, detail, icon, iconColor, image, imageTintColor, rightArrow, textColor, textId, togglable, theme, shouldRender, isLandscape} = props;
if (!shouldRender) {
return null;
@ -70,7 +70,10 @@ function channelInfoRow(props) {
}
const RowComponent = (
<View style={[style.container, padding(isLandscape)]}>
<View
testID={testID}
style={[style.container, padding(isLandscape)]}
>
{iconElement}
<FormattedText
style={[style.label, {color: textColor || theme.centerChannelColor}]}
@ -90,6 +93,7 @@ function channelInfoRow(props) {
}
channelInfoRow.propTypes = {
testID: PropTypes.string,
action: PropTypes.func.isRequired,
defaultMessage: PropTypes.string.isRequired,
detail: PropTypes.oneOfType([

View file

@ -0,0 +1,36 @@
// 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 Preferences from '@mm-redux/constants/preferences';
import ChannelInfoRow from './channel_info_row';
describe('ChannelInfoRow', () => {
const baseProps = {
action: jest.fn(),
testID: 'test-id',
defaultMessage: 'default-message',
detail: 'detail',
icon: 'icon',
iconColor: '#ababab',
image: 1,
imageTintColor: '#ffffff',
isLandscape: false,
rightArrow: true,
textId: 'text-id',
togglable: false,
textColor: '#000000',
theme: Preferences.THEMES.default,
};
test('should match snapshot', () => {
const wrapper = shallowWithIntl(
<ChannelInfoRow {...baseProps}/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
});

View file

@ -40,6 +40,7 @@ exports[`ChannelInfo -> EditChannel should match snapshot for Edit Channel 1`] =
isLandscape={false}
rightArrow={true}
shouldRender={true}
testID="test-id"
textId="mobile.channel_info.edit"
theme={
Object {

View file

@ -18,6 +18,7 @@ jest.mock('@utils/theme', () => {
describe('ChannelInfo -> EditChannel', () => {
const baseProps = {
testID: 'test-id',
canEdit: true,
isLandscape: false,
theme: Preferences.THEMES.default,

View file

@ -12,6 +12,7 @@ import {t} from '@utils/i18n';
import {preventDoubleTap} from '@utils/tap';
interface EditChannelProps {
testID?: string;
canEdit: boolean;
isLandscape: boolean;
theme: Theme;
@ -33,7 +34,7 @@ export default class EditChannel extends PureComponent<EditChannelProps> {
});
render() {
const {canEdit, isLandscape, theme} = this.props;
const {testID, canEdit, isLandscape, theme} = this.props;
if (!canEdit) {
return null;
@ -43,6 +44,7 @@ export default class EditChannel extends PureComponent<EditChannelProps> {
<>
<Separator theme={theme}/>
<ChannelInfoRow
testID={testID}
action={this.handleChannelEdit}
defaultMessage='Edit Channel'
icon='pencil-outline'

View file

@ -0,0 +1,45 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotificationPreference should match snapshot 1`] = `
<channelInfoRow
action={[Function]}
defaultMessage="Mobile Notifications"
detail="Default"
icon="cellphone"
isLandscape={false}
rightArrow={true}
shouldRender={true}
testID="test-id"
textId="channel_header.notificationPreference"
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
togglable={false}
/>
`;

View file

@ -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 Preferences from '@mm-redux/constants/preferences';
import NotificationPreference from './notification_preference';
describe('NotificationPreference', () => {
const baseProps = {
testID: 'test-id',
channelId: 'channel-id',
userId: 'user-id',
notifyProps: {
push: 'default',
},
isLandscape: false,
theme: Preferences.THEMES.default,
};
test('should match snapshot', () => {
const wrapper = shallowWithIntl(
<NotificationPreference {...baseProps}/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
});

View file

@ -13,6 +13,7 @@ import {t} from '@utils/i18n';
import {preventDoubleTap} from '@utils/tap';
interface NotificationPreferenceProps {
testID?: string;
channelId: string;
userId: string;
notifyProps: ChannelNotifyProps;
@ -65,7 +66,7 @@ export default class NotificationPreference extends PureComponent<NotificationPr
}
render() {
const {isLandscape, theme, notifyProps, userId, channelId} = this.props;
const {testID, isLandscape, theme, notifyProps, userId, channelId} = this.props;
const pushNotifyLevel = notifyProps.push || ViewTypes.NotificationLevels.DEFAULT;
if (!userId || !channelId) {
@ -74,6 +75,7 @@ export default class NotificationPreference extends PureComponent<NotificationPr
return (
<ChannelInfoRow
testID={testID}
action={this.goToChannelNotificationPreference}
defaultMessage='Mobile Notifications'
detail={this.notificationLevelToText(pushNotifyLevel)}

View file

@ -0,0 +1,284 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ChannelNotificationPreference should match snapshot 1`] = `
<Connect(SafeAreaIos)
excludeFooter={true}
excludeHeader={true}
>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.03)",
"flex": 1,
}
}
testID="channel_notification_preference.screen"
>
<Connect(StatusBar) />
<FormattedText
defaultMessage="Send Notifications"
id="channel_notifications.preference.header"
style={
Array [
Object {
"color": "rgba(61,60,64,0.56)",
"fontSize": 13,
"marginTop": 10,
"padding": 16,
"textTransform": "uppercase",
},
null,
]
}
/>
<ScrollView
alwaysBounceVertical={false}
contentContainerStyle={
Object {
"backgroundColor": "rgba(61,60,64,0.03)",
}
}
>
<View
style={
Object {
"backgroundColor": "rgba(255,255,255,1)",
}
}
>
<View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.1)",
"height": 1,
"marginLeft": 16,
"width": "100%",
}
}
/>
<sectionItem
action={[Function]}
actionType="select"
actionValue="default"
isLandscape={false}
label={
<FormattedText
defaultMessage="Global default ({notifyLevel})"
id="channel_notifications.preference.global_default"
values={
Object {
"notifyLevel": "Mentions",
}
}
/>
}
selected={true}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
</View>
<View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.1)",
"height": 1,
"marginLeft": 16,
"width": "100%",
}
}
/>
<sectionItem
action={[Function]}
actionType="select"
actionValue="all"
isLandscape={false}
label={
<FormattedText
defaultMessage="For all activity"
id="channel_notifications.preference.all_activity"
/>
}
selected={false}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
</View>
<View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.1)",
"height": 1,
"marginLeft": 16,
"width": "100%",
}
}
/>
<sectionItem
action={[Function]}
actionType="select"
actionValue="mention"
isLandscape={false}
label={
<FormattedText
defaultMessage="Only mentions and direct messages"
id="channel_notifications.preference.only_mentions"
/>
}
selected={false}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
</View>
<View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.1)",
"height": 1,
"marginLeft": 16,
"width": "100%",
}
}
/>
<sectionItem
action={[Function]}
actionType="select"
actionValue="none"
isLandscape={false}
label={
<FormattedText
defaultMessage="Never"
id="channel_notifications.preference.never"
/>
}
selected={false}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
</View>
<View
style={
Object {
"backgroundColor": "rgba(61,60,64,0.1)",
"height": 1,
"marginLeft": 16,
"width": "100%",
}
}
/>
</View>
</ScrollView>
</View>
</Connect(SafeAreaIos)>
`;

View file

@ -39,7 +39,10 @@ export default class ChannelNotificationPreferenceAndroid extends ChannelNotific
const options = this.getRadioItems();
return (
<View style={style.container}>
<View
testID='channel_notification_preference.screen'
style={style.container}
>
<StatusBar/>
<FormattedText
id='channel_notifications.preference.header'

View file

@ -26,7 +26,10 @@ export default class ChannelNotificationPreferenceIos extends ChannelNotificatio
excludeHeader={true}
excludeFooter={true}
>
<View style={style.container}>
<View
testID='channel_notification_preference.screen'
style={style.container}
>
<StatusBar/>
<FormattedText
id='channel_notifications.preference.header'

View file

@ -45,6 +45,15 @@ function checkNotificationSelected(pushNotificationLevel, trueIdx) {
}
describe('ChannelNotificationPreference', () => {
test('should match snapshot', () => {
const baseProps = makeProps('default');
const wrapper = shallowWithIntlMessages(
<ChannelNotificationPreference {...baseProps}/>,
);
expect(wrapper.getElement()).toMatchSnapshot();
});
test('should have correct setting selected', () => {
checkNotificationSelected(null, 0);
checkNotificationSelected(ViewTypes.NotificationLevels.DEFAULT, 0);

View file

@ -189,7 +189,10 @@ class Settings extends PureComponent {
}
return (
<View style={style.container}>
<View
testID='general_settings.screen'
style={style.container}
>
<StatusBar/>
<ScrollView
alwaysBounceVertical={false}
@ -197,6 +200,7 @@ class Settings extends PureComponent {
>
<View style={style.divider}/>
<SettingsItem
testID='general_settings.notifications.action'
defaultMessage='Notifications'
i18nId={t('user.settings.modal.notifications')}
iconName='bell-outline'

View file

@ -239,6 +239,7 @@ NotificationSettings {
"flex": 1,
}
}
testID="notification_settings.screen"
>
<Connect(StatusBar) />
<ScrollView
@ -310,6 +311,7 @@ NotificationSettings {
onPress={[Function]}
separator={true}
showArrow={true}
testID="notification_settings.mobile.action"
theme={
Object {
"awayIndicator": "#ffbc42",

View file

@ -197,7 +197,10 @@ export default class NotificationSettings extends PureComponent {
}
return (
<View style={style.container}>
<View
testID='notification_settings.screen'
style={style.container}
>
<StatusBar/>
<ScrollView
contentContainerStyle={style.wrapper}
@ -215,6 +218,7 @@ export default class NotificationSettings extends PureComponent {
isLandscape={isLandscape}
/>
<SettingsItem
testID='notification_settings.mobile.action'
defaultMessage='Mobile'
i18nId={t('mobile.notification_settings.mobile')}
iconName='cellphone'

View file

@ -110,6 +110,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
const {newPush} = this.state;
const options = [{
testID: 'notification_settings_mobile.all.action',
label: intl.formatMessage({
id: 'user.settings.notifications.allActivity',
defaultMessage: 'For all activity',
@ -117,6 +118,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
value: 'all',
checked: newPush === 'all',
}, {
testID: 'notification_settings_mobile.mentions.action',
label: intl.formatMessage({
id: 'user.settings.notifications.onlyMentions',
defaultMessage: 'Only for mentions and direct messages',
@ -124,6 +126,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
value: 'mention',
checked: newPush === 'mention',
}, {
testID: 'notification_settings_mobile.never.action',
label: intl.formatMessage({
id: 'user.settings.notifications.never',
defaultMessage: 'Never',
@ -139,7 +142,10 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
visible={this.state.showMobilePushModal}
onRequestClose={this.cancelMobilePushModal}
>
<View style={style.modalOverlay}>
<View
testID='notification_settings_mobile.push.modal'
style={style.modalOverlay}
>
<View style={style.modal}>
<View style={style.modalBody}>
<View style={style.modalTitleContainer}>
@ -168,6 +174,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
<View style={style.separator}/>
<View style={style.modalFooterContainer}>
<TouchableOpacity
testID='notification_settings_mobile.push_modal_cancel.button'
style={style.modalFooterOptionContainer}
onPress={this.cancelMobilePushModal}
>
@ -181,6 +188,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
<View>
<View style={{marginRight: 10}}/>
<TouchableOpacity
testID='notification_settings_mobile.push_modal_save.button'
style={style.modalFooterOptionContainer}
onPress={this.saveMobilePushModal}
>
@ -427,6 +435,7 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
return (
<SectionItem
testID='notification_settings_mobile.push.action'
{...props}
label={(
<FormattedText
@ -727,7 +736,10 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
const style = getStyleSheet(theme);
return (
<View style={style.container}>
<View
testID='notification_settings_mobile.screen'
style={style.container}
>
<StatusBar/>
<ScrollView
style={style.scrollView}

View file

@ -33,6 +33,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase {
{pushNotificationsEnabled &&
<View>
<SectionItem
testID='notification_settings_mobile.all.action'
label={(
<FormattedText
id='user.settings.notifications.allActivity'
@ -48,6 +49,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase {
/>
<View style={style.separator}/>
<SectionItem
testID='notification_settings_mobile.mentions.action'
label={(
<FormattedText
id='user.settings.notifications.onlyMentions'
@ -63,6 +65,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase {
/>
<View style={style.separator}/>
<SectionItem
testID='notification_settings_mobile.never.action'
label={(
<FormattedText
id='user.settings.notifications.never'
@ -161,7 +164,10 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase {
excludeHeader={true}
excludeFooter={true}
>
<View style={style.container}>
<View
testID='notification_settings_mobile.screen'
style={style.container}
>
<StatusBar/>
<ScrollView
style={style.scrollView}

View file

@ -22,6 +22,7 @@ const ActionTypes = {
function sectionItem(props) {
const {
testID,
action,
actionType,
actionValue,
@ -73,7 +74,10 @@ function sectionItem(props) {
}
const component = (
<View style={[style.container, padding(isLandscape)]}>
<View
testID={testID}
style={[style.container, padding(isLandscape)]}
>
<View style={description ? style.doubleContainer : style.singleContainer}>
{labelComponent}
{descriptionComponent}

View file

@ -14,6 +14,7 @@ import getStyleSheet from './style';
export default class SettingsItem extends PureComponent {
static propTypes = {
testID: PropTypes.string,
defaultMessage: PropTypes.string.isRequired,
messageValues: PropTypes.object,
i18nId: PropTypes.string,
@ -78,6 +79,7 @@ export default class SettingsItem extends PureComponent {
render() {
const {
testID,
iconName,
onPress,
rightComponent,
@ -126,6 +128,7 @@ export default class SettingsItem extends PureComponent {
return (
<TouchableOpacity
testID={testID}
onPress={onPress}
>
<View style={[style.container, paddingLeft(isLandscape)]}>

View file

@ -2,11 +2,13 @@
// See LICENSE.txt for license information.
import Autocomplete from './autocomplete';
import ChannelSidebar from './channel_sidebar';
import MainSidebar from './main_sidebar';
import PostOptions from './post_options';
import SettingsSidebar from './settings_sidebar';
export {
Autocomplete,
ChannelSidebar,
MainSidebar,
PostOptions,
SettingsSidebar,
};

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
class ChannelSidebar {
class MainSidebar {
testID = {
mainSidebar: 'main.sidebar',
channelItemDisplayName: 'channel_item.display_name',
@ -17,7 +17,9 @@ class ChannelSidebar {
addDirectChannel = element(by.id(this.testID.addDirectChannel));
toBeVisible = async () => {
await expect(element(by.id(this.testID.mainSidebar))).toBeVisible();
await expect(this.mainSidebar).toBeVisible();
return this.mainSidebar;
}
getChannelByDisplayName = (displayName) => {
@ -31,5 +33,5 @@ class ChannelSidebar {
}
}
const channelSidebar = new ChannelSidebar();
export default channelSidebar;
const mainSidebar = new MainSidebar();
export default mainSidebar;

View file

@ -7,10 +7,13 @@ class PostOptions {
openReactionPicker: 'open.reaction_picker',
}
postOptions = element(by.id(this.testID.postOptions));
openReactionPicker = element(by.id(this.testID.openReactionPicker));
toBeVisible = async () => {
await expect(element(by.id(this.testID.postOptions))).toBeVisible();
await expect(this.postOptions).toBeVisible();
return postOptions;
}
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
class SettingsSidebar {
testID = {
settingsSidebar: 'settings.sidebar',
settingsAction: 'settings.sidebar.settings.action',
logoutAction: 'settings.sidebar.logout.action',
}
settingsSidebar = element(by.id(this.testID.settingsSidebar));
settingsAction = element(by.id(this.testID.settingsAction));
logoutAction = element(by.id(this.testID.logoutAction));
toBeVisible = async () => {
await expect(this.settingsSidebar).toBeVisible();
return this.settingsSidebar;
}
}
const settingsSidebar = new SettingsSidebar();
export default settingsSidebar;

View file

@ -1,12 +1,13 @@
// 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';
class ChannelScreen {
testID = {
channelScreen: 'channel.screen',
channelDrawerButton: 'channel_drawer.button',
mainSidebarDrawerButton: 'main_sidebar_drawer.button',
channelIntro: 'channel_intro.beginning.text',
channelNavBarTitle: 'channel.nav_bar.title',
channelSearchButton: 'channel.search.button',
@ -14,11 +15,11 @@ class ChannelScreen {
disabledSendButton: 'disabled_send.button',
postInput: 'post.input',
sendButton: 'send.button',
sidebarSettingsButton: 'sidebar.settings.button',
settingsSidebarDrawerButton: 'settings_sidebar_drawer.button',
}
channelScreen = element(by.id(this.testID.channelScreen));
channelDrawerButton = element(by.id(this.testID.channelDrawerButton));
mainSidebarDrawerButton = element(by.id(this.testID.mainSidebarDrawerButton));
channelIntro = element(by.id(this.testID.channelIntro));
channelNavBarTitle = element(by.id(this.testID.channelNavBarTitle));
channelSearchButton = element(by.id(this.testID.channelSearchButton));
@ -26,7 +27,7 @@ class ChannelScreen {
disabledSendButton = element(by.id(this.testID.disabledSendButton));
postInput = element(by.id(this.testID.postInput));
sendButton = element(by.id(this.testID.sendButton));
sidebarSettingsButton = element(by.id(this.testID.sidebarSettingsButton));
settingsSidebarDrawerButton = element(by.id(this.testID.settingsSidebarDrawerButton));
toBeVisible = async () => {
await expect(this.channelScreen).toBeVisible();
@ -42,8 +43,8 @@ class ChannelScreen {
}
logout = async () => {
await this.sidebarSettingsButton.tap();
await element(by.text('Logout')).tap();
await this.settingsSidebarDrawerButton.tap();
await SettingsSidebar.logoutAction.tap();
await SelectServerScreen.toBeVisible();
}
}

View file

@ -2,34 +2,40 @@
// See LICENSE.txt for license information.
import {ChannelScreen} from '@support/ui/screen';
import {timeouts, wait} from '@support/utils';
class ChannelInfoScreen {
testID = {
channelInfoScreen: 'channel_info.screen',
channelInfoClose: 'screen.channel_info.close',
closeChannelInfoButton: 'close.channel_info.button',
channelIconGMMemberCount: 'channel_icon.gm_member_count',
notificationPreferenceAction: 'channel_info.notification_preference.action',
editChannelAction: 'channel_info.edit_channel.action',
}
channelInfoScreen = element(by.id(this.testID.channelInfoScreen));
channelInfoClose = element(by.id(this.testID.channelInfoClose));
closeChannelInfoButton = element(by.id(this.testID.closeChannelInfoButton));
channelIconGMMemberCount = element(by.id(this.testID.channelIconGMMemberCount));
notificationPreferenceAction = element(by.id(this.testID.notificationPreferenceAction));
editChannelAction = element(by.id(this.testID.editChannelAction));
toBeVisible = async () => {
const screen = await this.channelInfoScreen;
await expect(screen).toBeVisible();
await wait(timeouts.TWO_SEC);
await expect(this.channelInfoScreen).toBeVisible();
return screen;
return this.channelInfoScreen;
}
open = async () => {
// # Open channel info
// # Open channel info screen
await ChannelScreen.channelTitleButton.tap();
return this.toBeVisible();
}
close = async () => {
await this.channelInfoClose.tap();
await wait(timeouts.TWO_SEC);
await this.closeChannelInfoButton.tap();
await expect(this.channelInfoScreen).not.toBeVisible();
}
}

View file

@ -0,0 +1,42 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {ChannelInfoScreen} from '@support/ui/screen';
class ChannelNotificationPreferenceScreen {
testID = {
channelNotificationPreferenceScreen: 'channel_notification_preference.screen',
backButton: 'screen.back.button',
}
channelNotificationPreferenceScreen = element(by.id(this.testID.channelNotificationPreferenceScreen));
backButton = element(by.id(this.testID.backButton));
titleText = 'Mobile Notifications';
headerText = 'Send Notifications';
optionDefaultText = 'Global default';
optionAllText = 'For all activity';
optionMentionsText = 'Only mentions and direct messages';
optionNeverText = 'Never';
toBeVisible = async () => {
await expect(this.channelNotificationPreferenceScreen).toBeVisible();
return this.channelNotificationPreferenceScreen;
}
open = async () => {
// # Open channel notification preference screen
await ChannelInfoScreen.notificationPreferenceAction.tap();
return this.toBeVisible();
}
back = async () => {
await this.backButton.tap();
await expect(this.channelNotificationPreferenceScreen).not.toBeVisible();
}
}
const channelNotificationPreferenceScreen = new ChannelNotificationPreferenceScreen();
export default channelNotificationPreferenceScreen;

View file

@ -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 CreateChannelScreen {
testID = {
@ -27,9 +27,11 @@ class CreateChannelScreen {
}
open = async () => {
// # Open channel info then tap 'Edit Channel'
await ChannelScreen.channelTitleButton.tap();
await element(by.text('Edit Channel')).tap();
// # Open channel info screen
await ChannelInfoScreen.open();
// # Tap on Edit Channel
await ChannelInfoScreen.editChannelAction.tap();
return this.toBeVisible();
}

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import {ChannelScreen} from '@support/ui/component';
import {ChannelSidebar} from '@support/ui/screen';
import {MainSidebar} from '@support/ui/screen';
class DirectChannelsScreen {
testID = {
@ -24,8 +24,8 @@ class DirectChannelsScreen {
}
open = async () => {
await ChannelScreen.channelDrawerButton.tap();
await ChannelSidebar.addDirectChannel.tap();
await ChannelScreen.mainSidebarDrawerButton.tap();
await MainSidebar.addDirectChannel.tap();
return this.toBeVisible();
}

View file

@ -0,0 +1,37 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {SettingsSidebar} from '@support/ui/component';
class GeneralSettingsScreen {
testID = {
generalSettingsScreen: 'general_settings.screen',
closeSettingsButton: 'close.settings.button',
notificationsAction: 'general_settings.notifications.action',
}
generalSettingsScreen = element(by.id(this.testID.generalSettingsScreen));
closeSettingsButton = element(by.id(this.testID.closeSettingsButton));
notificationsAction = element(by.id(this.testID.notificationsAction));
toBeVisible = async () => {
await expect(this.generalSettingsScreen).toBeVisible();
return this.generalSettingsScreen;
}
open = async () => {
// # Open general settings screen
await SettingsSidebar.settingsAction.tap();
return this.toBeVisible();
}
close = async () => {
await this.closeSettingsButton.tap();
await expect(this.generalSettingsScreen).not.toBeVisible();
}
}
const generalSettingsScreen = new GeneralSettingsScreen();
export default generalSettingsScreen;

View file

@ -3,28 +3,36 @@
import AddReactionScreen from './add_reaction';
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 MoreChannelsScreen from './more_channels';
import NotificationScreen from './notification';
import NotificationSettingsMobileScreen from './notification_settings_mobile';
import NotificationSettingsScreen from './notification_settings';
import SearchScreen from './search';
import SelectServerScreen from './select_server';
export {
AddReactionScreen,
ChannelScreen,
ChannelInfoScreen,
ChannelNotificationPreferenceScreen,
ChannelScreen,
CreateChannelScreen,
DirectChannelsScreen,
EditChannelScreen,
EditPostScreen,
GeneralSettingsScreen,
LoginScreen,
MoreChannelsScreen,
NotificationScreen,
NotificationSettingsMobileScreen,
NotificationSettingsScreen,
SearchScreen,
SelectServerScreen,
};

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import {ChannelScreen} from '@support/ui/component';
import {ChannelSidebar} from '@support/ui/screen';
import {MainSidebar} from '@support/ui/screen';
class MoreChannelsScreen {
testID = {
@ -20,8 +20,8 @@ class MoreChannelsScreen {
}
open = async () => {
await ChannelScreen.channelDrawerButton.tap();
await ChannelSidebar.addChannel.tap();
await ChannelScreen.mainSidebarDrawerButton.tap();
await MainSidebar.addChannel.tap();
return this.toBeVisible();
}

View file

@ -0,0 +1,37 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {GeneralSettingsScreen} from '@support/ui/screen';
class NotificationSettingsScreen {
testID = {
notificationSettingsScreen: 'notification_settings.screen',
backButton: 'screen.back.button',
mobileAction: 'notification_settings.mobile.action',
}
notificationSettingsScreen = element(by.id(this.testID.notificationSettingsScreen));
backButton = element(by.id(this.testID.backButton));
mobileAction = element(by.id(this.testID.mobileAction));
toBeVisible = async () => {
await expect(this.notificationSettingsScreen).toBeVisible();
return this.notificationSettingsScreen;
}
open = async () => {
// # Open notification settings screen
await GeneralSettingsScreen.notificationAction.tap();
return this.toBeVisible();
}
back = async () => {
await this.backButton.tap();
await expect(this.notificationSettingsScreen).not.toBeVisible();
}
}
const notificationSettingsScreen = new NotificationSettingsScreen();
export default notificationSettingsScreen;

View file

@ -0,0 +1,66 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {NotificationSettingsScreen} from '@support/ui/screen';
class NotificationSettingsMobileScreen {
testID = {
notificationSettingsMobileScreen: 'notification_settings_mobile.screen',
backButton: 'screen.back.button',
allAction: 'notification_settings_mobile.all.action',
mentionsAction: 'notification_settings_mobile.mentions.action',
neverAction: 'notification_settings_mobile.never.action',
// ANDROID ONLY
pushAction: 'notification_settings_mobile.push.action',
pushModal: 'notification_settings_mobile.push.modal',
pushModalCancelButton: 'notification_settings_mobile.push_modal_cancel.button',
pushModalSaveButton: 'notification_settings_mobile.push_modal_save.button',
}
notificationSettingsMobileScreen = element(by.id(this.testID.notificationSettingsMobileScreen));
backButton = element(by.id(this.testID.backButton));
allAction = element(by.id(this.testID.allAction));
mentionsAction = element(by.id(this.testID.mentionsAction));
neverAction = element(by.id(this.testID.neverAction));
// ANDROID ONLY
pushAction = element(by.id(this.testID.pushAction));
pushModal = element(by.id(this.testID.pushModal));
pushModalCancelButton = element(by.id(this.testID.pushModalCancelButton));
pushModalSaveButton = element(by.id(this.testID.pushModalSaveButton));
toBeVisible = async () => {
await expect(this.notificationSettingsMobileScreen).toBeVisible();
return this.notificationSettingsMobileScreen;
}
open = async () => {
// # Open notification settings mobile screen
await NotificationSettingsScreen.mobileAction.tap();
return this.toBeVisible();
}
back = async () => {
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();
export default notificationSettingsMobileScreen;

View file

@ -7,10 +7,10 @@
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {ChannelSidebar} from '@support/ui/component';
import {MainSidebar} from '@support/ui/component';
import {
ChannelScreen,
ChannelInfoScreen,
ChannelScreen,
DirectChannelsScreen,
} from '@support/ui/screen';
import {timeouts, wait} from '@support/utils';
@ -27,18 +27,21 @@ describe('Channel Info Header', () => {
});
it('MM-T3406 should render correct GM member count in channel info header', async () => {
// # Open drawer
await ChannelScreen.channelDrawerButton.tap();
await expect(element(by.text('DIRECT MESSAGES'))).toBeVisible();
// # Open main sidebar
await ChannelScreen.mainSidebarDrawerButton.tap();
await MainSidebar.toBeVisible();
// # Open Direct Channels screen
await ChannelSidebar.addDirectChannel.tap();
await MainSidebar.addDirectChannel.tap();
await DirectChannelsScreen.toBeVisible();
// # Wait for some profiles to load
await wait(timeouts.ONE_SEC);
const {getUserAtIndex, startButton} = DirectChannelsScreen;
const {
getUserAtIndex,
startButton,
} = DirectChannelsScreen;
// # Select 3 profiles
await getUserAtIndex(0).tap();
@ -48,7 +51,7 @@ describe('Channel Info Header', () => {
// # Create a GM with selected profiles
await startButton.tap();
// # Open channel info modal
// # Open channel info screen
await ChannelInfoScreen.open();
// * Verify GM member count is 3

View file

@ -9,7 +9,7 @@
import jestExpect from 'expect';
import {ChannelSidebar} from '@support/ui/component';
import {MainSidebar} from '@support/ui/component';
import {
ChannelScreen,
ChannelInfoScreen,
@ -31,10 +31,10 @@ describe('Channels', () => {
it('MM-T3201 Create public channel', async () => {
// # Go to channel sidebar list
await ChannelScreen.channelDrawerButton.tap();
await ChannelScreen.mainSidebarDrawerButton.tap();
// # Tap on + public channels
await ChannelSidebar.addChannel.tap();
await MainSidebar.addChannel.tap();
// * Expect a list of public channels, initially empty
await MoreChannelsScreen.toBeVisible();
@ -77,7 +77,7 @@ describe('Channels', () => {
// * Expect a redirection to the created channel
await expect(ChannelScreen.channelIntro).toHaveText('Beginning of ' + expectedChannelName);
// # Open channel info
// # Open channel info screen
await ChannelInfoScreen.open();
// * Expect to see channel header and purpose in channel info

View file

@ -7,7 +7,7 @@
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {ChannelSidebar} from '@support/ui/component';
import {MainSidebar} from '@support/ui/component';
import {ChannelScreen} from '@support/ui/screen';
import {isAndroid} from '@support/utils';
import {Setup} from '@support/server_api';
@ -27,28 +27,28 @@ describe('Select channel', () => {
});
it('MM-T3412 should close the sidebar menu when selecting the same channel', async () => {
const {channelDrawerButton, channelNavBarTitle} = ChannelScreen;
const {mainSidebarDrawerButton, channelNavBarTitle} = ChannelScreen;
// # Open channel drawer (with at least one unread channel)
await channelDrawerButton.tap();
// # Open main sidebar (with at least one unread channel)
await mainSidebarDrawerButton.tap();
// * Main sidebar should be visible
await ChannelSidebar.toBeVisible();
await MainSidebar.toBeVisible();
// # Tap a channel to view it
const channelItem = ChannelSidebar.getChannelByDisplayName(newChannel.display_name);
const channelItem = MainSidebar.getChannelByDisplayName(newChannel.display_name);
await channelItem.tap();
// * Selected channel should be visible
await expect(channelNavBarTitle).toHaveText(newChannel.display_name);
// # Open channel drawer again and select the same channel
await channelDrawerButton.tap();
// # Open main sidebar again and select the same channel
await mainSidebarDrawerButton.tap();
await channelItem.tap();
// * Drawer should not be visible on Android
if (isAndroid()) {
await expect(ChannelSidebar.mainSidebar).not.toBeVisible();
await expect(MainSidebar.mainSidebar).not.toBeVisible();
}
// * Selected channel should remain the same

View file

@ -0,0 +1,135 @@
// 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 {
MainSidebar,
SettingsSidebar,
} from '@support/ui/component';
import {
ChannelInfoScreen,
ChannelNotificationPreferenceScreen,
ChannelScreen,
GeneralSettingsScreen,
NotificationSettingsMobileScreen,
NotificationSettingsScreen,
} from '@support/ui/screen';
import {Setup} from '@support/server_api';
import {isAndroid} from '@support/utils';
describe('Channel Notification Preference - Default', () => {
let testChannel;
beforeAll(async () => {
const {user, channel} = await Setup.apiInit();
testChannel = channel;
await ChannelScreen.open(user);
});
beforeEach(async () => {
// # Open main sidebar
await ChannelScreen.mainSidebarDrawerButton.tap();
await MainSidebar.toBeVisible();
// # Go to channel
await MainSidebar.getChannelByDisplayName(testChannel.display_name).tap();
});
afterAll(async () => {
await ChannelScreen.logout();
});
afterEach(async () => {
// # Close channel info screen
await ChannelInfoScreen.close();
});
it('MM-T3376_1 should be able to select Global Default option and display Default next to Mobile Notifications', async () => {
// # Set global notifications to mentions
await setGlobalNotificationsTo('mentions');
// # Open channel info screen
await ChannelInfoScreen.open();
// # Tap on Mobile Notifications
await ChannelInfoScreen.notificationPreferenceAction.tap();
// # Tap on For all activity option
await element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (Mentions)`)).tap();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
// * Verify notification level Default abbreviation
await ChannelInfoScreen.toBeVisible();
await expect(element(by.id(ChannelInfoScreen.testID.notificationPreferenceAction).withDescendant(by.text('Default')))).toBeVisible();
});
it('MM-T3376_2 should display correct Global default value on channel info mobile notifications options', async () => {
// # Set global notifications to never
await setGlobalNotificationsTo('never');
// * Verify Global default (Never) is displayed
await ChannelInfoScreen.open();
await ChannelInfoScreen.notificationPreferenceAction.tap();
await expect(element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (Never)`))).toBeVisible();
// # Go back to channel info screen
ChannelNotificationPreferenceScreen.back();
await ChannelInfoScreen.close();
// # Set global notifications to all
await setGlobalNotificationsTo('all');
// * Verify Global default (All) is displayed
await ChannelInfoScreen.open();
await ChannelInfoScreen.notificationPreferenceAction.tap();
await expect(element(by.text(`${ChannelNotificationPreferenceScreen.optionDefaultText} (All)`))).toBeVisible();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
});
});
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();
// # Tap on Send Notifications option if Android
if (isAndroid()) {
await NotificationSettingsMobileScreen.pushAction.tap();
await expect(NotificationSettingsMobileScreen.pushModal).toBeVisible();
}
// # Tap on push activity option
await NotificationSettingsMobileScreen.getPushActionFor(pushKey).tap();
// # Tap on Save button if Android
if (isAndroid()) {
await NotificationSettingsMobileScreen.pushModalSaveButton.tap();
}
// # Navigate back to channel screen
await NotificationSettingsMobileScreen.toBeVisible();
await NotificationSettingsMobileScreen.back();
await NotificationSettingsScreen.back();
await GeneralSettingsScreen.close();
}

View file

@ -0,0 +1,155 @@
// 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 {MainSidebar} from '@support/ui/component';
import {
ChannelInfoScreen,
ChannelNotificationPreferenceScreen,
ChannelScreen,
DirectChannelsScreen,
} from '@support/ui/screen';
import {Setup} from '@support/server_api';
import {isAndroid} from '@support/utils';
describe('Channel Notification Preference', () => {
let testChannel;
beforeAll(async () => {
const {user, channel} = await Setup.apiInit();
testChannel = channel;
await ChannelScreen.open(user);
});
beforeEach(async () => {
// # Open main sidebar
await ChannelScreen.mainSidebarDrawerButton.tap();
await MainSidebar.toBeVisible();
// # Go to channel
await MainSidebar.getChannelByDisplayName(testChannel.display_name).tap();
});
afterAll(async () => {
await ChannelScreen.logout();
});
afterEach(async () => {
// # Close channel info screen
await ChannelInfoScreen.close();
});
it('MM-T3375_1 should display Mobile Notifications option for non-DM Channels', async () => {
// # Open channel info screen
await ChannelInfoScreen.open();
// # Tap on Mobile Notifications
await ChannelInfoScreen.notificationPreferenceAction.tap();
const {
titleText,
headerText,
optionDefaultText,
optionAllText,
optionMentionsText,
optionNeverText,
} = ChannelNotificationPreferenceScreen;
// * Verify title, header, and options
await expect(element(by.text(titleText))).toBeVisible();
await expect(element(by.text(isAndroid() ? headerText : headerText.toUpperCase()))).toBeVisible();
await expect(element(by.text(`${optionDefaultText} (Mentions)`))).toBeVisible();
await expect(element(by.text(optionAllText))).toBeVisible();
await expect(element(by.text(optionMentionsText))).toBeVisible();
await expect(element(by.text(optionNeverText))).toBeVisible();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
});
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();
const {
getUserAtIndex,
startButton,
} = DirectChannelsScreen;
// # Select 1 profile
await getUserAtIndex(0).tap();
// # Create a DM with selected profile
await startButton.tap();
// # Open channel info screen
await ChannelInfoScreen.open();
// * Verify Mobile Notifications is not displayed
await expect(ChannelInfoScreen.notificationPreferenceAction).not.toBeVisible();
});
it('MM-T3377 should be able to select For all activity option and display All next to Mobile Notifications', async () => {
// # Open channel info screen
await ChannelInfoScreen.open();
// # Tap on Mobile Notifications
await ChannelInfoScreen.notificationPreferenceAction.tap();
// # Tap on For all activity option
await element(by.text(ChannelNotificationPreferenceScreen.optionAllText)).tap();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
// * Verify notification level All abbreviation
await ChannelInfoScreen.toBeVisible();
await expect(element(by.id(ChannelInfoScreen.testID.notificationPreferenceAction).withDescendant(by.text('All')))).toBeVisible();
});
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
await ChannelInfoScreen.open();
// # Tap on Mobile Notifications
await ChannelInfoScreen.notificationPreferenceAction.tap();
// # Tap on For all activity option
await element(by.text(ChannelNotificationPreferenceScreen.optionMentionsText)).tap();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
// * Verify notification level Mentions abbreviation
await ChannelInfoScreen.toBeVisible();
await expect(element(by.id(ChannelInfoScreen.testID.notificationPreferenceAction).withDescendant(by.text('Mentions')))).toBeVisible();
});
it('MM-T3379 should be able to select Never option and display Never next to Mobile Notifications', async () => {
// # Open channel info screen
await ChannelInfoScreen.open();
// # Tap on Mobile Notifications
await ChannelInfoScreen.notificationPreferenceAction.tap();
// # Tap on For all activity option
await element(by.text(ChannelNotificationPreferenceScreen.optionNeverText)).tap();
// # Tap on back button
ChannelNotificationPreferenceScreen.back();
// * Verify notification level Never abbreviation
await ChannelInfoScreen.toBeVisible();
await expect(element(by.id(ChannelInfoScreen.testID.notificationPreferenceAction).withDescendant(by.text('Never')))).toBeVisible();
});
});

View file

@ -8,7 +8,7 @@
// *******************************************************************
import {ChannelScreen} from '@support/ui/screen';
import {ChannelSidebar} from '@support/ui/component';
import {MainSidebar} from '@support/ui/component';
import {Setup, Channel} from '@support/server_api';
describe('Unread channels', () => {
@ -34,38 +34,38 @@ describe('Unread channels', () => {
});
it('MM-T3187 Unread channels sort at top', async () => {
const {channelDrawerButton} = ChannelScreen;
const {mainSidebarDrawerButton} = ChannelScreen;
// # Open channel drawer (with at least one unread channel)
await channelDrawerButton.tap();
// # Open main sidebar (with at least one unread channel)
await mainSidebarDrawerButton.tap();
// * Channel should be visible
await ChannelSidebar.toBeVisible();
await MainSidebar.toBeVisible();
// * 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();
await ChannelSidebar.hasChannelAtIndex(0, aChannel.display_name);
await ChannelSidebar.hasChannelAtIndex(1, newChannel.display_name);
await ChannelSidebar.hasChannelAtIndex(2, zChannel.display_name);
await MainSidebar.hasChannelAtIndex(0, aChannel.display_name);
await MainSidebar.hasChannelAtIndex(1, newChannel.display_name);
await MainSidebar.hasChannelAtIndex(2, zChannel.display_name);
// # Tap an unread channel to view it
await ChannelSidebar.getChannelByDisplayName(aChannel.display_name).tap();
await channelDrawerButton.tap();
await ChannelSidebar.getChannelByDisplayName(newChannel.display_name).tap();
await channelDrawerButton.tap();
await ChannelSidebar.getChannelByDisplayName(zChannel.display_name).tap();
await MainSidebar.getChannelByDisplayName(aChannel.display_name).tap();
await mainSidebarDrawerButton.tap();
await MainSidebar.getChannelByDisplayName(newChannel.display_name).tap();
await mainSidebarDrawerButton.tap();
await MainSidebar.getChannelByDisplayName(zChannel.display_name).tap();
// # Open channel drawer again
await channelDrawerButton.tap();
// # Open main sidebar again
await mainSidebarDrawerButton.tap();
// * Channel you just read is no longer listed in Unreads
await expect(element(by.text('UNREADS'))).not.toBeVisible();
await expect(element(by.text('PUBLIC CHANNELS'))).toBeVisible();
await ChannelSidebar.hasChannelAtIndex(0, aChannel.display_name);
await ChannelSidebar.hasChannelAtIndex(1, newChannel.display_name);
await ChannelSidebar.hasChannelAtIndex(2, 'Off-Topic');
await ChannelSidebar.hasChannelAtIndex(3, 'Town Square');
await ChannelSidebar.hasChannelAtIndex(4, zChannel.display_name);
await ChannelSidebar.getChannelByDisplayName(aChannel.display_name).tap();
await MainSidebar.hasChannelAtIndex(0, aChannel.display_name);
await MainSidebar.hasChannelAtIndex(1, newChannel.display_name);
await MainSidebar.hasChannelAtIndex(2, 'Off-Topic');
await MainSidebar.hasChannelAtIndex(3, 'Town Square');
await MainSidebar.hasChannelAtIndex(4, zChannel.display_name);
await MainSidebar.getChannelByDisplayName(aChannel.display_name).tap();
});
});