diff --git a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx index d01680eb3254..9453ecde0665 100644 --- a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx +++ b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx @@ -176,7 +176,7 @@ const CurrentChatsPage = ({ id, onRowClick }: { id?: string; onRowClick: (_id: s }; return ( - onRowClick(_id)} action> + onRowClick(_id)} action data-qa-id={fname}> {isPriorityEnabled && ( diff --git a/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx b/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx index a8c8ffc46764..41ba0bb6bf18 100644 --- a/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx +++ b/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx @@ -98,7 +98,14 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu }; setModal( - , + , ); }); @@ -114,8 +121,17 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu - - @@ -140,7 +156,7 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu {CurrentChatTags && ( - + diff --git a/apps/meteor/client/views/omnichannel/currentChats/RemoveChatButton.tsx b/apps/meteor/client/views/omnichannel/currentChats/RemoveChatButton.tsx index 915ec35e634a..7b82a969c4db 100644 --- a/apps/meteor/client/views/omnichannel/currentChats/RemoveChatButton.tsx +++ b/apps/meteor/client/views/omnichannel/currentChats/RemoveChatButton.tsx @@ -35,7 +35,14 @@ const RemoveChatButton: FC<{ _id: string }> = ({ _id }) => { }; setModal( - , + , ); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts index 85c523c20663..e77484cbd4f2 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts @@ -49,7 +49,7 @@ test.describe('Omnichannel close inquiry', () => { await test.step('Expect to have 1 omnichannel assigned to agent 1', async () => { await agent.poHomeOmnichannel.sidenav.openQueuedOmnichannelChat(newUser.name); - await expect(agent.poHomeOmnichannel.content.takeOmnichannelChatButton).toBeVisible(); + await expect(agent.poHomeOmnichannel.content.btnTakeChat).toBeVisible(); }); await test.step('Expect to be able to close an inquiry conversation', async () => { @@ -62,8 +62,8 @@ test.describe('Omnichannel close inquiry', () => { await test.step('Expect to inquiry be closed when navigate back', async () => { await agent.poHomeOmnichannel.sidenav.openAdministrationByLabel('Omnichannel'); await agent.poHomeOmnichannel.omnisidenav.linkCurrentChats.click(); - await agent.poHomeOmnichannel.currentChats.openChat(newUser.name); - await expect(agent.poHomeOmnichannel.content.takeOmnichannelChatButton).not.toBeVisible(); + await agent.poHomeOmnichannel.currentChats.findRowByName(newUser.name).click(); + await expect(agent.poHomeOmnichannel.content.btnTakeChat).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts index 8138ab839b75..a3d105136efe 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts @@ -1,15 +1,326 @@ +import { faker } from '@faker-js/faker'; +import { Page } from '@playwright/test'; + +import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; +import { OmnichannelCurrentChats } from '../page-objects'; +import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; +import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; +import { createConversation, updateRoom } from '../utils/omnichannel/rooms'; +import { createTag } from '../utils/omnichannel/tags'; import { test, expect } from '../utils/test'; +const visitorA = faker.person.firstName(); +const visitorB = faker.person.firstName(); +const visitorC = faker.person.firstName(); + +test.skip(!IS_EE, 'OC - Current Chats > Enterprise Only'); + test.use({ storageState: Users.admin.state }); -test.describe.parallel('Omnichannel current chats', () => { - test.beforeEach(async ({ page }) =>{ - await page.goto('/omnichannel/current') - }) +test.describe('OC - Current Chats [Auto Selection]', async () => { + let poCurrentChats: OmnichannelCurrentChats; + let departments: Awaited>[]; + let conversations: Awaited>[]; + let agents: Awaited>[]; + + // Allow manual on hold + test.beforeAll(async ({ api }) => { + const responses = await Promise.all([ + api.post('/settings/Livechat_allow_manual_on_hold', { value: true }), + api.post('/settings/Livechat_allow_manual_on_hold_upon_agent_engagement_only', { value: false }), + ]); + responses.forEach((res) => expect(res.status()).toBe(200)); + }); + + // Create departments + test.beforeAll(async ({ api }) => { + departments = await Promise.all([createDepartment(api), createDepartment(api)]); + }); + + // Create agents + test.beforeAll(async ({ api }) => { + agents = await Promise.all([createAgent(api, 'user1'), createAgent(api, 'user2')]); + + const agentsStatuses = await Promise.all(agents.map(({ data: agent }) => makeAgentAvailable(api, agent._id))); + + agentsStatuses.forEach((res) => expect(res.status()).toBe(200)); + }); + + // Add agents to departments + test.beforeAll(async ({ api }) => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + + const promises = await Promise.all([ + addAgentToDepartment(api, { department: departmentA, agentId: 'user1' }), + addAgentToDepartment(api, { department: departmentB, agentId: 'user2' }), + ]); + + promises.forEach((res) => expect(res.status()).toBe(200)); + }); + + // Create tags + test.beforeAll(async ({ api }) => { + const promises = await Promise.all([createTag(api, 'tagA'), createTag(api, 'tagB')]); + + promises.forEach((res) => expect(res.status()).toBe(200)); + }); + + // Create rooms + test.beforeAll(async ({ api }) => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + + conversations = await Promise.all([ + createConversation(api, { + visitorName: visitorA, + visitorToken: visitorA, + agentId: `user1`, + departmentId: departmentA._id, + }), + createConversation(api, { + visitorName: visitorB, + visitorToken: visitorB, + agentId: `user2`, + departmentId: departmentB._id, + }), + createConversation(api, { + visitorName: visitorC, + visitorToken: visitorC, + }), + ]); + + const [conversationA, conversationB] = conversations.map(({ data }) => data); + + await Promise.all([ + updateRoom(api, { + roomId: conversationA.room._id, + visitorId: conversationA.visitor._id, + tags: ['tagA'], + }), + updateRoom(api, { + roomId: conversationB.room._id, + visitorId: conversationB.visitor._id, + tags: ['tagB'], + }), + ]); + }); + + test.beforeEach(async ({ page }: { page: Page }) => { + poCurrentChats = new OmnichannelCurrentChats(page); + + await page.goto('/omnichannel'); + await poCurrentChats.sidenav.linkCurrentChats.click(); + }); + + test.afterAll(async ({ api }) => { + await Promise.all([ + // Delete conversations + ...conversations.map((conversation) => conversation.delete()), + // // Delete departments + ...departments.map((department) => department.delete()), + // Delete agents + ...agents.map((agent) => agent.delete()), + // Reset setting + api.post('/settings/Livechat_allow_manual_on_hold', { value: false }), + api.post('/settings/Livechat_allow_manual_on_hold_upon_agent_engagement_only', { value: true }), + // TODO: remove tags + ]); + }); + + // Change conversation A to on hold and close conversation B + test.beforeAll(async ({ api }) => { + const [conversationA, , conversationC] = conversations.map(({ data }) => data); + + const statesPromises = await Promise.all([ + api.post('/livechat/room.onHold', { roomId: conversationA.room._id }), + api.post('/livechat/room.close', { rid: conversationC.room._id, token: visitorC }), + ]); + + statesPromises.forEach((res) => expect(res.status()).toBe(200)); + }); + + test.skip('OC - Current chats - Accessibility violations', async ({ makeAxeBuilder }) => { + const results = await makeAxeBuilder().analyze(); + expect(results.violations).toEqual([]); + }); + + test('OC - Current chats - Filters', async () => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + + await test.step('expect to filter by guest', async () => { + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + + await poCurrentChats.inputGuest.fill(visitorA); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + + await poCurrentChats.inputGuest.fill(''); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step('expect to filter by server', async () => { + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + + await poCurrentChats.selectServedBy('user1'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + + await poCurrentChats.selectServedBy('user2'); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorA)).not.toBeVisible(); + + await poCurrentChats.selectServedBy('all'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step('expect to filter by status', async () => { + await poCurrentChats.selectStatus('closed'); + await expect(poCurrentChats.findRowByName(visitorA)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).toBeVisible(); + + await poCurrentChats.selectStatus('opened'); + await expect(poCurrentChats.findRowByName(visitorA)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).not.toBeVisible(); + + await poCurrentChats.selectStatus('onhold'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).not.toBeVisible(); + + await poCurrentChats.selectStatus('all'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).toBeVisible(); + }); + + await test.step('expect to filter by department', async () => { + await poCurrentChats.selectDepartment(departmentA.name); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).not.toBeVisible(); + + await poCurrentChats.selectDepartment(departmentB.name); + await expect(poCurrentChats.findRowByName(visitorA)).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).not.toBeVisible(); + + await poCurrentChats.selectDepartment('All'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).toBeVisible(); + }); + + await test.step('expect to filter by tags', async () => { + await poCurrentChats.addTag('tagA'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).not.toBeVisible(); + + await poCurrentChats.addTag('tagB'); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + + await poCurrentChats.removeTag('tagA'); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorA)).not.toBeVisible(); + + await poCurrentChats.removeTag('tagB'); + await expect(poCurrentChats.findRowByName(visitorB)).toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorA)).toBeVisible(); + }); + + // TODO: Unit test await test.step('expect to filter by period', async () => {}); + + // TODO: Unit test await test.step('expect to filter by custom fields', async () => {}); + + // TODO: Unit test await test.step('expect to filter clear all', async () => {}); + }); + + test('OC - Current chats - Basic navigation', async ({ page }) => { + await test.step('expect to be return using return button', async () => { + const { room: roomA } = conversations[0].data; + await poCurrentChats.findRowByName(visitorA).click(); + await expect(page).toHaveURL(`/omnichannel/current/${roomA._id}`); + await poCurrentChats.content.btnReturn.click(); + await expect(page).toHaveURL(`/omnichannel/current`); + }); + }); + + test('OC - Current chats - Access in progress conversation from another agent', async ({ page }) => { + await test.step('expect to be able to join', async () => { + const { room: roomB, visitor: visitorB } = conversations[1].data; + await poCurrentChats.findRowByName(visitorB.name).click(); + await expect(page).toHaveURL(`/omnichannel/current/${roomB._id}`); + await expect(poCurrentChats.content.btnJoinRoom).toBeVisible(); + await poCurrentChats.content.btnJoinRoom.click(); + await expect(poCurrentChats.content.btnJoinRoom).not.toBeVisible(); + }); + }); + + test('OC - Current chats - Remove conversations', async () => { + await test.step('expect to be able to remove conversation from table', async () => { + await poCurrentChats.btnRemoveByName(visitorC).click(); + await expect(poCurrentChats.modalConfirmRemove).toBeVisible(); + await poCurrentChats.btnConfirmRemove.click(); + await expect(poCurrentChats.modalConfirmRemove).not.toBeVisible(); + await expect(poCurrentChats.findRowByName(visitorC)).not.toBeVisible(); + }); + + // TODO: await test.step('expect to be able to close all closes conversations', async () => {}); + }); +}); + +test.describe('OC - Current Chats [Manual Selection]', () => { + let queuedConversation: Awaited>; + let poCurrentChats: OmnichannelCurrentChats; + let agent: Awaited>; + + test.beforeAll(async ({ api }) => { + const res = await api.post('/settings/Livechat_Routing_Method', { value: 'Manual_Selection' }); + expect(res.status()).toBe(200); + }); + + test.beforeAll(async ({ api }) => { + agent = await createAgent(api, 'rocketchat.internal.admin.test'); + + const agentStatus = await makeAgentAvailable(api, agent.data._id); + + expect(agentStatus.status()).toBe(200); + }); + + test.beforeEach(async ({ page }: { page: Page }) => { + poCurrentChats = new OmnichannelCurrentChats(page); + + await page.goto('/omnichannel'); + await poCurrentChats.sidenav.linkCurrentChats.click(); + }); + + test('OC - Current chats - Access queued conversation', async ({ page, api }) => { + queuedConversation = await createConversation(api, { visitorToken: 'visitorQueued' }); + + await test.step('expect to be able to take it', async () => { + const { room, visitor } = queuedConversation.data; + await poCurrentChats.inputGuest.fill(visitor.name); + await poCurrentChats.findRowByName(visitor.name).click(); + await expect(page).toHaveURL(`/omnichannel/current/${room._id}`); + await expect(poCurrentChats.content.btnTakeChat).toBeVisible(); + await poCurrentChats.content.btnTakeChat.click(); + await expect(poCurrentChats.content.btnTakeChat).not.toBeVisible(); + }); + }); + + test.afterAll(async ({ api }) => { + const res = await api.post('/settings/Livechat_Routing_Method', { value: 'Auto_Selection' }); + expect(res.status()).toBe(200); + }); - test.skip('should not have any accessibility violations', async ({ makeAxeBuilder }) => { - const results = await makeAxeBuilder().analyze(); - expect(results.violations).toEqual([]); - }) -}) + test.afterAll(async () => { + await queuedConversation.delete(); + await agent.delete(); + }); +}); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities-sidebar.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities-sidebar.spec.ts index d1572f7b5ce7..f9550ebbac0e 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities-sidebar.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities-sidebar.spec.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { HomeChannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; import { OmnichannelRoomInfo } from '../page-objects/omnichannel-room-info'; import { createConversation } from '../utils/omnichannel/rooms'; import { test, expect } from '../utils/test'; @@ -20,7 +20,7 @@ test.skip(!IS_EE, 'Omnichannel Priorities > Enterprise Only'); test.use({ storageState: Users.user1.state }); test.describe.serial('OC - Priorities [Sidebar]', () => { - let poHomeChannel: HomeChannel; + let poHomeChannel: HomeOmnichannel; let poRoomInfo: OmnichannelRoomInfo; test.beforeAll(async ({ api }) => { @@ -34,7 +34,7 @@ test.describe.serial('OC - Priorities [Sidebar]', () => { }); test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); + poHomeChannel = new HomeOmnichannel(page); poRoomInfo = new OmnichannelRoomInfo(page); }); @@ -82,7 +82,7 @@ test.describe.serial('OC - Priorities [Sidebar]', () => { }); await test.step('expect to change subscription priority using sidebar menu', async () => { - await poHomeChannel.content.takeOmnichannelChatButton.click(); + await poHomeChannel.content.btnTakeChat.click(); await systemMessage.locator('text="joined the channel"').waitFor(); await page.waitForTimeout(500); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts index 4738158ca23c..90087d968bec 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts @@ -3,14 +3,14 @@ import type { Page } from '@playwright/test'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; import { test, expect } from '../utils/test'; test.describe('omnichannel-takeChat', () => { let poLiveChat: OmnichannelLiveChat; let newVisitor: { email: string; name: string }; - let agent: { page: Page; poHomeChannel: HomeChannel }; + let agent: { page: Page; poHomeChannel: HomeOmnichannel }; test.beforeAll(async ({ api, browser }) => { await Promise.all([ @@ -20,7 +20,7 @@ test.describe('omnichannel-takeChat', () => { ]); const { page } = await createAuxContext(browser, Users.user1); - agent = { page, poHomeChannel: new HomeChannel(page) }; + agent = { page, poHomeChannel: new HomeOmnichannel(page) }; }); test.afterAll(async ({ api }) => { @@ -52,11 +52,11 @@ test.describe('omnichannel-takeChat', () => { test('expect "user1" to be able to take the chat from the queue', async () => { await agent.poHomeChannel.sidenav.openQueuedOmnichannelChat(newVisitor.name); - await expect(agent.poHomeChannel.content.takeOmnichannelChatButton).toBeVisible(); - await agent.poHomeChannel.content.takeOmnichannelChatButton.click(); + await expect(agent.poHomeChannel.content.btnTakeChat).toBeVisible(); + await agent.poHomeChannel.content.btnTakeChat.click(); await agent.poHomeChannel.sidenav.openChat(newVisitor.name); - await expect(agent.poHomeChannel.content.takeOmnichannelChatButton).not.toBeVisible(); + await expect(agent.poHomeChannel.content.btnTakeChat).not.toBeVisible(); await expect(agent.poHomeChannel.content.inputMessage).toBeVisible(); }); @@ -65,8 +65,8 @@ test.describe('omnichannel-takeChat', () => { await agent.poHomeChannel.sidenav.switchStatus('offline'); await agent.poHomeChannel.sidenav.openQueuedOmnichannelChat(newVisitor.name); - await expect(agent.poHomeChannel.content.takeOmnichannelChatButton).toBeVisible(); - await agent.poHomeChannel.content.takeOmnichannelChatButton.click(); + await expect(agent.poHomeChannel.content.btnTakeChat).toBeVisible(); + await agent.poHomeChannel.content.btnTakeChat.click(); // expect to see error message await expect(agent.page.locator('text=Agent status is offline or Omnichannel service is not active')).toBeVisible(); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index 2ba8cd6428d9..9ebc8cfcdb10 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -245,10 +245,6 @@ export class HomeContent { await this.page.locator('//main//aside >> [name="alsoSendThreadToChannel"]').setChecked(isChecked); } - get takeOmnichannelChatButton(): Locator { - return this.page.locator('role=button[name="Take it!"]'); - } - get lastSystemMessageBody(): Locator { return this.page.locator('[data-qa-type="system-message-body"]').last(); } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts index 307f94273d32..cfe2e1081c5b 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts @@ -11,6 +11,10 @@ export class HomeOmnichannelContent extends HomeContent { this.omnichannelCloseChatModal = new OmnichannelCloseChatModal(page); } + get btnTakeChat(): Locator { + return this.page.locator('role=button[name="Take it!"]'); + } + get inputMessage(): Locator { return this.page.locator('[name="msg"]'); } @@ -22,4 +26,24 @@ export class HomeOmnichannelContent extends HomeContent { get btnCloseChat(): Locator { return this.page.locator('[data-qa-id="ToolBoxAction-balloon-close-top-right"]'); } + + get btnReturn(): Locator { + return this.page.locator('[data-qa-id="ToolBoxAction-back"]'); + } + + get btnResume(): Locator { + return this.page.locator('role=button[name="Resume"]'); + } + + get modalOnHold(): Locator { + return this.page.locator('[data-qa-id="on-hold-modal"]'); + } + + get btnEditRoomInfo(): Locator { + return this.page.locator('button[data-qa-id="room-info-edit"]'); + } + + get btnOnHoldConfirm(): Locator { + return this.modalOnHold.locator('role=button[name="Place chat On-Hold"]'); + } } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-current-chats.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-current-chats.ts index b353285897a1..46773e0ca43a 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-current-chats.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-current-chats.ts @@ -1,110 +1,112 @@ import type { Locator, Page } from '@playwright/test'; -import { OmnichannelSidenav } from './fragments'; +import { HomeOmnichannelContent } from './fragments'; +import { OmnichannelAdministration } from './omnichannel-administration'; -export class OmnichannelCurrentChats { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; +export class OmnichannelCurrentChats extends OmnichannelAdministration { + readonly content: HomeOmnichannelContent; constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - } - - get btnToastClose(): Locator { - return this.page.locator('.rcx-toastbar').locator('button'); - } - - get currentChatsLink(): Locator { - return this.page.locator('a[href="omnichannel/current"]'); + super(page); + this.content = new HomeOmnichannelContent(page); } - get guestField(): Locator { + get inputGuest(): Locator { return this.page.locator('[data-qa="current-chats-guest"]'); } - get servedByField(): Locator { - return this.page.locator('[data-qa="autocomplete-agent"]'); + get inputServedBy(): Locator { + return this.page.locator('[data-qa="autocomplete-agent"] input'); } - get statusField(): Locator { + get inputStatus(): Locator { return this.page.locator('[data-qa="current-chats-status"]'); } - get fromField(): Locator { + get inputFrom(): Locator { return this.page.locator('[data-qa="current-chats-from"]'); } - get toField(): Locator { + get inputTo(): Locator { return this.page.locator('[data-qa="current-chats-to"]'); } - get departmentField(): Locator { - return this.page.locator('[data-qa="autocomplete-department"]'); + get inputDepartment(): Locator { + return this.page.locator('[data-qa="autocomplete-department"] input'); } - get tagsField(): Locator { - return this.page.locator('[data-qa="current-chats-tags"]'); + get inputTags(): Locator { + return this.page.locator('[data-qa="current-chats-tags"] [role="listbox"]'); } - get formOptions(): Locator { + get btnFilterOptions(): Locator { return this.page.locator('[data-qa="current-chats-options"]'); } - get clearFiltersOption(): Locator { + get optionClearFilter(): Locator { return this.page.locator('[data-qa="current-chats-options-clearFilters"]'); } - get removeAllClosedOption(): Locator { + get optionRemoveAllClosed(): Locator { return this.page.locator('[data-qa="current-chats-options-removeAllClosed"]'); } - get customFieldsOption(): Locator { - return this.page.locator('[data-qa="current-chats-options-customFields"]'); + get modalConfirmRemove(): Locator { + return this.page.locator('[data-qa-id="current-chats-modal-remove"]'); + } + + get modalConfirmRemoveAllClosed(): Locator { + return this.page.locator('[data-qa-id="current-chats-modal-remove-all-closed"]'); } - get table(): Locator { - return this.page.locator('.rcx-table'); + get btnConfirmRemove(): Locator { + return this.modalConfirmRemove.locator('role=button[name="Delete"]'); } - get tableHeaderName(): Locator { - return this.page.locator('[data-qa="current-chats-header-name"]'); + get btnConfirmRemoveAllClosed(): Locator { + return this.modalConfirmRemoveAllClosed.locator('role=button[name="Delete"]'); } - get tableHeaderDepartment(): Locator { - return this.page.locator('[data-qa="current-chats-header-department"]'); + get optionCustomFields(): Locator { + return this.page.locator('[data-qa="current-chats-options-customFields"]'); } - get tableHeaderServedBy(): Locator { - return this.page.locator('[data-qa="current-chats-header-servedBy"]'); + async selectServedBy(option: string) { + await this.inputServedBy.click(); + await this.inputServedBy.fill(option); + await this.page.locator(`[role='option'][value='${option}']`).click(); } - get tableHeaderStartedAt(): Locator { - return this.page.locator('[data-qa="current-chats-header-startedAt"]'); + async addTag(option: string) { + await this.inputTags.click(); + await this.page.locator(`[role='option'][value='${option}']`).click(); + await this.inputTags.click(); } - get tableHeaderLastMessage(): Locator { - return this.page.locator('[data-qa="current-chats-header-lastMessage"]'); + async removeTag(option: string) { + await this.page.locator(`role=option[name='${option}']`).click(); } - get tableHeaderStatus(): Locator { - return this.page.locator('[data-qa="current-chats-header-status"]'); + async selectDepartment(option: string) { + await this.inputDepartment.click(); + await this.inputDepartment.fill(option); + await this.page.locator(`role=option[name='${option}']`).click(); } - get tableHeaderRemove(): Locator { - return this.page.locator('[data-qa="current-chats-header-remove"]'); + async selectStatus(option: string) { + await this.inputStatus.click(); + await this.page.locator(`[role='option'][data-key='${option}']`).click(); } - get tableHeader(): Locator { - return this.page.locator('[data-qa=""]'); + btnRemoveByName(name: string): Locator { + return this.findRowByName(name).locator('role=button[name="Remove"]'); } - async openChat(name: string): Promise { - return this.page.locator(`table >> text="${name}"`).click(); + findRowByName(name: string) { + return this.page.locator(`tr[data-qa-id="${name}"]`); } - async doOpenOptions(): Promise { - await this.formOptions.click(); + findRowByServer(name: string) { + return this.page.locator('tr', { has: this.page.locator(`[data-qa="current-chats-cell-servedBy"] >> text=${name}`) }); } }