From 6fdfd57c113037fc7740fef4f5c5c8683a97d2ca Mon Sep 17 00:00:00 2001 From: yasser khan Date: Wed, 10 Dec 2025 11:01:04 +0530 Subject: [PATCH] E2E: Automate Edit profile tests from Rainforest (#9290) --- .../channels/localization/language.e2e.ts | 96 ++++++++ .../channels/messaging/markdown_list.e2e.ts | 6 - .../e2e/test/products/playbooks/playbooks.ts | 228 ++++++++++++++++++ 3 files changed, 324 insertions(+), 6 deletions(-) create mode 100644 detox/e2e/test/products/channels/localization/language.e2e.ts create mode 100644 detox/e2e/test/products/playbooks/playbooks.ts diff --git a/detox/e2e/test/products/channels/localization/language.e2e.ts b/detox/e2e/test/products/channels/localization/language.e2e.ts new file mode 100644 index 000000000..dd046f0ed --- /dev/null +++ b/detox/e2e/test/products/channels/localization/language.e2e.ts @@ -0,0 +1,96 @@ +// 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 {Setup, User} from '@support/server_api'; +import { + serverOneUrl, + siteOneUrl, +} from '@support/test_config'; +import { + AccountScreen, + DisplaySettingsScreen, + HomeScreen, + LoginScreen, + ServerScreen, + SettingsScreen, +} from '@support/ui/screen'; +import {timeouts, wait} from '@support/utils'; +import {expect} from 'detox'; + +describe('Localization', () => { + const serverOneDisplayName = 'Server 1'; + let testUser: any; + + beforeAll(async () => { + const {user} = await Setup.apiInit(siteOneUrl); + testUser = user; + + // # Patch user locale to Spanish + await User.apiPatchUser(siteOneUrl, testUser.id, {locale: 'es'}); + + // # Log in to server + await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName); + await LoginScreen.login(testUser); + }); + + it('MM-T303 - Text looks correct when viewed in a non-English language', async () => { + // * Verify Home screen elements are in Spanish + await expect(element(by.text('Hilos'))).toBeVisible(); + await expect(element(by.text('CANALES'))).toBeVisible(); + await expect(element(by.text('MENSAJES DIRECTOS'))).toBeVisible(); + await expect(element(by.text('Encontrar canales...'))).toBeVisible(); + + // # Go to Account screen + await AccountScreen.open(); + await wait(timeouts.TWO_SEC); + + // * Verify Account screen elements are in Spanish + await expect(element(by.text('Establecer un estado personalizado'))).toBeVisible(); + await expect(element(by.text('Tu Perfil'))).toBeVisible(); + await expect(element(by.text('Ajustes'))).toBeVisible(); + await expect(element(by.text('Salir'))).toBeVisible(); + + // # Go to Settings screen + await AccountScreen.settingsOption.tap(); + + // * Verify Settings screen title or elements + await SettingsScreen.toBeVisible(); + + // "Pantalla" instead of "Display" + await expect(element(by.text('Pantalla'))).toBeVisible(); + + // # Go to Display Settings + await DisplaySettingsScreen.open(); + await DisplaySettingsScreen.toBeVisible(); + + // * Verify Display Settings elements + // "Tema" instead of "Theme" + await expect(element(by.text('Tema'))).toBeVisible(); + + // # Navigate back + await DisplaySettingsScreen.back(); + await SettingsScreen.close(); + }); + + it('MM-T304 - RN: No crash when setting language to zh-TW (Chinese Traditional)', async () => { + // # Change language to zh-TW via API + await User.apiPatchUser(siteOneUrl, testUser.id, {locale: 'zh-TW'}); + + // # Wait for sync (simulating "Wait a few seconds for the RN app to sync") + await wait(timeouts.FOUR_SEC); + + // * Verify app is still running and not crashed (check for Home screen visibility) + await HomeScreen.channelListTab.tap(); + await HomeScreen.toBeVisible(); + + // * Verify text update (optional, checking for "Channels" translation in Traditional Chinese) + // "Channels" -> "頻道" + await expect(element(by.text('頻道'))).toBeVisible(); + }); +}); diff --git a/detox/e2e/test/products/channels/messaging/markdown_list.e2e.ts b/detox/e2e/test/products/channels/messaging/markdown_list.e2e.ts index 13ca17e5a..978a826b7 100644 --- a/detox/e2e/test/products/channels/messaging/markdown_list.e2e.ts +++ b/detox/e2e/test/products/channels/messaging/markdown_list.e2e.ts @@ -18,7 +18,6 @@ import { import { ChannelListScreen, ChannelScreen, - HomeScreen, LoginScreen, ServerScreen, } from '@support/ui/screen'; @@ -44,11 +43,6 @@ describe('Messaging - Markdown List', () => { await ChannelListScreen.toBeVisible(); }); - afterAll(async () => { - // # Log out - await HomeScreen.logout(); - }); - it('MM-T4894_1 - should be able to display markdown bullet list', async () => { // # Open a channel screen and post a markdown bullet list const item1 = 'item one'; diff --git a/detox/e2e/test/products/playbooks/playbooks.ts b/detox/e2e/test/products/playbooks/playbooks.ts new file mode 100644 index 000000000..6a2965456 --- /dev/null +++ b/detox/e2e/test/products/playbooks/playbooks.ts @@ -0,0 +1,228 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Setup, User, Team, Playbooks, PlaybooksHelpers, Channel} from '@support/server_api'; +import {siteOneUrl} from '@support/test_config'; +import {ServerScreen, LoginScreen, ChannelScreen, ChannelListScreen, ThreadScreen} from '@support/ui/screen'; + +describe.skip('Playbooks - Basic', () => { + const serverOneDisplayName = 'Server 1'; + const channelsCategory = 'channels'; + + let testUser: any; + let testTeam: any; + let testChannel: any; + let secondUser: any; + let thirdUser: any; + + beforeAll(async () => { + // Create test user, team, and channel + ({user: testUser, team: testTeam, channel: testChannel} = await Setup.apiInit(siteOneUrl)); + await Playbooks.apiEnablePlugin(siteOneUrl, 'playbooks'); + + // Create additional test users + ({user: secondUser} = await User.apiCreateUser(siteOneUrl)); + ({user: thirdUser} = await User.apiCreateUser(siteOneUrl)); + + await Team.apiAddUserToTeam(siteOneUrl, secondUser.id, testTeam.id); + await Team.apiAddUserToTeam(siteOneUrl, thirdUser.id, testTeam.id); + + await Channel.apiAddUserToChannel(siteOneUrl, secondUser.id, testChannel.id); + await Channel.apiAddUserToChannel(siteOneUrl, thirdUser.id, testChannel.id); + + // # Log in to server + await ServerScreen.connectToServer(siteOneUrl, serverOneDisplayName); + await LoginScreen.login(testUser); + }); + + beforeEach(async () => { + // * Verify on channel list screen + await ChannelListScreen.toBeVisible(); + }); + + it('should verify in-progress playbook information in Channel Header and Channel Info ', async () => { + // Generate a random playbook + const playbook = PlaybooksHelpers.generateRandomPlaybook({ + teamId: testTeam.id, + userId: secondUser.id, + prefix: 'e2e-test', + numChecklists: 2, + numItems: 3, + channel_id: testChannel.id, + }); + + // Create the playbook + const {id: playbookId} = await Playbooks.apiCreatePlaybook(siteOneUrl, playbook); + + // Get the created playbook + await Playbooks.apiGetPlaybook(siteOneUrl, playbookId); + + // Generate a playbook run + const playbookRun = PlaybooksHelpers.generateRandomPlaybookRun({ + teamId: testTeam.id, + playbookId, + channelId: testChannel.id, + ownerId: secondUser.id, + prefix: 'e2e-run', + }); + + // Start the playbook run + const activeRun = await Playbooks.apiRunPlaybook(siteOneUrl, playbookRun); + await Playbooks.apiAddUsersToRun(siteOneUrl, activeRun.id, [secondUser.id, thirdUser.id]); + await ChannelScreen.open(channelsCategory, testChannel.name); + + await pilot.perform( + 'Verify the Playbook icon and count "1" are visible in the Channel Header', + 'Tap the "Quick Actions" icon in the Channel Header', + 'Verify a bottom sheet with the "Playbook runs" option is displayed', + 'Verify that "Playbook runs" option is listed in the bottom sheet', + 'Tap the "Playbook runs" option in the bottom sheet', + 'Verify the "Playbook runs" screen opens', + 'Verify the "In Progress" tab is selected', + ); + + await Playbooks.apiDeletePlaybook(siteOneUrl, playbookId); + await ThreadScreen.back(); + await ChannelScreen.back(); + }); + + it('should verify finished playbooks are listed in the Finished tab', async () => { + // Create and finish a playbook run + const playbook = PlaybooksHelpers.generateRandomPlaybook({ + teamId: testTeam.id, + userId: secondUser.id, + prefix: 'finished-test', + channel_id: testChannel.id, + }); + const {id: playbookId} = await Playbooks.apiCreatePlaybook(siteOneUrl, playbook); + const playbookRun = PlaybooksHelpers.generateRandomPlaybookRun({ + teamId: testTeam.id, + playbookId, + channelId: testChannel.id, + ownerId: secondUser.id, + prefix: 'finished-run', + }); + const activeRun = await Playbooks.apiRunPlaybook(siteOneUrl, playbookRun); + await Playbooks.apiFinishRun(siteOneUrl, activeRun.id); + await ChannelScreen.open(channelsCategory, testChannel.name); + await pilot.perform( + 'Tap the "Quick Actions" icon in the Channel Header', + 'Tap the "Playbook runs" option in the bottom sheet', + 'Switch to the "Finished" tab', + 'Verify multiple finished playbook runs are listed', + ); + + await Playbooks.apiDeletePlaybook(siteOneUrl, playbookId); + await ThreadScreen.back(); + await ChannelScreen.back(); + }); + + it('should verify scrolling of playbooks in the In Progress tab', async () => { + const playbookRunsToDelete: string[] = []; + + // Create multiple in-progress playbook runs + const playbook = PlaybooksHelpers.generateRandomPlaybook({ + teamId: testTeam.id, + userId: secondUser.id, + prefix: 'scroll-inprogress', + channel_id: testChannel.id, + }); + const {id: playbookId} = await Playbooks.apiCreatePlaybook(siteOneUrl, playbook); + for (let i = 0; i < 10; i++) { + const playbookRun = PlaybooksHelpers.generateRandomPlaybookRun({ + teamId: testTeam.id, + playbookId, + channelId: testChannel.id, + ownerId: secondUser.id, + prefix: `scroll-inprogress-${i}`, + }); + // eslint-disable-next-line no-await-in-loop + const activeRun = await Playbooks.apiRunPlaybook(siteOneUrl, playbookRun); + playbookRunsToDelete.push(activeRun.id); + } + await ChannelScreen.open(channelsCategory, testChannel.name); + await pilot.perform( + 'Tap the "Quick Actions" icon in the Channel Header', + 'Tap the "Playbook runs" option in the bottom sheet', + 'Verify the "Playbook runs" screen opens', + ); + await pilot.autopilot('Scroll through the list of playbooks in the In Progress tab and verify that the list scrolls smoothly and all playbooks are visible'); + + await Promise.all(playbookRunsToDelete.map((runId) => Playbooks.apiDeletePlaybook(siteOneUrl, runId))); + await ThreadScreen.back(); + await ChannelScreen.back(); + }); + + it('should verify details of a checklist in a particular playbook', async () => { + // Create a playbook with a checklist + const playbook = PlaybooksHelpers.generateRandomPlaybook({ + teamId: testTeam.id, + userId: secondUser.id, + prefix: 'checklist-details', + numChecklists: 2, + numItems: 2, + channel_id: testChannel.id, + }); + const {id: playbookId} = await Playbooks.apiCreatePlaybook(siteOneUrl, playbook); + const playbookRun = PlaybooksHelpers.generateRandomPlaybookRun({ + teamId: testTeam.id, + playbookId, + channelId: testChannel.id, + ownerId: secondUser.id, + prefix: 'checklist-details-run', + }); + const activeRun = await Playbooks.apiRunPlaybook(siteOneUrl, playbookRun); + await Playbooks.apiAddUsersToRun(siteOneUrl, activeRun.id, [testUser.id, secondUser.id, thirdUser.id]); + await ChannelScreen.open(channelsCategory, testChannel.name); + await pilot.perform( + 'Tap the "Quick Actions" icon in the Channel Header', + 'Tap the "Playbook runs" option in the bottom sheet', + 'Tap on the Playbook run to open it', + 'Verify Owner and Participants are displayed', + 'Tap on the "Checklist 1" tab to collapse the checklist section', + 'Tap on the "Checklist 1" tab to expand the checklist section', + ); + await pilot.autopilot('Verify Interacting with checklist items and updating progress'); + + await Playbooks.apiDeletePlaybook(siteOneUrl, playbookId); + await ThreadScreen.back(); + await ThreadScreen.back(); + await ChannelScreen.back(); + }); + + it('should verify the participants list in the playbook', async () => { + // Create a playbook with a checklist + const playbook = PlaybooksHelpers.generateRandomPlaybook({ + teamId: testTeam.id, + userId: secondUser.id, + prefix: 'checklist-progress', + numChecklists: 1, + numItems: 2, + channel_id: testChannel.id, + }); + const {id: playbookId} = await Playbooks.apiCreatePlaybook(siteOneUrl, playbook); + const playbookRun = PlaybooksHelpers.generateRandomPlaybookRun({ + teamId: testTeam.id, + playbookId, + channelId: testChannel.id, + ownerId: secondUser.id, + prefix: 'checklist-progress-run', + }); + const activeRun = await Playbooks.apiRunPlaybook(siteOneUrl, playbookRun); + await Playbooks.apiAddUsersToRun(siteOneUrl, activeRun.id, [testUser.id, secondUser.id, thirdUser.id]); + await ChannelScreen.open(channelsCategory, testChannel.name); + await pilot.perform( + 'Tap the "Quick Actions" icon in the Channel Header', + 'Tap the "Playbook runs" option in the bottom sheet', + 'Tap on the Playbook run to open it', + 'Tap on the icons section below "Participants" label', + 'Verify bottom sheet with title "Run Participants" is displayed', + 'Verify the participants list contains list of 3 users', + ); + + await Playbooks.apiDeletePlaybook(siteOneUrl, playbookId); + await ThreadScreen.back(); + await ThreadScreen.back(); + await ChannelScreen.back(); + }); +});