diff --git a/apps/meteor/tests/e2e/file-upload.spec.ts b/apps/meteor/tests/e2e/file-upload.spec.ts index 815a1cd583f95..255ae2d229a6a 100644 --- a/apps/meteor/tests/e2e/file-upload.spec.ts +++ b/apps/meteor/tests/e2e/file-upload.spec.ts @@ -3,7 +3,26 @@ import { HomeChannel } from './page-objects'; import { FileUploadWarningModal } from './page-objects/fragments/modals'; import { createTargetChannel } from './utils'; import { setSettingValueById } from './utils/setSettingValueById'; -import { expect, test } from './utils/test'; +import { expect, test as baseTest } from './utils/test'; + +type FileUploadFixtures = { + targetChannel: string; + poHomeChannel: HomeChannel; +}; + +const test = baseTest.extend({ + targetChannel: async ({ api }, use) => { + const channel = await createTargetChannel(api, { members: ['user1'] }); + await use(channel); + await api.post('/channels.delete', { roomName: channel }); + }, + poHomeChannel: async ({ page, targetChannel }, use) => { + const poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + await poHomeChannel.navbar.openChat(targetChannel); + await use(poHomeChannel); + }, +}); test.use({ storageState: Users.user1.state }); @@ -12,136 +31,59 @@ const TEST_FILE_LST = 'lst-test.lst'; const TEST_FILE_DRAWIO = 'diagram.drawio'; const TEST_EMPTY_FILE = 'empty_file.txt'; -test.describe.serial('file-upload', () => { - let poHomeChannel: HomeChannel; - let targetChannel: string; - +test.describe('file-upload', () => { test.beforeAll(async ({ api }) => { await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'image/svg+xml'); - targetChannel = await createTargetChannel(api, { members: ['user1'] }); - }); - - test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); - - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); - }); - - test.afterAll(async ({ api }) => { - await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'image/svg+xml'); - expect((await api.post('/channels.delete', { roomName: targetChannel })).status()).toBe(200); - }); - - test('should cancel uploaded file attached to message composer', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.composer.removeFileByName(TEST_FILE_TXT); - - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); }); - test('should send file with name updated', async () => { - const updatedFileName = `edited_${TEST_FILE_TXT}`; - await poHomeChannel.content.dragAndDropTxtFile(); + test('Standard File Upload Operations', async ({ page, poHomeChannel, context }) => { + await test.step('should cancel uploaded file attached to message composer', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.composer.removeFileByName(TEST_FILE_TXT); + await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); + }); await test.step('update file name and send', async () => { + const updatedFileName = `edited_${TEST_FILE_TXT}`; + await poHomeChannel.content.dragAndDropTxtFile(); await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click(); await poHomeChannel.content.inputFileUploadName.fill(updatedFileName); await poHomeChannel.content.btnUpdateFileUpload.click(); - await expect(poHomeChannel.composer.getFileByName(updatedFileName)).toBeVisible(); await poHomeChannel.composer.btnSend.click(); + await expect(poHomeChannel.content.getLastMessageByFileName(updatedFileName)).toContainText(updatedFileName); }); - await expect(poHomeChannel.content.getLastMessageByFileName(updatedFileName)).toContainText(updatedFileName); - }); - - test('should attach multiple files and send one per message', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.dragAndDropLstFile(); - - await expect(poHomeChannel.composer.inputMessage).toBeFocused(); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).toBeVisible(); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_LST)).toBeVisible(); - - await poHomeChannel.composer.btnSend.click(); - await expect(poHomeChannel.content.lastUserMessageDownloadLink).toHaveCount(1); - }); - - test('should not be able to attach files when editing a message', async () => { - await poHomeChannel.content.sendMessage('message to be edited'); - await poHomeChannel.content.openLastMessageMenu(); - await poHomeChannel.content.btnOptionEditMessage.click(); - - await poHomeChannel.content.dragAndDropTxtFile({ waitForResponse: false }); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); - }); - - test('should send lst file successfully', async () => { - await poHomeChannel.content.dragAndDropLstFile(); - await poHomeChannel.composer.inputMessage.fill('lst_description'); - await poHomeChannel.composer.btnSend.click(); - - await expect(poHomeChannel.content.getFileDescription).toHaveText('lst_description'); - await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_LST)).toBeVisible(); - }); - - test('should send drawio (unknown media type) file successfully', async ({ page }) => { - await page.reload(); - await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO); - await poHomeChannel.composer.inputMessage.fill('drawio_description'); - await poHomeChannel.composer.btnSend.click(); - - await expect(poHomeChannel.content.getFileDescription).toHaveText('drawio_description'); - await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_DRAWIO)).toBeVisible(); - }); - - test('should not to send drawio file (unknown media type) when the default media type is blocked', async ({ api, page }) => { - await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'application/octet-stream'); - - await page.reload(); - await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO, { waitForResponse: false }); - - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).toHaveAttribute('readonly'); - }); - - test('should be able to remove file from composer before sending', async () => { - await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT); - await poHomeChannel.content.sendFileMessage(TEST_FILE_LST); - - await poHomeChannel.composer.removeFileByName(TEST_FILE_TXT); - - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_LST)).toBeVisible(); - - await poHomeChannel.composer.btnSend.click(); - - await expect(poHomeChannel.content.lastUserMessage).not.toContainText(TEST_FILE_TXT); - await expect(poHomeChannel.content.lastUserMessage).toContainText(TEST_FILE_LST); - }); + await test.step('should attach multiple files and send one per message', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.dragAndDropLstFile(); + await poHomeChannel.composer.btnSend.click(); - test('should respect the maximum number of files allowed per message: 10', async () => { - const files = new Array(10).fill('number1.png'); + await expect(poHomeChannel.content.lastUserMessageDownloadLink).toHaveCount(1); + }); - await Promise.all(files.map((file) => poHomeChannel.content.sendFileMessage(file))); - await poHomeChannel.content.dragAndDropTxtFile({ waitForResponse: false }); + await test.step('should not be able to attach files when editing a message', async () => { + await poHomeChannel.content.sendMessage('message to be edited'); + await poHomeChannel.content.openLastMessageMenu(); + await poHomeChannel.content.btnOptionEditMessage.click(); - await expect(poHomeChannel.composer.getFilesInComposer()).toHaveCount(10); - await expect(poHomeChannel.composer.getFileByName('any_file.txt')).not.toBeVisible(); - }); + await poHomeChannel.content.dragAndDropTxtFile({ waitForResponse: false }); + await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); - test('should upload file in composer after recording video message', async ({ context }) => { - await context.grantPermissions(['camera', 'microphone']); + await page.keyboard.press('Escape'); + await expect(poHomeChannel.composer.inputMessage).toBeVisible(); + }); - await poHomeChannel.navbar.openChat(targetChannel); - await poHomeChannel.composer.btnVideoMessage.click(); - await poHomeChannel.composer.videoRecorderPopup.record(); + await test.step('should upload file in composer after recording video message', async () => { + await context.grantPermissions(['camera', 'microphone']); + await poHomeChannel.composer.btnVideoMessage.click(); + await poHomeChannel.composer.videoRecorderPopup.record(); + await expect(poHomeChannel.composer.getFileByName('Video record.webm')).toBeVisible(); - await expect(poHomeChannel.composer.getFileByName('Video record.webm')).toBeVisible(); - }); + await poHomeChannel.composer.removeFileByName('Video record.webm'); + }); - test.describe.serial('thread multiple file upload', () => { - test('should be able to remove file from thread composer before sending', async () => { + await test.step('should be able to remove file from thread composer before sending', async () => { await poHomeChannel.content.sendMessage('this is a message for thread reply'); await poHomeChannel.content.openReplyInThread(); await poHomeChannel.content.sendFileMessageToThread(TEST_FILE_TXT); @@ -153,93 +95,46 @@ test.describe.serial('file-upload', () => { await expect(poHomeChannel.threadComposer.getFileByName(TEST_FILE_LST)).not.toBeVisible(); }); }); +}); - test.describe.serial('file upload fails', () => { - let fileUploadWarningModal: FileUploadWarningModal; +test.describe('file upload fails', () => { + let fileUploadWarningModal: FileUploadWarningModal; - test.beforeAll(async ({ api }) => { - await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'application/octet-stream'); - }); + test.beforeAll(async ({ api }) => { + await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'application/octet-stream'); + }); - test.afterAll(async ({ api }) => { - await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'image/svg+xml'); - }); + test.afterAll(async ({ api }) => { + await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'image/svg+xml'); + }); - test('should open warning modal when all file uploads fail', async ({ page }) => { - fileUploadWarningModal = new FileUploadWarningModal(page.getByRole('dialog', { name: 'Warning' })); + test('File Rejection & Warning Modal Journey', async ({ page, poHomeChannel }) => { + fileUploadWarningModal = new FileUploadWarningModal(page.getByRole('dialog')); - await poHomeChannel.content.sendFileMessage(TEST_EMPTY_FILE, { waitForResponse: false }); + await test.step('should not send drawio file when media type is blocked', async () => { await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO, { waitForResponse: false }); - await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toHaveAttribute('readonly'); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).toHaveAttribute('readonly'); - - await poHomeChannel.composer.btnSend.click(); - await fileUploadWarningModal.waitForDisplay(); - - await expect(fileUploadWarningModal.getContent('2 files failed to upload')).toBeVisible(); - await expect(fileUploadWarningModal.btnOk).toBeVisible(); - await expect(fileUploadWarningModal.btnSendAnyway).not.toBeVisible(); + await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).toHaveAttribute('readonly', ''); + await poHomeChannel.composer.removeFileByName(TEST_FILE_DRAWIO); + await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).not.toBeVisible(); }); - test('should handle multiple files with one failing upload', async ({ page }) => { - fileUploadWarningModal = new FileUploadWarningModal(page.getByRole('dialog', { name: 'Are you sure' })); - - await test.step('should only mark as "Upload failed" the specific file that failed to upload', async () => { - await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT, { waitForResponse: false }); - await poHomeChannel.content.sendFileMessage(TEST_EMPTY_FILE, { waitForResponse: false }); - - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toHaveAttribute('readonly'); - await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toHaveAttribute('readonly'); - }); - - await test.step('should open warning modal', async () => { - await poHomeChannel.composer.btnSend.click(); - await fileUploadWarningModal.waitForDisplay(); - - await expect(fileUploadWarningModal.getContent('1 file failed to upload')).toBeVisible(); - }); + await test.step('should handle multiple files with one failing upload', async () => { + await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT, { waitForResponse: false }); + await poHomeChannel.content.sendFileMessage(TEST_EMPTY_FILE, { waitForResponse: false }); - await test.step('should close modal when clicking "Cancel" button', async () => { - await fileUploadWarningModal.cancel(); + await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toHaveAttribute('readonly'); + await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toHaveAttribute('readonly', ''); - await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toBeVisible(); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).toBeVisible(); - }); + await poHomeChannel.composer.btnSend.click(); - await test.step('should send message with the valid file when confirming "Send anyway"', async () => { - await poHomeChannel.composer.btnSend.click(); - await fileUploadWarningModal.confirmSend(); + await fileUploadWarningModal.waitForDisplay(); + await expect(fileUploadWarningModal.getContent('1 file failed to upload')).toBeVisible(); + await fileUploadWarningModal.cancel(); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); - await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_TXT)).toContainText(TEST_FILE_TXT); - await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).not.toBeVisible(); - }); + await poHomeChannel.composer.btnSend.click(); + await fileUploadWarningModal.confirmSend(); + await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_TXT)).toContainText(TEST_FILE_TXT); }); }); }); - -test.describe('file-upload-not-member', () => { - let poHomeChannel: HomeChannel; - let targetChannel: string; - - test.beforeAll(async ({ api }) => { - targetChannel = await createTargetChannel(api); - }); - - test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); - - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); - }); - - test.afterAll(async ({ api }) => { - expect((await api.post('/channels.delete', { roomName: targetChannel })).status()).toBe(200); - }); - - test('should not be able to upload if not a member', async () => { - await poHomeChannel.content.dragAndDropTxtFile({ waitForResponse: false }); - await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible(); - }); -});