From 5e24c658a384b6e1a2be2db6181ffd028f61bc5a Mon Sep 17 00:00:00 2001 From: Harmeet221 Date: Sun, 13 Oct 2024 17:51:20 +0530 Subject: [PATCH 1/2] Tests-Current-Chats-Filter --- ...omnichannel-contact-center-filters.spec.ts | 297 ++++++++++++++++++ .../page-objects/omnichannel-contacts-list.ts | 93 +++++- 2 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts new file mode 100644 index 000000000000..72c4b3bd3a19 --- /dev/null +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts @@ -0,0 +1,297 @@ +import { faker } from '@faker-js/faker'; + +import { IS_EE } from '../config/constants'; +import { Users } from '../fixtures/userStates'; +import { OmnichannelContacts } from '../page-objects/omnichannel-contacts-list'; +import { OmnichannelSection } from '../page-objects/omnichannel-section'; +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 URL = { + contactCenterChats: '/omnichannel-directory/chats', +}; + +const visitorA = faker.person.firstName(); +const visitorB = faker.person.firstName(); +const visitorC = faker.person.firstName(); + +test.skip(!IS_EE, 'OC - Contact center Filters > Enterprise Only'); + +test.use({ storageState: Users.admin.state }); + +test.describe('OC - Contact Center [Auto Selection]', async () => { + let departments: Awaited>[]; + let conversations: Awaited>[]; + let agents: Awaited>[]; + let tags: Awaited>[]; + let poContacts: OmnichannelContacts; + let poOmniSection: OmnichannelSection; + + // 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 }) => { + tags = await Promise.all([createTag(api, { name: 'tagA' }), createTag(api, { name: 'tagB' })]); + + tags.forEach((res) => expect(res.response.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.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()), + // Delete tags + ...tags.map((tag) => tag.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 }), + ]); + }); + + // 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.beforeEach(async ({ page }) => { + poContacts = new OmnichannelContacts(page); + poOmniSection = new OmnichannelSection(page); + + }); + + test.beforeEach(async ({ page }) => { + await page.goto('/'); + await poOmniSection.btnContactCenter.click(); + await poContacts.clickChats.click(); + await page.waitForURL(URL.contactCenterChats); + }); + + test('OC - Contact Center - Filters', async () => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + + await test.step('expect to filter by guest', async () => { + + await poContacts.inputSearch.fill(visitorA); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(visitorA); + + await poContacts.inputSearch.fill(''); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step('expect to filter by Served By', async () => { + + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + + await poContacts.clickFilters.click(); + + await poContacts.selectServedBy('user1'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.chipName).toContainText('user1'); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + + await poContacts.selectServedBy('user2'); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.chipName).toContainText('user2'); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + + await poContacts.selectServedBy('all'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step('expect to filter by status', async () => { + + await poContacts.selectStatus('closed'); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + await expect(poContacts.chipName).toContainText('closed'); + await poContacts.closeChip.click(); + + await poContacts.selectStatus('opened'); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText('opened'); + + await poContacts.selectStatus('onhold'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText('onhold'); + await poContacts.closeChip.click(); + + await poContacts.selectStatus('all'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + + }); + + await test.step('expect to filter by department', async () => { + + await poContacts.selectDepartment(departmentA.name); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(departmentA.name); + await poContacts.closeChip.click(); + + await poContacts.selectDepartment(departmentB.name); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(departmentB.name); + await poContacts.closeChip.click(); + + await poContacts.selectDepartment('All'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + }); + + await test.step('expect to filter by tags', async () => { + await poContacts.addTag('tagA'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + + await poContacts.addTag('tagB'); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + + await poContacts.removeTag('tagA'); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + + await poContacts.removeTag('tagB'); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + }); + + }); + + test('Clear all applied Filters', async ({ }) => { + const [departmentA] = departments.map(({ data }) => data); + + await test.step('expect to display result as per applied filters ', async () => { + + await poContacts.clickFilters.click(); + await poContacts.selectServedBy('user1'); + await poContacts.selectStatus('onhold'); + await poContacts.selectDepartment(departmentA.name); + await poContacts.addTag('tagA'); + + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + + }); + + await test.step('expect to clear all filters ', async () => { + + await poContacts.clearFilters.click(); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + + }); + }); + + test('Close contextual bar with filter screen', async ({ }) => { + + await test.step('expect to close filters contextual bar ', async () => { + await poContacts.close.click(); + + }); + }); +}); \ No newline at end of file diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts index f5d863590bfa..c89b9256cd0f 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts @@ -31,4 +31,95 @@ export class OmnichannelContacts { get toastSuccess(): Locator { return this.page.locator('.rcx-toastbar.rcx-toastbar--success'); } -} + + get clickFilters(): Locator { + return this.page.getByText('Filters'); + } + + get chipName(): Locator{ + return this.page.locator('//span[contains(@class, "rcx-chip__text")]'); + } + + get closeChip(): Locator{ + return this.page.locator('//i[@class="rcx-box rcx-box--full rcx-icon--name-cross rcx-icon rcx-css-trljwa rcx-css-1wv1vf9"]'); + } + + get inputServedBy(): Locator { + return this.page.locator('[data-qa="autocomplete-agent"] div input'); + } + + get inputDepartment(): Locator { + return this.page.locator('[data-qa="autocomplete-department"] div input'); + } + + get clickApply(): Locator { + return this.page.getByRole('button', { name: 'Apply' }); + } + + get clickChats(): Locator { + return this.page.getByRole('tab', { name: 'Chats' }); + } + + get inputStatus(): Locator { + return this.page.locator('button[name="status"]'); + } + + get inputTags(): Locator { + return this.page.locator('[role="listbox"] [placeholder="Select an option"] '); + } + + get inputFromDate(): Locator { + return this.page.locator('[type="date"] [placeholder="From"]'); + } + + get clearFilters(): Locator { + return this.page.getByRole('button', { name: 'Clear filters' }); + } + + get deleteClosedChat(): Locator { + return this.page.locator('button[title="More"]'); + } + + get close(): Locator { + return this.page.locator('[data-qa="ContextualbarActionClose"]'); + } + + async selectServedBy(option: string) { + await this.inputServedBy.click(); + await this.inputServedBy.fill(option); + await this.page.locator(`[role='option'][value='${option}']`).click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } + + async selectStatus(option: string) { + await this.inputStatus.click(); + await this.page.locator(`[role='option'][data-key='${option}']`).click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } + + async selectDepartment(option: string) { + await this.inputDepartment.click(); + await this.inputDepartment.fill(option); + await this.page.locator(`role=option[name='${option}']`).click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } + + async addTag(option: string) { + await this.inputTags.click(); + await this.page.locator(`[role='option'][value='${option}']`).click(); + await this.inputTags.click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } + + async removeTag(option: string) { + await this.page.locator(`role=option[name='${option}']`).click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } + + async selectFromDate(option: string) { + await this.inputFromDate.click(); + await this.inputFromDate.fill(option); + //await this.page.locator(`type=date[value='${option}']`).click(); + await this.page.getByRole('button', { name: 'Apply' }).click(); + } +} \ No newline at end of file From 5e329ecb6f531717e12fa9403f15a859469cbb3f Mon Sep 17 00:00:00 2001 From: Harmeet221 Date: Fri, 18 Oct 2024 16:34:23 +0530 Subject: [PATCH 2/2] resolved lint isues --- ...omnichannel-contact-center-filters.spec.ts | 586 +++++++++--------- .../page-objects/omnichannel-contacts-list.ts | 15 +- 2 files changed, 304 insertions(+), 297 deletions(-) diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts index 72c4b3bd3a19..0a87e6860431 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-filters.spec.ts @@ -1,297 +1,311 @@ -import { faker } from '@faker-js/faker'; - -import { IS_EE } from '../config/constants'; -import { Users } from '../fixtures/userStates'; -import { OmnichannelContacts } from '../page-objects/omnichannel-contacts-list'; -import { OmnichannelSection } from '../page-objects/omnichannel-section'; -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'; +import { faker } from "@faker-js/faker"; + +import { IS_EE } from "../config/constants"; +import { Users } from "../fixtures/userStates"; +import { OmnichannelContacts } from "../page-objects/omnichannel-contacts-list"; +import { OmnichannelSection } from "../page-objects/omnichannel-section"; +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 URL = { - contactCenterChats: '/omnichannel-directory/chats', + contactCenterChats: "/omnichannel-directory/chats", }; const visitorA = faker.person.firstName(); const visitorB = faker.person.firstName(); const visitorC = faker.person.firstName(); -test.skip(!IS_EE, 'OC - Contact center Filters > Enterprise Only'); +test.skip(!IS_EE, "OC - Contact center Filters > Enterprise Only"); test.use({ storageState: Users.admin.state }); -test.describe('OC - Contact Center [Auto Selection]', async () => { - let departments: Awaited>[]; - let conversations: Awaited>[]; - let agents: Awaited>[]; - let tags: Awaited>[]; - let poContacts: OmnichannelContacts; - let poOmniSection: OmnichannelSection; - - // 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 }) => { - tags = await Promise.all([createTag(api, { name: 'tagA' }), createTag(api, { name: 'tagB' })]); - - tags.forEach((res) => expect(res.response.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.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()), - // Delete tags - ...tags.map((tag) => tag.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 }), - ]); - }); - - // 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.beforeEach(async ({ page }) => { - poContacts = new OmnichannelContacts(page); - poOmniSection = new OmnichannelSection(page); - - }); - - test.beforeEach(async ({ page }) => { - await page.goto('/'); - await poOmniSection.btnContactCenter.click(); - await poContacts.clickChats.click(); - await page.waitForURL(URL.contactCenterChats); - }); - - test('OC - Contact Center - Filters', async () => { - const [departmentA, departmentB] = departments.map(({ data }) => data); - - await test.step('expect to filter by guest', async () => { - - await poContacts.inputSearch.fill(visitorA); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.chipName).toContainText(visitorA); - - await poContacts.inputSearch.fill(''); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - }); - - await test.step('expect to filter by Served By', async () => { - - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - - await poContacts.clickFilters.click(); - - await poContacts.selectServedBy('user1'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.chipName).toContainText('user1'); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - - await poContacts.selectServedBy('user2'); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.chipName).toContainText('user2'); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - - await poContacts.selectServedBy('all'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - }); - - await test.step('expect to filter by status', async () => { - - await poContacts.selectStatus('closed'); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); - await expect(poContacts.chipName).toContainText('closed'); - await poContacts.closeChip.click(); - - await poContacts.selectStatus('opened'); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await expect(poContacts.chipName).toContainText('opened'); - - await poContacts.selectStatus('onhold'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await expect(poContacts.chipName).toContainText('onhold'); - await poContacts.closeChip.click(); - - await poContacts.selectStatus('all'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); - - }); - - await test.step('expect to filter by department', async () => { - - await poContacts.selectDepartment(departmentA.name); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await expect(poContacts.chipName).toContainText(departmentA.name); - await poContacts.closeChip.click(); - - await poContacts.selectDepartment(departmentB.name); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await expect(poContacts.chipName).toContainText(departmentB.name); - await poContacts.closeChip.click(); - - await poContacts.selectDepartment('All'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); - }); - - await test.step('expect to filter by tags', async () => { - await poContacts.addTag('tagA'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - - await poContacts.addTag('tagB'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - - await poContacts.removeTag('tagA'); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - - await poContacts.removeTag('tagB'); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - }); - - }); - - test('Clear all applied Filters', async ({ }) => { - const [departmentA] = departments.map(({ data }) => data); - - await test.step('expect to display result as per applied filters ', async () => { - - await poContacts.clickFilters.click(); - await poContacts.selectServedBy('user1'); - await poContacts.selectStatus('onhold'); - await poContacts.selectDepartment(departmentA.name); - await poContacts.addTag('tagA'); - - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - - }); - - await test.step('expect to clear all filters ', async () => { - - await poContacts.clearFilters.click(); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); - - }); - }); - - test('Close contextual bar with filter screen', async ({ }) => { - - await test.step('expect to close filters contextual bar ', async () => { - await poContacts.close.click(); - - }); - }); -}); \ No newline at end of file +test.describe("OC - Contact Center [Auto Selection]", async () => { + let departments: Awaited>[]; + let conversations: Awaited>[]; + let agents: Awaited>[]; + let tags: Awaited>[]; + let poContacts: OmnichannelContacts; + let poOmniSection: OmnichannelSection; + + // 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 }) => { + tags = await Promise.all([ + createTag(api, { name: "tagA" }), + createTag(api, { name: "tagB" }), + ]); + + tags.forEach((res) => expect(res.response.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.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()), + // Delete tags + ...tags.map((tag) => tag.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 } + ), + ]); + }); + + // 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.beforeEach(async ({ page }) => { + poContacts = new OmnichannelContacts(page); + poOmniSection = new OmnichannelSection(page); + }); + + test.beforeEach(async ({ page }) => { + await page.goto("/"); + await poOmniSection.btnContactCenter.click(); + await poContacts.clickChat.click(); + await page.waitForURL(URL.contactCenterChats); + }); + + test("OC - Contact Center - Filters", async () => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + + await test.step("expect to filter by guest", async () => { + await poContacts.inputSearch.fill(visitorA); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(visitorA); + + await poContacts.inputSearch.fill(""); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step("expect to filter by Served By", async () => { + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + + await poContacts.clickFilters.click(); + + await poContacts.selectServedBy("user1"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.chipName).toContainText("user1"); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + + await poContacts.selectServedBy("user2"); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.chipName).toContainText("user2"); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + + await poContacts.selectServedBy("all"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + }); + + await test.step("expect to filter by status", async () => { + await poContacts.selectStatus("closed"); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + await expect(poContacts.chipName).toContainText("closed"); + await poContacts.closeChip.click(); + + await poContacts.selectStatus("opened"); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText("opened"); + + await poContacts.selectStatus("onhold"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText("onhold"); + await poContacts.closeChip.click(); + + await poContacts.selectStatus("all"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + }); + + await test.step("expect to filter by department", async () => { + await poContacts.selectDepartment(departmentA.name); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(departmentA.name); + await poContacts.closeChip.click(); + + await poContacts.selectDepartment(departmentB.name); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poContacts.chipName).toContainText(departmentB.name); + await poContacts.closeChip.click(); + + await poContacts.selectDepartment("All"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + }); + + await test.step("expect to filter by tags", async () => { + await poContacts.addTag("tagA"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + + await poContacts.addTag("tagB"); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + + await poContacts.removeTag("tagA"); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + + await poContacts.removeTag("tagB"); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + }); + }); + + test("Clear all applied Filters", async ({}) => { + const [departmentA] = departments.map(({ data }) => data); + + await test.step("expect to display result as per applied filters ", async () => { + await poContacts.clickFilters.click(); + await poContacts.selectServedBy("user1"); + await poContacts.selectStatus("onhold"); + await poContacts.selectDepartment(departmentA.name); + await poContacts.addTag("tagA"); + + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + }); + + await test.step("expect to clear all filters ", async () => { + await poContacts.clearFilters.click(); + await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + }); + }); + + test("Close contextual bar with filter screen", async ({}) => { + await test.step("expect to close filters contextual bar ", async () => { + await poContacts.close.click(); + }); + }); +}); diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts index c89b9256cd0f..9b88438d1646 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts @@ -36,11 +36,11 @@ export class OmnichannelContacts { return this.page.getByText('Filters'); } - get chipName(): Locator{ + get chipName(): Locator { return this.page.locator('//span[contains(@class, "rcx-chip__text")]'); } - get closeChip(): Locator{ + get closeChip(): Locator { return this.page.locator('//i[@class="rcx-box rcx-box--full rcx-icon--name-cross rcx-icon rcx-css-trljwa rcx-css-1wv1vf9"]'); } @@ -56,7 +56,7 @@ export class OmnichannelContacts { return this.page.getByRole('button', { name: 'Apply' }); } - get clickChats(): Locator { + get clickChat(): Locator { return this.page.getByRole('tab', { name: 'Chats' }); } @@ -115,11 +115,4 @@ export class OmnichannelContacts { await this.page.locator(`role=option[name='${option}']`).click(); await this.page.getByRole('button', { name: 'Apply' }).click(); } - - async selectFromDate(option: string) { - await this.inputFromDate.click(); - await this.inputFromDate.fill(option); - //await this.page.locator(`type=date[value='${option}']`).click(); - await this.page.getByRole('button', { name: 'Apply' }).click(); - } -} \ No newline at end of file +}