diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts new file mode 100644 index 0000000000000..1da41ba238f91 --- /dev/null +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts @@ -0,0 +1,124 @@ +import { faker } from '@faker-js/faker'; + +import { createAuxContext } from '../fixtures/createAuxContext'; +import { Users } from '../fixtures/userStates'; +import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { createAgent } from '../utils/omnichannel/agents'; +import { test, expect } from '../utils/test'; + +const visitor = { + name: `${faker.person.firstName()} ${faker.string.uuid()}}`, + email: faker.internet.email(), +} + +// Endpoint defaults are reset after each test, so if not in matrix assume is true +const endpointMatrix = [ + [{ url: '/settings/FileUpload_Enabled', value: false}], + [{ url: '/settings/Livechat_fileupload_enabled', value: false}], + [{ url: '/settings/FileUpload_Enabled', value: false}, { url: '/settings/Livechat_fileupload_enabled', value: false}], +] + +const beforeTest = async (poLiveChat: OmnichannelLiveChat) => { + await poLiveChat.page.goto('/livechat'); + + await poLiveChat.openAnyLiveChat(); + await poLiveChat.sendMessage(visitor, false); + await poLiveChat.onlineAgentMessage.fill('this_a_test_message_from_user'); + await poLiveChat.btnSendMessageToOnlineAgent.click(); + + await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({state: 'visible'}); +} + +test.describe('OC - Livechat - OC - File Upload', () => { + let poLiveChat: OmnichannelLiveChat; + let poHomeOmnichannel: HomeOmnichannel; + let agent: Awaited>; + + test.beforeAll(async ({ browser, api }) => { + agent = await createAgent(api, 'user1'); + + const { page } = await createAuxContext(browser, Users.user1, '/'); + poHomeOmnichannel = new HomeOmnichannel(page); + }); + + test.beforeEach(async ({ page, api }) => { + poLiveChat = new OmnichannelLiveChat(page, api); + }); + + test.afterAll(async ({api}) => { + await api.post('/settings/FileUpload_Enabled', { value: true }); + await api.post('/settings/Livechat_fileupload_enabled', { value: true }); + + await poHomeOmnichannel.page?.close(); + await agent.delete(); + }); + + // Default settings are FileUpload_Enabled true and Livechat_fileupload_enabled true + test('OC - Livechat - txt Drag & Drop', async () => { + await beforeTest(poLiveChat); + + await test.step('expect to upload a txt file', async () => { + await poLiveChat.dragAndDropTxtFile(); + await expect(poLiveChat.findUploadedFileLink('any_file.txt')).toBeVisible(); + }); + }); + + test('OC - Livechat - lst Drag & Drop', async () => { + await beforeTest(poLiveChat); + + await test.step('expect to upload a lst file', async () => { + await poLiveChat.dragAndDropLstFile(); + await expect(poLiveChat.findUploadedFileLink('lst-test.lst')).toBeVisible(); + }); + }); +}); + +test.describe('OC - Livechat - OC - File Upload - Disabled', () => { + let poLiveChat: OmnichannelLiveChat; + let poHomeOmnichannel: HomeOmnichannel; + let agent: Awaited>; + + test.beforeAll(async ({ browser, api }) => { + agent = await createAgent(api, 'user1'); + + const { page } = await createAuxContext(browser, Users.user1, '/'); + poHomeOmnichannel = new HomeOmnichannel(page); + }); + + test.afterAll(async ({api}) => { + await api.post('/settings/FileUpload_Enabled', { value: true }); + await api.post('/settings/Livechat_fileupload_enabled', { value: true }); + + await poHomeOmnichannel.page?.close(); + await agent.delete(); + }); + + endpointMatrix.forEach((endpoints) => { + const testName = endpoints.map((endpoint) => endpoint.url.split('/').pop()?.concat(`=${endpoint.value}`)).join(' '); + + test(`OC - Livechat - txt Drag & Drop - ${testName}`, async ({ page, api }) => { + test.fail(); + + poLiveChat = new OmnichannelLiveChat(page, api); + + await Promise.all(endpoints.map(async (endpoint: { url: string, value: boolean }) => { + await api.post(endpoint.url, { value: endpoint.value }); + })); + + await poLiveChat.page.goto('/livechat'); + + await poLiveChat.openAnyLiveChat(); + await poLiveChat.sendMessage(visitor, false); + await poLiveChat.onlineAgentMessage.fill('this_a_test_message_from_user'); + await poLiveChat.btnSendMessageToOnlineAgent.click(); + + await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({state: 'visible'}); + + await test.step('expect to upload a txt file', async () => { + await poLiveChat.dragAndDropTxtFile(); + + await expect(poLiveChat.alertMessage('file_upload_disabled')).toBeVisible(); + }); + }); + }); +}); diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts index c372dd6d85720..7099af127ee2d 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts @@ -1,3 +1,5 @@ +import fs from 'fs/promises'; + import type { Page, Locator, APIResponse } from '@playwright/test'; import { expect } from '../utils/test'; @@ -49,6 +51,10 @@ export class OmnichannelLiveChat { return this.page.locator('[data-qa="header-title"]'); } + alertMessage(message: string): Locator { + return this.page.getByRole('alert').locator(`text="${message}"`); + } + txtChatMessage(message: string): Locator { return this.page.locator(`text="${message}"`); } @@ -130,6 +136,14 @@ export class OmnichannelLiveChat { return this.page.locator('div.message-text__WwYco p'); } + get fileUploadTarget(): Locator { + return this.page.locator('#files-drop-target'); + } + + findUploadedFileLink (fileName: string): Locator { + return this.page.getByRole('link', { name: fileName }); + } + public async sendMessage(liveChatUser: { name: string; email: string }, isOffline = true, department?: string): Promise { const buttonLabel = isOffline ? 'Send' : 'Start chat'; await this.inputName.fill(liveChatUser.name); @@ -158,4 +172,36 @@ export class OmnichannelLiveChat { await expect(this.txtChatMessage(message)).toBeVisible(); await this.closeChat(); } + + async dragAndDropTxtFile(): Promise { + const contract = await fs.readFile('./tests/e2e/fixtures/files/any_file.txt', 'utf-8'); + const dataTransfer = await this.page.evaluateHandle((contract) => { + const data = new DataTransfer(); + const file = new File([`${contract}`], 'any_file.txt', { + type: 'text/plain', + }); + data.items.add(file); + return data; + }, contract); + + await this.fileUploadTarget.dispatchEvent('dragenter', { dataTransfer }); + + await this.fileUploadTarget.dispatchEvent('drop', { dataTransfer }); + } + + async dragAndDropLstFile(): Promise { + const contract = await fs.readFile('./tests/e2e/fixtures/files/lst-test.lst', 'utf-8'); + const dataTransfer = await this.page.evaluateHandle((contract) => { + const data = new DataTransfer(); + const file = new File([`${contract}`], 'lst-test.lst', { + type: 'text/plain', + }); + data.items.add(file); + return data; + }, contract); + + await this.fileUploadTarget.dispatchEvent('dragenter', { dataTransfer }); + + await this.fileUploadTarget.dispatchEvent('drop', { dataTransfer }); + } } diff --git a/packages/livechat/src/components/FilesDropTarget/index.tsx b/packages/livechat/src/components/FilesDropTarget/index.tsx index 10d5dcbb9ac81..7a4d0959d54cf 100644 --- a/packages/livechat/src/components/FilesDropTarget/index.tsx +++ b/packages/livechat/src/components/FilesDropTarget/index.tsx @@ -105,6 +105,7 @@ export const FilesDropTarget = ({ onDrop={handleDrop} className={createClassName(styles, 'drop', { overlayed, dragover: dragLevel > 0 }, [className])} style={style} + id='files-drop-target' >