From 776f56efb16c4705bc3458b77a85f4d7e87a1820 Mon Sep 17 00:00:00 2001 From: Joseph Baylon Date: Tue, 26 Apr 2022 08:22:33 -0700 Subject: [PATCH] Detox/E2E: Team Sidebar e2e tests in Gekidou (#6188) * Detox/E2E: Team Sidebar e2e tests in Gekidou * Fixed spacing for component * Fixed spacing for component --- .../add_team/add_team_slide_up.tsx | 7 +++- .../team_sidebar/add_team/index.tsx | 1 + .../team_sidebar/add_team/team_list.tsx | 6 ++- .../team_list_item/team_list_item.tsx | 3 ++ .../team_list/team_item/team_icon.tsx | 7 +++- .../team_list/team_item/team_item.tsx | 5 +++ .../team_sidebar/team_list/team_list.tsx | 4 +- app/components/team_sidebar/team_sidebar.tsx | 2 +- .../browse_channels/channel_dropdown.tsx | 6 +-- .../browse_channels/dropdown_slideup.tsx | 8 ++-- detox/e2e/support/ui/component/index.ts | 2 + .../e2e/support/ui/component/team_sidebar.ts | 15 +++++++ .../e2e/support/ui/screen/browse_channels.ts | 8 ++++ .../ui/screen/channel_dropdown_menu.ts | 41 +++++++++++++++++++ detox/e2e/support/ui/screen/channel_list.ts | 18 +++++++- detox/e2e/support/ui/screen/index.ts | 2 + detox/e2e/support/ui/screen/post_options.ts | 1 + detox/e2e/test/channels/channel_list.e2e.ts | 34 ++++++++++++++- .../channels/create_direct_message.e2e.ts | 2 +- 19 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 detox/e2e/support/ui/component/team_sidebar.ts create mode 100644 detox/e2e/support/ui/screen/channel_dropdown_menu.ts diff --git a/app/components/team_sidebar/add_team/add_team_slide_up.tsx b/app/components/team_sidebar/add_team/add_team_slide_up.tsx index cdbacf1678..c46223b931 100644 --- a/app/components/team_sidebar/add_team/add_team_slide_up.tsx +++ b/app/components/team_sidebar/add_team/add_team_slide_up.tsx @@ -32,10 +32,13 @@ export default function AddTeamSlideUp({otherTeams, canCreateTeams, showTitle = onPress={onPressCreate} showButton={canCreateTeams} showTitle={showTitle} - testID='add_team_slide_up' + testID='team_sidebar.add_team_slide_up' title={intl.formatMessage({id: 'mobile.add_team.join_team', defaultMessage: 'Join Another Team'})} > - + ); } diff --git a/app/components/team_sidebar/add_team/index.tsx b/app/components/team_sidebar/add_team/index.tsx index f8c64778b4..7e412bb94a 100644 --- a/app/components/team_sidebar/add_team/index.tsx +++ b/app/components/team_sidebar/add_team/index.tsx @@ -65,6 +65,7 @@ export default function AddTeam({canCreateTeams, otherTeams}: Props) { onPress={onPress} type='opacity' style={styles.touchable} + testID='team_sidebar.add_team.button' > ({ @@ -58,7 +59,7 @@ const renderTeam = ({item: t}: ListRenderItemInfo) => { const keyExtractor = (item: TeamModel) => item.id; -export default function TeamList({teams}: Props) { +export default function TeamList({teams, testID}: Props) { const theme = useTheme(); const styles = getStyleSheet(theme); @@ -70,6 +71,7 @@ export default function TeamList({teams}: Props) { renderItem={renderTeam} keyExtractor={keyExtractor} contentContainerStyle={styles.contentContainer} + testID={`${testID}.flat_list`} /> ); @@ -82,11 +84,13 @@ export default function TeamList({teams}: Props) { id='team_list.no_other_teams.title' defaultMessage='No additional teams to join' style={styles.title} + testID={`${testID}.no_other_teams.title`} /> ); diff --git a/app/components/team_sidebar/add_team/team_list_item/team_list_item.tsx b/app/components/team_sidebar/add_team/team_list_item/team_list_item.tsx index 8d4c3bcf6b..8b7cfeba83 100644 --- a/app/components/team_sidebar/add_team/team_list_item/team_list_item.tsx +++ b/app/components/team_sidebar/add_team/team_list_item/team_list_item.tsx @@ -55,6 +55,8 @@ export default function TeamListItem({team, currentUserId}: Props) { dismissBottomSheet(); }, []); + const teamListItemTestId = `team_sidebar.team_list.team_list_item.${team.id}`; + return ( (null); const theme = useTheme(); @@ -41,8 +42,9 @@ export default function TeamIcon({id, lastIconUpdate, displayName, selected}: Pr teamIconContent = ( - {displayName?.substr(0, 2).toUpperCase()} + {displayName?.substring(0, 2).toUpperCase()} ); } else { @@ -59,6 +61,7 @@ export default function TeamIcon({id, lastIconUpdate, displayName, selected}: Pr {teamIconContent} diff --git a/app/components/team_sidebar/team_list/team_item/team_item.tsx b/app/components/team_sidebar/team_list/team_item/team_item.tsx index 5c374321e7..a76a89082c 100644 --- a/app/components/team_sidebar/team_list/team_item/team_item.tsx +++ b/app/components/team_sidebar/team_list/team_item/team_item.tsx @@ -82,18 +82,23 @@ export default function TeamItem({team, hasUnreads, mentionCount, currentTeamId} break; } + const teamItem = `team_sidebar.team_list.team_item.${team.id}`; + const teamItemTestId = selected ? `${teamItem}.selected` : `${teamItem}.not_selected`; + return ( <> handleTeamChange(serverUrl, team.id)} type='opacity' + testID={teamItemTestId} > diff --git a/app/components/team_sidebar/team_list/team_list.tsx b/app/components/team_sidebar/team_list/team_list.tsx index cf1e68a985..fa560e5e46 100644 --- a/app/components/team_sidebar/team_list/team_list.tsx +++ b/app/components/team_sidebar/team_list/team_list.tsx @@ -10,6 +10,7 @@ import type MyTeamModel from '@typings/database/models/servers/my_team'; type Props = { myOrderedTeams: MyTeamModel[]; + testID?: string; } const keyExtractor = (item: MyTeamModel) => item.id; @@ -22,7 +23,7 @@ const renderTeam = ({item: t}: ListRenderItemInfo) => { ); }; -export default function TeamList({myOrderedTeams}: Props) { +export default function TeamList({myOrderedTeams, testID}: Props) { return ( ); diff --git a/app/components/team_sidebar/team_sidebar.tsx b/app/components/team_sidebar/team_sidebar.tsx index 1aa08528a3..f5ee289ea0 100644 --- a/app/components/team_sidebar/team_sidebar.tsx +++ b/app/components/team_sidebar/team_sidebar.tsx @@ -68,7 +68,7 @@ export default function TeamSidebar({canCreateTeams, iconPad, otherTeams, teamsC return ( - + {showAddTeam && ( + {channelDropdownText} {' '} diff --git a/app/screens/browse_channels/dropdown_slideup.tsx b/app/screens/browse_channels/dropdown_slideup.tsx index 5f68e1246a..79b439674c 100644 --- a/app/screens/browse_channels/dropdown_slideup.tsx +++ b/app/screens/browse_channels/dropdown_slideup.tsx @@ -66,12 +66,12 @@ export default function DropdownSlideup({ { diff --git a/detox/e2e/support/ui/screen/channel_dropdown_menu.ts b/detox/e2e/support/ui/screen/channel_dropdown_menu.ts new file mode 100644 index 0000000000..2003dee1ee --- /dev/null +++ b/detox/e2e/support/ui/screen/channel_dropdown_menu.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {BrowseChannelsScreen} from '@support/ui/screen'; +import {timeouts} from '@support/utils'; +import {expect} from 'detox'; + +class ChannelDropdownMenuScreen { + testID = { + channelDropdownMenuScreen: 'browse_channels.dropdown_slideup.screen', + publicChannelsItem: 'browse_channels.dropdown_slideup_item.public_channels', + archivedChannelsItem: 'browse_channels.dropdown_slideup_item.public_channels', + sharedChannelsItem: 'browse_channels.dropdown_slideup_item.public_channels', + }; + + channelDropdownMenuScreen = element(by.id(this.testID.channelDropdownMenuScreen)); + publicChannelsItem = element(by.id(this.testID.publicChannelsItem)); + archivedChannelsItem = element(by.id(this.testID.archivedChannelsItem)); + sharedChannelsItem = element(by.id(this.testID.sharedChannelsItem)); + + toBeVisible = async () => { + await waitFor(this.channelDropdownMenuScreen).toExist().withTimeout(timeouts.TEN_SEC); + + return this.channelDropdownMenuScreen; + }; + + open = async () => { + // # Open channel dropdown menu screen + await BrowseChannelsScreen.channelDropdown.tap(); + + return this.toBeVisible(); + }; + + close = async () => { + await this.channelDropdownMenuScreen.tap({x: 5, y: 10}); + await expect(this.channelDropdownMenuScreen).not.toBeVisible(); + }; +} + +const channelDropdownMenuScreen = new ChannelDropdownMenuScreen(); +export default channelDropdownMenuScreen; diff --git a/detox/e2e/support/ui/screen/channel_list.ts b/detox/e2e/support/ui/screen/channel_list.ts index b446db8175..0b15114fa5 100644 --- a/detox/e2e/support/ui/screen/channel_list.ts +++ b/detox/e2e/support/ui/screen/channel_list.ts @@ -1,7 +1,10 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {PlusMenu} from '@support/ui/component'; +import { + PlusMenu, + TeamSidebar, +} from '@support/ui/component'; import {HomeScreen} from '@support/ui/screen'; import {timeouts} from '@support/utils'; @@ -27,6 +30,7 @@ class ChannelListScreen { threadsButton = element(by.id(this.testID.threadsButton)); // convenience props + teamFlatList = TeamSidebar.teamFlatList; browseChannelsItem = PlusMenu.browseChannelsItem; createNewChannelItem = PlusMenu.createNewChannelItem; openDirectMessageItem = PlusMenu.openDirectMessageItem; @@ -55,6 +59,18 @@ class ChannelListScreen { return element(by.id(`category.${categoryKey}.channel_list_item.${channelName}.display_name`)); }; + getTeamItemSelected = (teamId: string) => { + return element(by.id(`team_sidebar.team_list.team_item.${teamId}.selected`)); + }; + + getTeamItemNotSelected = (teamId: string) => { + return element(by.id(`team_sidebar.team_list.team_item.${teamId}.not_selected`)); + }; + + getTeamItemDisplayNameAbbreviation = (teamId: string) => { + return element(by.id(`team_sidebar.team_list.team_item.${teamId}.team_icon.display_name_abbreviation`)); + }; + toBeVisible = async () => { await waitFor(this.channelListScreen).toExist().withTimeout(timeouts.TEN_SEC); diff --git a/detox/e2e/support/ui/screen/index.ts b/detox/e2e/support/ui/screen/index.ts index 7adc1b75ce..ebb5ff4ea4 100644 --- a/detox/e2e/support/ui/screen/index.ts +++ b/detox/e2e/support/ui/screen/index.ts @@ -4,6 +4,7 @@ import AccountScreen from './account'; import BrowseChannelsScreen from './browse_channels'; import ChannelScreen from './channel'; +import ChannelDropdownMenuScreen from './channel_dropdown_menu'; import ChannelListScreen from './channel_list'; import CreateDirectMessageScreen from './create_direct_message'; import CreateOrEditChannelScreen from './create_or_edit_channel'; @@ -19,6 +20,7 @@ export { AccountScreen, BrowseChannelsScreen, ChannelScreen, + ChannelDropdownMenuScreen, ChannelListScreen, CreateDirectMessageScreen, CreateOrEditChannelScreen, diff --git a/detox/e2e/support/ui/screen/post_options.ts b/detox/e2e/support/ui/screen/post_options.ts index 780fb232f0..c551731b8e 100644 --- a/detox/e2e/support/ui/screen/post_options.ts +++ b/detox/e2e/support/ui/screen/post_options.ts @@ -53,6 +53,7 @@ class PostOptionsScreen { }; deletePost = async ({confirm = true} = {}) => { + await waitFor(this.deletePostOption).toExist().withTimeout(timeouts.TWO_SEC); await this.deletePostOption.tap({x: 1, y: 1}); const { deletePostTitle, diff --git a/detox/e2e/test/channels/channel_list.e2e.ts b/detox/e2e/test/channels/channel_list.e2e.ts index 1813a0a252..7b6d9d49d0 100644 --- a/detox/e2e/test/channels/channel_list.e2e.ts +++ b/detox/e2e/test/channels/channel_list.e2e.ts @@ -7,7 +7,10 @@ // - Use element testID when selecting an element. Create one if none. // ******************************************************************* -import {Setup} from '@support/server_api'; +import { + Setup, + Team, +} from '@support/server_api'; import { serverOneUrl, siteOneUrl, @@ -32,15 +35,17 @@ describe('Channels - Channel List', () => { const townSquareChannelName = 'town-square'; let testChannel: any; let testTeam: any; + let testUser: any; beforeAll(async () => { const {channel, team, user} = await Setup.apiInit(siteOneUrl); testChannel = channel; testTeam = team; + testUser = user; // # Log in to server await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName); - await LoginScreen.login(user); + await LoginScreen.login(testUser); }); beforeEach(async () => { @@ -162,4 +167,29 @@ describe('Channels - Channel List', () => { xit('MM-T4728_8 - should be able to find channels', async () => { // NOT YET IMPLEMENTED }); + + it('MM-T4728_9 - should be able to switch between teams', async () => { + // # As admin, create a second team and add user to the second team + const {team: testTeamTwo} = await Team.apiCreateTeam(siteOneUrl, {prefix: 'a'}); + await Team.apiAddUserToTeam(siteOneUrl, testUser.id, testTeamTwo.id); + + // * Verify on first team and team sidebar item is selected and has correct display name abbreviation + await expect(ChannelListScreen.headerTeamDisplayName).toHaveText(testTeam.display_name); + await expect(ChannelListScreen.getTeamItemSelected(testTeam.id)).toBeVisible(); + await expect(ChannelListScreen.getTeamItemDisplayNameAbbreviation(testTeam.id)).toHaveText(testTeam.display_name.substring(0, 2).toUpperCase()); + + // # Tap on second team item from team sidebar + await ChannelListScreen.getTeamItemNotSelected(testTeamTwo.id).tap(); + + // * Verify on second team and team sidebar item is selected and has correct display name abbreviation + await expect(ChannelListScreen.headerTeamDisplayName).toHaveText(testTeamTwo.display_name); + await expect(ChannelListScreen.getTeamItemSelected(testTeamTwo.id)).toBeVisible(); + await expect(ChannelListScreen.getTeamItemDisplayNameAbbreviation(testTeamTwo.id)).toHaveText(testTeamTwo.display_name.substring(0, 2).toUpperCase()); + + // # Tap back on first team item from team sidebar + await ChannelListScreen.getTeamItemNotSelected(testTeam.id).tap(); + + // * Verify on first team + await expect(ChannelListScreen.headerTeamDisplayName).toHaveText(testTeam.display_name); + }); }); diff --git a/detox/e2e/test/channels/create_direct_message.e2e.ts b/detox/e2e/test/channels/create_direct_message.e2e.ts index d4ea822884..36a16684ec 100644 --- a/detox/e2e/test/channels/create_direct_message.e2e.ts +++ b/detox/e2e/test/channels/create_direct_message.e2e.ts @@ -116,7 +116,7 @@ describe('Channels - Create Direct Message', () => { // * Verify no group message channel for the new users appears on channel list screen const firstNewUserDisplayName = firstNewUser.username; const secondNewUserDisplayName = secondNewUser.username; - const groupDisplayName = `${firstNewUserDisplayName}, ${secondNewUserDisplayName}, ${testUser.username}`; + const groupDisplayName = `${firstNewUserDisplayName}, ${secondNewUserDisplayName}`; await expect(element(by.text(groupDisplayName))).not.toBeVisible(); // # Open create direct message screen, search for the first new user and tap on the first new user item