diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts index 9d7b7ad819540..de0a46b3bae99 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts @@ -2,6 +2,8 @@ import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -15,7 +17,9 @@ const settingsList = [ preserveSettings(settingsList); test.describe('E2EE Encrypted Channels', () => { + const createdChannels: { name: string; id?: string | null }[] = []; let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; test.use({ storageState: Users.userE2EE.state }); @@ -29,13 +33,18 @@ test.describe('E2EE Encrypted Channels', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); await page.goto('/home'); }); + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); + }); + test('expect create a private channel encrypted and send an encrypted message', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -77,7 +86,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a private encrypted channel and send a encrypted thread message', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -109,7 +118,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a private encrypted channel and check disabled message menu actions on an encrypted message', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -141,6 +150,8 @@ test.describe('E2EE Encrypted Channels', () => { await poHomeChannel.toastMessage.waitForDisplay(); await poHomeChannel.toastMessage.dismissToast(); + await createE2EEChannel.resolveAndStore(channelName, createdChannels); + await poHomeChannel.tabs.kebab.click(); // TODO(@jessicaschelly/@dougfabris): fix this flaky behavior if (!(await poHomeChannel.tabs.btnEnableE2E.isVisible())) { @@ -162,7 +173,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a encrypted private channel and mention user', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -180,7 +191,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a encrypted private channel, mention a channel and navigate to it', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -202,7 +213,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a encrypted private channel, mention a channel and user', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -238,6 +249,9 @@ test.describe('E2EE Encrypted Channels', () => { await poHomeChannel.toastMessage.waitForDisplay(); await poHomeChannel.toastMessage.dismissToast(); + // Track channel for cleanup + await createE2EEChannel.resolveAndStore(channelName, createdChannels); + // Send Unencrypted Messages await poHomeChannel.content.sendMessage('first unencrypted message'); await poHomeChannel.content.sendMessage('second unencrypted message'); @@ -276,7 +290,7 @@ test.describe('E2EE Encrypted Channels', () => { test('expect create a private encrypted channel and pin/star an encrypted message', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -331,7 +345,7 @@ test.describe('E2EE Encrypted Channels', () => { const originalMessage = 'This is the original encrypted message'; const editedMessage = 'This is the edited encrypted message'; - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); @@ -356,7 +370,7 @@ test.describe('E2EE Encrypted Channels', () => { const editedMessage = 'This is the edited encrypted message with a mention to @user1 and #general'; const displayedMessage = 'This is the edited encrypted message with a mention to user1 and general'; - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts index 3769d88ea53fd..308028c899711 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts @@ -5,9 +5,10 @@ import { BASE_URL } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { EncryptedRoomPage } from '../page-objects/encrypted-room'; import { HomeSidenav } from '../page-objects/fragments'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; import { FileUploadModal } from '../page-objects/fragments/file-upload-modal'; import { LoginPage } from '../page-objects/login'; -import { createTargetGroupAndReturnFullRoom, deleteChannel, deleteRoom } from '../utils'; +import { createTargetGroupAndReturnFullRoom, deleteRoom } from '../utils'; import { preserveSettings } from '../utils/preserveSettings'; import { sendMessageFromUser } from '../utils/sendMessage'; import { test, expect } from '../utils/test'; @@ -17,6 +18,9 @@ const settingsList = ['E2E_Enable', 'E2E_Allow_Unencrypted_Messages']; preserveSettings(settingsList); test.describe('E2EE Encryption and Decryption - Basic Features', () => { + const createdChannels: { name: string; id?: string | null }[] = []; + let createE2EEChannel: CreateE2EEChannel; + test.use({ storageState: Users.admin.state }); test.beforeAll(async ({ api }) => { @@ -34,6 +38,11 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => { await page.goto('/home'); await loginPage.waitForIt(); await loginPage.loginByUserState(Users.admin); + createE2EEChannel = new CreateE2EEChannel(page); + }); + + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); }); test('expect placeholder text in place of encrypted message', async ({ page }) => { @@ -46,7 +55,7 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => { await setupE2EEPassword(page); - await sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); @@ -87,7 +96,7 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => { await setupE2EEPassword(page); // Create an encrypted channel - await sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); @@ -154,7 +163,6 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => { test.afterAll(async ({ api }) => { await deleteRoom(api, targetRoomId); - await deleteChannel(api, targetChannelName); }); test('expect to not crash and not show quote message for a message_link which is not accessible to the user', async ({ @@ -163,10 +171,9 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => { api, }) => { const encryptedRoomPage = new EncryptedRoomPage(page); - const sidenav = new HomeSidenav(page); targetChannelName = faker.string.uuid(); - await sidenav.createEncryptedChannel(targetChannelName); + await createE2EEChannel.createAndStore(targetChannelName, createdChannels); await expect(page).toHaveURL(`/group/${targetChannelName}`); await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts index bfb18e84f4b3f..0fd86919df28b 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts @@ -2,6 +2,8 @@ import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -16,7 +18,9 @@ const settingsList = [ const originalSettings = preserveSettings(settingsList); test.describe('E2EE File Encryption', () => { + const createdChannels: { name: string; id?: string | null }[] = []; let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; test.use({ storageState: Users.userE2EE.state }); @@ -29,12 +33,14 @@ test.describe('E2EE File Encryption', () => { }); test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); await api.post('/settings/FileUpload_MediaTypeWhiteList', { value: '' }); await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); }); test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); await page.goto('/home'); }); @@ -42,7 +48,7 @@ test.describe('E2EE File Encryption', () => { await test.step('create an encrypted channel', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -77,7 +83,7 @@ test.describe('E2EE File Encryption', () => { await test.step('create an encrypted room', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -141,7 +147,7 @@ test.describe('E2EE File Encryption', () => { await test.step('create an encrypted channel', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts index 4d0ea1a3478ed..236f7d063e789 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts @@ -4,6 +4,8 @@ import type { APIRequestContext } from '@playwright/test'; import { BASE_API_URL } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -33,7 +35,9 @@ const sendEncryptedMessage = async (request: APIRequestContext, rid: string, enc }; test.describe('E2EE Legacy Format', () => { + const createdChannels: { name: string; id?: string | null }[] = []; let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; test.use({ storageState: Users.userE2EE.state }); @@ -47,13 +51,18 @@ test.describe('E2EE Legacy Format', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); await page.goto('/home'); }); + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); + }); + test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts index c31419e860366..e48ad9c48ed8e 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts @@ -6,12 +6,14 @@ import { AccountSecurity, HomeChannel } from '../page-objects'; import { setupE2EEPassword } from './setupE2EEPassword'; import { HomeSidenav } from '../page-objects/fragments'; import { + CreateE2EEChannel, E2EEKeyDecodeFailureBanner, EnterE2EEPasswordBanner, EnterE2EEPasswordModal, ResetE2EEPasswordModal, } from '../page-objects/fragments/e2ee'; import { LoginPage } from '../page-objects/login'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -184,13 +186,17 @@ const roomSetupSettingsList = ['E2E_Enable', 'E2E_Allow_Unencrypted_Messages']; test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { let poAccountSecurity: AccountSecurity; let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; let e2eePassword: string; + const createdChannels: { name: string; id?: string | null }[] = []; + preserveSettings(roomSetupSettingsList); test.beforeEach(async ({ page }) => { poAccountSecurity = new AccountSecurity(page); poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); }); test.beforeAll(async ({ api }) => { @@ -202,6 +208,10 @@ test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { await api.recreateContext(); }); + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); + }); + test('expect save password state on encrypted room', async ({ page }) => { await page.goto('/account/security'); await poAccountSecurity.securityE2EEncryptionSection.click(); @@ -219,7 +229,7 @@ test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -261,7 +271,7 @@ test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -303,7 +313,7 @@ test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts index 610ce150d86d2..9c96db003bbc8 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts @@ -2,9 +2,10 @@ import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; import { EncryptedRoomPage } from '../page-objects/encrypted-room'; -import { HomeSidenav } from '../page-objects/fragments'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; import { ExportMessagesTab } from '../page-objects/fragments/export-messages-tab'; import { LoginPage } from '../page-objects/login'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -18,6 +19,9 @@ const settingsList = [ preserveSettings(settingsList); test.describe('E2EE PDF Export', () => { + const createdChannels: { name: string; id?: string | null }[] = []; + let createE2EEChannel: CreateE2EEChannel; + test.use({ storageState: Users.admin.state }); test.beforeAll(async ({ api }) => { @@ -25,7 +29,6 @@ test.describe('E2EE PDF Export', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - // Note: Using admin user, so no need for userE2EE cleanup }); test.beforeEach(async ({ api, page }) => { @@ -38,16 +41,20 @@ test.describe('E2EE PDF Export', () => { await page.goto('/home'); await loginPage.waitForIt(); await loginPage.loginByUserState(Users.admin); + createE2EEChannel = new CreateE2EEChannel(page); + }); + + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); }); test('should display only the download file method when exporting messages in an e2ee room', async ({ page }) => { - const sidenav = new HomeSidenav(page); const encryptedRoomPage = new EncryptedRoomPage(page); const exportMessagesTab = new ExportMessagesTab(page); const channelName = faker.string.uuid(); - await sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); @@ -57,13 +64,12 @@ test.describe('E2EE PDF Export', () => { }); test('should allow exporting messages as PDF in an encrypted room', async ({ page }) => { - const sidenav = new HomeSidenav(page); const encryptedRoomPage = new EncryptedRoomPage(page); const exportMessagesTab = new ExportMessagesTab(page); const channelName = faker.string.uuid(); - await sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts index 9a6fd5de8576d..f59d29a6ca3e5 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts @@ -3,6 +3,8 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; +import { CreateE2EEChannel } from '../page-objects/fragments/e2ee'; +import { deleteRoom } from '../utils/create-target-channel'; import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; @@ -16,7 +18,9 @@ const settingsList = [ preserveSettings(settingsList); test.describe('E2EE Server Settings', () => { + const createdChannels: { name: string; id?: string | null }[] = []; let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; test.use({ storageState: Users.userE2EE.state }); @@ -30,14 +34,19 @@ test.describe('E2EE Server Settings', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); await page.goto('/home'); }); + test.afterAll(async ({ api }) => { + await Promise.all(createdChannels.map(({ id }) => (id ? deleteRoom(api, id) : Promise.resolve()))); + }); + test('expect slash commands to be enabled in an e2ee room', async ({ page }) => { test.skip(!IS_EE, 'Premium Only'); const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); @@ -62,9 +71,11 @@ test.describe('E2EE Server Settings', () => { test.describe('un-encrypted messages not allowed in e2ee rooms', () => { test.skip(!IS_EE, 'Premium Only'); let poHomeChannel: HomeChannel; + let createE2EEChannel: CreateE2EEChannel; test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); + createE2EEChannel = new CreateE2EEChannel(page); await page.goto('/home'); }); @@ -79,7 +90,7 @@ test.describe('E2EE Server Settings', () => { test('expect slash commands to be disabled in an e2ee room', async ({ page }) => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.createEncryptedChannel(channelName); + await createE2EEChannel.createAndStore(channelName, createdChannels); await expect(page).toHaveURL(`/group/${channelName}`); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/e2ee.ts b/apps/meteor/tests/e2e/page-objects/fragments/e2ee.ts index 151915016bbc2..25dcaf9834447 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/e2ee.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/e2ee.ts @@ -1,9 +1,11 @@ import type { Locator, Page } from '@playwright/test'; +import { LoginPage } from '../login'; +import { HomeSidenav } from './home-sidenav'; import { Modal } from './modal'; import { ToastMessages } from './toast-messages'; +import { resolvePrivateRoomId } from '../../utils/resolve-room-id'; import { expect } from '../../utils/test'; -import { LoginPage } from '../login'; abstract class E2EEBanner { constructor(protected root: Locator) {} @@ -152,3 +154,37 @@ export class DisableRoomEncryptionModal extends Modal { await this.toastMessages.dismissToast('success'); } } +export class CreateE2EEChannel { + private readonly page: Page; + + private readonly sidenav: HomeSidenav; + + constructor(page: Page) { + this.page = page; + this.sidenav = new HomeSidenav(page); + } + + async create(name: string): Promise { + await this.sidenav.createEncryptedChannel(name); + const id = await resolvePrivateRoomId(this.page, name); + await expect(id, `Failed to resolve roomId for ${name}`).toBeTruthy(); + return id || ''; + } + + async storeChannel(name: string, id: string, createdChannels: { name: string; id?: string | null }[]): Promise { + createdChannels.push({ name, id }); + } + + async createAndStore(name: string, createdChannels: { name: string; id?: string | null }[]): Promise { + const id = await this.create(name); + await this.storeChannel(name, id, createdChannels); + return id; + } + + async resolveAndStore(name: string, createdChannels: { name: string; id?: string | null }[]): Promise { + const id = await resolvePrivateRoomId(this.page, name); + await expect(id, `Failed to resolve roomId for ${name}`).toBeTruthy(); + await this.storeChannel(name, id || '', createdChannels); + return id || ''; + } +} diff --git a/apps/meteor/tests/e2e/utils/resolve-room-id.ts b/apps/meteor/tests/e2e/utils/resolve-room-id.ts new file mode 100644 index 0000000000000..0359072df32e0 --- /dev/null +++ b/apps/meteor/tests/e2e/utils/resolve-room-id.ts @@ -0,0 +1,50 @@ +import type { Page } from '@playwright/test'; + +export type RoomType = 'c' | 'p' | 'd'; + +/** + * Resolves room ID from room name using the Meteor method getRoomByTypeAndName. + * This is necessary for E2E encrypted rooms as it uses the room coordinator system + * which has specialized logic that the REST API endpoints don't have. + */ +export async function resolveRoomId(page: Page, type: RoomType, name: string): Promise { + return page.evaluate( + async ({ roomType, roomName }: { roomType: RoomType; roomName: string }) => { + // Type-safe access to Meteor + const windowWithMeteor = window as unknown as { Meteor?: { call?: (method: string, ...args: unknown[]) => void } }; + const meteor = windowWithMeteor.Meteor; + + if (!meteor?.call || typeof meteor.call !== 'function') { + return null; + } + + const meteorCall = meteor.call; + + // Promisify the Meteor method call + return new Promise((resolve) => { + meteorCall('getRoomByTypeAndName', roomType, roomName, (error: unknown, room: { _id?: string } | null) => { + if (error || !room?._id) { + resolve(null); + return; + } + resolve(room._id); + }); + }); + }, + { roomType: type, roomName: name }, + ); +} + +/** + * Resolves private room (group) ID by name - for E2E encrypted channels + */ +export function resolvePrivateRoomId(page: Page, name: string): Promise { + return resolveRoomId(page, 'p', name); +} + +/** + * Resolves channel ID by name + */ +export function resolveChannelRoomId(page: Page, name: string): Promise { + return resolveRoomId(page, 'c', name); +}