MM-30431 Detox/E2E: Added e2e for MM-T3196, MM-T3210, MM-T3211, MM-T3262, MM-T3264 (#5313)

* MM-30431 Detox/E2E: Added e2e for MM-T3196, MM-T3210, MM-T3211, MM-T3262, MM-T3264

* Fix snap test
This commit is contained in:
Joseph Baylon 2021-04-13 09:28:39 -07:00 committed by GitHub
parent 26f6880c04
commit 09593f7184
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 512 additions and 51 deletions

View file

@ -22,7 +22,7 @@ export default class ChannelItem extends PureComponent {
channelId: PropTypes.string.isRequired,
channel: PropTypes.object,
currentChannelId: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
displayName: PropTypes.string,
isArchived: PropTypes.bool,
isChannelMuted: PropTypes.bool,
isManualUnread: PropTypes.bool,

View file

@ -86,6 +86,7 @@ export default class About extends PureComponent {
id='about.teamEditiont0'
defaultMessage='Team Edition'
style={style.title}
testID='about.title'
/>
);
@ -94,6 +95,7 @@ export default class About extends PureComponent {
id='about.teamEditionSt'
defaultMessage='All your team communication in one place, instantly searchable and accessible anywhere.'
style={style.subtitle}
testID='about.subtitle'
/>
);
@ -103,11 +105,15 @@ export default class About extends PureComponent {
id='about.teamEditionLearn'
defaultMessage='Join the Mattermost community at '
style={style.learn}
testID='about.learn_more'
/>
<TouchableOpacity
onPress={this.handleAboutTeam}
>
<Text style={style.learnLink}>
<Text
style={style.learnLink}
testID='about.learn_more.url'
>
{Config.TeamEditionLearnURL}
</Text>
</TouchableOpacity>
@ -121,6 +127,7 @@ export default class About extends PureComponent {
id='about.teamEditiont1'
defaultMessage='Enterprise Edition'
style={style.title}
testID='about.title'
/>
);
@ -129,6 +136,7 @@ export default class About extends PureComponent {
id='about.enterpriseEditionSt'
defaultMessage='Modern communication from behind your firewall.'
style={style.subtitle}
testID='about.subtitle'
/>
);
@ -138,11 +146,15 @@ export default class About extends PureComponent {
id='about.enterpriseEditionLearn'
defaultMessage='Learn more about Enterprise Edition at '
style={style.learn}
testID='about.learn_more'
/>
<TouchableOpacity
onPress={this.handleAboutEnterprise}
>
<Text style={style.learnLink}>
<Text
style={style.learnLink}
testID='about.learn_more.url'
>
{Config.EELearnURL}
</Text>
</TouchableOpacity>
@ -155,6 +167,7 @@ export default class About extends PureComponent {
id='about.enterpriseEditione1'
defaultMessage='Enterprise Edition'
style={style.title}
testID='about.title'
/>
);
@ -167,6 +180,7 @@ export default class About extends PureComponent {
values={{
company: license.Company,
}}
testID='about.licensee'
/>
</View>
);
@ -183,6 +197,7 @@ export default class About extends PureComponent {
values={{
version: config.Version,
}}
testID='about.server_version'
/>
);
} else {
@ -195,6 +210,7 @@ export default class About extends PureComponent {
version: config.Version,
number: config.BuildNumber,
}}
testID='about.server_version'
/>
);
}
@ -207,6 +223,7 @@ export default class About extends PureComponent {
defaultMessage='Terms of Service'
style={style.noticeLink}
onPress={this.handleTermsOfService}
testID='about.terms_of_service'
/>
);
}
@ -219,6 +236,7 @@ export default class About extends PureComponent {
defaultMessage='Privacy Policy'
style={style.noticeLink}
onPress={this.handlePrivacyPolicy}
testID='about.privacy_policy'
/>
);
}
@ -236,22 +254,28 @@ export default class About extends PureComponent {
<SafeAreaView
edges={['left', 'right']}
style={style.container}
testID='about.screen'
>
<StatusBar/>
<ScrollView
style={style.scrollView}
contentContainerStyle={style.scrollViewContent}
testID='about.scroll_view'
>
<View style={style.logoContainer}>
<CompassIcon
name='mattermost'
color={theme.centerChannelColor}
size={120}
testID='about.logo'
/>
</View>
<View style={style.infoContainer}>
<View style={style.titleContainer}>
<Text style={style.title}>
<Text
style={style.title}
testID='about.site_name'
>
{`${config.SiteName} `}
</Text>
{title}
@ -265,6 +289,7 @@ export default class About extends PureComponent {
version: DeviceInfo.getVersion(),
number: DeviceInfo.getBuildNumber(),
}}
testID='about.app_version'
/>
{serverVersion}
<FormattedText
@ -274,6 +299,7 @@ export default class About extends PureComponent {
values={{
type: config.SQLDriverName,
}}
testID='about.database'
/>
{licensee}
{learnMore}
@ -285,6 +311,7 @@ export default class About extends PureComponent {
values={{
site: this.props.config.SiteName,
}}
testID='about.powered_by'
/>
}
<FormattedText
@ -294,6 +321,7 @@ export default class About extends PureComponent {
values={{
currentYear: new Date().getFullYear(),
}}
testID='about.copyright'
/>
<View style={style.tosPrivacyContainer}>
{termsOfService}
@ -324,6 +352,7 @@ export default class About extends PureComponent {
/>
),
}}
testID='about.notice_text'
/>
</View>
</View>
@ -333,8 +362,12 @@ export default class About extends PureComponent {
id='about.hash'
defaultMessage='Build Hash:'
style={style.footerTitleText}
testID='about.build_hash.title'
/>
<Text style={style.footerText}>
<Text
style={style.footerText}
testID='about.build_hash.value'
>
{config.BuildHash}
</Text>
</View>
@ -343,8 +376,12 @@ export default class About extends PureComponent {
id='about.hashee'
defaultMessage='EE Build Hash:'
style={style.footerTitleText}
testID='about.build_hash_enterprise.title'
/>
<Text style={style.footerText}>
<Text
style={style.footerText}
testID='about.build_hash_enterprise.value'
>
{config.BuildHashEnterprise}
</Text>
</View>
@ -354,8 +391,12 @@ export default class About extends PureComponent {
id='about.date'
defaultMessage='Build Date:'
style={style.footerTitleText}
testID='about.build_date.title'
/>
<Text style={style.footerText}>
<Text
style={style.footerText}
testID='about.build_date.value'
>
{config.BuildDate}
</Text>
</View>

View file

@ -145,11 +145,13 @@ class AdvancedSettings extends Component {
<SafeAreaView
edges={['left', 'right']}
style={style.container}
testID='advanced_settings.screen'
>
<StatusBar/>
<ScrollView
contentContainerStyle={style.wrapper}
alwaysBounceVertical={false}
testID='advanced_settings.scroll_view'
>
<View style={style.divider}/>
<SettingsItem
@ -162,6 +164,7 @@ class AdvancedSettings extends Component {
showArrow={false}
rightComponent={this.renderCacheFileSize()}
theme={theme}
testID='advanced_settings.delete_documents_and_data.action'
/>
<View style={style.divider}/>
{this.renderSentryDebugOptions()}

View file

@ -7,6 +7,7 @@ exports[`user_profile should match snapshot 1`] = `
"flex": 1,
}
}
testID="user_profile.screen"
>
<Connect(StatusBar) />
<ScrollView
@ -21,6 +22,7 @@ exports[`user_profile should match snapshot 1`] = `
"flex": 1,
}
}
testID="user_profile.scroll_view"
>
<View
style={
@ -69,7 +71,9 @@ exports[`user_profile should match snapshot 1`] = `
}
}
>
<View>
<View
testID="user_profile.display_block"
>
<Text
style={
Object {
@ -81,6 +85,7 @@ exports[`user_profile should match snapshot 1`] = `
"textTransform": "uppercase",
}
}
testID="user_profile.display_block.nickname.label"
/>
<Text
style={
@ -89,6 +94,7 @@ exports[`user_profile should match snapshot 1`] = `
"fontSize": 15,
}
}
testID="user_profile.display_block.nickname.value"
>
nick
</Text>
@ -110,6 +116,7 @@ exports[`user_profile should match snapshot 1`] = `
icon="send"
iconColor="rgba(0, 0, 0, 0.7)"
iconSize={24}
testID="user_profile.send_message.action"
textColor="#000"
textId="mobile.routes.user_profile.send_message"
theme={

View file

@ -160,9 +160,19 @@ export default class UserProfile extends PureComponent {
}
return (
<View>
<Text style={style.header}>{label}</Text>
<Text style={style.text}>{user[property]}</Text>
<View testID='user_profile.display_block'>
<Text
style={style.header}
testID={`user_profile.display_block.${property}.label`}
>
{label}
</Text>
<Text
style={style.text}
testID={`user_profile.display_block.${property}.value`}
>
{user[property]}
</Text>
</View>
);
}
@ -186,12 +196,14 @@ export default class UserProfile extends PureComponent {
id='mobile.routes.user_profile.local_time'
defaultMessage='LOCAL TIME'
style={style.header}
testID='user_profile.timezone_block.local_time.label'
/>
<Text style={style.text}>
<FormattedTime
timeZone={currentTimezone}
hour12={!militaryTime}
value={nowDate}
testID='user_profile.timezone_block.local_time.value'
/>
</Text>
</View>
@ -287,6 +299,7 @@ export default class UserProfile extends PureComponent {
icon={l.icon}
theme={this.props.theme}
iconSize={l.iconSize}
testID='user_profile.additional_options.action'
/>
);
});
@ -331,11 +344,15 @@ export default class UserProfile extends PureComponent {
}
return (
<SafeAreaView style={style.container}>
<SafeAreaView
style={style.container}
testID='user_profile.screen'
>
<StatusBar/>
<ScrollView
style={style.scrollView}
contentContainerStyle={style.contentContainer}
testID='user_profile.scroll_view'
>
<View style={style.top}>
<ProfilePicture
@ -359,6 +376,7 @@ export default class UserProfile extends PureComponent {
iconSize={24}
textId={t('mobile.routes.user_profile.send_message')}
theme={theme}
testID='user_profile.send_message.action'
/>
{this.renderAdditionalOptions()}
</ScrollView>

View file

@ -57,7 +57,7 @@ function createTouchableComponent(children, action) {
}
function userProfileRow(props) {
const {action, defaultMessage, detail, icon, textId, togglable, theme, iconSize, shouldRender = true} = props;
const {action, defaultMessage, detail, icon, textId, togglable, theme, iconSize, shouldRender = true, testID} = props;
if (!shouldRender) {
return null;
@ -74,7 +74,10 @@ function userProfileRow(props) {
);
const RowComponent = (
<View style={style.wrapper}>
<View
style={style.wrapper}
testID={testID}
>
<View style={style.container}>
{iconComponent}
<FormattedText

View file

@ -6,6 +6,7 @@ import {isAndroid} from '@support/utils';
class Alert {
// alert titles
archivePublicChannelTitle = isAndroid() ? element(by.text('Archive Public Channel')) : element(by.label('Archive Public Channel')).atIndex(0);
deleteDocumentsAndDataTitle = isAndroid() ? element(by.text('Delete Documents & Data')) : element(by.label('Delete Documents & Data')).atIndex(0);
deletePostTitle = isAndroid() ? element(by.text('Delete Post')) : element(by.label('Delete Post')).atIndex(0);
joinPrivateChannelTitle = isAndroid() ? element(by.text('Join private channel')) : element(by.label('Join private channel')).atIndex(0);
removeMembersTitle = isAndroid() ? element(by.text('Remove Members')) : element(by.label('Remove Members')).atIndex(0);

View file

@ -0,0 +1,79 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {GeneralSettingsScreen} from '@support/ui/screen';
class AboutScreen {
testID = {
aboutScreen: 'about.screen',
aboutScrollView: 'about.scroll_view',
backButton: 'screen.back.button',
aboutAppVersion: 'about.app_version',
aboutBuildDateTitle: 'about.build_date.title',
aboutBuildDateValue: 'about.build_date.value',
aboutBuildHashEnterpriseTitle: 'about.build_hash_enterprise.title',
aboutBuildHashEnterpriseValue: 'about.build_hash_enterprise.value',
aboutBuildHashTitle: 'about.build_hash.title',
aboutBuildHashValue: 'about.build_hash.value',
aboutCopyRight: 'about.copyright',
aboutDatabase: 'about.database',
aboutNoticeText: 'about.notice_text',
aboutLearnMore: 'about.learn_more',
aboutLearnMoreUrl: 'about.learn_more.url',
aboutLicensee: 'about.licensee',
aboutLogo: 'about.logo',
aboutPoweredBy: 'about.powered_by',
aboutPrivacyPolicy: 'about.privacy_policy',
aboutServerVersion: 'about.server_version',
aboutSiteName: 'about.site_name',
aboutSubtitle: 'about.subtitle',
aboutTermsOfService: 'about.terms_of_service',
aboutTitle: 'about.title',
}
aboutScreen = element(by.id(this.testID.aboutScreen));
aboutScrollView = element(by.id(this.testID.aboutScrollView));
backButton = element(by.id(this.testID.backButton));
aboutAppVersion = element(by.id(this.testID.aboutAppVersion));
aboutBuildDateTitle = element(by.id(this.testID.aboutBuildDateTitle));
aboutBuildDateValue = element(by.id(this.testID.aboutBuildDateValue));
aboutBuildHashEnterpriseTitle = element(by.id(this.testID.aboutBuildHashEnterpriseTitle));
aboutBuildHashEnterpriseValue = element(by.id(this.testID.aboutBuildHashEnterpriseValue));
aboutBuildHashTitle = element(by.id(this.testID.aboutBuildHashTitle));
aboutBuildHashValue = element(by.id(this.testID.aboutBuildHashValue));
aboutCopyRight = element(by.id(this.testID.aboutCopyRight));
aboutDatabase = element(by.id(this.testID.aboutDatabase));
aboutNoticeText = element(by.id(this.testID.aboutNoticeText));
aboutLearnMore = element(by.id(this.testID.aboutLearnMore));
aboutLearnMoreUrl = element(by.id(this.testID.aboutLearnMoreUrl));
aboutLicensee = element(by.id(this.testID.aboutLicensee));
aboutLogo = element(by.id(this.testID.aboutLogo));
aboutPoweredBy = element(by.id(this.testID.aboutPoweredBy));
aboutPrivacyPolicy = element(by.id(this.testID.aboutPrivacyPolicy));
aboutServerVersion = element(by.id(this.testID.aboutServerVersion));
aboutSiteName = element(by.id(this.testID.aboutSiteName));
aboutSubtitle = element(by.id(this.testID.aboutSubtitle));
aboutTermsOfService = element(by.id(this.testID.aboutTermsOfService));
aboutTitle = element(by.id(this.testID.aboutTitle));
toBeVisible = async () => {
await expect(this.aboutScreen).toBeVisible();
return this.aboutScreen;
}
open = async () => {
// # Open about screen
await GeneralSettingsScreen.aboutAction.tap();
return this.toBeVisible();
}
back = async () => {
await this.backButton.tap();
await expect(this.aboutScreen).not.toBeVisible();
}
}
const aboutScreen = new AboutScreen();
export default aboutScreen;

View file

@ -0,0 +1,62 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Alert} from '@support/ui/component';
import {GeneralSettingsScreen} from '@support/ui/screen';
import {timeouts, wait} from '@support/utils';
class AdvancedSettingsScreen {
testID = {
advancedSettingsScreen: 'advanced_settings.screen',
advancedSettingsScrollView: 'advanced_settings.scroll_view',
backButton: 'screen.back.button',
deleteDocumentsAndDataAction: 'advanced_settings.delete_documents_and_data.action',
}
advancedSettingsScreen = element(by.id(this.testID.advancedSettingsScreen));
advancedSettingsScrollView = element(by.id(this.testID.advancedSettingsScrollView));
backButton = element(by.id(this.testID.backButton));
deleteDocumentsAndDataAction = element(by.id(this.testID.deleteDocumentsAndDataAction));
toBeVisible = async () => {
await expect(this.advancedSettingsScreen).toBeVisible();
return this.advancedSettingsScreen;
}
open = async () => {
// # Open advanced settings screen
await GeneralSettingsScreen.advancedAction.tap();
return this.toBeVisible();
}
back = async () => {
await this.backButton.tap();
await expect(this.advancedSettingsScreen).not.toBeVisible();
}
deleteDocumentsAndData = async ({confirm = true} = {}) => {
await this.deleteDocumentsAndDataAction.tap();
const {
deleteDocumentsAndDataTitle,
cancelButton,
deleteButton,
} = Alert;
await expect(deleteDocumentsAndDataTitle).toBeVisible();
await expect(cancelButton).toBeVisible();
await expect(deleteButton).toBeVisible();
if (confirm) {
deleteButton.tap();
await wait(timeouts.ONE_SEC);
await expect(this.advancedSettingsScreen).not.toBeVisible();
} else {
cancelButton.tap();
await wait(timeouts.ONE_SEC);
await expect(this.advancedSettingsScreen).toBeVisible();
}
}
}
const advancedSettingsScreen = new AdvancedSettingsScreen();
export default advancedSettingsScreen;

View file

@ -2,11 +2,9 @@
// See LICENSE.txt for license information.
import {
Alert,
MainSidebar,
SearchBar,
} from '@support/ui/component';
import {timeouts, wait} from '@support/utils';
class ChannelAddMembersScreen {
testID = {
@ -72,31 +70,6 @@ class ChannelAddMembersScreen {
await expect(this.channelAddMembersScreen).not.toBeVisible();
}
removeMembers = async (displayUsernameList, {confirm = true} = {}) => {
displayUsernameList.forEach(async (displayUsername) => {
await this.getUserByDisplayUsername(`@${displayUsername}`).tap();
});
await wait(timeouts.ONE_SEC);
await this.removeButton.tap();
const {
removeMembersTitle,
noButton,
yesButton,
} = Alert;
await expect(removeMembersTitle).toBeVisible();
await expect(noButton).toBeVisible();
await expect(yesButton).toBeVisible();
if (confirm) {
yesButton.tap();
await wait(timeouts.ONE_SEC);
await expect(this.channelAddMembersScreen).not.toBeVisible();
} else {
noButton.tap();
await wait(timeouts.ONE_SEC);
await expect(this.channelAddMembersScreen).toBeVisible();
}
}
hasUserDisplayUsernameAtIndex = async (index, displayUsername) => {
await expect(
this.getDisplayUsernameAtIndex(index),

View file

@ -1,6 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import AboutScreen from './about';
import AdvancedSettingsScreen from './advanced_settings';
import AddReactionScreen from './add_reaction';
import ChannelInfoScreen from './channel_info';
import ChannelAddMembersScreen from './channel_add_members';
@ -30,8 +32,11 @@ import SearchScreen from './search';
import SelectServerScreen from './select_server';
import SelectTeamScreen from './select_team';
import ThreadScreen from './thread';
import UserProfileScreen from './user_profile';
export {
AboutScreen,
AdvancedSettingsScreen,
AddReactionScreen,
ChannelInfoScreen,
ChannelAddMembersScreen,
@ -61,4 +66,5 @@ export {
SelectServerScreen,
SelectTeamScreen,
ThreadScreen,
UserProfileScreen,
};

View file

@ -0,0 +1,49 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
class UserProfileScreen {
testID = {
userProfileScreen: 'user_profile.screen',
userProfileScrollView: 'user_profile.scroll_view',
emailLabel: 'user_profile.display_block.email.label',
emailValue: 'user_profile.display_block.email.value',
firstNameLabel: 'user_profile.display_block.first_name.label',
firstNameValue: 'user_profile.display_block.first_name.value',
lastNameLabel: 'user_profile.display_block.last_name.label',
lastNameValue: 'user_profile.display_block.last_name.value',
nicknameLabel: 'user_profile.display_block.nickname.label',
nicknameValue: 'user_profile.display_block.nickname.value',
positionLabel: 'user_profile.display_block.position.label',
positionValue: 'user_profile.display_block.position.value',
localTimeLabel: 'user_profile.timezone_block.local_time.label',
localTimeValue: 'user_profile.timezone_block.local_time.value',
additionalOptionsAction: 'user_profile.additional_options.action',
sendMessageAction: 'user_profile.send_message.action',
}
userProfileScreen = element(by.id(this.testID.userProfileScreen));
userProfileScrollView = element(by.id(this.testID.userProfileScrollView));
emailLabel = element(by.id(this.testID.emailLabel));
emailValue = element(by.id(this.testID.emailValue));
firstNameLabel = element(by.id(this.testID.firstNameLabel));
firstNameValue = element(by.id(this.testID.firstNameValue));
lastNameLabel = element(by.id(this.testID.lastNameLabel));
lastNameValue = element(by.id(this.testID.lastNameValue));
nicknameLabel = element(by.id(this.testID.nicknameLabel));
nicknameValue = element(by.id(this.testID.nicknameValue));
positionLabel = element(by.id(this.testID.positionLabel));
positionValue = element(by.id(this.testID.positionValue));
localTimeLabel = element(by.id(this.testID.localTimeLabel));
localTimeValue = element(by.id(this.testID.localTimeValue));
additionalOptionsAction = element(by.id(this.testID.additionalOptionsAction));
sendMessageAction = element(by.id(this.testID.sendMessageAction));
toBeVisible = async () => {
await expect(this.userProfileScreen).toBeVisible();
return this.userProfileScreen;
}
}
const userProfileScreen = new UserProfileScreen();
export default userProfileScreen;

View file

@ -0,0 +1,73 @@
// 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 {
AboutScreen,
ChannelScreen,
GeneralSettingsScreen,
} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('About', () => {
beforeAll(async () => {
const {user} = await Setup.apiInit();
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T3264 should be able to display about info', async () => {
const {
aboutAppVersion,
aboutBuildDateTitle,
aboutBuildDateValue,
aboutBuildHashTitle,
aboutBuildHashValue,
aboutBuildHashEnterpriseTitle,
aboutBuildHashEnterpriseValue,
aboutDatabase,
aboutLicensee,
aboutLogo,
aboutScrollView,
aboutServerVersion,
aboutSubtitle,
aboutTitle,
} = AboutScreen;
// # Open about screen
await ChannelScreen.openSettingsSidebar();
await GeneralSettingsScreen.open();
await AboutScreen.open();
// * Verify about info
await expect(aboutLogo).toBeVisible();
await expect(aboutSubtitle).toBeVisible();
await expect(aboutTitle).toBeVisible();
await expect(aboutSubtitle).toBeVisible();
await expect(aboutAppVersion).toBeVisible();
await expect(aboutServerVersion).toBeVisible();
await expect(aboutDatabase).toBeVisible();
await expect(aboutLicensee).toBeVisible();
await aboutScrollView.scrollTo('bottom');
await expect(aboutBuildHashTitle).toBeVisible();
await expect(aboutBuildHashValue).toBeVisible();
await expect(aboutBuildHashEnterpriseTitle).toBeVisible();
await expect(aboutBuildHashEnterpriseValue).toBeVisible();
await expect(aboutBuildDateTitle).toBeVisible();
await expect(aboutBuildDateValue).toBeVisible();
// # Go back to channel
await AboutScreen.back();
await GeneralSettingsScreen.close();
});
});

View file

@ -0,0 +1,49 @@
// 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 {
AdvancedSettingsScreen,
ChannelScreen,
GeneralSettingsScreen,
} from '@support/ui/screen';
import {
Channel,
Setup,
} from '@support/server_api';
describe('Advanced Settings', () => {
let townSquareChannel;
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T3262 should be able to delete documents and data', async () => {
// # Open advanced settings screen
await ChannelScreen.openSettingsSidebar();
await GeneralSettingsScreen.open();
await AdvancedSettingsScreen.open();
// # Delete documents and data
await AdvancedSettingsScreen.deleteDocumentsAndData();
// * Verify redirects to town square
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.channelNavBarTitle).toHaveText(townSquareChannel.display_name);
});
});

View file

@ -19,7 +19,21 @@ import {
} from '@support/server_api';
describe('Channel Add Members', () => {
const {
goToChannel,
postMessage,
} = ChannelScreen;
const {
addMembersAction,
channelInfoScrollView,
} = ChannelInfoScreen;
const {
addButton,
getUserByDisplayUsername,
searchInput,
} = ChannelAddMembersScreen;
let testChannel;
let testAnotherUser;
let testLastUser;
beforeAll(async () => {
@ -30,7 +44,9 @@ describe('Channel Add Members', () => {
const {user: testOtherUser} = await User.apiCreateUser({prefix: `a-${key}-`});
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
});
({user: testAnotherUser} = await User.apiCreateUser({prefix: 'b-other-'}));
({user: testLastUser} = await User.apiCreateUser({prefix: 'z-'}));
await Team.apiAddUserToTeam(testAnotherUser.id, team.id);
await Team.apiAddUserToTeam(testLastUser.id, team.id);
// # Open channel screen
@ -41,20 +57,37 @@ describe('Channel Add Members', () => {
await ChannelScreen.logout();
});
it('MM-T3197 should be able load users in long add members list', async () => {
const {
addMembersAction,
channelInfoScrollView,
} = ChannelInfoScreen;
it('MM-T3196 should be able to add members to channel', async () => {
// # Open add members screen
await ChannelScreen.goToChannel(testChannel.display_name);
await goToChannel(testChannel.display_name);
await postMessage('divider');
await ChannelInfoScreen.open();
await expect(element(by.id(ChannelInfoScreen.testID.manageMembersAction).withDescendant(by.text('2')))).toBeVisible();
await channelInfoScrollView.scrollTo('bottom');
await addMembersAction.tap();
// # Add members to channel
await searchInput.typeText('b-other');
await getUserByDisplayUsername(`@${testAnotherUser.username}`).tap();
await addButton.tap();
// * Verify members are added
await expect(element(by.id(ChannelInfoScreen.testID.manageMembersAction).withDescendant(by.text('3')))).toBeVisible();
// * Verify system message
await ChannelInfoScreen.close();
await expect(element(by.text(`@${testAnotherUser.username} added to the channel by you.`))).toBeVisible();
});
it('MM-T3197 should be able load users in long add members list', async () => {
// # Open add members screen
await goToChannel(testChannel.display_name);
await ChannelInfoScreen.open();
await channelInfoScrollView.scrollTo('bottom');
await addMembersAction.tap();
// * Verify user can scroll down multiple times until last user is seen
await waitFor(ChannelAddMembersScreen.getUserByDisplayUsername(`@${testLastUser.username}`)).toBeVisible().whileElement(by.id(ChannelAddMembersScreen.testID.usersList)).scroll(500, 'down');
await waitFor(getUserByDisplayUsername(`@${testLastUser.username}`)).toBeVisible().whileElement(by.id(ChannelAddMembersScreen.testID.usersList)).scroll(500, 'down');
await ChannelAddMembersScreen.back();
// # Close channel info screen

View file

@ -12,9 +12,12 @@ import {
ChannelInfoScreen,
ChannelScreen,
MoreDirectMessagesScreen,
ThreadScreen,
UserProfileScreen,
} from '@support/ui/screen';
import {
Channel,
Post,
Setup,
Team,
User,
@ -26,8 +29,10 @@ describe('Direct Messages', () => {
const {
channelNavBarTitle,
closeMainSidebar,
getPostListPostItem,
goToChannel,
openMainSidebar,
openReplyThreadFor,
} = ChannelScreen;
const {
getUserAtIndex,
@ -38,6 +43,7 @@ describe('Direct Messages', () => {
let testUser;
let testOtherUser;
let townSquareChannel;
let testMessage;
beforeAll(async () => {
const {user, team} = await Setup.apiInit();
@ -48,6 +54,14 @@ describe('Direct Messages', () => {
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
// # Post message by other user
testMessage = `Message by ${testOtherUser.username}`;
await User.apiLogin(testOtherUser);
await Post.apiCreatePost({
channelId: townSquareChannel.id,
message: testMessage,
});
// # Open channel screen
await ChannelScreen.open(testUser);
});
@ -56,6 +70,35 @@ describe('Direct Messages', () => {
await ChannelScreen.logout();
});
it('MM-T3210 should be able to open direct message from profile info in channel', async () => {
// # Open user profile screen from channel
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
const {postListPostItemProfilePicture} = await getPostListPostItem(post.id, testMessage, {userId: testOtherUser.id});
await postListPostItemProfilePicture.tap();
await UserProfileScreen.toBeVisible();
// # Open direct message from profile and verify can post message
await openDirectMessageFromProfileAndVerifyCanPostMessage(testOtherUser);
// # Go back to channel
await goToChannel(townSquareChannel.display_name);
});
it('MM-T3211 should be able to open direct message from profile info in reply thread', async () => {
// # Open user profile screen from reply thread
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
await openReplyThreadFor(post.id, testMessage);
const {postListPostItemProfilePicture} = await ThreadScreen.getPostListPostItem(post.id, testMessage, {userId: testOtherUser.id});
await postListPostItemProfilePicture.tap();
await UserProfileScreen.toBeVisible();
// # Open direct message from profile and verify can post message
await openDirectMessageFromProfileAndVerifyCanPostMessage(testOtherUser);
// # Go back to channel
await goToChannel(townSquareChannel.display_name);
});
it('MM-T3215 should be able to close direct message', async () => {
// # Create a DM with the other user
await openMainSidebar();
@ -94,3 +137,24 @@ describe('Direct Messages', () => {
await expect(channelNavBarTitle).toHaveText(`${testUser.username} (you) `);
});
});
async function openDirectMessageFromProfileAndVerifyCanPostMessage(testOtherUser) {
const {
sendMessageAction,
userProfileScrollView,
} = UserProfileScreen;
// # Open direct message from profile
await userProfileScrollView.scrollTo('bottom');
await sendMessageAction.tap();
// * Verify DM channel is created
await ChannelInfoScreen.open();
await expect(ChannelInfoScreen.channelDisplayName).toHaveText(testOtherUser.username);
// * Verify direct message can be posted
const directMessage = Date.now().toString();
await ChannelInfoScreen.close();
await ChannelScreen.postMessage(directMessage);
await expect(element(by.text(directMessage))).toBeVisible();
}

View file

@ -651,10 +651,10 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
DoubleConversion: cde416483dac037923206447da6e1454df403714
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
FBLazyVector: 49cbe4b43e445b06bf29199b6ad2057649e4c8f5
FBReactNativeSpec: 4862b23f27a9cdb8fdb1710af411fa677dcdd3cf
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
jail-monkey: 80c9e34da2cd54023e5ad08bf7051ec75bd43d5b
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
MMKV: 22e5136f7d00197bc0fc9694b7f71519f0d1ca12