diff --git a/apps/meteor/.mocharc.js b/apps/meteor/.mocharc.js index a2230bb7dd5ff..0e9b30dffa699 100644 --- a/apps/meteor/.mocharc.js +++ b/apps/meteor/.mocharc.js @@ -10,7 +10,7 @@ module.exports = { ...base, // see https://github.com/mochajs/mocha/issues/3916 exit: true, spec: [ - 'lib/callbacks.spec.ts', + 'server/lib/callbacks.spec.ts', 'server/lib/ldap/*.spec.ts', 'server/lib/ldap/**/*.spec.ts', 'server/lib/dataExport/**/*.spec.ts', diff --git a/apps/meteor/app/livechat/server/lib/sendTranscript.ts b/apps/meteor/app/livechat/server/lib/sendTranscript.ts index 8a6f861907488..11ca540ab87bf 100644 --- a/apps/meteor/app/livechat/server/lib/sendTranscript.ts +++ b/apps/meteor/app/livechat/server/lib/sendTranscript.ts @@ -9,7 +9,7 @@ import { isFileImageAttachment, type AtLeast, } from '@rocket.chat/core-typings'; -import colors from '@rocket.chat/fuselage-tokens/colors'; +import colors from '@rocket.chat/fuselage-tokens/colors.json'; import { Logger } from '@rocket.chat/logger'; import { MessageTypes } from '@rocket.chat/message-types'; import { LivechatRooms, Messages, Uploads, Users } from '@rocket.chat/models'; diff --git a/apps/meteor/app/slackbridge/server/RocketAdapter.js b/apps/meteor/app/slackbridge/server/RocketAdapter.ts similarity index 98% rename from apps/meteor/app/slackbridge/server/RocketAdapter.js rename to apps/meteor/app/slackbridge/server/RocketAdapter.ts index b6a0b1ccbcfec..87f549a07eb08 100644 --- a/apps/meteor/app/slackbridge/server/RocketAdapter.js +++ b/apps/meteor/app/slackbridge/server/RocketAdapter.ts @@ -1,3 +1,8 @@ +// This is a JS File that was renamed to TS so it won't lose its git history when converted to TS +// TODO: Remove the following lint/ts instructions when the file gets properly converted +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ +// @ts-nocheck import util from 'util'; import { Messages, Rooms, Users } from '@rocket.chat/models'; diff --git a/apps/meteor/app/slackbridge/server/SlackAPI.js b/apps/meteor/app/slackbridge/server/SlackAPI.ts similarity index 95% rename from apps/meteor/app/slackbridge/server/SlackAPI.js rename to apps/meteor/app/slackbridge/server/SlackAPI.ts index 540aa3b911605..e9338ce5792e2 100644 --- a/apps/meteor/app/slackbridge/server/SlackAPI.js +++ b/apps/meteor/app/slackbridge/server/SlackAPI.ts @@ -1,3 +1,7 @@ +// This is a JS File that was renamed to TS so it won't lose its git history when converted to TS +// TODO: Remove the following lint/ts instructions when the file gets properly converted +/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ +// @ts-nocheck import { serverFetch as fetch } from '@rocket.chat/server-fetch'; export class SlackAPI { diff --git a/apps/meteor/app/slackbridge/server/SlackAdapter.js b/apps/meteor/app/slackbridge/server/SlackAdapter.ts similarity index 99% rename from apps/meteor/app/slackbridge/server/SlackAdapter.js rename to apps/meteor/app/slackbridge/server/SlackAdapter.ts index 3783416c8d4d8..2bc5d56da88b3 100644 --- a/apps/meteor/app/slackbridge/server/SlackAdapter.js +++ b/apps/meteor/app/slackbridge/server/SlackAdapter.ts @@ -1,3 +1,9 @@ +// This is a JS File that was renamed to TS so it won't lose its git history when converted to TS +// TODO: Remove the following lint/ts instructions when the file gets properly converted +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ +// @ts-nocheck import http from 'http'; import https from 'https'; import url from 'url'; diff --git a/apps/meteor/app/slackbridge/server/slackbridge.js b/apps/meteor/app/slackbridge/server/slackbridge.ts similarity index 93% rename from apps/meteor/app/slackbridge/server/slackbridge.js rename to apps/meteor/app/slackbridge/server/slackbridge.ts index 75409f4314ceb..13455b8068508 100644 --- a/apps/meteor/app/slackbridge/server/slackbridge.js +++ b/apps/meteor/app/slackbridge/server/slackbridge.ts @@ -1,7 +1,12 @@ +// This is a JS File that was renamed to TS so it won't lose its git history when converted to TS +// TODO: Remove the following lint/ts instructions when the file gets properly converted +/* eslint-disable @typescript-eslint/no-floating-promises */ +/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ +// @ts-nocheck import { debounce } from 'lodash'; -import RocketAdapter from './RocketAdapter.js'; -import SlackAdapter from './SlackAdapter.js'; +import RocketAdapter from './RocketAdapter'; +import SlackAdapter from './SlackAdapter'; import { classLogger, connLogger } from './logger'; import { settings } from '../../settings/server'; diff --git a/apps/meteor/app/slackbridge/server/slackbridge_import.server.js b/apps/meteor/app/slackbridge/server/slackbridge_import.server.ts similarity index 88% rename from apps/meteor/app/slackbridge/server/slackbridge_import.server.js rename to apps/meteor/app/slackbridge/server/slackbridge_import.server.ts index 6e7117af976a2..7eda03f908c44 100644 --- a/apps/meteor/app/slackbridge/server/slackbridge_import.server.js +++ b/apps/meteor/app/slackbridge/server/slackbridge_import.server.ts @@ -1,3 +1,7 @@ +// This is a JS File that was renamed to TS so it won't lose its git history when converted to TS +// TODO: Remove the following lint/ts instructions when the file gets properly converted +/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ +// @ts-nocheck import { Rooms, Users } from '@rocket.chat/models'; import { Random } from '@rocket.chat/random'; import { Match } from 'meteor/check'; diff --git a/apps/meteor/client/components/Sidebar/SidebarGenericItem.tsx b/apps/meteor/client/components/Sidebar/SidebarGenericItem.tsx index 4f62cda740cf1..1aee93a52c350 100644 --- a/apps/meteor/client/components/Sidebar/SidebarGenericItem.tsx +++ b/apps/meteor/client/components/Sidebar/SidebarGenericItem.tsx @@ -1,5 +1,4 @@ import { Box, SidebarItem } from '@rocket.chat/fuselage'; -import type colors from '@rocket.chat/fuselage-tokens/colors'; import type { ReactElement, ReactNode } from 'react'; import { memo } from 'react'; @@ -8,11 +7,6 @@ type SidebarGenericItemProps = { active?: boolean; featured?: boolean; children: ReactNode; - customColors?: { - default: (typeof colors)[string]; - hover: (typeof colors)[string]; - active: (typeof colors)[string]; - }; externalUrl?: boolean; }; diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx index de550a7c05424..5903e26bfad2c 100644 --- a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx @@ -17,15 +17,7 @@ const CustomUserStatusRow = ({ status, onClick }: CustomUserStatusRowProps): Rea const { t } = useTranslation(); return ( - onClick(_id)} - onClick={(): void => onClick(_id)} - tabIndex={0} - role='link' - action - qa-user-id={_id} - > + onClick(_id)} onClick={() => onClick(_id)} tabIndex={0} action> diff --git a/apps/meteor/client/views/admin/engagementDashboard/users/ContentForDays.tsx b/apps/meteor/client/views/admin/engagementDashboard/users/ContentForDays.tsx index 3265533b5b196..01c622829e6be 100644 --- a/apps/meteor/client/views/admin/engagementDashboard/users/ContentForDays.tsx +++ b/apps/meteor/client/views/admin/engagementDashboard/users/ContentForDays.tsx @@ -1,6 +1,6 @@ import { ResponsiveBar } from '@nivo/bar'; import { Box, Flex, IconButton, Margins, Skeleton } from '@rocket.chat/fuselage'; -import colors from '@rocket.chat/fuselage-tokens/colors'; +import colors from '@rocket.chat/fuselage-tokens/colors.json'; import moment from 'moment'; import type { ReactElement } from 'react'; import { useMemo } from 'react'; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentEdit.tsx b/apps/meteor/client/views/omnichannel/agents/AgentEdit.tsx index 91532ebbfb91e..d7efcbd7b5ac7 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentEdit.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentEdit.tsx @@ -164,13 +164,7 @@ const AgentEdit = ({ agentData, agentDepartments }: AgentEditProps) => { name='status' control={control} render={({ field }) => ( - )} /> @@ -185,7 +179,7 @@ const AgentEdit = ({ agentData, agentDepartments }: AgentEditProps) => { - diff --git a/apps/meteor/client/views/omnichannel/agents/AgentInfoAction.tsx b/apps/meteor/client/views/omnichannel/agents/AgentInfoAction.tsx index 71ee19bf36bba..1d922f530adb0 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentInfoAction.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentInfoAction.tsx @@ -9,7 +9,7 @@ type AgentInfoActionProps = { } & Omit, 'is'>; const AgentInfoAction = ({ icon, label, ...props }: AgentInfoActionProps) => ( - ); diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTable.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTable.tsx index e8bd1faff7e08..7ea8bb3d9719c 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTable.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTable.tsx @@ -96,9 +96,9 @@ const AgentsTable = () => { )} {isSuccess && data?.users.length > 0 && ( <> - + {headers} - + {data?.users.map((user) => )} diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTableRow.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTableRow.tsx index e4381f1aab523..4cff09defc94e 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTableRow.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsTable/AgentsTableRow.tsx @@ -27,7 +27,7 @@ const AgentsTableRow = ({ const handleDelete = useRemoveAgent(_id); return ( - router.navigate(`/omnichannel/agents/info/${_id}`)}> + router.navigate(`/omnichannel/agents/info/${_id}`)}> {username && } diff --git a/apps/meteor/client/views/omnichannel/agents/hooks/useRemoveAgent.tsx b/apps/meteor/client/views/omnichannel/agents/hooks/useRemoveAgent.tsx index f32facb2287ac..670d2eb802312 100644 --- a/apps/meteor/client/views/omnichannel/agents/hooks/useRemoveAgent.tsx +++ b/apps/meteor/client/views/omnichannel/agents/hooks/useRemoveAgent.tsx @@ -30,15 +30,7 @@ export const useRemoveAgent = (uid: ILivechatAgent['_id']) => { } }; - setModal( - setModal()} - confirmText={t('Delete')} - />, - ); + setModal( setModal()} confirmText={t('Delete')} />); }); return handleDelete; diff --git a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursRow.tsx b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursRow.tsx index 836acdcaaa6ce..a9249f4eb5f33 100644 --- a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursRow.tsx +++ b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursRow.tsx @@ -27,7 +27,7 @@ const BusinessHoursRow = ({ _id, name, timezone, workHours, active, type }: Seri const openDays = useMemo(() => workHours.filter(({ open }) => !!open).map(({ day }) => day), [workHours]); return ( - + {name || t('Default')} {t(timezone.name as TranslationKey)} {openDays.join(', ')} diff --git a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTable.tsx b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTable.tsx index 8d25bbce31142..239995250419c 100644 --- a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTable.tsx +++ b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTable.tsx @@ -65,7 +65,7 @@ const BusinessHoursTable = () => { {isSuccess && data?.businessHours.length === 0 && } {isSuccess && data?.businessHours.length > 0 && ( <> - + {headers} {data?.businessHours.map((businessHour) => )} diff --git a/apps/meteor/client/views/omnichannel/cannedResponses/modals/CannedResponsesTable.tsx b/apps/meteor/client/views/omnichannel/cannedResponses/modals/CannedResponsesTable.tsx index 32dc9728572a5..40b982c809c9b 100644 --- a/apps/meteor/client/views/omnichannel/cannedResponses/modals/CannedResponsesTable.tsx +++ b/apps/meteor/client/views/omnichannel/cannedResponses/modals/CannedResponsesTable.tsx @@ -152,7 +152,7 @@ const CannedResponsesTable = () => { {headers} {data?.cannedResponses.map(({ _id, shortcut, scope, createdBy, _createdAt, tags = [] }) => ( - + {shortcut} {defaultOptions[scope as Scope]} diff --git a/apps/meteor/client/views/omnichannel/customFields/CustomFieldsPage.tsx b/apps/meteor/client/views/omnichannel/customFields/CustomFieldsPage.tsx index e5688517642e5..1fcf092ede7c3 100644 --- a/apps/meteor/client/views/omnichannel/customFields/CustomFieldsPage.tsx +++ b/apps/meteor/client/views/omnichannel/customFields/CustomFieldsPage.tsx @@ -21,9 +21,7 @@ const CustomFieldsPage = () => { - + diff --git a/apps/meteor/client/views/omnichannel/customFields/CustomFieldsTable.tsx b/apps/meteor/client/views/omnichannel/customFields/CustomFieldsTable.tsx index fcc62b50ca908..d249d816e4e70 100644 --- a/apps/meteor/client/views/omnichannel/customFields/CustomFieldsTable.tsx +++ b/apps/meteor/client/views/omnichannel/customFields/CustomFieldsTable.tsx @@ -104,11 +104,11 @@ const CustomFieldsTable = () => { {isSuccess && data.customFields.length > 0 && ( <> - + {headers} {data.customFields.map(({ label, _id, scope, visibility }) => ( - + {_id} {label} {scope === 'visitor' ? t('Visitor') : t('Room')} diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx index bfc14fc58b889..e732a84b0e80d 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx @@ -19,7 +19,7 @@ const AgentRow = ({ index, agent, register, onRemove }: AgentRowProps) => { const { t } = useTranslation(); return ( - + diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/DepartmentAgentsTable.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/DepartmentAgentsTable.tsx index b6cd94e4cb2f6..0cfdf7e2bb3cf 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/DepartmentAgentsTable.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/DepartmentAgentsTable.tsx @@ -26,22 +26,19 @@ function DepartmentAgentsTable({ control, register, 'aria-labelledby': ariaLabel return ( <> - - + {t('Name')} {t('Count')} {t('Order')} {t('Remove')} - {page.map((agent, index) => ( remove(index)} /> ))} - ) => setTagText(e.currentTarget.value)} {...props} /> - diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentItemMenu.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentItemMenu.tsx index e6a0b555b4e67..253ad9d10c4b6 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentItemMenu.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentItemMenu.tsx @@ -18,6 +18,7 @@ type DepartmentItemMenuProps = { archived: boolean; }; +// TODO: Use MenuV2 instead of Menu const DepartmentItemMenu = ({ department, archived }: DepartmentItemMenuProps): ReactElement => { const t = useTranslation(); const queryClient = useQueryClient(); @@ -91,7 +92,7 @@ const DepartmentItemMenu = ({ department, archived }: DepartmentItemMenuProps): disabled: !departmentRemovalEnabled, }, }; - return ; + return ; }; export default DepartmentItemMenu; diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentsTable.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentsTable.tsx index a6cafe6dcfa4c..a0f5a72e50743 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentsTable.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/DepartmentsTable.tsx @@ -121,7 +121,7 @@ const DepartmentsTable = ({ archived }: { archived: boolean }) => { )} {isSuccess && data?.departments.length > 0 && ( <> - + {headers} {data.departments.map((department: Omit) => ( diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/RemoveDepartmentModal.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/RemoveDepartmentModal.tsx index 155b1c48d8521..38d704a7cf7bb 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/RemoveDepartmentModal.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentsTable/RemoveDepartmentModal.tsx @@ -41,13 +41,13 @@ const RemoveDepartmentModal = ({ _id = '', name, reset, onClose }: RemoveDepartm title={t('Delete_Department?')} onClose={onClose} variant='danger' - data-qa-id='delete-department-modal' confirmDisabled={text !== name} > {t('Are_you_sure_delete_department')} ) => setText(event.currentTarget.value)} /> diff --git a/apps/meteor/client/views/omnichannel/departments/EditDepartment.tsx b/apps/meteor/client/views/omnichannel/departments/EditDepartment.tsx index 895706a3962cc..f29d60eace55f 100644 --- a/apps/meteor/client/views/omnichannel/departments/EditDepartment.tsx +++ b/apps/meteor/client/views/omnichannel/departments/EditDepartment.tsx @@ -161,7 +161,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen - {t('Name')} @@ -169,7 +168,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen {errors.name && ( - + {errors.name?.message} )} - {t('Description')} - + - - + {t('Show_on_registration_page')} - {t('Email')} @@ -209,7 +199,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen } placeholder={t('Email')} @@ -221,19 +210,17 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen /> {errors.email && ( - + {errors.email?.message} )} - {t('Show_on_offline_page')} - {t('Livechat_DepartmentOfflineMessageToChannel')} @@ -243,7 +230,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen render={({ field: { value, onChange } }) => ( - {hasLicense && ( <> @@ -274,7 +259,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen )} /> - - - - {t('List_of_departments_for_forward')} @@ -338,7 +319,6 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen {t('List_of_departments_for_forward_description')} - {t('Fallback_forward_department')} - {t('Unit')} @@ -389,21 +368,19 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen /> {errors.unit && ( - + {errors.unit?.message} )} )} - {t('Request_tag_before_closing_chat')} - {t('Conversation_closing_tags')} )} - {t('Accept_receive_inquiry_no_online_agents')} @@ -439,9 +415,7 @@ function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmen - - {t('Agents')} diff --git a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx index 731b6d690756d..cb519d2c151f0 100644 --- a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx +++ b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx @@ -32,15 +32,7 @@ const ChatsTableFilter = () => { } }; - setModal( - setModal(null)} - confirmText={t('Delete')} - />, - ); + setModal( setModal(null)} confirmText={t('Delete')} />); }); const menuItems = [ diff --git a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableRow.tsx b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableRow.tsx index ebecb53fe8b91..e42127f5e75d0 100644 --- a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableRow.tsx +++ b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableRow.tsx @@ -46,7 +46,7 @@ const ChatsTableRow = (room: IOmnichannelRoomWithDepartment) => { ); return ( - onRowClick(_id)} action qa-user-id={_id}> + onRowClick(_id)} action> {fname} diff --git a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/RemoveChatButton.tsx b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/RemoveChatButton.tsx index 2b355f667f13b..ce568b3462c97 100644 --- a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/RemoveChatButton.tsx +++ b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/RemoveChatButton.tsx @@ -31,15 +31,7 @@ const RemoveChatButton = ({ _id }: RemoveChatButtonProps) => { setModal(null); }; - setModal( - setModal(null)} - confirmText={t('Delete')} - />, - ); + setModal( setModal(null)} confirmText={t('Delete')} />); }); return ; diff --git a/apps/meteor/client/views/omnichannel/directory/contacts/ContactTable.tsx b/apps/meteor/client/views/omnichannel/directory/contacts/ContactTable.tsx index f6187ef4294e9..d467cc5244195 100644 --- a/apps/meteor/client/views/omnichannel/directory/contacts/ContactTable.tsx +++ b/apps/meteor/client/views/omnichannel/directory/contacts/ContactTable.tsx @@ -121,7 +121,7 @@ function ContactTable() { )} {isSuccess && data?.contacts.length > 0 && ( <> - + {headers} {data?.contacts.map((contact) => )} diff --git a/apps/meteor/client/views/omnichannel/directory/contacts/ContactTableRow.tsx b/apps/meteor/client/views/omnichannel/directory/contacts/ContactTableRow.tsx index c6189f796cfec..602be761ef59f 100644 --- a/apps/meteor/client/views/omnichannel/directory/contacts/ContactTableRow.tsx +++ b/apps/meteor/client/views/omnichannel/directory/contacts/ContactTableRow.tsx @@ -31,16 +31,7 @@ const ContactTableRow = ({ _id, name, contactManager, lastChat, channels }: ILiv ); return ( - onRowClick(_id)} - > + onRowClick(_id)}> {name} {latestChannel?.details && ( diff --git a/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx b/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx index 3830008cfa4d3..f2201dd005a56 100644 --- a/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx +++ b/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx @@ -85,7 +85,7 @@ const ManagersTable = () => { setText(event.target.value)} /> )} {isLoading && ( - + {headers} @@ -107,7 +107,7 @@ const ManagersTable = () => { {headers} {data.users.map((user) => ( - + diff --git a/apps/meteor/client/views/omnichannel/modals/EnterpriseDepartmentsModal.tsx b/apps/meteor/client/views/omnichannel/modals/EnterpriseDepartmentsModal.tsx index f864f57f57667..1561619827da6 100644 --- a/apps/meteor/client/views/omnichannel/modals/EnterpriseDepartmentsModal.tsx +++ b/apps/meteor/client/views/omnichannel/modals/EnterpriseDepartmentsModal.tsx @@ -21,6 +21,8 @@ import { useTranslation } from 'react-i18next'; import { useExternalLink } from '../../../hooks/useExternalLink'; import { useCheckoutUrl } from '../../admin/subscription/hooks/useCheckoutUrl'; +// TODO: use `GenericModal` instead of creating a new modal from scratch +// This seems a upSell modal for enterprise feature const EnterpriseDepartmentsModal = ({ closeModal }: { closeModal: () => void }): ReactElement => { const { t } = useTranslation(); const router = useRouter(); @@ -42,13 +44,13 @@ const EnterpriseDepartmentsModal = ({ closeModal }: { closeModal: () => void }): useOutsideClick([ref], onClose); return ( - + {t('Premium_capability')} {t('Departments')} - + @@ -60,7 +62,6 @@ const EnterpriseDepartmentsModal = ({ closeModal }: { closeModal: () => void }): - diff --git a/apps/meteor/client/views/omnichannel/modals/ForwardChatModal.tsx b/apps/meteor/client/views/omnichannel/modals/ForwardChatModal.tsx index a0b59d9add935..3bc17602ce755 100644 --- a/apps/meteor/client/views/omnichannel/modals/ForwardChatModal.tsx +++ b/apps/meteor/client/views/omnichannel/modals/ForwardChatModal.tsx @@ -137,7 +137,7 @@ const ForwardChatModal = ({ onForward, onCancel, room, ...props }: ForwardChatMo - + diff --git a/apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx b/apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx index 9107d41a18c4b..09c912dec0d48 100644 --- a/apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx +++ b/apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx @@ -16,11 +16,12 @@ type ReturnChatQueueModalProps = { onCancel: () => void; }; +// TODO: use `GenericModal` instead of creating a new modal from scratch const ReturnChatQueueModal = ({ onCancel, onMoveChat, ...props }: ReturnChatQueueModalProps) => { const { t } = useTranslation(); return ( - + {t('Return_to_the_queue')} diff --git a/apps/meteor/client/views/omnichannel/monitors/MonitorsTable.tsx b/apps/meteor/client/views/omnichannel/monitors/MonitorsTable.tsx index 3aca318d9a480..d790c15b22c43 100644 --- a/apps/meteor/client/views/omnichannel/monitors/MonitorsTable.tsx +++ b/apps/meteor/client/views/omnichannel/monitors/MonitorsTable.tsx @@ -109,15 +109,7 @@ const MonitorsTable = () => { setModal(); }; - setModal( - setModal()} - confirmText={t('Delete')} - />, - ); + setModal( setModal()} confirmText={t('Delete')} />); }; const headers = useMemo( @@ -172,11 +164,11 @@ const MonitorsTable = () => { )} {isSuccess && data.monitors.length > 0 && ( <> - + {headers} {data.monitors?.map((monitor) => ( - + {monitor.name} {monitor.username} {monitor.email} diff --git a/apps/meteor/client/views/omnichannel/priorities/PrioritiesTable.tsx b/apps/meteor/client/views/omnichannel/priorities/PrioritiesTable.tsx index 010ea55e31496..5f8629d90ac16 100644 --- a/apps/meteor/client/views/omnichannel/priorities/PrioritiesTable.tsx +++ b/apps/meteor/client/views/omnichannel/priorities/PrioritiesTable.tsx @@ -42,7 +42,7 @@ export const PrioritiesTable = ({ priorities, onRowClick, isLoading }: Prioritie )} {priorities?.length === 0 && } {priorities && priorities?.length > 0 && ( - + {headers} {priorities?.map(({ _id, name, i18n, sortItem, dirty }) => ( diff --git a/apps/meteor/client/views/omnichannel/priorities/PrioritiesTableRow.tsx b/apps/meteor/client/views/omnichannel/priorities/PrioritiesTableRow.tsx index 19ad5262ac24f..1d298dbfde8dd 100644 --- a/apps/meteor/client/views/omnichannel/priorities/PrioritiesTableRow.tsx +++ b/apps/meteor/client/views/omnichannel/priorities/PrioritiesTableRow.tsx @@ -16,7 +16,7 @@ type PrioritiesTableRowProps = { const PrioritiesTableRow = ({ id, name, i18n, sortItem, dirty, onClick }: PrioritiesTableRowProps) => { const { t } = useTranslation(); return ( - + diff --git a/apps/meteor/client/views/omnichannel/priorities/PriorityEditForm.tsx b/apps/meteor/client/views/omnichannel/priorities/PriorityEditForm.tsx index 7b42fd3d92027..3a407477fe448 100644 --- a/apps/meteor/client/views/omnichannel/priorities/PriorityEditForm.tsx +++ b/apps/meteor/client/views/omnichannel/priorities/PriorityEditForm.tsx @@ -91,14 +91,12 @@ const PriorityEditForm = ({ data, onSave, onCancel }: PriorityEditFormProps): Re /> )} /> - {errors.name?.message} + {errors.name?.message} - - - diff --git a/apps/meteor/client/views/omnichannel/sidebar/OmnichannelSidebar.tsx b/apps/meteor/client/views/omnichannel/sidebar/OmnichannelSidebar.tsx index cae285427cac5..d11fdffed1fa3 100644 --- a/apps/meteor/client/views/omnichannel/sidebar/OmnichannelSidebar.tsx +++ b/apps/meteor/client/views/omnichannel/sidebar/OmnichannelSidebar.tsx @@ -16,7 +16,7 @@ const OmnichannelSidebar = () => { return ( - + diff --git a/apps/meteor/client/views/omnichannel/slaPolicies/SlaEdit.tsx b/apps/meteor/client/views/omnichannel/slaPolicies/SlaEdit.tsx index a7ffcc96d66ec..e8a5954499d73 100644 --- a/apps/meteor/client/views/omnichannel/slaPolicies/SlaEdit.tsx +++ b/apps/meteor/client/views/omnichannel/slaPolicies/SlaEdit.tsx @@ -80,7 +80,7 @@ function SlaEdit({ data, isNew, slaId, reload, ...props }: SlaEditProps): ReactE - {errors.name?.message} + {errors.name?.message} {t('Description')} @@ -98,7 +98,7 @@ function SlaEdit({ data, isNew, slaId, reload, ...props }: SlaEditProps): ReactE error={errors.dueTimeInMinutes?.message} /> - {errors.dueTimeInMinutes?.message} + {errors.dueTimeInMinutes?.message} diff --git a/apps/meteor/client/views/omnichannel/slaPolicies/SlaTable.tsx b/apps/meteor/client/views/omnichannel/slaPolicies/SlaTable.tsx index 217c927b11632..43fd80f41ec02 100644 --- a/apps/meteor/client/views/omnichannel/slaPolicies/SlaTable.tsx +++ b/apps/meteor/client/views/omnichannel/slaPolicies/SlaTable.tsx @@ -115,11 +115,11 @@ const SlaTable = ({ reload }: { reload: MutableRefObject<() => void> }) => { )} {isSuccess && data?.sla.length > 0 && ( <> - + {headers} {data?.sla.map(({ _id, name, description, dueTimeInMinutes }) => ( - + {name} {description} diff --git a/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx b/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx index 65294be980648..a8202f637b17b 100644 --- a/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx +++ b/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx @@ -95,11 +95,13 @@ const TagEdit = ({ tagData, currentDepartments, onClose }: TagEditProps) => { name='name' control={control} rules={{ required: t('Required_field', { field: t('Name') }) }} - render={({ field }) => } + render={({ field }) => ( + + )} /> {errors?.name && ( - + {errors?.name?.message} )} @@ -111,12 +113,14 @@ const TagEdit = ({ tagData, currentDepartments, onClose }: TagEditProps) => { - {t('Departments')} + {t('Departments')} } + render={({ field }) => ( + + )} /> diff --git a/apps/meteor/client/views/omnichannel/tags/TagsTable.tsx b/apps/meteor/client/views/omnichannel/tags/TagsTable.tsx index 00ea16484f7c6..2515e82a1fa29 100644 --- a/apps/meteor/client/views/omnichannel/tags/TagsTable.tsx +++ b/apps/meteor/client/views/omnichannel/tags/TagsTable.tsx @@ -101,11 +101,11 @@ const TagsTable = () => { )} {isSuccess && data?.tags.length > 0 && ( <> - + {headers} {data?.tags.map(({ _id, name, description }) => ( - onRowClick(_id)} action qa-user-id={_id}> + onRowClick(_id)} action> {name} {description} diff --git a/apps/meteor/client/views/omnichannel/triggers/TriggersRow.tsx b/apps/meteor/client/views/omnichannel/triggers/TriggersRow.tsx index ca381f25e02d2..fbf7431cfab0c 100644 --- a/apps/meteor/client/views/omnichannel/triggers/TriggersRow.tsx +++ b/apps/meteor/client/views/omnichannel/triggers/TriggersRow.tsx @@ -47,7 +47,7 @@ const TriggersRow = ({ _id, name, description, enabled, reload }: TriggersRowPro }); return ( - + {name} {description} {enabled ? t('Yes') : t('No')} diff --git a/apps/meteor/client/views/omnichannel/triggers/TriggersTable.tsx b/apps/meteor/client/views/omnichannel/triggers/TriggersTable.tsx index 081c27e472a73..1770d14094777 100644 --- a/apps/meteor/client/views/omnichannel/triggers/TriggersTable.tsx +++ b/apps/meteor/client/views/omnichannel/triggers/TriggersTable.tsx @@ -71,7 +71,7 @@ const TriggersTable = () => { )} {isSuccess && data.triggers.length > 0 && ( <> - + {headers} {data.triggers.map(({ _id, name, description, enabled }) => ( diff --git a/apps/meteor/client/views/omnichannel/units/UnitEdit.tsx b/apps/meteor/client/views/omnichannel/units/UnitEdit.tsx index 77cab5e92af63..a14aba067cb80 100644 --- a/apps/meteor/client/views/omnichannel/units/UnitEdit.tsx +++ b/apps/meteor/client/views/omnichannel/units/UnitEdit.tsx @@ -161,7 +161,7 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, /> {errors?.name && ( - + {errors?.name.message} )} @@ -189,7 +189,11 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, )} /> - {errors?.visibility && {errors?.visibility.message}} + {errors?.visibility && ( + + {errors?.visibility.message} + + )} @@ -218,13 +222,13 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, /> {errors?.departments && ( - + {errors?.departments.message} )} - + {t('Monitors')} @@ -234,13 +238,13 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, rules={{ required: t('Required_field', { field: t('Monitors') }) }} render={({ field: { name, value, onChange, onBlur } }) => ( @@ -248,7 +252,7 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, /> {errors?.monitors && ( - + {errors?.monitors.message} )} diff --git a/apps/meteor/client/views/omnichannel/units/UnitTableRow.tsx b/apps/meteor/client/views/omnichannel/units/UnitTableRow.tsx index 2b546024b268a..a97bf405c6484 100644 --- a/apps/meteor/client/views/omnichannel/units/UnitTableRow.tsx +++ b/apps/meteor/client/views/omnichannel/units/UnitTableRow.tsx @@ -14,7 +14,7 @@ const UnitsTableRow = ({ _id, name, visibility }: { _id: string; name: string; v const handleDelete = useRemoveUnit(_id); return ( - + {name} {visibility} @@ -22,7 +22,6 @@ const UnitsTableRow = ({ _id, name, visibility }: { _id: string; name: string; v icon='trash' small title={t('Remove')} - data-qa-id={`remove-unit-${name}`} onClick={(e) => { e.stopPropagation(); handleDelete(); diff --git a/apps/meteor/client/views/omnichannel/units/UnitsTable.tsx b/apps/meteor/client/views/omnichannel/units/UnitsTable.tsx index ed4a0f88c8e36..0fc76f74e684f 100644 --- a/apps/meteor/client/views/omnichannel/units/UnitsTable.tsx +++ b/apps/meteor/client/views/omnichannel/units/UnitsTable.tsx @@ -96,7 +96,7 @@ const UnitsTable = () => { )} {isSuccess && data?.units.length > 0 && ( <> - + {headers} {data.units.map(({ _id, name, visibility }) => ( diff --git a/apps/meteor/client/views/omnichannel/units/useRemoveUnit.tsx b/apps/meteor/client/views/omnichannel/units/useRemoveUnit.tsx index ba5b9131f2c7f..4beea2ebb5326 100644 --- a/apps/meteor/client/views/omnichannel/units/useRemoveUnit.tsx +++ b/apps/meteor/client/views/omnichannel/units/useRemoveUnit.tsx @@ -28,15 +28,7 @@ export const useRemoveUnit = (id: string) => { } }; - setModal( - setModal()} - confirmText={t('Delete')} - />, - ); + setModal( setModal()} confirmText={t('Delete')} />); }); return handleDelete; diff --git a/apps/meteor/client/views/room/Header/icons/Encrypted.tsx b/apps/meteor/client/views/room/Header/icons/Encrypted.tsx index a4386d6b86336..65ffd3ecac502 100644 --- a/apps/meteor/client/views/room/Header/icons/Encrypted.tsx +++ b/apps/meteor/client/views/room/Header/icons/Encrypted.tsx @@ -1,5 +1,5 @@ import type { IRoom } from '@rocket.chat/core-typings'; -import colors from '@rocket.chat/fuselage-tokens/colors'; +import colors from '@rocket.chat/fuselage-tokens/colors.json'; import { HeaderState } from '@rocket.chat/ui-client'; import { useSetting } from '@rocket.chat/ui-contexts'; import { memo } from 'react'; diff --git a/apps/meteor/definition/externals/rocket.chat/fuselage-tokens/colors.d.ts b/apps/meteor/definition/externals/rocket.chat/fuselage-tokens/colors.d.ts deleted file mode 100644 index d9d4090972a92..0000000000000 --- a/apps/meteor/definition/externals/rocket.chat/fuselage-tokens/colors.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module '@rocket.chat/fuselage-tokens/colors' { - const Colors: { - [key: string]: string; - }; - export = Colors; -} diff --git a/apps/meteor/jest.config.ts b/apps/meteor/jest.config.ts index 01d1fc9559519..6c13cd68ca135 100644 --- a/apps/meteor/jest.config.ts +++ b/apps/meteor/jest.config.ts @@ -19,6 +19,7 @@ export default { moduleNameMapper: { '^react($|/.+)': '/node_modules/react$1', + '^react-virtuoso($|/.+)': '/node_modules/react-virtuoso$1', '^react-dom($|/.+)': '/node_modules/react-dom$1', '^react-i18next($|/.+)': '/node_modules/react-i18next$1', '^@rocket.chat/(.+)': '/node_modules/@rocket.chat/$1', diff --git a/apps/meteor/tests/e2e/administration.spec.ts b/apps/meteor/tests/e2e/administration.spec.ts index 30c26ead2815d..7b63a8cdf8f07 100644 --- a/apps/meteor/tests/e2e/administration.spec.ts +++ b/apps/meteor/tests/e2e/administration.spec.ts @@ -91,12 +91,12 @@ test.describe.parallel('administration', () => { const username = faker.internet.userName(); await poAdminUsers.btnNewUser.click(); - await poAdminUsers.editUser.inputName.type(faker.person.firstName()); - await poAdminUsers.editUser.inputUserName.type(username); - await poAdminUsers.editUser.inputEmail.type(faker.internet.email()); + await poAdminUsers.editUser.inputName.fill(faker.person.firstName()); + await poAdminUsers.editUser.inputUserName.fill(username); + await poAdminUsers.editUser.inputEmail.fill(faker.internet.email()); await poAdminUsers.editUser.inputSetManually.click(); - await poAdminUsers.editUser.inputPassword.type('P@ssw0rd1234.!'); - await poAdminUsers.editUser.inputConfirmPassword.type('P@ssw0rd1234.!'); + await poAdminUsers.editUser.inputPassword.fill('P@ssw0rd1234.!'); + await poAdminUsers.editUser.inputConfirmPassword.fill('P@ssw0rd1234.!'); await expect(poAdminUsers.editUser.userRole).toBeVisible(); await expect(poAdminUsers.editUser.joinDefaultChannels).toBeVisible(); await poAdminUsers.editUser.btnAddUser.click(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-agents.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-agents.spec.ts index 2c7f203329d11..26ee32afd7215 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-agents.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-agents.spec.ts @@ -1,7 +1,7 @@ import { createFakeDepartment } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelAgents } from '../page-objects'; +import { OmnichannelAgents } from '../page-objects/omnichannel'; import { createDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; @@ -21,7 +21,7 @@ test.describe.serial('OC - Manage Agents', () => { poOmnichannelAgents = new OmnichannelAgents(page); await page.goto('/omnichannel'); - await poOmnichannelAgents.sidenav.linkAgents.click(); + await poOmnichannelAgents.sidebar.linkAgents.click(); }); // Ensure that there is no leftover data even if test fails @@ -42,20 +42,18 @@ test.describe.serial('OC - Manage Agents', () => { await test.step('expect add "user1" as agent', async () => { await poOmnichannelAgents.selectUsername('user1'); - await poOmnichannelAgents.btnAdd.click(); + await poOmnichannelAgents.btnAddAgent.click(); - await poOmnichannelAgents.inputSearch.fill('user1'); - await expect(poOmnichannelAgents.firstRowInTable).toBeVisible(); - await expect(poOmnichannelAgents.firstRowInTable).toHaveText('user1'); + await poOmnichannelAgents.search('user1'); + await expect(poOmnichannelAgents.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect remove "user1" as agent', async () => { - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.btnDeleteFirstRowInTable.click(); - await poOmnichannelAgents.btnModalRemove.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.deleteAgent('user1'); - await poOmnichannelAgents.inputSearch.fill('user1'); - await expect(poOmnichannelAgents.findRowByUsername('user1')).not.toBeVisible(); + await poOmnichannelAgents.search('user1'); + await expect(poOmnichannelAgents.table.findRowByName('user1')).not.toBeVisible(); }); }); @@ -63,26 +61,26 @@ test.describe.serial('OC - Manage Agents', () => { test.skip(IS_EE, 'Community Edition Only'); await poOmnichannelAgents.selectUsername('user1'); - await poOmnichannelAgents.btnAdd.click(); + await poOmnichannelAgents.btnAddAgent.click(); - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.firstRowInTable.click(); - await poOmnichannelAgents.btnEdit.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.table.findRowByName('user1').click(); + await poOmnichannelAgents.agentInfo.btnEdit.click(); await test.step('expect max chats fields to be hidden', async () => { - await expect(poOmnichannelAgents.inputMaxChats).toBeHidden(); + await expect(poOmnichannelAgents.editAgent.inputMaxChats).toBeHidden(); }); await test.step('expect update "user1" information', async () => { - await poOmnichannelAgents.selectStatus('Not available'); - await poOmnichannelAgents.selectDepartment(department.data.name); - await poOmnichannelAgents.btnSave.click(); + await poOmnichannelAgents.editAgent.selectStatus('Not Available'); + await poOmnichannelAgents.editAgent.selectDepartment(department.data.name); + await poOmnichannelAgents.editAgent.btnSave.click(); }); await test.step('expect removing "user1" via sidebar', async () => { - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.firstRowInTable.click(); - await poOmnichannelAgents.btnRemove.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.table.findRowByName('user1').click(); + await poOmnichannelAgents.agentInfo.btnRemove.click(); }); }); @@ -90,33 +88,33 @@ test.describe.serial('OC - Manage Agents', () => { test.skip(!IS_EE, 'Enterprise Only'); await poOmnichannelAgents.selectUsername('user1'); - await poOmnichannelAgents.btnAdd.click(); + await poOmnichannelAgents.btnAddAgent.click(); - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.findRowByUsername('user1').click(); - await poOmnichannelAgents.btnEdit.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.table.findRowByName('user1').click(); + await poOmnichannelAgents.agentInfo.btnEdit.click(); await test.step('expect max chats field to be visible', async () => { - await expect(poOmnichannelAgents.inputMaxChats).toBeVisible(); + await expect(poOmnichannelAgents.editAgent.inputMaxChats).toBeVisible(); }); await test.step('expect update "user1" information', async () => { - await poOmnichannelAgents.inputMaxChats.click(); - await poOmnichannelAgents.inputMaxChats.fill('2'); - await poOmnichannelAgents.btnSave.click(); + await poOmnichannelAgents.editAgent.inputMaxChats.click(); + await poOmnichannelAgents.editAgent.inputMaxChats.fill('2'); + await poOmnichannelAgents.editAgent.btnSave.click(); }); }); test('OC - Edit agent - Manage departments', async ({ page }) => { await poOmnichannelAgents.selectUsername('user1'); - await poOmnichannelAgents.btnAdd.click(); - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.findRowByUsername('user1').click(); + await poOmnichannelAgents.btnAddAgent.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.table.findRowByName('user1').click(); - await poOmnichannelAgents.btnEdit.click(); - await poOmnichannelAgents.selectDepartment(department.data.name); + await poOmnichannelAgents.agentInfo.btnEdit.click(); + await poOmnichannelAgents.editAgent.selectDepartment(department.data.name); const response = page.waitForResponse('**/api/v1/livechat/agents.saveInfo'); - await poOmnichannelAgents.btnSave.click(); + await poOmnichannelAgents.editAgent.btnSave.click(); /** * between saving and opening the agent info again it is necessary to @@ -127,18 +125,18 @@ test.describe.serial('OC - Manage Agents', () => { await response; - await expect(poOmnichannelAgents.editCtxBar).not.toBeVisible(); + await expect(poOmnichannelAgents.editAgent.root).not.toBeVisible(); await test.step('expect the selected department is visible', async () => { - await poOmnichannelAgents.findRowByUsername('user1').click(); + await poOmnichannelAgents.table.findRowByName('user1').click(); // mock the endpoint to use the one without pagination await page.route('/api/v1/livechat/department?showArchived=true', async (route) => { await route.fulfill({ json: { departments: [] } }); }); - await poOmnichannelAgents.btnEdit.click(); - await expect(poOmnichannelAgents.findSelectedDepartment(department.data.name)).toBeVisible(); + await poOmnichannelAgents.agentInfo.btnEdit.click(); + await expect(poOmnichannelAgents.editAgent.findSelectedDepartment(department.data.name)).toBeVisible(); }); }); @@ -159,32 +157,31 @@ test.describe.serial('OC - Manage Agents', () => { await test.step('expect to add agent', async () => { await poOmnichannelAgents.selectUsername('user1'); - await poOmnichannelAgents.btnAdd.click(); + await poOmnichannelAgents.btnAddAgent.click(); }); await test.step('expect to edit agent', async () => { - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.findRowByUsername('user1').click(); - await poOmnichannelAgents.btnEdit.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.table.findRowByName('user1').click(); + await poOmnichannelAgents.agentInfo.btnEdit.click(); }); await test.step('expect department field to be paginated', async () => { - await poOmnichannelAgents.inputDepartment.click(); - await expect(poOmnichannelAgents.findOption('Department 0')).toBeVisible(); + await poOmnichannelAgents.editAgent.inputDepartment.click(); + await expect(poOmnichannelAgents.editAgent.getDepartmentOption('Department 0')).toBeVisible(); await poOmnichannelAgents.scrollToListBottom(); - await expect(poOmnichannelAgents.findOption('Department 49')).toBeVisible(); + await expect(poOmnichannelAgents.editAgent.getDepartmentOption('Department 49')).toBeVisible(); await poOmnichannelAgents.scrollToListBottom(); - await expect(poOmnichannelAgents.findOption('Department 99')).toBeVisible(); - await poOmnichannelAgents.btnClose.click(); + await expect(poOmnichannelAgents.editAgent.getDepartmentOption('Department 99')).toBeVisible(); + await poOmnichannelAgents.editAgent.close(); }); await test.step('expect remove "user1" as agent', async () => { - await poOmnichannelAgents.inputSearch.fill('user1'); - await poOmnichannelAgents.btnDeleteFirstRowInTable.click(); - await poOmnichannelAgents.btnModalRemove.click(); + await poOmnichannelAgents.search('user1'); + await poOmnichannelAgents.deleteAgent('user1'); - await poOmnichannelAgents.inputSearch.fill('user1'); - await expect(poOmnichannelAgents.findRowByUsername('user1')).not.toBeVisible(); + await poOmnichannelAgents.search('user1'); + await expect(poOmnichannelAgents.table.findRowByName('user1')).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-appearance.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-appearance.spec.ts index e0d9f92df2ea6..f9a8747d3c3a1 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-appearance.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-appearance.spec.ts @@ -1,6 +1,6 @@ import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLivechatAppearance } from '../page-objects/omnichannel-livechat-appearance'; +import { OmnichannelLivechatAppearance } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); @@ -13,7 +13,7 @@ test.describe.serial('OC - Livechat Appearance - EE', () => { poLivechatAppearance = new OmnichannelLivechatAppearance(page); await page.goto('/omnichannel'); - await poLivechatAppearance.sidenav.linkLivechatAppearance.click(); + await poLivechatAppearance.sidebar.linkLivechatAppearance.click(); }); test.afterAll(async ({ api }) => { @@ -42,7 +42,7 @@ test.describe.serial('OC - Livechat Appearance - EE', () => { await poLivechatAppearance.inputHideSystemMessages.locator('.rcx-icon--name-chevron-down').click(); await poLivechatAppearance.findHideSystemMessageOption('livechat_transfer_history').click(); await poLivechatAppearance.findHideSystemMessageOption('livechat-close').click(); - await poLivechatAppearance.btnSave.click(); + await poLivechatAppearance.btnSaveChanges.click(); }); await test.step('expect to have saved changes', async () => { @@ -63,7 +63,7 @@ test.describe.serial('OC - Livechat Appearance - EE', () => { await test.step('expect to change value', async () => { await poLivechatAppearance.inputLivechatBackground.fill('rgb(186, 1, 85)'); - await poLivechatAppearance.btnSave.click(); + await poLivechatAppearance.btnSaveChanges.click(); }); await test.step('expect to have saved changes', async () => { @@ -80,7 +80,7 @@ test.describe('OC - Livechat Appearance - CE', () => { poLivechatAppearance = new OmnichannelLivechatAppearance(page); await page.goto('/omnichannel'); - await poLivechatAppearance.sidenav.linkLivechatAppearance.click(); + await poLivechatAppearance.sidebar.linkLivechatAppearance.click(); }); test.afterAll(async ({ api }) => { @@ -98,7 +98,7 @@ test.describe('OC - Livechat Appearance - CE', () => { await test.step('expect to change value', async () => { await poLivechatAppearance.inputLivechatTitle.fill('Test Title'); - await poLivechatAppearance.btnSave.click(); + await poLivechatAppearance.btnSaveChanges.click(); }); await test.step('expect to have saved changes', async () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-assign-room-tags.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-assign-room-tags.spec.ts index 187d3428a39ee..c3ceeae55d853 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-assign-room-tags.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-assign-room-tags.spec.ts @@ -81,31 +81,31 @@ test.describe('OC - Tags Visibility', () => { }); await test.step('check available tags', async () => { - await poOmnichannel.roomInfo.btnEditRoomInfo.click(); - await expect(poOmnichannel.roomInfo.dialogEditRoom).toBeVisible(); - await poOmnichannel.roomInfo.inputTags.click(); + await poOmnichannel.roomInfo.btnEdit.click(); + await expect(poOmnichannel.editRoomInfo.root).toBeVisible(); + await poOmnichannel.editRoomInfo.inputTags.click(); }); await test.step('Should see TagA (department A specific)', async () => { - await expect(poOmnichannel.roomInfo.optionTags(tagA.data.name)).toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(tagA.data.name)).toBeVisible(); }); await test.step('Should see SharedTag (both departments)', async () => { - await expect(poOmnichannel.roomInfo.optionTags(sharedTag.data.name)).toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(sharedTag.data.name)).toBeVisible(); }); await test.step('Should see Public Tags for all chats (no department restriction)', async () => { - await expect(poOmnichannel.roomInfo.optionTags(globalTag.data.name)).toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(globalTag.data.name)).toBeVisible(); }); await test.step('Should not see TagB (department B specific)', async () => { - await expect(poOmnichannel.roomInfo.optionTags(tagB.data.name)).not.toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(tagB.data.name)).not.toBeVisible(); }); await test.step('add tags and save', async () => { - await poOmnichannel.roomInfo.selectTag(tagA.data.name); - await poOmnichannel.roomInfo.selectTag(globalTag.data.name); - await poOmnichannel.roomInfo.btnSaveEditRoom.click(); + await poOmnichannel.editRoomInfo.selectTag(tagA.data.name); + await poOmnichannel.editRoomInfo.selectTag(globalTag.data.name); + await poOmnichannel.editRoomInfo.btnSave.click(); }); await test.step('verify selected tags are displayed under room information', async () => { @@ -118,17 +118,17 @@ test.describe('OC - Tags Visibility', () => { test('Verify tags visibility for agent associated with multiple departments', async () => { await test.step('Open room info', async () => { await poOmnichannel.sidebar.getSidebarItemByName(visitorB.name).click(); - await poOmnichannel.roomInfo.btnEditRoomInfo.click(); - await expect(poOmnichannel.roomInfo.dialogEditRoom).toBeVisible(); - await poOmnichannel.roomInfo.inputTags.click(); + await poOmnichannel.roomInfo.btnEdit.click(); + await expect(poOmnichannel.editRoomInfo.root).toBeVisible(); + await poOmnichannel.editRoomInfo.inputTags.click(); }); await test.step('Agent associated with DepartmentB should be able to see tags for Department B', async () => { - await expect(poOmnichannel.roomInfo.optionTags(tagB.data.name)).toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(tagB.data.name)).toBeVisible(); }); await test.step('Agent associated with DepartmentB should not be able to see tags for DepartmentA', async () => { - await expect(poOmnichannel.roomInfo.optionTags(tagA.data.name)).not.toBeVisible(); + await expect(poOmnichannel.editRoomInfo.optionTag(tagA.data.name)).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-onhold-chat-closing.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-onhold-chat-closing.spec.ts index 56875ec87f0dc..9789d0b858850 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-onhold-chat-closing.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-onhold-chat-closing.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('omnichannel-auto-onhold-chat-closing', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-transfer-unanswered-chat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-transfer-unanswered-chat.spec.ts index 4fcae544ea84f..f8dc8c1833292 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-transfer-unanswered-chat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-auto-transfer-unanswered-chat.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { HomeChannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('omnichannel-auto-transfer-unanswered-chat', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-business-hours.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-business-hours.spec.ts index f1904e053cd1c..40a064256c401 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-business-hours.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-business-hours.spec.ts @@ -2,7 +2,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelBusinessHours } from '../page-objects'; +import { OmnichannelBusinessHours } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { createBusinessHour } from '../utils/omnichannel/businessHours'; import { createDepartment } from '../utils/omnichannel/departments'; @@ -10,6 +10,7 @@ import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); +// TODO: These tests needs to be refactored to be independent from each other test.describe('OC - Business Hours', () => { test.skip(!IS_EE, 'OC - Manage Business Hours > Enterprise Edition Only'); @@ -42,7 +43,7 @@ test.describe('OC - Business Hours', () => { test('OC - Manage Business Hours - Create Business Hours', async ({ page }) => { await page.goto('/omnichannel'); - await poOmnichannelBusinessHours.sidenav.linkBusinessHours.click(); + await poOmnichannelBusinessHours.sidebar.linkBusinessHours.click(); await test.step('expect correct form default state', async () => { await poOmnichannelBusinessHours.btnCreateBusinessHour.click(); @@ -58,29 +59,17 @@ test.describe('OC - Business Hours', () => { await test.step('expect business hours to have been created', async () => { await poOmnichannelBusinessHours.search(BHName); - await expect(poOmnichannelBusinessHours.findRowByName(BHName)).toBeVisible(); + await expect(poOmnichannelBusinessHours.table.findRowByName(BHName)).toBeVisible(); }); }); await test.step('expect to be able to delete business hours', async () => { - await test.step('expect to be able to cancel delete', async () => { - await poOmnichannelBusinessHours.btnDeleteByName(BHName).click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).toBeVisible(); - await poOmnichannelBusinessHours.btnCancelDeleteModal.click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).not.toBeVisible(); - }); - - await test.step('expect to confirm delete', async () => { - await poOmnichannelBusinessHours.btnDeleteByName(BHName).click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).toBeVisible(); - await poOmnichannelBusinessHours.btnConfirmDeleteModal.click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).not.toBeVisible(); - }); + await poOmnichannelBusinessHours.deleteBusinessHour(BHName); }); await test.step('expect business hours to have been deleted', async () => { await poOmnichannelBusinessHours.search(BHName); - await expect(poOmnichannelBusinessHours.findRowByName(BHName)).not.toBeVisible(); + await expect(poOmnichannelBusinessHours.table.findRowByName(BHName)).not.toBeVisible(); }); }); @@ -95,41 +84,38 @@ test.describe('OC - Business Hours', () => { }); await page.goto('/omnichannel'); - await poOmnichannelBusinessHours.sidenav.linkBusinessHours.click(); + await poOmnichannelBusinessHours.sidebar.linkBusinessHours.click(); await test.step('expect to add business hours departments', async () => { await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await poOmnichannelBusinessHours.selectDepartment(department2.data.name); await poOmnichannelBusinessHours.btnSave.click(); }); await test.step('expect department to be in the chosen departments list', async () => { await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await expect(poOmnichannelBusinessHours.findDepartmentsChipOption(department2.data.name)).toBeVisible(); await poOmnichannelBusinessHours.btnBack.click(); }); await test.step('expect to remove business hours departments', async () => { await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await poOmnichannelBusinessHours.selectDepartment(department2.data.name); await poOmnichannelBusinessHours.btnSave.click(); }); await test.step('expect department to not be in the chosen departments list', async () => { await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await expect(poOmnichannelBusinessHours.findDepartmentsChipOption(department2.data.name)).toBeHidden(); await poOmnichannelBusinessHours.btnBack.click(); }); await test.step('expect delete business hours', async () => { - await poOmnichannelBusinessHours.btnDeleteByName(BHName).click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).toBeVisible(); - await poOmnichannelBusinessHours.btnConfirmDeleteModal.click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).not.toBeVisible(); + await poOmnichannelBusinessHours.deleteBusinessHour(BHName); }); }); @@ -144,13 +130,13 @@ test.describe('OC - Business Hours', () => { }); await page.goto('/omnichannel'); - await poOmnichannelBusinessHours.sidenav.linkBusinessHours.click(); + await poOmnichannelBusinessHours.sidebar.linkBusinessHours.click(); await test.step('expect to disable business hours', async () => { - await poOmnichannelBusinessHours.sidenav.linkBusinessHours.click(); + await poOmnichannelBusinessHours.sidebar.linkBusinessHours.click(); await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await poOmnichannelBusinessHours.getCheckboxByLabel('Enabled').click(); await expect(poOmnichannelBusinessHours.getCheckboxByLabel('Enabled')).not.toBeChecked(); @@ -159,10 +145,10 @@ test.describe('OC - Business Hours', () => { }); await test.step('expect to enable business hours', async () => { - await poOmnichannelBusinessHours.sidenav.linkBusinessHours.click(); + await poOmnichannelBusinessHours.sidebar.linkBusinessHours.click(); await poOmnichannelBusinessHours.search(BHName); - await poOmnichannelBusinessHours.findRowByName(BHName).click(); + await poOmnichannelBusinessHours.table.findRowByName(BHName).click(); await poOmnichannelBusinessHours.getCheckboxByLabel('Enabled').click(); await expect(poOmnichannelBusinessHours.getCheckboxByLabel('Enabled')).toBeChecked(); @@ -171,9 +157,7 @@ test.describe('OC - Business Hours', () => { }); await test.step('expect delete business hours', async () => { - await poOmnichannelBusinessHours.btnDeleteByName(BHName).click(); - await expect(poOmnichannelBusinessHours.confirmDeleteModal).toBeVisible(); - await poOmnichannelBusinessHours.btnConfirmDeleteModal.click(); + await poOmnichannelBusinessHours.deleteBusinessHour(BHName); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-sidebar.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-sidebar.spec.ts index 52434f08e4f72..c81117b4dcb90 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-sidebar.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-sidebar.spec.ts @@ -5,7 +5,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test } from '../utils/test'; test.describe.serial('OC - Canned Responses Sidebar', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-usage.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-usage.spec.ts index 15daec85c8070..a6c8be054e005 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-usage.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-canned-responses-usage.spec.ts @@ -5,7 +5,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('OC - Canned Responses Usage', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-changing-room-priority-and-sla.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-changing-room-priority-and-sla.spec.ts index 4dcecb76d5d06..47ee200924cfb 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-changing-room-priority-and-sla.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-changing-room-priority-and-sla.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { ADMIN_CREDENTIALS, IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { HomeChannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { getPriorityByi18nLabel } from '../utils/omnichannel/priority'; import { createSLA } from '../utils/omnichannel/sla'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-history.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-history.spec.ts index 52823f0aefd2f..a9b4137365532 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-history.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-history.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('Omnichannel chat history', () => { @@ -49,11 +50,11 @@ test.describe('Omnichannel chat history', () => { }); await test.step('expect to be able to edit room info', async () => { - await agent.poHomeOmnichannel.roomInfo.btnEditRoomInfo.click(); - await agent.poHomeOmnichannel.roomInfo.inputTopic.fill('any_topic'); - await agent.poHomeOmnichannel.roomInfo.btnSaveEditRoom.click(); + await agent.poHomeOmnichannel.roomInfo.btnEdit.click(); + await agent.poHomeOmnichannel.editRoomInfo.inputTopic.fill('any_topic'); + await agent.poHomeOmnichannel.editRoomInfo.btnSave.click(); - await expect(agent.poHomeOmnichannel.roomInfo.dialogRoomInfo).toContainText('any_topic'); + await expect(agent.poHomeOmnichannel.roomInfo.root).toContainText('any_topic'); }); await test.step('Expect to be able to close an omnichannel to conversation', async () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-close-chat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-close-chat.spec.ts index e4a7dabc5fd06..936d4c93ea2fd 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-close-chat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-close-chat.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test } from '../utils/test'; test.describe('Omnichannel close chat', () => { 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 da744ce849e94..28fa3f2d1f758 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-close-inquiry.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('Omnichannel close inquiry', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats-filters.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats-filters.spec.ts index 9a62b6b376fac..9cebdc580443c 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats-filters.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats-filters.spec.ts @@ -1,7 +1,7 @@ import { faker } from '@faker-js/faker/locale/af_ZA'; import { Users } from '../fixtures/userStates'; -import { OmnichannelChats } from '../page-objects/omnichannel-contact-center-chats'; +import { OmnichannelContactCenterChats } from '../page-objects/omnichannel'; import { setSettingValueById } from '../utils'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { createConversation } from '../utils/omnichannel/rooms'; @@ -13,7 +13,7 @@ test.describe('OC - Contact Center - Chats', () => { let conversations: Awaited>[]; let agent: Awaited>; - let poOmniChats: OmnichannelChats; + let poOmniChats: OmnichannelContactCenterChats; const uuid = faker.string.uuid(); const visitorA = `visitorA_${uuid}`; @@ -37,7 +37,7 @@ test.describe('OC - Contact Center - Chats', () => { }); test.beforeEach(async ({ page }) => { - poOmniChats = new OmnichannelChats(page); + poOmniChats = new OmnichannelContactCenterChats(page); await page.goto('/omnichannel-directory/chats'); }); @@ -54,8 +54,8 @@ test.describe('OC - Contact Center - Chats', () => { test(`OC - Contact Center - Chats - Filter from and to same date`, async ({ page }) => { await test.step('expect conversations to be visible', async () => { await poOmniChats.inputSearch.fill(uuid); - await expect(poOmniChats.findRowByName(visitorA)).toBeVisible(); - await expect(poOmniChats.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); }); await test.step('expect to filter [from] and [to] today', async () => { @@ -70,8 +70,8 @@ test.describe('OC - Contact Center - Chats', () => { }); await test.step('expect conversations to be visible', async () => { - await expect(poOmniChats.findRowByName(visitorA)).toBeVisible(); - await expect(poOmniChats.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats.spec.ts index 3e46bfc04960b..873fc625f8686 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-chats.spec.ts @@ -3,23 +3,24 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelChats } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelContactCenterChats } from '../page-objects/omnichannel'; 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(); +const visitorA = `${faker.person.firstName()}-${faker.database.mongodbObjectId()}`; +const visitorB = `${faker.person.firstName()}-${faker.database.mongodbObjectId()}`; +const visitorC = `${faker.person.firstName()}-${faker.database.mongodbObjectId()}`; test.skip(!IS_EE, 'OC - Contact Center Chats > Enterprise Only'); test.use({ storageState: Users.admin.state }); test.describe('OC - Contact Center Chats [Auto Selection]', async () => { - let poOmnichats: OmnichannelChats; + let poOmnichats: OmnichannelContactCenterChats; let poHomeOmnichannel: HomeOmnichannel; let departments: Awaited>[]; let conversations: Awaited>[]; @@ -110,10 +111,11 @@ test.describe('OC - Contact Center Chats [Auto Selection]', async () => { }); test.beforeEach(async ({ page }: { page: Page }) => { - poOmnichats = new OmnichannelChats(page); + poOmnichats = new OmnichannelContactCenterChats(page); + poHomeOmnichannel = new HomeOmnichannel(page); await page.goto('/omnichannel'); - await poOmnichats.sidenav.linkCurrentChats.click(); + await poOmnichats.sidebar.linkCurrentChats.click(); }); test.afterAll(async ({ api }) => { @@ -147,14 +149,12 @@ test.describe('OC - Contact Center Chats [Auto Selection]', async () => { test('OC - Contact Center Chats - Basic navigation', async ({ page }) => { await test.step('expect to be return using return button', async () => { await poOmnichats.openChat(visitorA); - await poOmnichats.content.btnReturn.click(); + await poHomeOmnichannel.content.btnReturn.click(); expect(page.url()).toContain(`/omnichannel/current`); }); }); - test('OC - Contact Center Chats - Access in progress conversation from another agent', async ({ page }) => { - poHomeOmnichannel = new HomeOmnichannel(page); - + test('OC - Contact Center Chats - Access in progress conversation from another agent', async () => { await test.step('expect to be able to join', async () => { const { visitor: visitorB } = conversations[1].data; await poOmnichats.openChat(visitorB.name); @@ -167,7 +167,7 @@ test.describe('OC - Contact Center Chats [Auto Selection]', async () => { test('OC - Contact Center Chats - Remove conversations', async () => { await test.step('expect to be able to remove conversation from table', async () => { await poOmnichats.removeChatByName(visitorC); - await expect(poOmnichats.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmnichats.table.findRowByName(visitorC)).not.toBeVisible(); }); // TODO: await test.step('expect to be able to close all closes conversations', async () => {}); @@ -176,7 +176,8 @@ test.describe('OC - Contact Center Chats [Auto Selection]', async () => { test.describe('OC - Contact Center [Manual Selection]', () => { let queuedConversation: Awaited>; - let poCurrentChats: OmnichannelChats; + let poHomeOmnichannel: HomeOmnichannel; + let poCurrentChats: OmnichannelContactCenterChats; let agent: Awaited>; test.beforeAll(async ({ api }) => { @@ -193,10 +194,11 @@ test.describe('OC - Contact Center [Manual Selection]', () => { }); test.beforeEach(async ({ page }: { page: Page }) => { - poCurrentChats = new OmnichannelChats(page); + poCurrentChats = new OmnichannelContactCenterChats(page); + poHomeOmnichannel = new HomeOmnichannel(page); await page.goto('/omnichannel'); - await poCurrentChats.sidenav.linkCurrentChats.click(); + await poCurrentChats.sidebar.linkCurrentChats.click(); }); test('OC - Contact Center Chats - Access queued conversation', async ({ api }) => { @@ -206,9 +208,9 @@ test.describe('OC - Contact Center [Manual Selection]', () => { const { visitor } = queuedConversation.data; await poCurrentChats.inputSearch.fill(visitor.name); await poCurrentChats.openChat(visitor.name); - await expect(poCurrentChats.content.btnTakeChat).toBeVisible(); - await poCurrentChats.content.btnTakeChat.click(); - await expect(poCurrentChats.content.btnTakeChat).not.toBeVisible(); + await expect(poHomeOmnichannel.content.btnTakeChat).toBeVisible(); + await poHomeOmnichannel.content.btnTakeChat.click(); + await expect(poHomeOmnichannel.content.btnTakeChat).not.toBeVisible(); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-contacts.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-contacts.spec.ts index 15a38eba7f8de..14c54560a4af0 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-contacts.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-center-contacts.spec.ts @@ -3,8 +3,8 @@ import { randomBytes } from 'crypto'; import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; -import { OmnichannelContacts } from '../page-objects/omnichannel-contacts-list'; -import { OmnichannelSection } from '../page-objects/omnichannel-section'; +import { Navbar } from '../page-objects/fragments'; +import { OmnichannelContactCenterContacts } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const createToken = (): string => { @@ -66,8 +66,8 @@ const ERROR = { test.use({ storageState: Users.admin.state }); test.describe('OC - Contact Center - Contacts', () => { - let poContacts: OmnichannelContacts; - let poOmniSection: OmnichannelSection; + let poContacts: OmnichannelContactCenterContacts; + let poNavbar: Navbar; test.beforeAll(async ({ api }) => { // Add contacts @@ -80,8 +80,8 @@ test.describe('OC - Contact Center - Contacts', () => { }); test.beforeEach(async ({ page }) => { - poContacts = new OmnichannelContacts(page); - poOmniSection = new OmnichannelSection(page); + poContacts = new OmnichannelContactCenterContacts(page); + poNavbar = new Navbar(page); }); test.afterEach(async ({ api }) => { @@ -104,8 +104,8 @@ test.describe('OC - Contact Center - Contacts', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); - await poOmniSection.btnContactCenter.click(); - await poOmniSection.tabContacts.click(); + await poNavbar.btnContactCenter.click(); + await poContacts.tabContacts.click(); await page.waitForURL(URL.contactCenter); }); @@ -113,75 +113,75 @@ test.describe('OC - Contact Center - Contacts', () => { await test.step('cancel button', async () => { await poContacts.btnNewContact.click(); await page.waitForURL(URL.newContact); - await expect(poContacts.newContact.inputName).toBeVisible(); - await poContacts.newContact.btnCancel.click(); + await expect(poContacts.editContact.inputName).toBeVisible(); + await poContacts.editContact.btnCancel.click(); await page.waitForURL(URL.contactCenter); - await expect(poContacts.newContact.inputName).not.toBeVisible(); + await expect(poContacts.editContact.inputName).not.toBeVisible(); }); await test.step('open contextual bar', async () => { await poContacts.btnNewContact.click(); await page.waitForURL(URL.newContact); - await expect(poContacts.newContact.inputName).toBeVisible(); + await expect(poContacts.editContact.inputName).toBeVisible(); }); await test.step('input name', async () => { - await poContacts.newContact.inputName.fill(NEW_CONTACT.name); + await poContacts.editContact.inputName.fill(NEW_CONTACT.name); }); await test.step('validate email format', async () => { - await poContacts.newContact.btnAddEmail.click(); - await poContacts.newContact.inputEmail.fill('invalidemail'); + await poContacts.editContact.btnAddEmail.click(); + await poContacts.editContact.inputEmail.fill('invalidemail'); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.invalidEmail)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.invalidEmail)).toBeVisible(); }); await test.step('validate email is duplicated', async () => { - await poContacts.newContact.inputEmail.fill(EXISTING_CONTACT.emails[0]); + await poContacts.editContact.inputEmail.fill(EXISTING_CONTACT.emails[0]); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailAlreadyExists)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailAlreadyExists)).toBeVisible(); }); await test.step('validate email is required', async () => { - await poContacts.newContact.inputEmail.clear(); + await poContacts.editContact.inputEmail.clear(); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailRequired)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailRequired)).toBeVisible(); }); await test.step('input email', async () => { - await poContacts.newContact.inputEmail.fill(NEW_CONTACT.email); + await poContacts.editContact.inputEmail.fill(NEW_CONTACT.email); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.invalidEmail)).not.toBeVisible(); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailRequired)).not.toBeVisible(); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailAlreadyExists)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.invalidEmail)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailRequired)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailAlreadyExists)).not.toBeVisible(); }); await test.step('validate phone is duplicated', async () => { - await poContacts.newContact.btnAddPhone.click(); - await poContacts.newContact.inputPhone.fill(EXISTING_CONTACT.phones[0]); + await poContacts.editContact.btnAddPhone.click(); + await poContacts.editContact.inputPhone.fill(EXISTING_CONTACT.phones[0]); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.phoneAlreadyExists)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.phoneAlreadyExists)).toBeVisible(); }); await test.step('input phone', async () => { - await poContacts.newContact.inputPhone.fill(NEW_CONTACT.phone); + await poContacts.editContact.inputPhone.fill(NEW_CONTACT.phone); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.phoneRequired)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.phoneRequired)).not.toBeVisible(); }); await test.step('save new contact', async () => { - await expect(poContacts.newContact.btnSave).toBeEnabled(); - await poContacts.newContact.btnSave.click(); + await expect(poContacts.editContact.btnSave).toBeEnabled(); + await poContacts.editContact.btnSave.click(); await poContacts.inputSearch.fill(NEW_CONTACT.name); - await expect(poContacts.findRowByName(NEW_CONTACT.name)).toBeVisible(); + await expect(poContacts.table.findRowByName(NEW_CONTACT.name)).toBeVisible(); }); }); test('Edit new contact', async ({ page }) => { await test.step('search contact and open contextual bar', async () => { await poContacts.inputSearch.fill(NEW_CONTACT.name); - const row = poContacts.findRowByName(NEW_CONTACT.name); + const row = poContacts.table.findRowByName(NEW_CONTACT.name); await expect(row).toBeVisible(); await row.click(); await page.waitForURL(URL.contactInfo); @@ -190,7 +190,7 @@ test.describe('OC - Contact Center - Contacts', () => { await test.step('cancel button', async () => { await poContacts.contactInfo.btnEdit.click(); await page.waitForURL(URL.editContact); - await poContacts.contactInfo.btnCancel.click(); + await poContacts.editContact.btnCancel.click(); await page.waitForURL(URL.contactInfo); }); @@ -200,93 +200,87 @@ test.describe('OC - Contact Center - Contacts', () => { }); await test.step('initial values', async () => { - await expect(poContacts.contactInfo.inputName).toHaveValue(NEW_CONTACT.name); - await expect(poContacts.contactInfo.inputEmail).toHaveValue(NEW_CONTACT.email); - await expect(poContacts.contactInfo.inputPhone).toHaveValue(NEW_CONTACT.phone); + await expect(poContacts.editContact.inputName).toHaveValue(NEW_CONTACT.name); + await expect(poContacts.editContact.inputEmail).toHaveValue(NEW_CONTACT.email); + await expect(poContacts.editContact.inputPhone).toHaveValue(NEW_CONTACT.phone); }); await test.step('validate email format', async () => { - await poContacts.newContact.inputEmail.fill('invalidemail'); + await poContacts.editContact.inputEmail.fill('invalidemail'); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.invalidEmail)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.invalidEmail)).toBeVisible(); }); await test.step('validate email is duplicated', async () => { - await poContacts.newContact.inputEmail.fill(EXISTING_CONTACT.emails[0]); + await poContacts.editContact.inputEmail.fill(EXISTING_CONTACT.emails[0]); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailAlreadyExists)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailAlreadyExists)).toBeVisible(); }); await test.step('validate email is required', async () => { - await poContacts.newContact.inputEmail.clear(); + await poContacts.editContact.inputEmail.clear(); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailRequired)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailRequired)).toBeVisible(); }); await test.step('validate name is required', async () => { - await poContacts.contactInfo.inputName.clear(); + await poContacts.editContact.inputName.clear(); await page.keyboard.press('Tab'); - await expect(poContacts.contactInfo.getErrorMessage(ERROR.nameRequired)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.nameRequired)).toBeVisible(); }); await test.step('edit name', async () => { - await poContacts.contactInfo.inputName.fill(EDIT_CONTACT.name); + await poContacts.editContact.inputName.fill(EDIT_CONTACT.name); }); await test.step('validate phone is duplicated', async () => { - await poContacts.newContact.inputPhone.fill(EXISTING_CONTACT.phones[0]); + await poContacts.editContact.inputPhone.fill(EXISTING_CONTACT.phones[0]); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.phoneAlreadyExists)).toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.phoneAlreadyExists)).toBeVisible(); }); await test.step('input phone ', async () => { - await poContacts.newContact.inputPhone.fill(EDIT_CONTACT.phone); + await poContacts.editContact.inputPhone.fill(EDIT_CONTACT.phone); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.phoneRequired)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.phoneRequired)).not.toBeVisible(); }); await test.step('input email', async () => { - await poContacts.newContact.inputEmail.fill(EDIT_CONTACT.email); + await poContacts.editContact.inputEmail.fill(EDIT_CONTACT.email); await page.keyboard.press('Tab'); - await expect(poContacts.newContact.getErrorMessage(ERROR.invalidEmail)).not.toBeVisible(); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailRequired)).not.toBeVisible(); - await expect(poContacts.newContact.getErrorMessage(ERROR.emailAlreadyExists)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.invalidEmail)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailRequired)).not.toBeVisible(); + await expect(poContacts.editContact.getErrorMessage(ERROR.emailAlreadyExists)).not.toBeVisible(); }); await test.step('save new contact ', async () => { - await poContacts.contactInfo.btnSave.click(); + await poContacts.editContact.btnSave.click(); await poContacts.inputSearch.fill(EDIT_CONTACT.name); - await expect(poContacts.findRowByName(EDIT_CONTACT.name)).toBeVisible(); + await expect(poContacts.table.findRowByName(EDIT_CONTACT.name)).toBeVisible(); }); }); test('Delete a contact', async () => { await test.step('Find contact and open modal', async () => { await poContacts.inputSearch.fill(DELETE_CONTACT.name); - await poContacts.findRowMenu(DELETE_CONTACT.name).click(); - await poContacts.findMenuItem('Delete').click(); + await poContacts.deleteContact(DELETE_CONTACT.name); }); await test.step('Fill confirmation and delete contact', async () => { - await expect(poContacts.deleteContactModal).toBeVisible(); - await expect(poContacts.btnDeleteContact).toBeDisabled(); - // Fills the input with the wrong confirmation - await poContacts.inputDeleteContactConfirmation.fill('wrong'); - await expect(poContacts.btnDeleteContact).toBeDisabled(); + await poContacts.deleteContactModal.inputConfirmation.fill('wrong'); + await expect(poContacts.deleteContactModal.btnDelete).toBeDisabled(); // Fills the input correctly - await poContacts.inputDeleteContactConfirmation.fill('delete'); - await expect(poContacts.btnDeleteContact).toBeEnabled(); - await poContacts.btnDeleteContact.click(); - - await expect(poContacts.deleteContactModal).not.toBeVisible(); + await poContacts.deleteContactModal.inputConfirmation.fill('delete'); + await expect(poContacts.deleteContactModal.btnDelete).toBeEnabled(); + await poContacts.deleteContactModal.delete(); }); await test.step('Confirm contact removal', async () => { await poContacts.inputSearch.fill(DELETE_CONTACT.name); - await expect(poContacts.findRowByName(DELETE_CONTACT.name)).not.toBeVisible(); + await expect(poContacts.table.findRowByName(DELETE_CONTACT.name)).not.toBeVisible(); }); }); }); 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 f84707292cb84..bbe5a52572ab6 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,8 +1,8 @@ import { createFakeVisitor } from '../../mocks/data'; 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 { Navbar } from '../page-objects/fragments'; +import { OmnichannelContactCenterChats } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; import { createConversation, updateRoom } from '../utils/omnichannel/rooms'; @@ -29,8 +29,8 @@ test.describe('OC - Contact Center', async () => { let tagA: Awaited>; let tagB: Awaited>; let units: Awaited>[]; - let poContacts: OmnichannelContacts; - let poOmniSection: OmnichannelSection; + let poNavbar: Navbar; + let poOmniChats: OmnichannelContactCenterChats; // Allow manual on hold test.beforeAll(async ({ api }) => { @@ -164,11 +164,12 @@ test.describe('OC - Contact Center', async () => { }); test.beforeEach(async ({ page }) => { - poContacts = new OmnichannelContacts(page); - poOmniSection = new OmnichannelSection(page); + poOmniChats = new OmnichannelContactCenterChats(page); + poNavbar = new Navbar(page); + await page.goto('/'); - await poOmniSection.btnContactCenter.click(); - await poContacts.tabChats.click(); + await poNavbar.btnContactCenter.click(); + await poOmniChats.tabChats.click(); await page.waitForURL(URL.contactCenterChats); }); @@ -177,131 +178,131 @@ test.describe('OC - Contact Center', async () => { const [unitA, unitB] = units.map((unit) => unit.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.btnSearchChip(visitorA)).toBeVisible(); - - await poContacts.inputSearch.fill(''); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await poOmniChats.inputSearch.fill(visitorA); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.btnSearchChip(visitorA)).toBeVisible(); + + await poOmniChats.inputSearch.fill(''); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.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 expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); - await poContacts.btnFilters.click(); + await poOmniChats.btnFilters.click(); // Select user1 - await poContacts.selectServedBy('user1'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.btnServedByChip('user1')).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await poOmniChats.filters.selectServedBy('user1'); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.btnServedByChip('user1')).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); // Select user2 - await poContacts.btnServedByChip('user1').locator('i').click(); - await poContacts.selectServedBy('user2'); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - await expect(poContacts.btnServedByChip('user2')).toBeVisible(); + await poOmniChats.btnServedByChip('user1').locator('i').click(); + await poOmniChats.filters.selectServedBy('user2'); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); + await expect(poOmniChats.btnServedByChip('user2')).toBeVisible(); // Select all users - await poContacts.btnServedByChip('user2').locator('i').click(); - await poContacts.selectServedBy('user1'); - await poContacts.selectServedBy('user2'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await poContacts.btnServedByChip('user1').locator('i').click(); + await poOmniChats.btnServedByChip('user2').locator('i').click(); + await poOmniChats.filters.selectServedBy('user1'); + await poOmniChats.filters.selectServedBy('user2'); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await poOmniChats.btnServedByChip('user1').locator('i').click(); }); 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.btnStatusChip('Closed')).toBeVisible(); - - 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.btnStatusChip('Open')).toBeVisible(); - - await poContacts.selectStatus('all'); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); - - 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.btnStatusChip('On hold')).toBeVisible(); - await poContacts.btnStatusChip('On hold').locator('i').click(); + await poOmniChats.filters.selectStatus('Closed'); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).toBeVisible(); + await expect(poOmniChats.btnStatusChip('Closed')).toBeVisible(); + + await poOmniChats.filters.selectStatus('Open'); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmniChats.btnStatusChip('Open')).toBeVisible(); + + await poOmniChats.filters.selectStatus('all'); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).toBeVisible(); + + await poOmniChats.filters.selectStatus('On hold'); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmniChats.btnStatusChip('On hold')).toBeVisible(); + await poOmniChats.btnStatusChip('On hold').locator('i').click(); }); await test.step('expect to filter by department', async () => { // select department A - 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.btnDepartmentChip(departmentA.name)).toBeVisible(); - await poContacts.btnDepartmentChip(departmentA.name).locator('i').click(); + await poOmniChats.filters.selectDepartment(departmentA.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmniChats.btnDepartmentChip(departmentA.name)).toBeVisible(); + await poOmniChats.btnDepartmentChip(departmentA.name).locator('i').click(); // select department B - 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.btnDepartmentChip(departmentB.name)).toBeVisible(); - await poContacts.btnDepartmentChip(departmentB.name).locator('i').click(); + await poOmniChats.filters.selectDepartment(departmentB.name); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmniChats.btnDepartmentChip(departmentB.name)).toBeVisible(); + await poOmniChats.btnDepartmentChip(departmentB.name).locator('i').click(); // select all departments - await poContacts.selectDepartment(departmentA.name); - await poContacts.selectDepartment(departmentB.name); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await poOmniChats.filters.selectDepartment(departmentA.name); + await poOmniChats.filters.selectDepartment(departmentB.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); }); await test.step('expect to filter by tags', async () => { - await poContacts.selectTag(tagA.data.name); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); + await poOmniChats.filters.selectTag(tagA.data.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); - await poContacts.selectTag(tagB.data.name); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); + await poOmniChats.filters.selectTag(tagB.data.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); - await poContacts.removeTag(tagA.data.name); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); + await poOmniChats.filters.removeTag(tagA.data.name); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); - await poContacts.removeTag(tagB.data.name); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); + await poOmniChats.filters.removeTag(tagB.data.name); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); }); await test.step('expect to filter by units', async () => { // select unitA - await poContacts.selectUnit(unitA.name); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await poContacts.btnUnitsChip(unitA.name).locator('i').click(); + await poOmniChats.filters.selectUnit(unitA.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await poOmniChats.btnUnitsChip(unitA.name).locator('i').click(); // select unitB - await poContacts.selectUnit(unitB.name); - await expect(poContacts.findRowByName(visitorA)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); - await poContacts.btnUnitsChip(unitB.name).locator('i').click(); + await poOmniChats.filters.selectUnit(unitB.name); + await expect(poOmniChats.table.findRowByName(visitorA)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); + await poOmniChats.btnUnitsChip(unitB.name).locator('i').click(); // no unit selected - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); }); }); @@ -310,32 +311,31 @@ test.describe('OC - Contact Center', async () => { const [unitA] = units.map((unit) => unit.data); await test.step('expect to display result as per applied filters ', async () => { - await poContacts.btnFilters.click(); - await poContacts.selectServedBy('user1'); - await poContacts.selectStatus('onhold'); - await poContacts.selectDepartment(departmentA.name); - await poContacts.selectTag(tagA.data.name); - await poContacts.selectUnit(unitA.name); - - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).not.toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).not.toBeVisible(); + await poOmniChats.btnFilters.click(); + await poOmniChats.filters.selectServedBy('user1'); + await poOmniChats.filters.selectStatus('On hold'); + await poOmniChats.filters.selectDepartment(departmentA.name); + await poOmniChats.filters.selectTag(tagA.data.name); + await poOmniChats.filters.selectUnit(unitA.name); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).not.toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).not.toBeVisible(); }); await test.step('expect to clear all filters ', async () => { - await poContacts.btnClearFilters.click(); - await expect(poContacts.findRowByName(visitorA)).toBeVisible(); - await expect(poContacts.findRowByName(visitorB)).toBeVisible(); - await expect(poContacts.findRowByName(visitorC)).toBeVisible(); + await poOmniChats.filters.btnClearFilters.click(); + await expect(poOmniChats.table.findRowByName(visitorA)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorB)).toBeVisible(); + await expect(poOmniChats.table.findRowByName(visitorC)).toBeVisible(); }); }); test('OC - Contact Center - Close contextual bar with filter screen', async () => { await test.step('expect to close filters contextual bar ', async () => { - await poContacts.btnFilters.click(); - await poContacts.btnClose.click(); - await expect(poContacts.btnFilters).toBeVisible(); - await expect(poContacts.btnClearFilters).not.toBeVisible(); + await poOmniChats.btnFilters.click(); + await poOmniChats.filters.close(); + await expect(poOmniChats.btnFilters).toBeVisible(); + await expect(poOmniChats.filters.btnClearFilters).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-info.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-info.spec.ts index c0e590cbd5545..b4e18cd88b442 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-info.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-info.spec.ts @@ -3,15 +3,15 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; -import { OmnichannelContacts } from '../page-objects/omnichannel-contacts-list'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { expect, test } from '../utils/test'; test.describe('Omnichannel contact info', () => { let poLiveChat: OmnichannelLiveChat; let newVisitor: { email: string; name: string }; - let agent: { page: Page; poHomeChannel: HomeOmnichannel; poContacts: OmnichannelContacts }; + let agent: { page: Page; poHomeChannel: HomeOmnichannel }; test.beforeAll(async ({ api, browser }) => { newVisitor = createFakeVisitor(); @@ -21,7 +21,7 @@ test.describe('Omnichannel contact info', () => { await api.post('/livechat/users/manager', { username: 'user1' }); const { page } = await createAuxContext(browser, Users.user1); - agent = { page, poHomeChannel: new HomeOmnichannel(page), poContacts: new OmnichannelContacts(page) }; + agent = { page, poHomeChannel: new HomeOmnichannel(page) }; }); test.beforeEach(async ({ page, api }) => { poLiveChat = new OmnichannelLiveChat(page, api); @@ -48,12 +48,12 @@ test.describe('Omnichannel contact info', () => { await test.step('Expect to be able to see contact information and edit', async () => { await agent.poHomeChannel.roomToolbar.openContactInfo(); - await agent.poHomeChannel.content.btnContactEdit.click(); + await agent.poHomeChannel.contacts.contactInfo.btnEdit.click(); }); await test.step('Expect to update room name and subscription when updating contact name', async () => { - await agent.poContacts.newContact.inputName.fill('Edited Contact Name'); - await agent.poContacts.newContact.btnSave.click(); + await agent.poHomeChannel.contacts.editContact.inputName.fill('Edited Contact Name'); + await agent.poHomeChannel.contacts.editContact.btnSave.click(); await expect(agent.poHomeChannel.sidebar.channelsList.getByText('Edited Contact Name')).toBeVisible(); await expect(agent.poHomeChannel.content.channelHeader.getByText('Edited Contact Name')).toBeVisible(); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts index 7dfc43ee40cc1..684e3f7c3f4af 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { HomeChannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { expect, test } from '../utils/test'; test.describe('OC - Contact Unknown Callout', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-custom-fields.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-custom-fields.spec.ts index 6749f6905466c..7613201c7afde 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-custom-fields.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-custom-fields.spec.ts @@ -1,5 +1,5 @@ import { Users } from '../fixtures/userStates'; -import { OmnichannelCustomFields } from '../page-objects'; +import { OmnichannelCustomFields } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); @@ -11,40 +11,38 @@ test.describe('omnichannel-customFields', () => { poOmnichannelCustomFields = new OmnichannelCustomFields(page); await page.goto('/omnichannel'); - await poOmnichannelCustomFields.sidenav.linkCustomFields.click(); + await poOmnichannelCustomFields.sidebar.linkCustomFields.click(); }); test('expect add new "custom field"', async ({ page }) => { - await poOmnichannelCustomFields.btnAdd.click(); + await poOmnichannelCustomFields.createNew(); await page.waitForURL('/omnichannel/customfields/new'); - await poOmnichannelCustomFields.inputField.type(newField); - await poOmnichannelCustomFields.inputLabel.type('any_label'); + await poOmnichannelCustomFields.manageCustomFields.inputField.fill(newField); + await poOmnichannelCustomFields.manageCustomFields.inputLabel.fill('any_label'); + await poOmnichannelCustomFields.manageCustomFields.save(); - await poOmnichannelCustomFields.btnSave.click(); - - await expect(poOmnichannelCustomFields.firstRowInTable(newField)).toBeVisible(); + await expect(poOmnichannelCustomFields.table.findRowByName(newField)).toBeVisible(); }); - test('expect update "newField"', async ({ page }) => { + test('expect update "newField"', async () => { const newLabel = 'new_any_label'; await poOmnichannelCustomFields.inputSearch.fill(newField); - await poOmnichannelCustomFields.firstRowInTable(newField).click(); + await poOmnichannelCustomFields.table.findRowByName(newField).click(); - await poOmnichannelCustomFields.inputLabel.fill('new_any_label'); - await poOmnichannelCustomFields.visibleLabel.click(); - await poOmnichannelCustomFields.btnSave.click(); + await poOmnichannelCustomFields.manageCustomFields.inputLabel.fill('new_any_label'); + await poOmnichannelCustomFields.manageCustomFields.labelVisible.click(); + await poOmnichannelCustomFields.manageCustomFields.save(); - await expect(page.locator(`[qa-user-id="${newField}"] td:nth-child(2)`)).toHaveText(newLabel); + await expect(poOmnichannelCustomFields.table.findRowByName(newField)).toContainText(newLabel); }); test('expect remove "new_field"', async () => { await poOmnichannelCustomFields.inputSearch.fill(newField); - await poOmnichannelCustomFields.firstRowInTable(newField).click(); - await poOmnichannelCustomFields.btnDeleteCustomField.click(); - await poOmnichannelCustomFields.btnModalRemove.click(); + await poOmnichannelCustomFields.table.findRowByName(newField).click(); + await poOmnichannelCustomFields.deleteCustomField(newField); await poOmnichannelCustomFields.inputSearch.fill(newField); - await expect(poOmnichannelCustomFields.firstRowInTable(newField)).toBeHidden(); + await expect(poOmnichannelCustomFields.table.findRowByName(newField)).toBeHidden(); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments-ce.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments-ce.spec.ts index aab1b27ff1d0d..922de338cdc70 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments-ce.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments-ce.spec.ts @@ -1,9 +1,8 @@ import { faker } from '@faker-js/faker'; -import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelDepartments } from '../page-objects'; +import { OmnichannelDepartments } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); @@ -11,39 +10,32 @@ test.use({ storageState: Users.admin.state }); test.describe.serial('OC - Manage Departments (CE)', () => { test.skip(IS_EE, 'Community Edition Only'); let poOmnichannelDepartments: OmnichannelDepartments; - let departmentName: string; test.beforeAll(async () => { departmentName = faker.string.uuid(); }); - test.beforeEach(async ({ page }: { page: Page }) => { + test.beforeEach(async ({ page }) => { poOmnichannelDepartments = new OmnichannelDepartments(page); await page.goto('/omnichannel'); - await poOmnichannelDepartments.sidenav.linkDepartments.click(); + await poOmnichannelDepartments.sidebar.linkDepartments.click(); }); test('OC - Manage Departments (CE) - Create department', async () => { await test.step('expect create new department', async () => { - await poOmnichannelDepartments.headingButtonNew('Create department').click(); - await poOmnichannelDepartments.btnEnabled.click(); - await poOmnichannelDepartments.inputName.fill(departmentName); - await poOmnichannelDepartments.inputEmail.fill(faker.internet.email()); - await poOmnichannelDepartments.btnSave.click(); - await poOmnichannelDepartments.toastMessage.dismissToast(); + await poOmnichannelDepartments.createNew(); + await poOmnichannelDepartments.createDepartment(departmentName, faker.internet.email()); await poOmnichannelDepartments.inputSearch.fill(departmentName); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentName)).toBeVisible(); }); await test.step('expect to not be possible adding a second department ', async () => { - await poOmnichannelDepartments.headingButtonNew('Create department').click(); - - await expect(poOmnichannelDepartments.upgradeDepartmentsModal).toBeVisible(); - - await poOmnichannelDepartments.btnUpgradeDepartmentsModalClose.click(); + await poOmnichannelDepartments.createNew(); + await poOmnichannelDepartments.upsellDepartmentsModal.waitForDisplay(); + await poOmnichannelDepartments.upsellDepartmentsModal.close(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments.spec.ts index e555c4da7f6a9..9070744d23f4c 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-departaments.spec.ts @@ -3,7 +3,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelDepartments } from '../page-objects'; +import { OmnichannelDepartments } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { createDepartment, deleteDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; @@ -39,38 +39,34 @@ test.describe('OC - Manage Departments', () => { poOmnichannelDepartments = new OmnichannelDepartments(page); await page.goto('/omnichannel'); - await poOmnichannelDepartments.sidenav.linkDepartments.click(); + await poOmnichannelDepartments.sidebar.linkDepartments.click(); }); test('Create department', async ({ page }) => { const departmentName = faker.string.uuid(); - await poOmnichannelDepartments.headingButtonNew('Create department').click(); + await poOmnichannelDepartments.createNew(); await test.step('expect name and email to be required', async () => { - await expect(poOmnichannelDepartments.invalidInputEmail).not.toBeVisible(); + await expect(poOmnichannelDepartments.errorMessage(ERROR.requiredName)).not.toBeVisible(); await poOmnichannelDepartments.inputName.fill('any_text'); await poOmnichannelDepartments.inputName.fill(''); - await expect(poOmnichannelDepartments.invalidInputName).toBeVisible(); await expect(poOmnichannelDepartments.errorMessage(ERROR.requiredName)).toBeVisible(); await poOmnichannelDepartments.inputName.fill('any_text'); - await expect(poOmnichannelDepartments.invalidInputName).not.toBeVisible(); + await expect(poOmnichannelDepartments.errorMessage(ERROR.requiredName)).not.toBeVisible(); await poOmnichannelDepartments.inputEmail.fill('any_text'); - await expect(poOmnichannelDepartments.invalidInputEmail).toBeVisible(); await expect(poOmnichannelDepartments.errorMessage(ERROR.invalidEmail)).toBeVisible(); await poOmnichannelDepartments.inputEmail.fill(''); - await expect(poOmnichannelDepartments.invalidInputEmail).toBeVisible(); await expect(poOmnichannelDepartments.errorMessage(ERROR.requiredEmail)).toBeVisible(); await poOmnichannelDepartments.inputEmail.fill(faker.internet.email()); - await expect(poOmnichannelDepartments.invalidInputEmail).not.toBeVisible(); await expect(poOmnichannelDepartments.errorMessage(ERROR.requiredEmail)).not.toBeVisible(); }); await test.step('expect to fill required fields', async () => { - await poOmnichannelDepartments.btnEnabled.click(); + await poOmnichannelDepartments.labelEnabled.click(); await poOmnichannelDepartments.inputName.fill(departmentName); await poOmnichannelDepartments.inputEmail.fill(faker.internet.email()); }); @@ -98,38 +94,38 @@ test.describe('OC - Manage Departments', () => { await poOmnichannelDepartments.inputAgents.fill('user1'); await poOmnichannelDepartments.findOption('user1 (@user1)').click(); await poOmnichannelDepartments.btnAddAgent.click(); - await expect(poOmnichannelDepartments.findAgentRow('user1')).toBeVisible(); + await expect(poOmnichannelDepartments.agentsTable.findRowByName('user1')).toBeVisible(); }); await test.step('expect create new department', async () => { await poOmnichannelDepartments.btnSave.click(); await poOmnichannelDepartments.search(departmentName); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentName)).toBeVisible(); }); await test.step('expect to delete department', async () => { await poOmnichannelDepartments.search(departmentName); - await poOmnichannelDepartments.selectedDepartmentMenu(departmentName).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(departmentName).click(); await poOmnichannelDepartments.menuDeleteOption.click(); await test.step('expect confirm delete department', async () => { await test.step('expect delete to be disabled when name is incorrect', async () => { - await expect(poOmnichannelDepartments.btnModalConfirmDelete).toBeDisabled(); - await poOmnichannelDepartments.inputModalConfirmDelete.fill('someramdomname'); - await expect(poOmnichannelDepartments.btnModalConfirmDelete).toBeDisabled(); + await expect(poOmnichannelDepartments.deleteModal.btnDelete).toBeDisabled(); + await poOmnichannelDepartments.deleteModal.inputConfirmDepartmentName.fill('someramdomname'); + await expect(poOmnichannelDepartments.deleteModal.btnDelete).toBeDisabled(); }); await test.step('expect to successfuly delete if department name is correct', async () => { - await expect(poOmnichannelDepartments.btnModalConfirmDelete).toBeDisabled(); - await poOmnichannelDepartments.inputModalConfirmDelete.fill(departmentName); - await expect(poOmnichannelDepartments.btnModalConfirmDelete).toBeEnabled(); - await poOmnichannelDepartments.btnModalConfirmDelete.click(); + await expect(poOmnichannelDepartments.deleteModal.btnDelete).toBeDisabled(); + await poOmnichannelDepartments.deleteModal.inputConfirmDepartmentName.fill(departmentName); + await expect(poOmnichannelDepartments.deleteModal.btnDelete).toBeEnabled(); + await poOmnichannelDepartments.deleteModal.deleteDepartment(departmentName); }); }); await test.step('expect department to have been deleted', async () => { await poOmnichannelDepartments.search(departmentName); - await expect(poOmnichannelDepartments.firstRowInTable).toHaveCount(0); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentName)).toHaveCount(0); }); }); }); @@ -152,63 +148,59 @@ test.describe('OC - Manage Departments', () => { test('Edit department', async () => { await test.step('expect create new department', async () => { await poOmnichannelDepartments.search(department.name); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); return department; }); await test.step('expect update department name', async () => { await poOmnichannelDepartments.search(department.name); - - await poOmnichannelDepartments.firstRowInTableMenu.click(); + await poOmnichannelDepartments.getDepartmentMenuByName(department.name).click(); await poOmnichannelDepartments.menuEditOption.click(); await poOmnichannelDepartments.inputName.fill(`edited-${department.name}`); await poOmnichannelDepartments.btnSave.click(); await poOmnichannelDepartments.search(`edited-${department.name}`); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(`edited-${department.name}`)).toBeVisible(); }); }); test('Archive department', async () => { await test.step('expect create new department', async () => { await poOmnichannelDepartments.search(department.name); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); }); await test.step('expect archive department', async () => { await poOmnichannelDepartments.search(department.name); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); - await poOmnichannelDepartments.firstRowInTableMenu.click(); - await poOmnichannelDepartments.menuArchiveOption.click(); - await poOmnichannelDepartments.toastMessage.waitForDisplay(); - - await poOmnichannelDepartments.archivedDepartmentsTab.click(); + await poOmnichannelDepartments.archiveDepartmentByName(department.name); + await poOmnichannelDepartments.tabArchivedDepartments.click(); await poOmnichannelDepartments.search(department.name); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); }); await test.step('expect archived department to not be editable', async () => { - await poOmnichannelDepartments.firstRowInTableMenu.click(); + await poOmnichannelDepartments.getDepartmentMenuByName(department.name).click(); await expect(poOmnichannelDepartments.menuEditOption).not.toBeVisible(); }); await test.step('expect unarchive department', async () => { await poOmnichannelDepartments.menuUnarchiveOption.click(); - await expect(poOmnichannelDepartments.firstRowInTable).toHaveCount(0); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toHaveCount(0); }); }); test('Request tag(s) before closing conversation', async () => { await test.step('should create new department', async () => { await poOmnichannelDepartments.search(department.name); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); }); const tagName = faker.string.sample(5); - await poOmnichannelDepartments.firstRowInTableMenu.click(); + await poOmnichannelDepartments.getDepartmentMenuByName(department.name).click(); await poOmnichannelDepartments.menuEditOption.click(); await test.step('should form save button be disabled', async () => { @@ -216,8 +208,8 @@ test.describe('OC - Manage Departments', () => { }); await test.step('should be able to add a tag properly', async () => { - await poOmnichannelDepartments.inputTags.fill(tagName); - await poOmnichannelDepartments.btnTagsAdd.click(); + await poOmnichannelDepartments.inputConversationClosingTags.fill(tagName); + await poOmnichannelDepartments.btnAddTags.click(); await expect(poOmnichannelDepartments.btnTag(tagName)).toBeVisible(); await expect(poOmnichannelDepartments.btnSave).toBeEnabled(); @@ -225,32 +217,32 @@ test.describe('OC - Manage Departments', () => { await test.step('should be able to remove a tag properly', async () => { await poOmnichannelDepartments.btnTag(tagName).click(); - await expect(poOmnichannelDepartments.btnTagsAdd).toBeDisabled(); + await expect(poOmnichannelDepartments.btnAddTags).toBeDisabled(); }); await test.step('should not be possible to add empty tags', async () => { - await poOmnichannelDepartments.inputTags.fill(''); - await expect(poOmnichannelDepartments.btnTagsAdd).toBeDisabled(); + await poOmnichannelDepartments.inputConversationClosingTags.fill(''); + await expect(poOmnichannelDepartments.btnAddTags).toBeDisabled(); }); await test.step('should not be possible to add same tag twice', async () => { const tagName = faker.string.sample(5); - await poOmnichannelDepartments.inputTags.fill(tagName); - await poOmnichannelDepartments.btnTagsAdd.click(); - await poOmnichannelDepartments.inputTags.fill(tagName); - await expect(poOmnichannelDepartments.btnTagsAdd).toBeDisabled(); + await poOmnichannelDepartments.inputConversationClosingTags.fill(tagName); + await poOmnichannelDepartments.btnAddTags.click(); + await poOmnichannelDepartments.inputConversationClosingTags.fill(tagName); + await expect(poOmnichannelDepartments.btnAddTags).toBeDisabled(); }); }); test('Toggle department removal', async ({ api }) => { await test.step('expect create new department', async () => { await poOmnichannelDepartments.search(department.name); - await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(department.name)).toBeVisible(); }); await test.step('expect to be able to delete department', async () => { await poOmnichannelDepartments.search(department.name); - await poOmnichannelDepartments.selectedDepartmentMenu(department.name).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(department.name).click(); await expect(poOmnichannelDepartments.menuDeleteOption).toBeEnabled(); }); @@ -261,7 +253,7 @@ test.describe('OC - Manage Departments', () => { await test.step('expect not to be able to delete department', async () => { await poOmnichannelDepartments.search(department.name); - await poOmnichannelDepartments.selectedDepartmentMenu(department.name).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(department.name).click(); await expect(poOmnichannelDepartments.menuDeleteOption).toBeDisabled(); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts index 852020dae50d5..581394c5910d2 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts @@ -5,7 +5,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChatEmbedded } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; @@ -489,7 +490,9 @@ test.describe('OC - Livechat API', () => { await poAuxContext.poHomeOmnichannel.roomToolbar.openContactInfo(); // For some reason the guest info email information is being set to lowercase - await expect(poAuxContext.poHomeOmnichannel.content.infoContactEmail).toHaveText(registerGuestVisitor.email.toLowerCase()); + await expect(poAuxContext.poHomeOmnichannel.contacts.contactInfo.infoContactEmail).toHaveText( + registerGuestVisitor.email.toLowerCase(), + ); }); await test.step('Expect registerGuest to log in an existing guest and load chat history', async () => { @@ -623,7 +626,7 @@ test.describe('OC - Livechat API', () => { await poAuxContext.poHomeOmnichannel.roomToolbar.openContactInfo(); // For some reason the guest info email information is being set to lowercase - await expect(poAuxContext.poHomeOmnichannel.content.infoContactEmail).toHaveText( + await expect(poAuxContext.poHomeOmnichannel.contacts.contactInfo.infoContactEmail).toHaveText( `changed${registerGuestVisitor.email}`.toLowerCase(), ); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts index bf384c864d791..0eb318b871119 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChatEmbedded } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-background.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-background.spec.ts index b7a058e719ee1..dcd2dbc0a68c1 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-background.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-background.spec.ts @@ -1,7 +1,7 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChatEmbedded } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts index e10c134de579d..37fb79abc25cd 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts @@ -2,7 +2,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts index d96aa4006bc4b..4bbc1292dd423 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts @@ -1,7 +1,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-hide-expand-chat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-hide-expand-chat.spec.ts index 2e6640c1b435c..a256dd09d8b45 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-hide-expand-chat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-hide-expand-chat.spec.ts @@ -1,8 +1,7 @@ import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat } from '../page-objects'; -import { OmnichannelLivechatAppearance } from '../page-objects/omnichannel-livechat-appearance'; +import { OmnichannelLiveChat, OmnichannelLivechatAppearance } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; @@ -55,7 +54,7 @@ test.describe('OC - Livechat - Hide "Expand chat"', async () => { await test.step('expect to change setting', async () => { await poLivechatAppearance.labelHideExpandChat.click(); - await poLivechatAppearance.btnSave.click(); + await poLivechatAppearance.btnSaveChanges.click(); }); await test.step('expect "Expand chat" button to be hidden', async () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-logo.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-logo.spec.ts index 51f59b5af2879..fe6581cf0f932 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-logo.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-logo.spec.ts @@ -1,7 +1,7 @@ import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, OmnichannelSettings } from '../page-objects'; +import { OmnichannelLiveChat, OmnichannelSettings } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.skip(!IS_EE, 'Enterprise Only'); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts index 76b255a11157a..370fdf191463f 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChatEmbedded } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management-autoselection.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management-autoselection.spec.ts index a11ae455e9ad6..c666d4a603a30 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management-autoselection.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management-autoselection.spec.ts @@ -2,7 +2,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const firstVisitor = createFakeVisitor(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management.spec.ts index a55ef80ecb1b4..f807014636041 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-queue-management.spec.ts @@ -2,7 +2,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const firstVisitor = createFakeVisitor(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts index 5f3a35004a8da..3e76820283543 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts @@ -1,7 +1,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-watermark.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-watermark.spec.ts index 09883da3c16b6..6a064c5c4b76e 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-watermark.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-watermark.spec.ts @@ -2,7 +2,7 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, OmnichannelSettings } from '../page-objects'; +import { OmnichannelLiveChat, OmnichannelSettings } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; @@ -60,7 +60,7 @@ test.describe('OC - Livechat - Hide watermark', async () => { await test.step('expect to change setting', async () => { await poOmnichannelSettings.group('Livechat').click(); await poOmnichannelSettings.labelHideWatermark.click(); - await poOmnichannelSettings.btnSave.click(); + await poOmnichannelSettings.btnSaveChanges.click(); }); await test.step('expect watermark to be hidden', async () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-widget.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-widget.spec.ts index 5b57920bb7a43..1ea37ee7c3c2c 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-widget.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-widget.spec.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test'; -import { OmnichannelLiveChatEmbedded } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('Omnichannel - Livechat Widget Embedded', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts index 81283f264d07a..2822a9c691321 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts @@ -3,7 +3,8 @@ import type { Page } from 'playwright-core'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChat } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { setSettingValueById } from '../utils'; import { createAgent } from '../utils/omnichannel/agents'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts index 5df8a4218ab18..27eea4e9f2ce1 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts @@ -4,6 +4,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelAgents, OmnichannelManager, OmnichannelMonitors } from '../page-objects/omnichannel'; import { createAgent, makeAgentAvailable } from '../utils/omnichannel/agents'; import { createDepartment } from '../utils/omnichannel/departments'; import { createManager } from '../utils/omnichannel/managers'; @@ -114,9 +115,9 @@ test.describe('OC - Manager Role', () => { test('OC - Manager Role - Contact Center', async ({ page }) => { await test.step('expect to be able to view all chats', async () => { - await expect(poOmnichannel.chats.findRowByName(ROOM_A)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_B)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_C)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_A)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_B)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_C)).toBeVisible(); }); await test.step('expect to be able to join chats', async () => { @@ -153,76 +154,74 @@ test.describe('OC - Manager Role', () => { await test.step('expect to be able to remove closed rooms', async () => { await poOmnichannel.chats.removeChatByName(ROOM_A); - await expect(poOmnichannel.chats.findRowByName(ROOM_A)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_A)).not.toBeVisible(); }); }); - test('OC - Manager Role - Add/remove agents', async () => { - await poOmnichannel.agents.sidenav.linkAgents.click(); + test('OC - Manager Role - Add/remove agents', async ({ page }) => { + const poOmnichannelAgents = new OmnichannelAgents(page); + await poOmnichannelAgents.sidebar.linkAgents.click(); await test.step('expect add "user1" as agent', async () => { - await poOmnichannel.agents.selectUsername('user1'); - await poOmnichannel.agents.btnAdd.click(); + await poOmnichannelAgents.selectUsername('user1'); + await poOmnichannelAgents.btnAddAgent.click(); - await poOmnichannel.agents.inputSearch.fill('user1'); - await expect(poOmnichannel.agents.findRowByName('user1')).toBeVisible(); + await poOmnichannelAgents.inputSearch.fill('user1'); + await expect(poOmnichannelAgents.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect remove "user1" as agent', async () => { - await poOmnichannel.agents.inputSearch.fill('user1'); - await poOmnichannel.agents.btnDeleteFirstRowInTable.click(); - await poOmnichannel.agents.btnModalRemove.click(); + await poOmnichannelAgents.inputSearch.fill('user1'); + await poOmnichannelAgents.deleteAgent('user1'); - await poOmnichannel.agents.inputSearch.fill(''); - await poOmnichannel.agents.inputSearch.fill('user1'); - await expect(poOmnichannel.agents.findRowByName('user1')).toBeHidden(); + await poOmnichannelAgents.inputSearch.fill(''); + await poOmnichannelAgents.inputSearch.fill('user1'); + await expect(poOmnichannelAgents.table.findRowByName('user1')).toBeHidden(); }); }); - test('OC - Manager Role - Add/remove managers', async () => { - await poOmnichannel.omnisidenav.linkManagers.click(); + test('OC - Manager Role - Add/remove managers', async ({ page }) => { + const poOmnichannelManagers = new OmnichannelManager(page); + await poOmnichannelManagers.sidebar.linkManagers.click(); await test.step('expect add "user1" as manager', async () => { - await poOmnichannel.managers.selectUsername('user1'); - await poOmnichannel.managers.btnAdd.click(); + await poOmnichannelManagers.selectUsername('user1'); + await poOmnichannelManagers.btnAddManager.click(); - await expect(poOmnichannel.managers.findRowByName('user1')).toBeVisible(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect search for manager', async () => { - await poOmnichannel.managers.search('user1'); - await expect(poOmnichannel.managers.findRowByName('user1')).toBeVisible(); + await poOmnichannelManagers.search('user1'); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeVisible(); - await poOmnichannel.managers.search('NonExistingUser'); - await expect(poOmnichannel.managers.findRowByName('user1')).toBeHidden(); - - await poOmnichannel.managers.clearSearch(); + await poOmnichannelManagers.search('NonExistingUser'); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeHidden(); + await poOmnichannelManagers.clearSearch(); }); await test.step('expect remove "user1" as manager', async () => { - await poOmnichannel.managers.search('user1'); - await poOmnichannel.managers.btnDeleteSelectedAgent('user1').click(); - await poOmnichannel.managers.btnModalRemove.click(); + await poOmnichannelManagers.search('user1'); + await poOmnichannelManagers.removeManager('user1'); - await expect(poOmnichannel.managers.findRowByName('user1')).toBeHidden(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeHidden(); }); }); - test('OC - Manager Role - Add/remove monitors', async () => { - await poOmnichannel.omnisidenav.linkMonitors.click(); + test('OC - Manager Role - Add/remove monitors', async ({ page }) => { + const poOmnichannelMonitors = new OmnichannelMonitors(page); + await poOmnichannelMonitors.sidebar.linkMonitors.click(); await test.step('expect to add agent as monitor', async () => { - await expect(poOmnichannel.monitors.findRowByName('user1')).not.toBeVisible(); - await poOmnichannel.monitors.selectMonitor('user1'); - await poOmnichannel.monitors.btnAddMonitor.click(); - await expect(poOmnichannel.monitors.findRowByName('user1')).toBeVisible(); + await expect(poOmnichannelMonitors.table.findRowByName('user1')).not.toBeVisible(); + await poOmnichannelMonitors.addMonitor('user1'); + await expect(poOmnichannelMonitors.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect to remove agent from monitor', async () => { - await poOmnichannel.monitors.btnRemoveByName('user1').click(); - await expect(poOmnichannel.monitors.modalConfirmRemove).toBeVisible(); - await poOmnichannel.monitors.btnConfirmRemove.click(); - await expect(poOmnichannel.monitors.findRowByName('user1')).not.toBeVisible(); + await poOmnichannelMonitors.removeMonitor('user1'); + + await expect(poOmnichannelMonitors.table.findRowByName('user1')).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager.spec.ts index c11978abcb692..1574928db18ce 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager.spec.ts @@ -1,5 +1,5 @@ import { Users } from '../fixtures/userStates'; -import { OmnichannelManager } from '../page-objects'; +import { OmnichannelManager } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); @@ -11,7 +11,7 @@ test.describe.serial('omnichannel-manager', () => { poOmnichannelManagers = new OmnichannelManager(page); await page.goto('/omnichannel'); - await poOmnichannelManagers.sidenav.linkManagers.click(); + await poOmnichannelManagers.sidebar.linkManagers.click(); }); test('OC - Manage Managers - Add, Search and Remove', async ({ page }) => { @@ -22,27 +22,26 @@ test.describe.serial('omnichannel-manager', () => { await test.step('expect add "user1" as manager', async () => { await poOmnichannelManagers.selectUsername('user1'); - await poOmnichannelManagers.btnAdd.click(); + await poOmnichannelManagers.btnAddManager.click(); - await expect(poOmnichannelManagers.findRowByName('user1')).toBeVisible(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect search for manager', async () => { await poOmnichannelManagers.search('user1'); - await expect(poOmnichannelManagers.findRowByName('user1')).toBeVisible(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeVisible(); await poOmnichannelManagers.search('NonExistingUser'); - await expect(poOmnichannelManagers.findRowByName('user1')).toBeHidden(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeHidden(); await poOmnichannelManagers.clearSearch(); }); await test.step('expect remove "user1" as manager', async () => { await poOmnichannelManagers.search('user1'); - await poOmnichannelManagers.btnDeleteSelectedAgent('user1').click(); - await poOmnichannelManagers.btnModalRemove.click(); + await poOmnichannelManagers.removeManager('user1'); - await expect(poOmnichannelManagers.findRowByName('user1')).toBeHidden(); + await expect(poOmnichannelManagers.table.findRowByName('user1')).toBeHidden(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts index 1a96b2f8eaab7..41f647111b0c0 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts @@ -87,7 +87,7 @@ test.describe('OC - Manual Selection', () => { await test.step('expect to be able return to queue', async () => { await poOmnichannel.content.btnReturnToQueue.click(); - await poOmnichannel.content.btnReturnToQueueConfirm.click(); + await poOmnichannel.content.returnToQueueModal.confirm(); await expect(page).toHaveURL('/home'); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-department.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-department.spec.ts index 92b40fb477bfd..109198cfe5bfa 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-department.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-department.spec.ts @@ -3,7 +3,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelDepartments } from '../page-objects'; +import { OmnichannelDepartments } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { createDepartment } from '../utils/omnichannel/departments'; import { createMonitor } from '../utils/omnichannel/monitors'; @@ -86,11 +86,11 @@ test.describe.serial('OC - Monitor Role', () => { const [unitA, unitB, unitC] = units.map((unit) => unit.data); await test.step('expect to see only departmentA in the list', async () => { - await expect(poOmnichannelDepartments.findDepartment(departmentA.name)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentA.name)).toBeVisible(); }); await test.step('expect to fill departments mandatory field', async () => { - await poOmnichannelDepartments.headingButtonNew('Create department').click(); + await poOmnichannelDepartments.createNew(); await poOmnichannelDepartments.inputName.fill(newDepartmentName); await poOmnichannelDepartments.inputEmail.fill(faker.internet.email()); }); @@ -121,20 +121,20 @@ test.describe.serial('OC - Monitor Role', () => { }); await test.step('expect to save department', async () => { - await poOmnichannelDepartments.btnEnabled.click(); + await poOmnichannelDepartments.labelEnabled.click(); await poOmnichannelDepartments.btnSave.click(); }); await test.step('expect to have departmentA and departmentB visible', async () => { - await expect(poOmnichannelDepartments.findDepartment(departmentA.name)).toBeVisible(); - await expect(poOmnichannelDepartments.findDepartment(newDepartmentName)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentA.name)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(newDepartmentName)).toBeVisible(); }); }); test('OC - Monitor Role - Not allow editing department business unit', async () => { await test.step('expect not to be able to edit unit', async () => { await poOmnichannelDepartments.search(newDepartmentName); - await poOmnichannelDepartments.selectedDepartmentMenu(newDepartmentName).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(newDepartmentName).click(); await poOmnichannelDepartments.menuEditOption.click(); await expect(poOmnichannelDepartments.inputUnit).toBeDisabled(); }); @@ -147,16 +147,16 @@ test.describe.serial('OC - Monitor Role', () => { await test.step('expect to edit unit', async () => { await poOmnichannelDepartments.search(newDepartmentName); - await poOmnichannelDepartments.selectedDepartmentMenu(newDepartmentName).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(newDepartmentName).click(); await poOmnichannelDepartments.menuEditOption.click(); await poOmnichannelDepartments.selectUnit(unitC.name); - await poOmnichannelDepartments.btnEnabled.click(); + await poOmnichannelDepartments.labelEnabled.click(); await poOmnichannelDepartments.btnSave.click(); }); await test.step('expect departmentB to still be visible', async () => { - await expect(poOmnichannelDepartments.findDepartment(departmentA.name)).toBeVisible(); - await expect(poOmnichannelDepartments.findDepartment(newDepartmentName)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentA.name)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(newDepartmentName)).toBeVisible(); }); }); @@ -165,16 +165,16 @@ test.describe.serial('OC - Monitor Role', () => { await test.step('expect to edit unit', async () => { await poOmnichannelDepartments.search(newDepartmentName); - await poOmnichannelDepartments.selectedDepartmentMenu(newDepartmentName).click(); + await poOmnichannelDepartments.getDepartmentMenuByName(newDepartmentName).click(); await poOmnichannelDepartments.menuEditOption.click(); await poOmnichannelDepartments.selectUnit('None'); - await poOmnichannelDepartments.btnEnabled.click(); + await poOmnichannelDepartments.labelEnabled.click(); await poOmnichannelDepartments.btnSave.click(); }); await test.step('expect departmentB to not be visible', async () => { - await expect(poOmnichannelDepartments.findDepartment(departmentA.name)).toBeVisible(); - await expect(poOmnichannelDepartments.findDepartment(newDepartmentName)).not.toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(departmentA.name)).toBeVisible(); + await expect(poOmnichannelDepartments.departmentsTable.findRowByName(newDepartmentName)).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts index 618b63c13b1b2..4cde8f2e0a35d 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts @@ -165,10 +165,10 @@ test.describe('OC - Monitor Role', () => { test('OC - Monitor Role - Contact Center', async ({ page }) => { await test.step('expect to be able to view only chats from same unit', async () => { - await expect(poOmnichannel.chats.findRowByName(ROOM_A)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_B)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_C)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_D)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_A)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_B)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_C)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_D)).not.toBeVisible(); }); await test.step('expect to be able to join chats from same unit', async () => { @@ -204,8 +204,8 @@ test.describe('OC - Monitor Role', () => { }); await test.step('expect not to be able to remove closed room', async () => { - await expect(poOmnichannel.chats.findRowByName(ROOM_A)).toBeVisible(); - await expect(poOmnichannel.chats.btnRemoveByName(ROOM_A)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_A)).toBeVisible(); + await expect(poOmnichannel.chats.table.btnRemoveByName(ROOM_A)).not.toBeVisible(); }); }); @@ -217,9 +217,9 @@ test.describe('OC - Monitor Role', () => { await test.step('expect not to be able to see chats from removed department', async () => { await test.step('expect rooms from both departments to be visible', async () => { - await expect(poOmnichannel.chats.findRowByName(ROOM_B)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_C)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_D)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_B)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_C)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_D)).not.toBeVisible(); }); await test.step('expect to remove departmentB from unit', async () => { @@ -235,9 +235,9 @@ test.describe('OC - Monitor Role', () => { }); await test.step('expect to have only room B visible', async () => { - await expect(poOmnichannel.chats.findRowByName(ROOM_B)).toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_C)).not.toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_D)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_B)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_C)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_D)).not.toBeVisible(); }); }); @@ -245,16 +245,16 @@ test.describe('OC - Monitor Role', () => { const res = await unitA.delete(); expect(res.status()).toBe(200); await page.reload(); - await expect(poOmnichannel.chats.findRowByName(ROOM_B)).not.toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_C)).not.toBeVisible(); - await expect(poOmnichannel.chats.findRowByName(ROOM_D)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_B)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_C)).not.toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_D)).not.toBeVisible(); }); await test.step('expect to be able to see all conversations once all units are removed', async () => { const res = await unitB.delete(); expect(res.status()).toBe(200); await page.reload(); - await expect(poOmnichannel.chats.findRowByName(ROOM_D)).toBeVisible(); + await expect(poOmnichannel.chats.table.findRowByName(ROOM_D)).toBeVisible(); }); await test.step('expect not to be able to see chats once role is removed', async () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitors.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitors.spec.ts index 5a118afcc508e..be7b8b996a44a 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitors.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitors.spec.ts @@ -1,6 +1,6 @@ import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelMonitors } from '../page-objects'; +import { OmnichannelMonitors } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.user1.state }); @@ -32,67 +32,54 @@ test.describe.serial('OC - Manage Monitors', () => { await page.goto('/omnichannel'); await page.locator('#main-content').waitFor(); - await poMonitors.sidenav.linkMonitors.click(); + await poMonitors.sidebar.linkMonitors.click(); }); test('OC - Manager Monitors - Add monitor', async () => { await test.step('expect to add agent as monitor', async () => { - await expect(poMonitors.findRowByName('user1')).not.toBeVisible(); - await poMonitors.selectMonitor('user1'); - await poMonitors.btnAddMonitor.click(); - await expect(poMonitors.findRowByName('user1')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user1')).not.toBeVisible(); + await poMonitors.addMonitor('user1'); + await expect(poMonitors.table.findRowByName('user1')).toBeVisible(); }); await test.step('expect to remove agent from monitor', async () => { - await poMonitors.btnRemoveByName('user1').click(); - await expect(poMonitors.modalConfirmRemove).toBeVisible(); - await poMonitors.btnConfirmRemove.click(); - await expect(poMonitors.findRowByName('user1')).not.toBeVisible(); + await poMonitors.removeMonitor('user1'); + await expect(poMonitors.table.findRowByName('user1')).not.toBeVisible(); }); }); test('OC - Manager Monitors - Search', async () => { await test.step('expect to add 2 monitors', async () => { - await poMonitors.selectMonitor('user1'); - await poMonitors.btnAddMonitor.click(); + await poMonitors.addMonitor('user1'); + await expect(poMonitors.table.findRowByName('user1')).toBeVisible(); - await expect(poMonitors.findRowByName('user1')).toBeVisible(); - - await poMonitors.selectMonitor('user2'); - await poMonitors.btnAddMonitor.click(); - - await expect(poMonitors.findRowByName('user2')).toBeVisible(); + await poMonitors.addMonitor('user2'); + await expect(poMonitors.table.findRowByName('user2')).toBeVisible(); }); await test.step('expect to search monitor', async () => { - await expect(poMonitors.findRowByName('user1')).toBeVisible(); - await expect(poMonitors.findRowByName('user2')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user1')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user2')).toBeVisible(); await poMonitors.inputSearch.fill('user1'); - await expect(poMonitors.findRowByName('user1')).toBeVisible(); - await expect(poMonitors.findRowByName('user2')).not.toBeVisible(); + await expect(poMonitors.table.findRowByName('user1')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user2')).not.toBeVisible(); await poMonitors.inputSearch.fill('user2'); - await expect(poMonitors.findRowByName('user1')).not.toBeVisible(); - await expect(poMonitors.findRowByName('user2')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user1')).not.toBeVisible(); + await expect(poMonitors.table.findRowByName('user2')).toBeVisible(); await poMonitors.inputSearch.fill(''); - await expect(poMonitors.findRowByName('user1')).toBeVisible(); - await expect(poMonitors.findRowByName('user2')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user1')).toBeVisible(); + await expect(poMonitors.table.findRowByName('user2')).toBeVisible(); }); await test.step('expect to remove monitors', async () => { - await poMonitors.btnRemoveByName('user1').click(); - await expect(poMonitors.modalConfirmRemove).toBeVisible(); - await poMonitors.btnConfirmRemove.click(); - - await expect(poMonitors.findRowByName('user1')).not.toBeVisible(); - - await poMonitors.btnRemoveByName('user2').click(); - await expect(poMonitors.modalConfirmRemove).toBeVisible(); - await poMonitors.btnConfirmRemove.click(); + await poMonitors.removeMonitor('user1'); + await expect(poMonitors.table.findRowByName('user1')).not.toBeVisible(); - await expect(poMonitors.findRowByName('user2')).not.toBeVisible(); + await poMonitors.removeMonitor('user2'); + await expect(poMonitors.table.findRowByName('user2')).not.toBeVisible(); }); }); }); 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 5b0e3dd46dc87..53224ea2b4232 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,6 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; 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'; @@ -17,7 +16,6 @@ test.use({ storageState: Users.user1.state }); test.describe.serial('OC - Priorities [Sidebar]', () => { let poHomeChannel: HomeOmnichannel; - let poRoomInfo: OmnichannelRoomInfo; test.beforeAll(async ({ api }) => { ( @@ -31,7 +29,6 @@ test.describe.serial('OC - Priorities [Sidebar]', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeOmnichannel(page); - poRoomInfo = new OmnichannelRoomInfo(page); }); test.beforeEach(async ({ page }) => { @@ -61,23 +58,23 @@ test.describe.serial('OC - Priorities [Sidebar]', () => { await poHomeChannel.sidebar.getSidebarItemByName(visitor.name).click(); await expect(poHomeChannel.content.btnTakeChat).toBeVisible(); - await expect(poRoomInfo.getLabel('Priority')).not.toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).not.toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Lowest'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Lowest')}"`).waitFor(); - await expect(poRoomInfo.getLabel('Priority')).toBeVisible(); - await expect(poRoomInfo.getBadgeIndicator(visitor.name, 'Lowest')).toBeVisible(); - await expect(poRoomInfo.getInfo('Lowest')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).toBeVisible(); + await expect(poHomeChannel.sidebar.getBadgeIndicator(visitor.name, 'Lowest')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getInfo('Lowest')).toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Highest'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Highest')}"`).waitFor(); - await expect(poRoomInfo.getInfo('Highest')).toBeVisible(); - await expect(poRoomInfo.getBadgeIndicator(visitor.name, 'Highest')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getInfo('Highest')).toBeVisible(); + await expect(poHomeChannel.sidebar.getBadgeIndicator(visitor.name, 'Highest')).toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Unprioritized'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Unprioritized')}"`).waitFor(); - await expect(poRoomInfo.getLabel('Priority')).not.toBeVisible(); - await expect(poRoomInfo.getInfo('Unprioritized')).not.toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).not.toBeVisible(); + await expect(poHomeChannel.sidebar.getBadgeIndicator(visitor.name, 'Unprioritized')).not.toBeVisible(); }); await test.step('expect to change subscription priority using sidebar menu', async () => { @@ -85,23 +82,23 @@ test.describe.serial('OC - Priorities [Sidebar]', () => { await systemMessage.locator('text="joined the channel"').waitFor(); await page.waitForTimeout(500); - await expect(poRoomInfo.getLabel('Priority')).not.toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).not.toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Lowest'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Lowest')}"`).waitFor(); - await expect(poRoomInfo.getLabel('Priority')).toBeVisible(); - await expect(poRoomInfo.getInfo('Lowest')).toBeVisible(); - await expect(poRoomInfo.getBadgeIndicator(visitor.name, 'Lowest')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getInfo('Lowest')).toBeVisible(); + await expect(poHomeChannel.sidebar.getBadgeIndicator(visitor.name, 'Lowest')).toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Highest'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Highest')}"`).waitFor(); - await expect(poRoomInfo.getInfo('Highest')).toBeVisible(); - await expect(poRoomInfo.getBadgeIndicator(visitor.name, 'Highest')).toBeVisible(); + await expect(poHomeChannel.roomInfo.getInfo('Highest')).toBeVisible(); + await expect(poHomeChannel.sidebar.getBadgeIndicator(visitor.name, 'Highest')).toBeVisible(); await poHomeChannel.sidebar.selectPriority(visitor.name, 'Unprioritized'); await systemMessage.locator(`text="${getPrioritySystemMessage('user1', 'Unprioritized')}"`).waitFor(); - await expect(poRoomInfo.getLabel('Priority')).not.toBeVisible(); - await expect(poRoomInfo.getInfo('Unprioritized')).not.toBeVisible(); + await expect(poHomeChannel.roomInfo.getLabel('Priority')).not.toBeVisible(); + await expect(poHomeChannel.roomInfo.getInfo('Unprioritized')).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities.spec.ts index 5aa5a76596d3a..625af75f5afca 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-priorities.spec.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelPriorities } from '../page-objects/omnichannel-priorities'; +import { OmnichannelPriorities } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const PRIORITY_NAME = faker.person.firstName(); @@ -30,7 +30,7 @@ test.describe.serial('Omnichannel Priorities', () => { await page.goto('/omnichannel'); await page.locator('#main-content').waitFor(); - await poOmnichannelPriorities.sidenav.linkPriorities.click(); + await poOmnichannelPriorities.sidebar.linkPriorities.click(); }); test.afterAll(async ({ api }) => { @@ -54,31 +54,30 @@ test.describe.serial('Omnichannel Priorities', () => { await test.step('default state', async () => { await Promise.all([ - expect(poOmnichannelPriorities.managePriority.btnSave).toBeDisabled(), - expect(poOmnichannelPriorities.managePriority.btnReset).not.toBeVisible(), - expect(poOmnichannelPriorities.managePriority.inputName).toHaveValue('Highest'), + expect(poOmnichannelPriorities.editPriority.btnSave).toBeDisabled(), + expect(poOmnichannelPriorities.editPriority.btnReset).not.toBeVisible(), + expect(poOmnichannelPriorities.editPriority.inputName).toHaveValue('Highest'), ]); }); await test.step('field name is required', async () => { - await poOmnichannelPriorities.managePriority.inputName.fill('any_text'); - await expect(poOmnichannelPriorities.managePriority.btnSave).toBeEnabled(); - await poOmnichannelPriorities.managePriority.inputName.fill(''); - await expect(poOmnichannelPriorities.managePriority.errorMessage(ERROR.fieldNameRequired)).toBeVisible(); - await expect(poOmnichannelPriorities.managePriority.btnSave).toBeDisabled(); + await poOmnichannelPriorities.editPriority.inputName.fill('any_text'); + await expect(poOmnichannelPriorities.editPriority.btnSave).toBeEnabled(); + await poOmnichannelPriorities.editPriority.inputName.fill(''); + await expect(poOmnichannelPriorities.editPriority.errorMessage(ERROR.fieldNameRequired)).toBeVisible(); + await expect(poOmnichannelPriorities.editPriority.btnSave).toBeDisabled(); }); await test.step('edit and save priority', async () => { - await poOmnichannelPriorities.managePriority.inputName.fill(PRIORITY_NAME); + await poOmnichannelPriorities.editPriority.inputName.fill(PRIORITY_NAME); await Promise.all([ - expect(poOmnichannelPriorities.managePriority.btnReset).toBeVisible(), - expect(poOmnichannelPriorities.managePriority.btnSave).toBeEnabled(), + expect(poOmnichannelPriorities.editPriority.btnReset).toBeVisible(), + expect(poOmnichannelPriorities.editPriority.btnSave).toBeEnabled(), ]); - await poOmnichannelPriorities.managePriority.btnSave.click(); + await poOmnichannelPriorities.editPriority.save(); await Promise.all([ - poOmnichannelPriorities.toastMessage.dismissToast(), - expect(poOmnichannelPriorities.managePriority.inputName).not.toBeVisible(), + expect(poOmnichannelPriorities.editPriority.inputName).not.toBeVisible(), expect(poOmnichannelPriorities.findPriority(PRIORITY_NAME)).toBeVisible(), expect(poOmnichannelPriorities.findPriority('Highest')).not.toBeVisible(), ]); @@ -88,16 +87,15 @@ test.describe.serial('Omnichannel Priorities', () => { await test.step('Reset priority', async () => { await test.step('reset individual', async () => { await poOmnichannelPriorities.findPriority(PRIORITY_NAME).click(); - await expect(poOmnichannelPriorities.managePriority.btnReset).toBeVisible(); - await poOmnichannelPriorities.managePriority.btnReset.click(); + await expect(poOmnichannelPriorities.editPriority.btnReset).toBeVisible(); + await poOmnichannelPriorities.editPriority.btnReset.click(); await Promise.all([ - expect(poOmnichannelPriorities.managePriority.inputName).toHaveValue('Highest'), - expect(poOmnichannelPriorities.managePriority.btnReset).not.toBeVisible(), + expect(poOmnichannelPriorities.editPriority.inputName).toHaveValue('Highest'), + expect(poOmnichannelPriorities.editPriority.btnReset).not.toBeVisible(), ]); - await expect(poOmnichannelPriorities.managePriority.btnSave).toBeEnabled(); - await poOmnichannelPriorities.managePriority.btnSave.click(); - await poOmnichannelPriorities.toastMessage.dismissToast(); + await expect(poOmnichannelPriorities.editPriority.btnSave).toBeEnabled(); + await poOmnichannelPriorities.editPriority.save(); await expect(poOmnichannelPriorities.findPriority('Highest')).toBeVisible(); await expect(poOmnichannelPriorities.btnReset).not.toBeEnabled(); }); @@ -105,25 +103,23 @@ test.describe.serial('Omnichannel Priorities', () => { await test.step('reset all', async () => { await poOmnichannelPriorities.findPriority('Highest').click(); - await poOmnichannelPriorities.managePriority.inputName.fill(PRIORITY_NAME); + await poOmnichannelPriorities.editPriority.inputName.fill(PRIORITY_NAME); await Promise.all([ - expect(poOmnichannelPriorities.managePriority.btnReset).toBeVisible(), - expect(poOmnichannelPriorities.managePriority.btnSave).toBeEnabled(), + expect(poOmnichannelPriorities.editPriority.btnReset).toBeVisible(), + expect(poOmnichannelPriorities.editPriority.btnSave).toBeEnabled(), ]); - await poOmnichannelPriorities.managePriority.btnSave.click(); - await poOmnichannelPriorities.toastMessage.dismissToast(); + await poOmnichannelPriorities.editPriority.save(); + await Promise.all([ - expect(poOmnichannelPriorities.managePriority.inputName).not.toBeVisible(), + expect(poOmnichannelPriorities.editPriority.inputName).not.toBeVisible(), expect(poOmnichannelPriorities.findPriority(PRIORITY_NAME)).toBeVisible(), expect(poOmnichannelPriorities.findPriority('Highest')).not.toBeVisible(), ]); await expect(poOmnichannelPriorities.btnReset).toBeEnabled(); - await poOmnichannelPriorities.btnReset.click(); - await poOmnichannelPriorities.btnResetConfirm.click(); + await poOmnichannelPriorities.resetPriorities(); await Promise.all([ - await poOmnichannelPriorities.toastMessage.waitForDisplay(), expect(poOmnichannelPriorities.btnReset).not.toBeEnabled(), expect(poOmnichannelPriorities.findPriority(PRIORITY_NAME)).not.toBeVisible(), expect(poOmnichannelPriorities.findPriority('Highest')).toBeVisible(), diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts index ba598900bac81..125c4568f8e45 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts @@ -2,7 +2,7 @@ import type { Route } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelReports } from '../page-objects/omnichannel-reports'; +import { OmnichannelReports } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const ENDPOINTS = { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts index 4421636f33627..5171e1c4739f6 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.skip(!IS_EE, 'Export transcript as PDF > Enterprie Only'); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-send-transcript.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-send-transcript.spec.ts index ea73de532709a..a21dd3853ff0b 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-send-transcript.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-send-transcript.spec.ts @@ -4,7 +4,8 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { HomeChannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('omnichannel-transcript', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies-sidebar.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies-sidebar.spec.ts index 57ca3e424243b..0cd3811069678 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies-sidebar.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies-sidebar.spec.ts @@ -8,7 +8,6 @@ import { createFakeVisitor } from '../../mocks/data'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { HomeOmnichannel } from '../page-objects'; -import { OmnichannelRoomInfo } from '../page-objects/omnichannel-room-info'; import { createConversation } from '../utils/omnichannel/rooms'; import { createSLA } from '../utils/omnichannel/sla'; import { test, expect } from '../utils/test'; @@ -23,7 +22,6 @@ test.use({ storageState: Users.user1.state }); test.describe('OC - SLA Policies [Sidebar]', () => { let poHomeChannel: HomeOmnichannel; - let poRoomInfo: OmnichannelRoomInfo; let conversations: Awaited>[] = []; let slas: Serialized>[] = []; @@ -50,7 +48,6 @@ test.describe('OC - SLA Policies [Sidebar]', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeOmnichannel(page); - poRoomInfo = new OmnichannelRoomInfo(page); }); test.beforeEach(async ({ page }) => { @@ -91,18 +88,18 @@ test.describe('OC - SLA Policies [Sidebar]', () => { await test.step('expect to change room SLA policy to "Not urgent"', async () => { await test.step('expect to open room and room info to be visible', async () => { await poHomeChannel.sidebar.getSidebarItemByName(visitorA.name).click(); - await expect(poRoomInfo.dialogRoomInfo).toBeVisible(); + await expect(poHomeChannel.roomInfo.root).toBeVisible(); }); await test.step('expect to update room SLA policy', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); - await poRoomInfo.btnEditRoomInfo.click(); - await poRoomInfo.selectSLA('Not Urgent'); - await poRoomInfo.btnSaveEditRoom.click(); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); + await poHomeChannel.roomInfo.btnEdit.click(); + await poHomeChannel.editRoomInfo.selectSLA('Not Urgent'); + await poHomeChannel.editRoomInfo.btnSave.click(); }); await test.step('expect SLA to have been updated in the room info and queue order to be correct', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).toHaveText('Not Urgent'); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).toHaveText('Not Urgent'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorA.name)).toBeVisible(); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorA.name)).toHaveAttribute('data-index', '1'); }); @@ -111,18 +108,18 @@ test.describe('OC - SLA Policies [Sidebar]', () => { await test.step('expect to change room SLA policy to "Urgent"', async () => { await test.step('expect to open room and room info to be visible', async () => { await poHomeChannel.sidebar.getSidebarItemByName(visitorB.name).click(); - await expect(poRoomInfo.dialogRoomInfo).toBeVisible(); + await expect(poHomeChannel.roomInfo.root).toBeVisible(); }); await test.step('expect to update room SLA policy', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); - await poRoomInfo.btnEditRoomInfo.click(); - await poRoomInfo.selectSLA('Urgent'); - await poRoomInfo.btnSaveEditRoom.click(); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); + await poHomeChannel.roomInfo.btnEdit.click(); + await poHomeChannel.editRoomInfo.selectSLA('Urgent'); + await poHomeChannel.editRoomInfo.btnSave.click(); }); await test.step('expect SLA to have been updated in the room info and queue order to be correct', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).toHaveText('Urgent'); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).toHaveText('Urgent'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorB.name)).toHaveAttribute('data-index', '1'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorA.name)).toHaveAttribute('data-index', '2'); }); @@ -131,18 +128,18 @@ test.describe('OC - SLA Policies [Sidebar]', () => { await test.step('expect to change room SLA policy to "Very Urgent"', async () => { await test.step('expect to open room and room info to be visible', async () => { await poHomeChannel.sidebar.getSidebarItemByName(visitorC.name).click(); - await expect(poRoomInfo.dialogRoomInfo).toBeVisible(); + await expect(poHomeChannel.roomInfo.root).toBeVisible(); }); await test.step('expect to update room SLA policy', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); - await poRoomInfo.btnEditRoomInfo.click(); - await poRoomInfo.selectSLA('Very Urgent'); - await poRoomInfo.btnSaveEditRoom.click(); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).not.toBeVisible(); + await poHomeChannel.roomInfo.btnEdit.click(); + await poHomeChannel.editRoomInfo.selectSLA('Very Urgent'); + await poHomeChannel.editRoomInfo.btnSave.click(); }); await test.step('expect SLA to have been updated in the room info and queue order to be correct', async () => { - await expect(poRoomInfo.getInfoByLabel('SLA Policy')).toHaveText('Very Urgent'); + await expect(poHomeChannel.roomInfo.getInfoByLabel('SLA Policy')).toHaveText('Very Urgent'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorC.name)).toHaveAttribute('data-index', '1'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorB.name)).toHaveAttribute('data-index', '2'); await expect(poHomeChannel.sidebar.getSidebarListItem(visitorA.name)).toHaveAttribute('data-index', '3'); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies.spec.ts index d5b5544e9ace3..e467798cbac00 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-sla-policies.spec.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelSlaPolicies } from '../page-objects/omnichannel-sla-policies'; +import { OmnichannelSlaPolicies } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; const ERROR = { @@ -38,7 +38,7 @@ test.describe('Omnichannel SLA Policies', () => { poOmnichannelSlaPolicies = new OmnichannelSlaPolicies(page); await page.goto('/omnichannel'); - await poOmnichannelSlaPolicies.sidenav.linkSlaPolicies.click(); + await poOmnichannelSlaPolicies.sidebar.linkSlaPolicies.click(); }); test.afterAll(async ({ api }) => { @@ -48,7 +48,7 @@ test.describe('Omnichannel SLA Policies', () => { test('Manage SLAs', async () => { await test.step('Add new SLA', async () => { - await poOmnichannelSlaPolicies.headingButtonNew('Create SLA policy').click(); + await poOmnichannelSlaPolicies.createNew(); await test.step('field name is required', async () => { await poOmnichannelSlaPolicies.manageSlaPolicy.inputName.fill('any_text'); @@ -89,22 +89,22 @@ test.describe('Omnichannel SLA Policies', () => { await poOmnichannelSlaPolicies.manageSlaPolicy.btnSave.click(); await expect(poOmnichannelSlaPolicies.manageSlaPolicy.inputName).not.toBeVisible(); - await expect(poOmnichannelSlaPolicies.findRowByName(INITIAL_SLA.name)).toBeVisible(); + await expect(poOmnichannelSlaPolicies.table.findRowByName(INITIAL_SLA.name)).toBeVisible(); }); }); await test.step('Search SLA', async () => { - await poOmnichannelSlaPolicies.inputSearch.type('random_text_that_should_have_no_match'); - await expect(poOmnichannelSlaPolicies.findRowByName(INITIAL_SLA.name)).not.toBeVisible(); + await poOmnichannelSlaPolicies.inputSearch.fill('random_text_that_should_have_no_match'); + await expect(poOmnichannelSlaPolicies.table.findRowByName(INITIAL_SLA.name)).not.toBeVisible(); await expect(poOmnichannelSlaPolicies.txtEmptyState).toBeVisible(); await poOmnichannelSlaPolicies.inputSearch.fill(INITIAL_SLA.name); - await expect(poOmnichannelSlaPolicies.findRowByName(INITIAL_SLA.name)).toBeVisible(); + await expect(poOmnichannelSlaPolicies.table.findRowByName(INITIAL_SLA.name)).toBeVisible(); await expect(poOmnichannelSlaPolicies.txtEmptyState).not.toBeVisible(); await poOmnichannelSlaPolicies.inputSearch.fill(''); }); await test.step('Edit SLA', async () => { - await poOmnichannelSlaPolicies.findRowByName(INITIAL_SLA.name).click(); + await poOmnichannelSlaPolicies.table.findRowByName(INITIAL_SLA.name).click(); await expect(poOmnichannelSlaPolicies.manageSlaPolicy.inputName).toHaveValue(INITIAL_SLA.name); await expect(poOmnichannelSlaPolicies.manageSlaPolicy.inputDescription).toHaveValue(INITIAL_SLA.description); @@ -129,15 +129,13 @@ test.describe('Omnichannel SLA Policies', () => { await poOmnichannelSlaPolicies.manageSlaPolicy.btnSave.click(); await expect(poOmnichannelSlaPolicies.manageSlaPolicy.inputName).not.toBeVisible(); - await expect(poOmnichannelSlaPolicies.findRowByName(EDITED_SLA.name)).toBeVisible(); + await expect(poOmnichannelSlaPolicies.table.findRowByName(EDITED_SLA.name)).toBeVisible(); }); }); await test.step('Remove SLA', async () => { - await poOmnichannelSlaPolicies.btnRemove(EDITED_SLA.name).click(); - await expect(poOmnichannelSlaPolicies.txtDeleteModalTitle).toBeVisible(); - await poOmnichannelSlaPolicies.btnDelete.click(); - await expect(poOmnichannelSlaPolicies.findRowByName(EDITED_SLA.name)).not.toBeVisible(); + await poOmnichannelSlaPolicies.removeSLA(EDITED_SLA.name); + await expect(poOmnichannelSlaPolicies.table.findRowByName(EDITED_SLA.name)).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts index d29bac292f1fa..d17aab773cef1 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts @@ -3,7 +3,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelTags } from '../page-objects'; +import { OmnichannelTags } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { createDepartment } from '../utils/omnichannel/departments'; import { createTag } from '../utils/omnichannel/tags'; @@ -43,45 +43,33 @@ test.describe('OC - Manage Tags', () => { const tagName = faker.string.uuid(); await page.goto('/omnichannel'); - await poOmnichannelTags.sidenav.linkTags.click(); + await poOmnichannelTags.sidebar.linkTags.click(); await test.step('expect correct form default state', async () => { - await poOmnichannelTags.btnCreateTag.click(); - await expect(poOmnichannelTags.contextualBar).toBeVisible(); - await expect(poOmnichannelTags.btnSave).toBeDisabled(); - await expect(poOmnichannelTags.btnCancel).toBeEnabled(); - await poOmnichannelTags.btnCancel.click(); - await expect(poOmnichannelTags.contextualBar).not.toBeVisible(); + await poOmnichannelTags.createNew(); + await expect(poOmnichannelTags.editTag.root).toBeVisible(); + await expect(poOmnichannelTags.editTag.btnSave).toBeDisabled(); + await expect(poOmnichannelTags.editTag.btnCancel).toBeEnabled(); + await poOmnichannelTags.editTag.btnCancel.click(); + await expect(poOmnichannelTags.editTag.root).not.toBeVisible(); }); await test.step('expect to create new tag', async () => { - await poOmnichannelTags.btnCreateTag.click(); - await poOmnichannelTags.inputName.fill(tagName); - await poOmnichannelTags.selectDepartment(department.data.name); - await poOmnichannelTags.btnSave.click(); - await expect(poOmnichannelTags.contextualBar).not.toBeVisible(); + await poOmnichannelTags.createNew(); + await poOmnichannelTags.editTag.inputName.fill(tagName); + await poOmnichannelTags.editTag.selectDepartment(department.data.name); + await poOmnichannelTags.editTag.btnSave.click(); + await expect(poOmnichannelTags.editTag.root).not.toBeVisible(); await test.step('expect tag to have been created', async () => { await poOmnichannelTags.search(tagName); - await expect(poOmnichannelTags.findRowByName(tagName)).toBeVisible(); + await expect(poOmnichannelTags.table.findRowByName(tagName)).toBeVisible(); }); }); - await test.step('expect to delete tag', async () => { - await test.step('expect to be able to cancel delete', async () => { - await poOmnichannelTags.btnDeleteByName(tagName).click(); - await expect(poOmnichannelTags.confirmDeleteModal).toBeVisible(); - await poOmnichannelTags.btnCancelDeleteModal.click(); - await expect(poOmnichannelTags.confirmDeleteModal).not.toBeVisible(); - }); - - await test.step('expect to confirm delete', async () => { - await poOmnichannelTags.btnDeleteByName(tagName).click(); - await expect(poOmnichannelTags.confirmDeleteModal).toBeVisible(); - await poOmnichannelTags.btnConfirmDeleteModal.click(); - await expect(poOmnichannelTags.confirmDeleteModal).not.toBeVisible(); - await expect(page.locator('h3 >> text="No results found"')).toBeVisible(); - }); + await test.step('should be able to delete tag', async () => { + await poOmnichannelTags.deleteTag(tagName); + await poOmnichannelTags.waitForEmptyState(); }); }); @@ -96,45 +84,42 @@ test.describe('OC - Manage Tags', () => { }); await page.goto('/omnichannel'); - await poOmnichannelTags.sidenav.linkTags.click(); + await poOmnichannelTags.sidebar.linkTags.click(); await test.step('expect to add tag departments', async () => { await poOmnichannelTags.search(tag.name); - await poOmnichannelTags.findRowByName(tag.name).click(); - await expect(poOmnichannelTags.contextualBar).toBeVisible(); - await poOmnichannelTags.selectDepartment(department2.data.name); - await poOmnichannelTags.btnSave.click(); + await poOmnichannelTags.table.findRowByName(tag.name).click(); + await expect(poOmnichannelTags.editTag.root).toBeVisible(); + await poOmnichannelTags.editTag.selectDepartment(department2.data.name); + await poOmnichannelTags.editTag.btnSave.click(); }); await test.step('expect department to be in the chosen departments list', async () => { await poOmnichannelTags.search(tag.name); - await poOmnichannelTags.findRowByName(tag.name).click(); - await expect(poOmnichannelTags.contextualBar).toBeVisible(); - await expect(page.getByRole('option', { name: department2.data.name })).toBeVisible(); - await poOmnichannelTags.btnContextualbarClose.click(); + await poOmnichannelTags.table.findRowByName(tag.name).click(); + await expect(poOmnichannelTags.editTag.root).toBeVisible(); + await expect(poOmnichannelTags.editTag.inputDepartments).toBeVisible(); + await poOmnichannelTags.editTag.close(); }); await test.step('expect to remove tag departments', async () => { await poOmnichannelTags.search(tag.name); - await poOmnichannelTags.findRowByName(tag.name).click(); - await expect(poOmnichannelTags.contextualBar).toBeVisible(); - await poOmnichannelTags.selectDepartment(department2.data.name); - await poOmnichannelTags.btnSave.click(); + await poOmnichannelTags.table.findRowByName(tag.name).click(); + await expect(poOmnichannelTags.editTag.root).toBeVisible(); + await poOmnichannelTags.editTag.selectDepartment(department2.data.name); + await poOmnichannelTags.editTag.btnSave.click(); }); await test.step('expect department to not be in the chosen departments list', async () => { await poOmnichannelTags.search(tag.name); - await poOmnichannelTags.findRowByName(tag.name).click(); - await expect(poOmnichannelTags.contextualBar).toBeVisible(); + await poOmnichannelTags.table.findRowByName(tag.name).click(); + await expect(poOmnichannelTags.editTag.root).toBeVisible(); await expect(page.getByRole('option', { name: department2.data.name })).toBeHidden(); }); await test.step('expect to delete tag', async () => { - await poOmnichannelTags.btnDeleteByName(tag.name).click(); - await expect(poOmnichannelTags.confirmDeleteModal).toBeVisible(); - await poOmnichannelTags.btnConfirmDeleteModal.click(); - await expect(poOmnichannelTags.confirmDeleteModal).not.toBeVisible(); - await expect(page.locator('h3 >> text="No results found"')).toBeVisible(); + await poOmnichannelTags.deleteTag(tag.name); + await poOmnichannelTags.waitForEmptyState(); }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts index 2b11fdad694a0..745d82d87526d 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-takeChat.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('omnichannel-takeChat', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts index 75d104cf02dcc..9f89a3d267d90 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts @@ -4,7 +4,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe('OC - Livechat New Chat Triggers - After Registration', () => { diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-open-by-visitor.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-open-by-visitor.spec.ts index 1045036a926c5..610d7d5bd1358 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-open-by-visitor.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-open-by-visitor.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts index 0c6415dd058ed..6b07f2156ae50 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts @@ -1,7 +1,8 @@ import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { HomeOmnichannel, OmnichannelLiveChatEmbedded } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChatEmbedded } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-time-on-site.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-time-on-site.spec.ts index 66bf1058ebfa6..7f1aaa5499ed3 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-time-on-site.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-time-on-site.spec.ts @@ -3,7 +3,8 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers.spec.ts index 67266c142a16c..f5a5a3c921cda 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers.spec.ts @@ -4,7 +4,7 @@ import type { Page } from '@playwright/test'; import { createFakeVisitor } from '../../mocks/data'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; -import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects'; +import { OmnichannelLiveChat, OmnichannelTriggers } from '../page-objects/omnichannel'; import { test, expect } from '../utils/test'; test.describe.serial('OC - Livechat Triggers', () => { @@ -12,7 +12,7 @@ test.describe.serial('OC - Livechat Triggers', () => { let triggerMessage: string; let poLiveChat: OmnichannelLiveChat; let newVisitor: { email: string; name: string }; - let agent: { page: Page; poHomeOmnichannel: HomeOmnichannel }; + let agent: { page: Page; poHomeOmnichannelTriggers: OmnichannelTriggers }; test.beforeAll(async ({ api, browser }) => { newVisitor = createFakeVisitor(); @@ -26,7 +26,7 @@ test.describe.serial('OC - Livechat Triggers', () => { requests.every((e) => expect(e.status()).toBe(200)); const { page } = await createAuxContext(browser, Users.user1, '/omnichannel/triggers'); - agent = { page, poHomeOmnichannel: new HomeOmnichannel(page) }; + agent = { page, poHomeOmnichannelTriggers: new OmnichannelTriggers(page) }; await page.emulateMedia({ reducedMotion: 'reduce' }); }); @@ -73,15 +73,13 @@ test.describe.serial('OC - Livechat Triggers', () => { test('OC - Livechat Triggers - Create and edit trigger', async () => { triggerMessage = 'This is a trigger message time on site'; await test.step('expect create new trigger', async () => { - await agent.poHomeOmnichannel.triggers.createTrigger(triggersName, triggerMessage, 'time-on-site', 5); - await agent.poHomeOmnichannel.triggers.toastMessage.dismissToast(); + await agent.poHomeOmnichannelTriggers.createTrigger(triggersName, triggerMessage, 'Visitor time on site', 5); }); triggerMessage = 'This is a trigger message chat opened by visitor'; await test.step('expect update trigger', async () => { - await agent.poHomeOmnichannel.triggers.firstRowInTriggerTable(triggersName).click(); - await agent.poHomeOmnichannel.triggers.updateTrigger(triggersName, triggerMessage); - await agent.poHomeOmnichannel.triggers.toastMessage.dismissToast(); + await agent.poHomeOmnichannelTriggers.table.findRowByName(triggersName).click(); + await agent.poHomeOmnichannelTriggers.updateTrigger(`edited-${triggersName}`, triggerMessage); }); }); @@ -119,11 +117,8 @@ test.describe.serial('OC - Livechat Triggers', () => { test('OC - Livechat Triggers - Condition: after guest registration', async ({ page }) => { triggerMessage = 'This is a trigger message after guest registration'; await test.step('expect update trigger to after guest registration', async () => { - await agent.poHomeOmnichannel.triggers.firstRowInTriggerTable(`edited-${triggersName}`).click(); - await agent.poHomeOmnichannel.triggers.fillTriggerForm({ condition: 'after-guest-registration', triggerMessage }); - await agent.poHomeOmnichannel.triggers.btnSave.click(); - await agent.poHomeOmnichannel.triggers.toastMessage.dismissToast(); - await agent.page.waitForTimeout(500); + await agent.poHomeOmnichannelTriggers.table.findRowByName(`edited-${triggersName}`).click(); + await agent.poHomeOmnichannelTriggers.updateTrigger(`re-edited-${triggersName}`, triggerMessage, 'After guest registration'); }); await test.step('expect to start conversation', async () => { @@ -158,8 +153,6 @@ test.describe.serial('OC - Livechat Triggers', () => { }); test('OC - Livechat Triggers - Delete trigger', async () => { - await agent.poHomeOmnichannel.triggers.btnDeletefirstRowInTable.click(); - await agent.poHomeOmnichannel.triggers.btnModalRemove.click(); - await expect(agent.poHomeOmnichannel.triggers.removeToastMessage).toBeVisible(); + await agent.poHomeOmnichannelTriggers.removeTrigger(`re-edited-${triggersName}`); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts index 9e0f8eac1bebc..0af2c31bc108e 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts @@ -3,7 +3,7 @@ import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; -import { OmnichannelUnits } from '../page-objects'; +import { OmnichannelUnits } from '../page-objects/omnichannel'; import { createAgent } from '../utils/omnichannel/agents'; import { createDepartment } from '../utils/omnichannel/departments'; import { createMonitor } from '../utils/omnichannel/monitors'; @@ -51,39 +51,36 @@ test.describe('OC - Manage Units', () => { test.beforeEach(async ({ page }: { page: Page }) => { poOmnichannelUnits = new OmnichannelUnits(page); await page.goto('/omnichannel'); - await poOmnichannelUnits.sidenav.linkUnits.click(); + await poOmnichannelUnits.sidebar.linkUnits.click(); }); test('OC - Manage Units - Create Unit', async ({ page }) => { const unitName = faker.string.uuid(); await test.step('expect correct form default state', async () => { - await poOmnichannelUnits.btnCreateUnit.click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await expect(poOmnichannelUnits.btnSave).toBeDisabled(); - await expect(poOmnichannelUnits.btnCancel).toBeEnabled(); - await poOmnichannelUnits.btnCancel.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.createNew(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await expect(poOmnichannelUnits.manageUnit.btnSave).toBeDisabled(); + await expect(poOmnichannelUnits.manageUnit.btnCancel).toBeEnabled(); + await poOmnichannelUnits.manageUnit.btnCancel.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); }); await test.step('expect to create new unit', async () => { - await poOmnichannelUnits.btnCreateUnit.click(); - await poOmnichannelUnits.inputName.fill(unitName); - await poOmnichannelUnits.selectVisibility('public'); - await poOmnichannelUnits.selectDepartment(department.data.name); - await poOmnichannelUnits.selectMonitor('user2'); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.createNew(); + await poOmnichannelUnits.manageUnit.inputName.fill(unitName); + await poOmnichannelUnits.manageUnit.selectVisibility('public'); + await poOmnichannelUnits.manageUnit.selectDepartment(department.data.name); + await poOmnichannelUnits.manageUnit.selectMonitor('user2'); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await poOmnichannelUnits.search(unitName); - await expect(poOmnichannelUnits.findRowByName(unitName)).toBeVisible(); + await expect(poOmnichannelUnits.table.findRowByName(unitName)).toBeVisible(); }); await test.step('expect to delete unit', async () => { - await poOmnichannelUnits.btnDeleteByName(unitName).click(); - await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible(); - await poOmnichannelUnits.btnConfirmDeleteModal.click(); - await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible(); + await poOmnichannelUnits.deleteUnit(unitName); await expect(page.locator('h3 >> text="No units yet"')).toBeVisible(); }); }); @@ -104,59 +101,52 @@ test.describe('OC - Manage Units', () => { }); await page.goto('/omnichannel'); - await poOmnichannelUnits.sidenav.linkUnits.click(); + await poOmnichannelUnits.sidebar.linkUnits.click(); await test.step('expect to edit unit', async () => { await poOmnichannelUnits.search(unit.name); - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await poOmnichannelUnits.inputName.fill(editedUnitName); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await poOmnichannelUnits.manageUnit.inputName.fill(editedUnitName); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await expect(poOmnichannelUnits.inputSearch).toBeVisible(); await poOmnichannelUnits.search(editedUnitName); - await expect(poOmnichannelUnits.findRowByName(editedUnitName)).toBeVisible(); + await expect(poOmnichannelUnits.table.findRowByName(editedUnitName)).toBeVisible(); }); await test.step('expect to add another monitor to list', async () => { - await poOmnichannelUnits.findRowByName(editedUnitName).click(); - await poOmnichannelUnits.selectMonitor('user3'); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.table.findRowByName(editedUnitName).click(); + await poOmnichannelUnits.manageUnit.selectMonitor('user3'); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await poOmnichannelUnits.search(editedUnitName); - await poOmnichannelUnits.findRowByName(editedUnitName).click(); + await poOmnichannelUnits.table.findRowByName(editedUnitName).click(); - await expect(poOmnichannelUnits.inputMonitors).toHaveText(/user2/); - await expect(poOmnichannelUnits.inputMonitors).toHaveText(/user3/); + await expect(poOmnichannelUnits.manageUnit.findMonitorChipOption('user2')).toBeVisible(); + await expect(poOmnichannelUnits.manageUnit.findMonitorChipOption('user3')).toBeVisible(); }); await test.step('expect unit to remove one of the two monitors', async () => { await poOmnichannelUnits.search(editedUnitName); - await poOmnichannelUnits.findRowByName(editedUnitName).click(); - await poOmnichannelUnits.selectMonitor('user2'); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.table.findRowByName(editedUnitName).click(); + await poOmnichannelUnits.manageUnit.removeMonitor('user2'); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await poOmnichannelUnits.search(editedUnitName); - await poOmnichannelUnits.findRowByName(editedUnitName).click(); - await expect(poOmnichannelUnits.inputMonitors).toHaveText(/user3/); - await expect(poOmnichannelUnits.inputMonitors).not.toHaveText(/user2/); + await poOmnichannelUnits.table.findRowByName(editedUnitName).click(); + await expect(poOmnichannelUnits.manageUnit.findMonitorChipOption('user3')).toBeVisible(); + await expect(poOmnichannelUnits.manageUnit.findMonitorChipOption('user2')).toBeHidden(); }); await test.step('expect to delete unit', async () => { - await poOmnichannelUnits.findRowByName(editedUnitName).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - - await test.step('expect to confirm delete', async () => { - await poOmnichannelUnits.btnDelete.click(); - await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible(); - await poOmnichannelUnits.btnConfirmDeleteModal.click(); - await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible(); - }); + await poOmnichannelUnits.table.findRowByName(editedUnitName).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); - await expect(poOmnichannelUnits.findRowByName(editedUnitName)).not.toBeVisible(); + await poOmnichannelUnits.deleteUnit(editedUnitName); + await expect(poOmnichannelUnits.table.findRowByName(editedUnitName)).not.toBeVisible(); }); }); @@ -176,49 +166,44 @@ test.describe('OC - Manage Units', () => { await test.step('expect to add unit departments', async () => { await poOmnichannelUnits.search(unit.name); - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await poOmnichannelUnits.selectDepartment(department2.data.name); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await poOmnichannelUnits.manageUnit.selectDepartment(department2.data.name); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await poOmnichannelUnits.search(unit.name); - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await expect(poOmnichannelUnits.findDepartmentsChipOption(department2.data.name)).toBeVisible(); - await poOmnichannelUnits.findDepartmentsChipOption(department2.data.name).hover(); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await expect(poOmnichannelUnits.manageUnit.findDepartmentsChipOption(department2.data.name)).toBeVisible(); + await poOmnichannelUnits.manageUnit.findDepartmentsChipOption(department2.data.name).hover(); await expect(page.getByRole('tooltip', { name: department2.data.name })).toBeVisible(); - await poOmnichannelUnits.btnContextualbarClose.click(); + await poOmnichannelUnits.manageUnit.close(); }); await test.step('expect to remove unit departments', async () => { await poOmnichannelUnits.search(unit.name); - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await poOmnichannelUnits.selectDepartment(department2.data.name); - await poOmnichannelUnits.btnSave.click(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await poOmnichannelUnits.manageUnit.selectDepartment(department2.data.name); + await poOmnichannelUnits.manageUnit.btnSave.click(); + await expect(poOmnichannelUnits.manageUnit.root).not.toBeVisible(); await poOmnichannelUnits.search(unit.name); - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await expect(page.getByRole('option', { name: department2.data.name })).toBeHidden(); - await poOmnichannelUnits.btnContextualbarClose.click(); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); + await expect(poOmnichannelUnits.manageUnit.findDepartmentsChipOption(department2.data.name)).toBeHidden(); + await poOmnichannelUnits.manageUnit.close(); }); await test.step('expect to delete unit', async () => { - await poOmnichannelUnits.findRowByName(unit.name).click(); - await expect(poOmnichannelUnits.contextualBar).toBeVisible(); - await test.step('expect to confirm delete', async () => { - await poOmnichannelUnits.btnDelete.click(); - await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible(); - await poOmnichannelUnits.btnConfirmDeleteModal.click(); - await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible(); - }); + await poOmnichannelUnits.search(unit.name); + await poOmnichannelUnits.table.findRowByName(unit.name).click(); + await expect(poOmnichannelUnits.manageUnit.root).toBeVisible(); - await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); - await expect(poOmnichannelUnits.findRowByName(unit.name)).not.toBeVisible(); + await poOmnichannelUnits.deleteUnit(unit.name); + await expect(poOmnichannelUnits.table.findRowByName(unit.name)).not.toBeVisible(); }); }); }); diff --git a/apps/meteor/tests/e2e/page-objects/admin-rooms.ts b/apps/meteor/tests/e2e/page-objects/admin-rooms.ts index 79194654bc42c..eda0a45707606 100644 --- a/apps/meteor/tests/e2e/page-objects/admin-rooms.ts +++ b/apps/meteor/tests/e2e/page-objects/admin-rooms.ts @@ -8,7 +8,7 @@ export class AdminRooms extends Admin { constructor(page: Page) { super(page); - this.editRoom = new EditRoomFlexTab(page); + this.editRoom = new EditRoomFlexTab(page.getByRole('dialog', { name: 'Room Information' })); } get adminPageContent(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts b/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts index e587457ea1db4..5821a77ae6b55 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts @@ -1,41 +1,18 @@ -import type { Locator, Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { FlexTab } from './flextab'; -abstract class EmojiFlexTab extends FlexTab { - constructor(root: Locator) { - super(root); - } - - get inputName(): Locator { - return this.root.getByRole('textbox', { name: 'Name' }); - } - - private get btnSave() { - return this.root.getByRole('button', { name: 'Save' }); - } - - async save() { - await this.btnSave.click(); - await this.waitForDismissal(); - } -} - -export class AddEmojiFlexTab extends EmojiFlexTab { +export class AddEmojiFlexTab extends FlexTab { constructor(page: Page) { super(page.getByRole('dialog', { name: 'Add New Emoji' })); } } -export class EditEmojiFlexTab extends EmojiFlexTab { +export class EditEmojiFlexTab extends FlexTab { constructor(page: Page) { super(page.getByRole('dialog', { name: 'Custom Emoji Info' })); } - private get btnDelete() { - return this.root.getByRole('button', { name: 'Delete' }); - } - async delete() { await this.btnDelete.click(); } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/edit-contact-flaxtab.ts b/apps/meteor/tests/e2e/page-objects/fragments/edit-contact-flaxtab.ts new file mode 100644 index 0000000000000..05afd758691fe --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/edit-contact-flaxtab.ts @@ -0,0 +1,33 @@ +import type { Locator, Page } from '@playwright/test'; + +import { FlexTab } from './flextab'; + +export class OmnichannelEditContactFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'contact' })); + } + + get inputEmail(): Locator { + return this.root.locator('input[name="emails.0.address"]'); + } + + get inputPhone(): Locator { + return this.root.locator('input[name="phones.0.phoneNumber"]'); + } + + get inputContactManager(): Locator { + return this.root.locator('input[name=contactManager]'); + } + + get btnAddEmail(): Locator { + return this.root.locator('role=button[name="Add email"]'); + } + + get btnAddPhone(): Locator { + return this.root.locator('role=button[name="Add phone"]'); + } + + getErrorMessage(message: string): Locator { + return this.root.locator(`role=alert >> text="${message}"`); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/edit-room-flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/edit-room-flextab.ts index 1b5e48fc168b8..bfc88661991bb 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/edit-room-flextab.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/edit-room-flextab.ts @@ -1,14 +1,11 @@ import type { Locator, Page } from '@playwright/test'; import { FlexTab } from './flextab'; +import { Listbox } from './listbox'; export class EditRoomFlexTab extends FlexTab { - constructor(page: Page) { - super(page.getByRole('dialog', { name: 'Room Information' })); - } - - get btnSave(): Locator { - return this.root.locator('button >> text="Save"'); + constructor(locator: Locator) { + super(locator); } get roomNameInput(): Locator { @@ -51,3 +48,40 @@ export class EditRoomFlexTab extends FlexTab { return this.root.locator('input[name="isDefault"]'); } } + +export class OmnichannelEditRoomFlexTab extends EditRoomFlexTab { + private readonly tagsListbox: Listbox; + + private readonly slaListbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Edit Room' })); + this.tagsListbox = new Listbox(page); + this.slaListbox = new Listbox(page, 'SLA Policy'); + } + + get inputTopic(): Locator { + return this.root.getByRole('textbox', { name: 'Topic', exact: true }); + } + + get inputSLAPolicy(): Locator { + return this.root.getByRole('button', { name: 'SLA Policy', exact: true }); + } + + optionTag(name: string): Locator { + return this.tagsListbox.getOption(name); + } + + async selectTag(name: string) { + await this.tagsListbox.selectOption(name); + } + + async selectSLA(name: string) { + await this.inputSLAPolicy.click(); + await this.slaListbox.selectOption(name, true); + } + + get inputTags(): Locator { + return this.root.getByRole('textbox', { name: 'Select an option' }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/edit-user-flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/edit-user-flextab.ts index 796660efc25d1..0133c63d7694e 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/edit-user-flextab.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/edit-user-flextab.ts @@ -15,10 +15,6 @@ export class EditUserFlexTab extends FlexTab { return this.root.locator('role=button[name="Save user"]'); } - get inputName(): Locator { - return this.root.getByRole('textbox', { name: 'Name', exact: true }); - } - get inputUserName(): Locator { return this.root.getByRole('textbox', { name: 'Username', exact: true }); } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/flextab.ts index 770cf5997b440..e406a0decb43a 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/flextab.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/flextab.ts @@ -14,11 +14,40 @@ export abstract class FlexTab { } private get btnClose() { - return this.root.getByRole('button', { name: 'Close' }); + return this.root.getByRole('button', { name: 'Close', exact: true }); + } + + get inputName() { + return this.root.getByRole('textbox', { name: 'Name', exact: true }); + } + + get btnSave() { + return this.root.getByRole('button', { name: 'Save', exact: true }); + } + + get btnCancel() { + return this.root.getByRole('button', { name: 'Cancel', exact: true }); + } + + get btnDelete() { + return this.root.getByRole('button', { name: 'Delete', exact: true }); + } + + get btnReset() { + return this.root.getByRole('button', { name: 'Reset', exact: true }); + } + + errorMessage(message: string): Locator { + return this.root.locator('[role="alert"]', { hasText: message }); } async close() { await this.btnClose.click(); await this.waitForDismissal(); } + + async save() { + await this.btnSave.click(); + await this.waitForDismissal(); + } } 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 3f36cc6d13ca7..eba1a2f986a26 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -307,10 +307,6 @@ export class HomeContent { return this.page.getByRole('group').getByRole('button', { name: 'Voice call' }); } - get btnContactEdit(): Locator { - return this.page.getByRole('dialog').getByRole('button', { name: 'Edit', exact: true }); - } - get btnSendTranscript(): Locator { return this.page.locator('role=button[name="Send transcript"]'); } 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 47630b06220ad..71534bdb38498 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 @@ -1,44 +1,27 @@ import type { Locator, Page } from '@playwright/test'; import { HomeContent } from './home-content'; -import { OmnichannelTransferChatModal } from './modals'; +import { OmnichannelTransferChatModal, OmnichannelReturnToQueueModal } from './modals'; export class HomeOmnichannelContent extends HomeContent { readonly forwardChatModal: OmnichannelTransferChatModal; + readonly returnToQueueModal: OmnichannelReturnToQueueModal; + constructor(page: Page) { super(page); this.forwardChatModal = new OmnichannelTransferChatModal(page); + this.returnToQueueModal = new OmnichannelReturnToQueueModal(page); } get btnReturnToQueue(): Locator { return this.page.locator('role=button[name="Move to the queue"]'); } - get modalReturnToQueue(): Locator { - return this.page.locator('[data-qa-id="return-to-queue-modal"]'); - } - - get btnReturnToQueueConfirm(): Locator { - return this.modalReturnToQueue.locator('role=button[name="Confirm"]'); - } - - get btnReturnToQueueCancel(): Locator { - return this.modalReturnToQueue.locator('role=button[name="Cancel"]'); - } - get btnTakeChat(): Locator { return this.page.locator('role=button[name="Take it!"]'); } - get contactContextualBar() { - return this.page.getByRole('dialog', { name: 'Contact' }); - } - - get infoContactEmail(): Locator { - return this.contactContextualBar.getByRole('list', { name: 'Email' }).getByRole('listitem').first().locator('p'); - } - get header(): Locator { return this.page.locator('header'); } @@ -55,6 +38,9 @@ export class HomeOmnichannelContent extends HomeContent { return this.page.locator('.rcx-room-header').getByRole('heading'); } + /** + * FIXME: useX naming convention should be exclusively for react hooks + **/ async useCannedResponse(cannedResponseName: string): Promise { await this.composer.inputMessage.pressSequentially('!'); await this.page.locator('[role="menu"][name="ComposerBoxPopup"]').waitFor({ state: 'visible' }); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/index.ts b/apps/meteor/tests/e2e/page-objects/fragments/index.ts index f1f349b6a82ab..f6a076472ab99 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/index.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/index.ts @@ -3,7 +3,6 @@ export * from './user-info-flextab'; export * from './home-content'; export * from './home-omnichannel-content'; export * from './home-flextab'; -export * from './omnichannel-sidenav'; export * from './navbar'; export * from './sidebar'; export * from './sidepanel'; diff --git a/apps/meteor/tests/e2e/page-objects/fragments/listbox.ts b/apps/meteor/tests/e2e/page-objects/fragments/listbox.ts index 055c7ccb56b84..8b22ca2f27484 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/listbox.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/listbox.ts @@ -1,13 +1,21 @@ -import type { Locator } from 'playwright-core'; +import type { Locator, Page } from 'playwright-core'; export class Listbox { - constructor(private root: Locator) {} + readonly root: Locator; - async selectOption(name: string) { - return this.root.getByRole('option', { name }).click(); + constructor(page: Page, name?: string) { + /** + * Currently, our selects and multiSelects has multiple listboxes in the DOM. + * So, to avoid selecting the wrong one, we will always select the last until we fix it. + */ + this.root = page.getByRole('listbox', { name }).last(); + } + + async selectOption(name: string, exact?: boolean) { + return this.root.getByRole('option', { name, exact }).click(); } public getOption(name: string): Locator { - return this.root.getByRole('option', { name }); + return this.root.getByRole('option', { name, exact: true }); } } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/menu.ts b/apps/meteor/tests/e2e/page-objects/fragments/menu.ts index 1bafdbcaa0cd4..4353ec8d12e03 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/menu.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/menu.ts @@ -12,6 +12,10 @@ export abstract class Menu { waitForDismissal() { return expect(this.root).not.toBeVisible(); } + + selectMenuItem(itemName: string) { + return this.root.getByRole('menuitem', { name: itemName, exact: true }).click(); + } } export class MenuMore extends Menu { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/confirm-delete-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/confirm-delete-modal.ts index 66826b0489d40..64967bbdf19ca 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/confirm-delete-modal.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/confirm-delete-modal.ts @@ -1,4 +1,4 @@ -import type { Locator } from 'playwright-core'; +import type { Locator, Page } from 'playwright-core'; import { Modal } from './modal'; @@ -7,12 +7,27 @@ export class ConfirmDeleteModal extends Modal { super(root); } - private btnDelete() { + get btnDelete() { return this.root.getByRole('button', { name: 'Delete' }); } async confirmDelete() { - await this.btnDelete().click(); + await this.btnDelete.click(); await this.waitForDismissal(); } } + +export class ConfirmDeleteDepartmentModal extends ConfirmDeleteModal { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Delete Department?' })); + } + + get inputConfirmDepartmentName() { + return this.root.getByRole('textbox', { name: 'Department name' }); + } + + async deleteDepartment(departmentName: string) { + await this.inputConfirmDepartmentName.fill(departmentName); + await this.confirmDelete(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/create-new-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/create-new-modal.ts index 2ad3e2fe12666..33d6cc4f8b934 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/create-new-modal.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/create-new-modal.ts @@ -8,7 +8,7 @@ export abstract class CreateNewModal extends Modal { constructor(root: Locator, page: Page) { super(root, page); - this.listbox = new Listbox(page.getByRole('listbox')); + this.listbox = new Listbox(page); } get inputName(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/index.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/index.ts index 462b2836f5ec2..77c38b3dd78db 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/index.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/index.ts @@ -12,6 +12,9 @@ export * from './omnichannel-on-hold-modal'; export * from './omnichannel-transfer-chat-modal'; export * from './omnichannel-confirm-remove-chat'; export * from './omnichannel-contact-review-modal'; +export * from './omnichannel-delete-contact-modal'; +export * from './omnichannel-reset-priorities-modal'; +export * from './omnichannel-return-to-queue-modal'; export * from './report-message-modal'; export * from './reset-e2ee-password-modal'; export * from './save-e2ee-password-modal'; diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-contact-review-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-contact-review-modal.ts index b4314202283a9..9ed8beb2b22b2 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-contact-review-modal.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-contact-review-modal.ts @@ -9,7 +9,7 @@ export class OmnichannelContactReviewModal extends Modal { constructor(page: Page) { super(page.getByRole('dialog', { name: 'Review contact' }), page); - this.listbox = new Listbox(page.getByRole('listbox')); + this.listbox = new Listbox(page); } private getFieldByName(name: string): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-delete-contact-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-delete-contact-modal.ts new file mode 100644 index 0000000000000..a7494ce08da64 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-delete-contact-modal.ts @@ -0,0 +1,22 @@ +import type { Locator, Page } from '@playwright/test'; + +import { Modal } from './modal'; + +export class OmnichannelDeleteContactModal extends Modal { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Delete Contact' })); + } + + get inputConfirmation(): Locator { + return this.root.getByRole('textbox', { name: 'Confirm Contact Removal' }); + } + + get btnDelete(): Locator { + return this.root.getByRole('button', { name: 'Delete' }); + } + + async delete() { + await this.btnDelete.click(); + await this.waitForDismissal(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-reset-priorities-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-reset-priorities-modal.ts new file mode 100644 index 0000000000000..d5be391821edb --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-reset-priorities-modal.ts @@ -0,0 +1,18 @@ +import type { Page } from '@playwright/test'; + +import { Modal } from './modal'; + +export class OmnichannelResetPrioritiesModal extends Modal { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Reset priorities' })); + } + + private get btnResetConfirm() { + return this.root.getByRole('button', { name: 'Reset' }); + } + + async reset() { + await this.btnResetConfirm.click(); + await this.waitForDismissal(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-return-to-queue-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-return-to-queue-modal.ts new file mode 100644 index 0000000000000..6a6eb706e94ff --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-return-to-queue-modal.ts @@ -0,0 +1,18 @@ +import type { Page } from '@playwright/test'; + +import { Modal } from './modal'; + +export class OmnichannelReturnToQueueModal extends Modal { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Return back to the Queue' })); + } + + private get btnReturnToQueueConfirm() { + return this.root.getByRole('button', { name: 'Confirm' }); + } + + async confirm() { + await this.btnReturnToQueueConfirm.click(); + await this.waitForDismissal(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-transfer-chat-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-transfer-chat-modal.ts index 9398213613477..9aa499d0bc851 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-transfer-chat-modal.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/omnichannel-transfer-chat-modal.ts @@ -8,7 +8,7 @@ export class OmnichannelTransferChatModal extends Modal { constructor(page: Page) { super(page.getByRole('dialog', { name: 'Forward chat' })); - this.listbox = new Listbox(page.getByRole('listbox')); + this.listbox = new Listbox(page); } get inputComment(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/upsell-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/upsell-modal.ts index d56da056247b0..0881a016e6449 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/modals/upsell-modal.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/upsell-modal.ts @@ -7,3 +7,9 @@ export class VoiceCallsUpsellModal extends Modal { super(page.getByRole('dialog', { name: 'Team voice calls' })); } } + +export class OmnichannelUpsellDepartmentsModal extends Modal { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Departments' })); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/omnichannel-sidenav.ts b/apps/meteor/tests/e2e/page-objects/fragments/omnichannel-sidenav.ts deleted file mode 100644 index 63fc3c3919358..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/fragments/omnichannel-sidenav.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -export class OmnichannelSidenav { - private readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - get linkDepartments(): Locator { - return this.page.locator('a[href="/omnichannel/departments"]'); - } - - get linkAgents(): Locator { - return this.page.locator('a[href="/omnichannel/agents"]'); - } - - get linkManagers(): Locator { - return this.page.locator('a[href="/omnichannel/managers"]'); - } - - get linkCustomFields(): Locator { - return this.page.locator('a[href="/omnichannel/customfields"]'); - } - - get linkCurrentChats(): Locator { - return this.page.locator('a[href="/omnichannel/current"]'); - } - - get linkTriggers(): Locator { - return this.page.locator('a[href="/omnichannel/triggers"]'); - } - - get linkSlaPolicies(): Locator { - return this.page.locator('a[href="/omnichannel/sla-policies"]'); - } - - get linkPriorities(): Locator { - return this.page.locator('a[href="/omnichannel/priorities"]'); - } - - get linkMonitors(): Locator { - return this.page.locator('a[href="/omnichannel/monitors"]'); - } - - get linkBusinessHours(): Locator { - return this.page.locator('a[href="/omnichannel/businessHours"]'); - } - - get linkAnalytics(): Locator { - return this.page.locator('a[href="/omnichannel/analytics"]'); - } - - get linkRealTimeMonitoring(): Locator { - return this.page.locator('a[href="/omnichannel/realtime-monitoring"]'); - } - - get linkReports(): Locator { - return this.page.locator('a[href="/omnichannel/reports"]'); - } - - get linkCannedResponses(): Locator { - return this.page.locator('a[href="/omnichannel/canned-responses"]'); - } - - get linkUnits(): Locator { - return this.page.locator('a[href="/omnichannel/units"]'); - } - - get linkLivechatAppearance(): Locator { - return this.page.locator('a[href="/omnichannel/appearance"]'); - } - - get linkTags(): Locator { - return this.page.locator('a[href="/omnichannel/tags"]'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/room-info-flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/room-info-flextab.ts new file mode 100644 index 0000000000000..1983f8c6c57b7 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/room-info-flextab.ts @@ -0,0 +1,31 @@ +import type { Locator, Page } from '@playwright/test'; + +import { FlexTab } from './flextab'; + +export class RoomInfoFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Room Information' })); + } + + get btnEdit(): Locator { + return this.root.getByRole('button', { name: 'Edit' }); + } +} + +export class OmnichannelRoomInfoFlexTab extends RoomInfoFlexTab { + getInfo(value: string): Locator { + return this.root.locator(`span >> text="${value}"`); + } + + getLabel(label: string): Locator { + return this.root.locator(`div >> text="${label}"`); + } + + getInfoByLabel(label: string): Locator { + return this.root.getByLabel(label); + } + + getTagInfoByLabel(label: string): Locator { + return this.root.getByRole('list', { name: 'Tags' }).getByText(label, { exact: true }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts b/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts index 26600055cea29..1d041a3db1735 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts @@ -101,6 +101,10 @@ export class RoomSidebar extends Sidebar { return item.getByRole('status', { name: 'unread' }); } + getBadgeIndicator(name: string, title: string): Locator { + return this.getSidebarItemByName(name).getByTitle(title); + } + async selectPriority(name: string, priority: string) { const sidebarItem = this.getSidebarItemByName(name); await sidebarItem.hover(); @@ -143,3 +147,73 @@ export class AccountSidebar extends Sidebar { await this.waitForDismissal(); } } + +export class OmnichannelSidebar extends Sidebar { + constructor(page: Page) { + super(page.getByRole('navigation', { name: 'Omnichannel' })); + } + + get linkDepartments(): Locator { + return this.root.locator('a[href="/omnichannel/departments"]'); + } + + get linkAgents(): Locator { + return this.root.locator('a[href="/omnichannel/agents"]'); + } + + get linkManagers(): Locator { + return this.root.locator('a[href="/omnichannel/managers"]'); + } + + get linkCustomFields(): Locator { + return this.root.locator('a[href="/omnichannel/customfields"]'); + } + + get linkCurrentChats(): Locator { + return this.root.locator('a[href="/omnichannel/current"]'); + } + + get linkSlaPolicies(): Locator { + return this.root.locator('a[href="/omnichannel/sla-policies"]'); + } + + get linkPriorities(): Locator { + return this.root.locator('a[href="/omnichannel/priorities"]'); + } + + get linkMonitors(): Locator { + return this.root.locator('a[href="/omnichannel/monitors"]'); + } + + get linkBusinessHours(): Locator { + return this.root.locator('a[href="/omnichannel/businessHours"]'); + } + + get linkAnalytics(): Locator { + return this.root.locator('a[href="/omnichannel/analytics"]'); + } + + get linkRealTimeMonitoring(): Locator { + return this.root.locator('a[href="/omnichannel/realtime-monitoring"]'); + } + + get linkReports(): Locator { + return this.root.locator('a[href="/omnichannel/reports"]'); + } + + get linkCannedResponses(): Locator { + return this.root.locator('a[href="/omnichannel/canned-responses"]'); + } + + get linkUnits(): Locator { + return this.root.locator('a[href="/omnichannel/units"]'); + } + + get linkLivechatAppearance(): Locator { + return this.root.locator('a[href="/omnichannel/appearance"]'); + } + + get linkTags(): Locator { + return this.root.locator('a[href="/omnichannel/tags"]'); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/table.ts b/apps/meteor/tests/e2e/page-objects/fragments/table.ts new file mode 100644 index 0000000000000..f91557ab4ef00 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/table.ts @@ -0,0 +1,17 @@ +import type { Locator } from '@playwright/test'; + +import { expect } from '../../utils/test'; + +export abstract class Table { + constructor(protected root: Locator) {} + + waitForDisplay() { + return expect(this.root).toBeVisible(); + } + + findRowByName(name: string): Locator { + return this.root.getByRole('row').filter({ + has: this.root.page().getByText(name, { exact: true }), + }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/home-omnichannel.ts b/apps/meteor/tests/e2e/page-objects/home-omnichannel.ts index 9b23eadef8d12..ea7695d398bf5 100644 --- a/apps/meteor/tests/e2e/page-objects/home-omnichannel.ts +++ b/apps/meteor/tests/e2e/page-objects/home-omnichannel.ts @@ -1,38 +1,30 @@ import type { Locator, Page } from '@playwright/test'; -import { HomeOmnichannelContent, OmnichannelSidenav } from './fragments'; -import { OmnichannelQuickActionsRoomToolbar, OmnichannelRoomToolbar } from './fragments/toolbar'; +import { HomeOmnichannelContent, OmnichannelQuickActionsRoomToolbar, OmnichannelRoomToolbar, OmnichannelSidebar } from './fragments'; +import { OmnichannelEditRoomFlexTab } from './fragments/edit-room-flextab'; +import { OmnichannelRoomInfoFlexTab } from './fragments/room-info-flextab'; import { HomeChannel } from './home-channel'; -import { OmnichannelAgents } from './omnichannel-agents'; -import { OmnichannelCannedResponses } from './omnichannel-canned-responses'; -import { OmnichannelChats } from './omnichannel-contact-center-chats'; -import { OmnichannelContacts } from './omnichannel-contacts-list'; -import { OmnichannelManager } from './omnichannel-manager'; -import { OmnichannelMonitors } from './omnichannel-monitors'; -import { OmnichannelRoomInfo } from './omnichannel-room-info'; -import { OmnichannelTranscript } from './omnichannel-transcript'; -import { OmnichannelTriggers } from './omnichannel-triggers'; +import { + OmnichannelCannedResponses, + OmnichannelTranscript, + OmnichannelContactCenterContacts, + OmnichannelContactCenterChats, +} from './omnichannel'; export class HomeOmnichannel extends HomeChannel { - readonly triggers: OmnichannelTriggers; - - readonly omnisidenav: OmnichannelSidenav; + readonly omnisidenav: OmnichannelSidebar; readonly transcript: OmnichannelTranscript; readonly cannedResponses: OmnichannelCannedResponses; - readonly agents: OmnichannelAgents; - - readonly managers: OmnichannelManager; - - readonly monitors: OmnichannelMonitors; + readonly contacts: OmnichannelContactCenterContacts; - readonly contacts: OmnichannelContacts; + readonly chats: OmnichannelContactCenterChats; - readonly chats: OmnichannelChats; + readonly roomInfo: OmnichannelRoomInfoFlexTab; - readonly roomInfo: OmnichannelRoomInfo; + readonly editRoomInfo: OmnichannelEditRoomFlexTab; readonly quickActionsRoomToolbar: OmnichannelQuickActionsRoomToolbar; @@ -42,19 +34,16 @@ export class HomeOmnichannel extends HomeChannel { constructor(page: Page) { super(page); - this.triggers = new OmnichannelTriggers(page); - this.omnisidenav = new OmnichannelSidenav(page); + this.omnisidenav = new OmnichannelSidebar(page); this.transcript = new OmnichannelTranscript(page); this.cannedResponses = new OmnichannelCannedResponses(page); - this.agents = new OmnichannelAgents(page); - this.managers = new OmnichannelManager(page); - this.monitors = new OmnichannelMonitors(page); - this.contacts = new OmnichannelContacts(page); - this.chats = new OmnichannelChats(page); - this.roomInfo = new OmnichannelRoomInfo(page); + this.contacts = new OmnichannelContactCenterContacts(page); + this.chats = new OmnichannelContactCenterChats(page); + this.roomInfo = new OmnichannelRoomInfoFlexTab(page); this.quickActionsRoomToolbar = new OmnichannelQuickActionsRoomToolbar(page); this.content = new HomeOmnichannelContent(page); this.roomToolbar = new OmnichannelRoomToolbar(page); + this.editRoomInfo = new OmnichannelEditRoomFlexTab(page); } get btnContactInfo(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/index.ts b/apps/meteor/tests/e2e/page-objects/index.ts index e6b3c41e01120..f69b583b5c756 100644 --- a/apps/meteor/tests/e2e/page-objects/index.ts +++ b/apps/meteor/tests/e2e/page-objects/index.ts @@ -15,17 +15,5 @@ export * from './auth'; export * from './home-channel'; export * from './home-discussion'; export * from './home-team'; -export * from './omnichannel-agents'; -export * from './omnichannel-departments'; -export * from './omnichannel-contact-center-chats'; -export * from './omnichannel-livechat'; -export * from './omnichannel-livechat-embedded'; -export * from './omnichannel-manager'; -export * from './omnichannel-custom-fields'; -export * from './omnichannel-units'; export * from './home-omnichannel'; -export * from './omnichannel-monitors'; -export * from './omnichannel-settings'; -export * from './omnichannel-business-hours'; -export * from './omnichannel-tags'; export * from './marketplace'; diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-administration.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-administration.ts deleted file mode 100644 index 01b8a6ed6ed45..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-administration.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Page } from '@playwright/test'; - -import { OmnichannelSidenav } from './fragments'; - -export class OmnichannelAdministration { - protected readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-agents.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-agents.ts deleted file mode 100644 index 3eaf9fa304d09..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-agents.ts +++ /dev/null @@ -1,122 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav } from './fragments'; - -export class OmnichannelAgents { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - readonly editCtxBar: Locator; - - readonly infoCtxBar: Locator; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - this.editCtxBar = page.getByRole('dialog', { name: 'Edit User' }); - this.infoCtxBar = page.getByRole('dialog', { name: 'User Info' }); - } - - get inputUsername(): Locator { - return this.page.getByRole('textbox', { name: 'Username' }); - } - - get inputSearch(): Locator { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - get btnAdd(): Locator { - return this.page.locator('role=button[name="Add agent"]'); - } - - get firstRowInTable() { - return this.page.locator('[data-qa-id="agents-table"] tr:first-child td:first-child'); - } - - get btnDeleteFirstRowInTable() { - return this.page.locator('[data-qa-id="agents-table"] tr:first-child').locator('role=button[name="Remove"]'); - } - - get modalRemoveAgent(): Locator { - return this.page.locator('[data-qa-id="remove-agent-modal"]'); - } - - get btnModalRemove(): Locator { - return this.modalRemoveAgent.locator('role=button[name="Delete"]'); - } - - get btnEdit(): Locator { - return this.infoCtxBar.locator('[data-qa="agent-info-action-edit"]'); - } - - get btnRemove(): Locator { - return this.infoCtxBar.locator('role=button[name="Remove"]'); - } - - get btnClose(): Locator { - return this.editCtxBar.getByRole('button', { name: 'Close', exact: true }); - } - - get btnSave(): Locator { - return this.editCtxBar.locator('[data-qa-id="agent-edit-save"]'); - } - - get inputMaxChats(): Locator { - return this.editCtxBar.locator('input[name="maxNumberSimultaneousChat"]'); - } - - get inputStatus(): Locator { - return this.page.locator('[data-qa-id="agent-edit-status"]'); - } - - get inputDepartment(): Locator { - return this.editCtxBar.getByLabel('Departments').getByRole('textbox'); - } - - get scrollContainer(): Locator { - return this.page.locator('#position-container').getByTestId('virtuoso-scroller'); - } - - findOption(name: string) { - return this.page.locator('#position-container').getByRole('option', { name, exact: true }); - } - - scrollToListBottom() { - return this.scrollContainer.evaluate((el) => { - el.scrollTop = el.scrollHeight; - el.dispatchEvent(new Event('scroll')); - }); - } - - async selectDepartment(name: string) { - await this.inputDepartment.click(); - await this.inputDepartment.fill(name); - await this.findOption(name).click(); - // TODO: This is necessary due to the PaginatedMultiSelectFiltered not closing the list when an option is selected nor when close is clicked. - // The line below can be removed once the component is adjusted in Fuselage - await this.editCtxBar.click(); - } - - async selectStatus(status: string) { - await this.inputStatus.click(); - await this.page.locator(`.rcx-option__content:has-text("${status}")`).click(); - } - - async selectUsername(username: string) { - await this.inputUsername.fill(username); - await this.page.locator(`role=option[name="${username}"]`).click(); - } - - findRowByUsername(username: string) { - return this.page.locator(`[data-qa-id="${username}"]`); - } - - findRowByName(name: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${name}"`) }); - } - - findSelectedDepartment(name: string) { - return this.editCtxBar.getByLabel('Departments', { exact: true }).getByRole('option', { name }); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-business-hours.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-business-hours.ts deleted file mode 100644 index 4417d6a274143..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-business-hours.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { Locator } from '@playwright/test'; - -import { OmnichannelAdministration } from './omnichannel-administration'; - -export class OmnichannelBusinessHours extends OmnichannelAdministration { - get btnCreateBusinessHour(): Locator { - return this.page.locator('header').locator('role=button[name="New"]'); - } - - get btnSave(): Locator { - return this.page.locator('role=button[name="Save"]'); - } - - get btnBack(): Locator { - return this.page.locator('role=button[name="Back"]'); - } - - get inputSearch(): Locator { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - get inputName(): Locator { - return this.page.locator('[name="name"]'); - } - - get fieldDepartment(): Locator { - return this.page.getByLabel('Departments', { exact: true }); - } - - get inputDepartments(): Locator { - return this.fieldDepartment.getByRole('textbox'); - } - - findRowByName(name: string): Locator { - return this.page.locator(`tr:has-text("${name}")`); - } - - btnDeleteByName(name: string): Locator { - return this.page.locator(`tr:has-text("${name}") button[title="Remove"]`); - } - - get confirmDeleteModal(): Locator { - return this.page.locator('dialog:has(h2:has-text("Are you sure?"))'); - } - - get btnCancelDeleteModal(): Locator { - return this.confirmDeleteModal.locator('role=button[name="Cancel"]'); - } - - get btnConfirmDeleteModal(): Locator { - return this.confirmDeleteModal.locator('role=button[name="Delete"]'); - } - - getCheckboxByLabel(name: string): Locator { - return this.page.locator('label', { has: this.page.getByRole('checkbox', { name }) }); - } - - findOption(name: string): Locator { - return this.page.locator('#position-container').getByRole('option', { name, exact: true }); - } - - findDepartmentsChipOption(name: string) { - return this.fieldDepartment.getByRole('option', { name, exact: true }); - } - - async selectDepartment(name: string) { - await this.inputDepartments.click(); - await this.inputDepartments.fill(name); - await this.findOption(name).click(); - } - - async search(text: string) { - await this.inputSearch.fill(text); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats-filters.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats-filters.ts deleted file mode 100644 index 2bc57c870b2bb..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats-filters.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { FlexTab } from './fragments/flextab'; - -export class OmnichannelChatsFilters extends FlexTab { - constructor(page: Page) { - super(page.getByRole('dialog', { name: 'Filters' })); - } - - get inputFrom(): Locator { - return this.root.locator('input[name="from"]'); - } - - get inputTo(): Locator { - return this.root.locator('input[name="to"]'); - } - - get btnApply(): Locator { - return this.root.locator('role=button[name="Apply"]'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats.ts deleted file mode 100644 index 3f5918ba07787..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-contact-center-chats.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { HomeOmnichannelContent } from './fragments'; -import { FlexTab } from './fragments/flextab'; -import { OmnichannelConfirmRemoveChat } from './fragments/modals'; -import { OmnichannelAdministration } from './omnichannel-administration'; -import { OmnichannelChatsFilters } from './omnichannel-contact-center-chats-filters'; - -class ConversationFlexTab extends FlexTab { - constructor(page: Page) { - super(page.getByRole('dialog', { name: 'Conversation' })); - } - - private get btnOpenChat(): Locator { - return this.root.getByRole('button', { name: 'Open chat' }); - } - - async openChat() { - await this.btnOpenChat.click(); - await this.waitForDismissal(); - } -} - -export class OmnichannelChats extends OmnichannelAdministration { - private readonly confirmRemoveChatModal: OmnichannelConfirmRemoveChat; - - private readonly conversation: ConversationFlexTab; - - readonly filters: OmnichannelChatsFilters; - - readonly content: HomeOmnichannelContent; - - constructor(page: Page) { - super(page); - this.filters = new OmnichannelChatsFilters(page); - this.confirmRemoveChatModal = new OmnichannelConfirmRemoveChat(page); - this.content = new HomeOmnichannelContent(page); - this.conversation = new ConversationFlexTab(page); - } - - get btnFilters(): Locator { - return this.page.locator('role=button[name="Filters"]'); - } - - get inputSearch(): Locator { - return this.page.locator('role=textbox[name="Search"]'); - } - - private get contactCenterChatsTable(): Locator { - return this.page.getByRole('table', { name: 'Omnichannel Contact Center Chats' }); - } - - findRowByName(contactName: string) { - return this.contactCenterChatsTable.getByRole('link', { name: contactName }); - } - - get inputStatus(): Locator { - return this.page.locator('[data-qa="current-chats-status"]'); - } - - get inputTags(): Locator { - return this.page.locator('[data-qa="current-chats-tags"] [role="listbox"]'); - } - - get modalConfirmRemoveAllClosed(): Locator { - return this.page.locator('[data-qa-id="current-chats-modal-remove-all-closed"]'); - } - - async addTag(option: string) { - await this.inputTags.click(); - await this.page.locator(`[role='option'][value='${option}']`).click(); - await this.inputTags.click(); - } - - async removeTag(option: string) { - await this.page.locator(`role=option[name='${option}']`).click(); - } - - async selectStatus(option: string) { - await this.inputStatus.click(); - await this.page.locator(`[role='option'][data-key='${option}']`).click(); - } - - btnRemoveByName(name: string): Locator { - return this.findRowByName(name).getByRole('button', { name: 'Remove' }); - } - - async removeChatByName(name: string) { - await this.btnRemoveByName(name).click(); - await this.confirmRemoveChatModal.confirm(); - } - - async openChat(name: string) { - await this.findRowByName(name).click(); - await this.conversation.openChat(); - await this.page.locator('#main-content').waitFor(); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts deleted file mode 100644 index 5a288ccf3e639..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-contacts-list.ts +++ /dev/null @@ -1,159 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelContactInfo } from './omnichannel-info'; -import { OmnichannelManageContact } from './omnichannel-manage-contact'; - -export class OmnichannelContacts { - private readonly page: Page; - - readonly newContact: OmnichannelManageContact; - - readonly contactInfo: OmnichannelContactInfo; - - constructor(page: Page) { - this.page = page; - this.newContact = new OmnichannelManageContact(page); - this.contactInfo = new OmnichannelContactInfo(page); - } - - get btnNewContact(): Locator { - return this.page.locator('button >> text="New contact"'); - } - - get inputSearch(): Locator { - return this.page.locator('input[placeholder="Search"]'); - } - - findRowByName(contactName: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${contactName}"`) }); - } - - findRowMenu(contactName: string): Locator { - return this.findRowByName(contactName).getByRole('button', { name: 'More Actions' }); - } - - findMenuItem(name: string): Locator { - return this.page.getByRole('menuitem', { name }); - } - - get deleteContactModal(): Locator { - return this.page.getByRole('dialog', { name: 'Delete Contact' }); - } - - get inputDeleteContactConfirmation(): Locator { - return this.deleteContactModal.getByRole('textbox', { name: 'Confirm contact removal' }); - } - - get btnDeleteContact(): Locator { - return this.deleteContactModal.getByRole('button', { name: 'Delete' }); - } - - get btnFilters(): Locator { - return this.page.getByRole('button', { name: 'Filters' }); - } - - get inputServedBy(): Locator { - return this.filtersContextualBar.getByLabel('Served By').locator('input'); - } - - get inputDepartment(): Locator { - return this.filtersContextualBar.getByLabel('Department').locator('input'); - } - - get btnApply(): Locator { - return this.page.getByRole('button', { name: 'Apply' }); - } - - get tabChats(): Locator { - return this.page.getByRole('tab', { name: 'Chats' }); - } - - get selectStatusContainer(): Locator { - return this.filtersContextualBar.getByRole('button', { name: 'Status' }); - } - - get inputTags(): Locator { - return this.filtersContextualBar.getByLabel('Tags').locator('input'); - } - - get inputUnits(): Locator { - return this.filtersContextualBar.getByLabel('Units').locator('input'); - } - - get btnClearFilters(): Locator { - return this.page.getByRole('button', { name: 'Clear filters' }); - } - - get filtersContextualBar(): Locator { - return this.page.getByRole('dialog', { name: 'Filters' }); - } - - get btnClose(): Locator { - return this.filtersContextualBar.getByRole('button', { name: 'Close' }); - } - - btnStatusChip(name: string): Locator { - return this.page.getByRole('button', { name: `Status: ${name}` }); - } - - btnServedByChip(name: string): Locator { - return this.page.getByRole('button', { name: `Served by: ${name}` }); - } - - btnDepartmentChip(name: string): Locator { - return this.page.getByRole('button', { name: `Department: ${name}` }); - } - - btnSearchChip(name: string): Locator { - return this.page.getByRole('button', { name: `Text: ${name}` }); - } - - btnUnitsChip(name: string): Locator { - return this.page.getByRole('button', { name: `Units: ${name}` }); - } - - async selectServedBy(option: string) { - await this.inputServedBy.click(); - await this.inputServedBy.fill(option); - await this.page.locator(`[role='option'][value='${option}']`).click(); - await this.btnApply.click(); - } - - async selectStatus(option: string) { - await this.selectStatusContainer.click(); - await this.page.locator(`[role='option'][data-key='${option}']`).click(); - await this.btnApply.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.inputDepartment.click(); - await this.btnApply.click(); - } - - async selectTag(option: string) { - await this.inputTags.click(); - await this.inputTags.fill(option); - await this.page.locator(`[role='option'][value='${option}']`).click(); - await this.inputTags.click(); - await this.btnApply.click(); - } - - async removeTag(option: string) { - await this.page.locator(`role=option[name='${option}']`).click(); - await this.btnApply.click(); - } - - findOption(optionText: string) { - return this.page.locator(`role=option[name="${optionText}"]`); - } - - async selectUnit(unitName: string) { - await this.inputUnits.click(); - await this.inputUnits.fill(unitName); - await this.findOption(unitName).click(); - await this.btnApply.click(); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-custom-fields.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-custom-fields.ts deleted file mode 100644 index e3fd6e382b9fa..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-custom-fields.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav } from './fragments'; - -export class OmnichannelCustomFields { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - } - - get btnAdd(): Locator { - return this.page.locator('[data-qa-id="CustomFieldPageBtnNew"]'); - } - - get inputField(): Locator { - return this.page.locator('input[name="field"]'); - } - - get inputLabel(): Locator { - return this.page.locator('input[name="label"]'); - } - - get visibleLabel(): Locator { - return this.page.locator('label >> text="Visible"'); - } - - get btnSave(): Locator { - return this.page.locator('button >> text=Save'); - } - - get inputSearch(): Locator { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - firstRowInTable(filedName: string) { - return this.page.locator(`[qa-user-id="${filedName}"]`); - } - - get btnDeleteCustomField() { - return this.page.locator('button >> text=Delete'); - } - - get btnModalRemove(): Locator { - return this.page.locator('#modal-root dialog .rcx-modal__inner .rcx-modal__footer .rcx-button--danger'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-departments.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-departments.ts deleted file mode 100644 index e5965b67a3a5a..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-departments.ts +++ /dev/null @@ -1,164 +0,0 @@ -import type { Page, Locator } from '@playwright/test'; - -import { OmnichannelSidenav, ToastMessages } from './fragments'; - -export class OmnichannelDepartments { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - // TODO: This will be inherited from a BasePage Object - readonly toastMessage: ToastMessages; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - this.toastMessage = new ToastMessages(page); - } - - get inputSearch() { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - async search(text: string) { - await this.inputSearch.fill(text); - await this.page.waitForTimeout(500); - } - - headingButtonNew(name: string) { - return this.page.locator(`role=main >> role=button[name="${name}"]`).first(); - } - - get btnEnabled() { - return this.page.locator('label >> text="Enabled"'); - } - - get inputName() { - return this.page.locator('[data-qa="DepartmentEditTextInput-Name"]'); - } - - get inputEmail() { - return this.page.locator('[data-qa="DepartmentEditTextInput-Email"]'); - } - - get toggleRequestTags() { - return this.page.locator('label >> text="Request tag(s) before closing conversation"'); - } - - get inputTags() { - return this.page.locator('[data-qa="DepartmentEditTextInput-ConversationClosingTags"]'); - } - - get invalidInputName() { - return this.page.locator('[data-qa="DepartmentEditTextInput-Name"]:invalid'); - } - - get invalidInputEmail() { - return this.page.locator('[data-qa="DepartmentEditTextInput-Email"]:invalid'); - } - - get btnTagsAdd() { - return this.page.locator('[data-qa="DepartmentEditAddButton-ConversationClosingTags"]'); - } - - get btnSave() { - return this.page.locator('role=button[name="Save"]'); - } - - get btnBack() { - return this.page.locator('role=button[name="Back"]'); - } - - get archivedDepartmentsTab() { - return this.page.locator('[role="tab"]:nth-child(2)'); - } - - get firstRowInTable() { - return this.page.locator('table tr:first-child td:first-child'); - } - - get firstRowInTableMenu() { - return this.page.locator('table tr:first-child [data-testid="menu"]'); - } - - findDepartment(name: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${name}"`) }); - } - - selectedDepartmentMenu(name: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${name}"`) }).locator('[data-testid="menu"]'); - } - - get menuEditOption() { - return this.page.locator('[role=option][value="edit"]'); - } - - get menuDeleteOption() { - return this.page.locator('[role=option][value="delete"]'); - } - - get menuArchiveOption() { - return this.page.locator('[role=option][value="archive"]'); - } - - get menuUnarchiveOption() { - return this.page.locator('[role=option][value="unarchive"]'); - } - - get inputModalConfirmDelete() { - return this.modalConfirmDelete.locator('input[name="confirmDepartmentName"]'); - } - - get modalConfirmDelete() { - return this.page.locator('[data-qa-id="delete-department-modal"]'); - } - - get btnModalConfirmDelete() { - return this.modalConfirmDelete.locator('role=button[name="Delete"]'); - } - - get upgradeDepartmentsModal() { - return this.page.locator('[data-qa-id="enterprise-departments-modal"]'); - } - - get btnUpgradeDepartmentsModalClose() { - return this.page.locator('[data-qa="modal-close"]'); - } - - get inputUnit(): Locator { - return this.page.getByLabel('Unit').getByRole('textbox', { name: 'Select an option' }); - } - - btnTag(tagName: string) { - return this.page.locator('button', { hasText: tagName }); - } - - errorMessage(message: string): Locator { - return this.page.locator(`.rcx-field__error >> text="${message}"`); - } - - findOption(optionText: string) { - return this.page.locator(`role=option[name="${optionText}"]`); - } - - async selectUnit(unitName: string) { - await this.inputUnit.click(); - await this.findOption(unitName).click(); - } - - get fieldGroupAgents() { - return this.page.getByLabel('Agents', { exact: true }); - } - - get inputAgents() { - return this.fieldGroupAgents.getByRole('textbox'); - } - - get btnAddAgent() { - return this.fieldGroupAgents.getByRole('button', { name: 'Add', exact: true }); - } - - findAgentRow(name: string) { - return this.page.locator('tr', { has: this.page.getByText(name, { exact: true }) }); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-info.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-info.ts deleted file mode 100644 index c6b5dc3e25e81..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-info.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelContactReviewModal } from './fragments'; -import { OmnichannelManageContact } from './omnichannel-manage-contact'; - -export class OmnichannelContactInfo extends OmnichannelManageContact { - readonly contactReviewModal: OmnichannelContactReviewModal; - - constructor(page: Page) { - super(page); - this.contactReviewModal = new OmnichannelContactReviewModal(page); - } - - get dialogContactInfo(): Locator { - return this.page.getByRole('dialog', { name: 'Contact' }); - } - - get btnEdit(): Locator { - return this.page.locator('role=button[name="Edit"]'); - } - - get tabHistory(): Locator { - return this.dialogContactInfo.getByRole('tab', { name: 'History' }); - } - - get historyItem(): Locator { - return this.dialogContactInfo.getByRole('listitem').first(); - } - - get historyMessage(): Locator { - return this.dialogContactInfo.getByRole('listitem').first(); - } - - get btnOpenChat(): Locator { - return this.dialogContactInfo.getByRole('button', { name: 'Open chat' }); - } - - get btnSeeConflicts(): Locator { - return this.dialogContactInfo.getByRole('button', { name: 'See conflicts' }); - } - - async solveConflict(field: string, value: string) { - await this.btnSeeConflicts.click(); - await this.contactReviewModal.solveConfirmation(field, value); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-manage-contact.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-manage-contact.ts deleted file mode 100644 index 6d87af0d52b82..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-manage-contact.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -export class OmnichannelManageContact { - protected readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - get inputName(): Locator { - return this.page.locator('input[name=name]'); - } - - get inputEmail(): Locator { - return this.page.locator('input[name="emails.0.address"]'); - } - - get inputPhone(): Locator { - return this.page.locator('input[name="phones.0.phoneNumber"]'); - } - - get inputContactManager(): Locator { - return this.page.locator('input[name=contactManager]'); - } - - get btnSave(): Locator { - return this.page.locator('button >> text="Save"'); - } - - get btnCancel(): Locator { - return this.page.locator('button >> text="Cancel"'); - } - - get btnAddEmail(): Locator { - return this.page.locator('role=button[name="Add email"]'); - } - - get btnAddPhone(): Locator { - return this.page.locator('role=button[name="Add phone"]'); - } - - getErrorMessage(message: string): Locator { - return this.page.locator(`role=alert >> text="${message}"`); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-manager.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-manager.ts deleted file mode 100644 index f52aa66fda629..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-manager.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav } from './fragments'; - -export class OmnichannelManager { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - } - - private get inputSearch() { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - async search(text: string) { - await this.inputSearch.fill(text); - await this.page.waitForTimeout(500); - } - - async clearSearch() { - await this.inputSearch.fill(''); - await this.page.waitForTimeout(500); - } - - get inputUsername(): Locator { - return this.page.getByRole('main').getByLabel('Username'); - } - - async selectUsername(username: string) { - await this.inputUsername.fill(username); - await this.page.locator(`role=option[name="${username}"]`).click(); - } - - get btnAdd(): Locator { - return this.page.locator('button.rcx-button--primary.rcx-button >> text="Add manager"'); - } - - findRowByName(name: string) { - return this.page.locator('role=table[name="Managers"] >> role=row', { has: this.page.locator(`role=cell[name="${name}"]`) }); - } - - btnDeleteSelectedAgent(text: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${text}"`) }).locator('button[title="Remove"]'); - } - - get btnModalRemove(): Locator { - return this.page.locator('#modal-root dialog .rcx-modal__inner .rcx-modal__footer .rcx-button--danger'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-monitors.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-monitors.ts deleted file mode 100644 index e31878842ddb4..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-monitors.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { Locator } from '@playwright/test'; - -import { OmnichannelAdministration } from './omnichannel-administration'; - -export class OmnichannelMonitors extends OmnichannelAdministration { - get modalConfirmRemove(): Locator { - return this.page.locator('[data-qa-id="manage-monitors-confirm-remove"]'); - } - - get btnConfirmRemove(): Locator { - return this.modalConfirmRemove.locator('role=button[name="Delete"]'); - } - - get btnAddMonitor(): Locator { - return this.page.locator('role=button[name="Add monitor"]'); - } - - get inputMonitor(): Locator { - return this.page.locator('input[name="monitor"]'); - } - - get inputSearch(): Locator { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - findRowByName(name: string): Locator { - return this.page.locator(`tr[data-qa-id="${name}"]`); - } - - btnRemoveByName(name: string): Locator { - return this.findRowByName(name).locator('role=button[name="Remove"]'); - } - - async selectMonitor(name: string) { - await this.inputMonitor.fill(name); - await this.page.locator(`li[role="option"]`, { has: this.page.locator(`[data-username='${name}']`) }).click(); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-priorities.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-priorities.ts deleted file mode 100644 index ec75c336adff7..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-priorities.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav, ToastMessages } from './fragments'; - -class OmnichannelManagePriority { - private readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - get inputName(): Locator { - return this.page.locator('[name="name"]'); - } - - get btnSave() { - return this.page.locator('button.rcx-button >> text="Save"'); - } - - get btnReset() { - return this.page.locator('.rcx-vertical-bar').locator('role=button[name="Reset"]'); - } - - errorMessage(message: string): Locator { - return this.page.locator(`.rcx-field__error >> text="${message}"`); - } -} - -export class OmnichannelPriorities { - private readonly page: Page; - - readonly managePriority: OmnichannelManagePriority; - - readonly sidenav: OmnichannelSidenav; - - // TODO: This will be inherited from a BasePage Object - readonly toastMessage: ToastMessages; - - constructor(page: Page) { - this.page = page; - this.managePriority = new OmnichannelManagePriority(page); - this.sidenav = new OmnichannelSidenav(page); - this.toastMessage = new ToastMessages(page); - } - - get btnReset() { - return this.page.locator('role=button[name="Reset"]'); - } - - get btnResetConfirm() { - return this.page.locator('.rcx-modal').locator('role=button[name="Reset"]'); - } - - findPriority(name: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${name}"`) }); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-room-info.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-room-info.ts deleted file mode 100644 index e7f6430fc38e0..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-room-info.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { RoomSidebar } from './fragments'; - -export class OmnichannelRoomInfo { - private readonly page: Page; - - private readonly sidebar: RoomSidebar; - - constructor(page: Page) { - this.page = page; - this.sidebar = new RoomSidebar(page); - } - - get dialogRoomInfo(): Locator { - return this.page.getByRole('dialog', { name: 'Room Information' }); - } - - get btnEditRoomInfo(): Locator { - return this.dialogRoomInfo.getByRole('button', { name: 'Edit' }); - } - - get dialogEditRoom(): Locator { - return this.page.getByRole('dialog', { name: 'Edit Room' }); - } - - get inputTopic(): Locator { - return this.dialogEditRoom.getByRole('textbox', { name: 'Topic' }); - } - - get btnSaveEditRoom(): Locator { - return this.dialogEditRoom.getByRole('button', { name: 'Save' }); - } - - getInfo(value: string): Locator { - return this.page.locator(`span >> text="${value}"`); - } - - getLabel(label: string): Locator { - return this.page.locator(`div >> text="${label}"`); - } - - getInfoByLabel(label: string): Locator { - return this.dialogRoomInfo.getByLabel(label); - } - - get inputSLAPolicy(): Locator { - return this.dialogEditRoom.getByRole('button', { name: 'SLA Policy' }); - } - - async selectSLA(name: string): Promise { - await this.inputSLAPolicy.click(); - return this.page.getByRole('option', { name, exact: true }).click(); - } - - get inputTags(): Locator { - return this.page.getByRole('textbox', { name: 'Select an option' }); - } - - optionTags(name: string): Locator { - return this.page.getByRole('option', { name, exact: true }); - } - - async selectTag(name: string): Promise { - await this.optionTags(name).click(); - } - - getTagInfoByLabel(label: string): Locator { - return this.dialogRoomInfo.getByRole('list', { name: 'Tags' }).getByText(label, { exact: true }); - } - - getBadgeIndicator(name: string, title: string): Locator { - return this.sidebar.getSidebarItemByName(name).getByTitle(title); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-section.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-section.ts deleted file mode 100644 index 10887fef5672b..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-section.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -export class OmnichannelSection { - private readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - get btnContactCenter(): Locator { - return this.page.locator('role=button[name="Contact Center"]'); - } - - get tabContacts(): Locator { - return this.page.locator('role=tab[name="Contacts"]'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-sla-policies.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-sla-policies.ts deleted file mode 100644 index f884a876fb841..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-sla-policies.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav } from './fragments'; - -class OmnichannelManageSlaPolicy { - private readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - get inputName(): Locator { - return this.page.locator('[name="name"]'); - } - - get inputDescription(): Locator { - return this.page.locator('[name="description"]'); - } - - get inputEstimatedWaitTime(): Locator { - return this.page.locator('[name="dueTimeInMinutes"]'); - } - - get btnSave() { - return this.page.locator('button.rcx-button >> text="Save"'); - } - - errorMessage(message: string): Locator { - return this.page.locator(`.rcx-field__error >> text="${message}"`); - } -} - -export class OmnichannelSlaPolicies { - private readonly page: Page; - - readonly manageSlaPolicy: OmnichannelManageSlaPolicy; - - readonly sidenav: OmnichannelSidenav; - - constructor(page: Page) { - this.page = page; - this.manageSlaPolicy = new OmnichannelManageSlaPolicy(page); - this.sidenav = new OmnichannelSidenav(page); - } - - findRowByName(name: string) { - return this.page.locator('tr', { has: this.page.locator(`td >> text="${name}"`) }); - } - - btnRemove(name: string) { - return this.findRowByName(name).locator('button[title="Remove"]'); - } - - get inputSearch() { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - headingButtonNew(name: string) { - return this.page.locator(`role=main >> role=button[name="${name}"]`).first(); - } - - get btnDelete() { - return this.page.locator('button.rcx-button >> text="Delete"'); - } - - get txtDeleteModalTitle() { - return this.page.locator('role=dialog >> text="Are you sure?"'); - } - - get txtEmptyState() { - return this.page.locator('div >> text="No results found"'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts deleted file mode 100644 index 015db21fdd4fc..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { Locator } from '@playwright/test'; - -import { OmnichannelAdministration } from './omnichannel-administration'; - -export class OmnichannelTags extends OmnichannelAdministration { - get btnCreateTag(): Locator { - return this.page.locator('header').locator('role=button[name="Create tag"]'); - } - - get contextualBar(): Locator { - return this.page.locator('div[role="dialog"].rcx-vertical-bar'); - } - - get btnSave(): Locator { - return this.contextualBar.locator('role=button[name="Save"]'); - } - - get btnCancel(): Locator { - return this.contextualBar.locator('role=button[name="Cancel"]'); - } - - get inputName(): Locator { - return this.page.locator('[name="name"]'); - } - - get inputSearch(): Locator { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - get confirmDeleteModal(): Locator { - return this.page.locator('dialog:has(h2:has-text("Are you sure?"))'); - } - - get btnCancelDeleteModal(): Locator { - return this.confirmDeleteModal.locator('role=button[name="Cancel"]'); - } - - get btnConfirmDeleteModal(): Locator { - return this.confirmDeleteModal.locator('role=button[name="Delete"]'); - } - - get btnContextualbarClose(): Locator { - return this.contextualBar.locator('button[aria-label="Close"]'); - } - - btnDeleteByName(name: string): Locator { - return this.page.getByRole('link', { name }).getByRole('button'); - } - - findRowByName(name: string): Locator { - return this.page.getByRole('link', { name }); - } - - get inputDepartments(): Locator { - return this.page.locator('input[placeholder="Select an option"]'); - } - - private selectOption(name: string): Locator { - return this.page.locator('#position-container').getByRole('option', { name }); - } - - async search(text: string) { - await this.inputSearch.fill(text); - } - - async selectDepartment(name: string) { - await this.inputDepartments.click(); - await this.inputDepartments.fill(name); - await this.selectOption(name).click(); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts deleted file mode 100644 index 273343f731d3b..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts +++ /dev/null @@ -1,138 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -import { OmnichannelSidenav, ToastMessages } from './fragments'; - -export class OmnichannelTriggers { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - // TODO: This will be inherited from a BasePage Object - readonly toastMessage: ToastMessages; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - this.toastMessage = new ToastMessages(page); - } - - headingButtonNew(name: string) { - return this.page.locator(`role=main >> role=button[name="${name}"]`).first(); - } - - get inputName(): Locator { - return this.page.locator('input[name="name"]'); - } - - get inputDescription(): Locator { - return this.page.locator('input[name="description"]'); - } - - get btnSave(): Locator { - return this.page.locator('button >> text="Save"'); - } - - firstRowInTriggerTable(triggersName1: string) { - return this.page.locator(`text="${triggersName1}"`); - } - - get btnDeletefirstRowInTable() { - return this.page.locator('table tr:first-child td:last-child button'); - } - - get btnModalRemove(): Locator { - return this.page.locator('#modal-root dialog .rcx-modal__inner .rcx-modal__footer .rcx-button--danger'); - } - - get removeToastMessage(): Locator { - return this.page.locator('text=Trigger removed'); - } - - get conditionLabel(): Locator { - return this.page.locator('label >> text="Condition"'); - } - - get inputConditionValue(): Locator { - return this.page.locator('input[name="conditions.0.value"]'); - } - - get senderLabel(): Locator { - return this.page.locator('label >> text="Sender"'); - } - - get inputAgentName(): Locator { - return this.page.locator('input[name="actions.0.params.name"]'); - } - - get inputTriggerMessage(): Locator { - return this.page.locator('textarea[name="actions.0.params.msg"]'); - } - - async selectCondition(condition: string) { - await this.conditionLabel.click(); - await this.page.locator(`li.rcx-option[data-key="${condition}"]`).click(); - } - - async selectSender(sender: 'queue' | 'custom') { - await this.senderLabel.click(); - await this.page.locator(`li.rcx-option[data-key="${sender}"]`).click(); - } - - public async createTrigger( - triggersName: string, - triggerMessage: string, - condition: 'time-on-site' | 'chat-opened-by-visitor' | 'after-guest-registration', - conditionValue?: number | string, - ) { - await this.headingButtonNew('Create trigger').click(); - await this.fillTriggerForm({ - name: triggersName, - description: 'Creating a fresh trigger', - condition, - conditionValue, - triggerMessage, - }); - await this.btnSave.click(); - } - - public async updateTrigger(newName: string, triggerMessage: string) { - await this.fillTriggerForm({ - name: `edited-${newName}`, - description: 'Updating the existing trigger', - condition: 'chat-opened-by-visitor', - sender: 'custom', - agentName: 'Rocket.cat', - triggerMessage, - }); - await this.btnSave.click(); - } - - public async fillTriggerForm( - data: Partial<{ - name: string; - description: string; - condition: 'time-on-site' | 'chat-opened-by-visitor' | 'after-guest-registration'; - conditionValue?: string | number; - sender: 'queue' | 'custom'; - agentName?: string; - triggerMessage: string; - }>, - ) { - data.name && (await this.inputName.fill(data.name)); - data.description && (await this.inputDescription.fill(data.description)); - data.condition && (await this.selectCondition(data.condition)); - - if (data.conditionValue) { - await this.inputConditionValue.fill(data.conditionValue.toString()); - } - - data.sender && (await this.selectSender(data.sender)); - if (data.sender === 'custom' && !data.agentName) { - throw new Error('A custom agent is required for this action'); - } else { - data.agentName && (await this.inputAgentName.fill(data.agentName)); - } - - data.triggerMessage && (await this.inputTriggerMessage.fill(data.triggerMessage)); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-units.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-units.ts deleted file mode 100644 index ba0a2b863d61d..0000000000000 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-units.ts +++ /dev/null @@ -1,99 +0,0 @@ -import type { Locator } from '@playwright/test'; - -import { OmnichannelAdministration } from './omnichannel-administration'; - -export class OmnichannelUnits extends OmnichannelAdministration { - get inputSearch() { - return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); - } - - async search(text: string) { - await this.inputSearch.fill(text); - } - - findRowByName(name: string) { - return this.page.locator(`tr[data-qa-id="${name}"]`); - } - - get inputName() { - return this.page.locator('[name="name"]'); - } - - get fieldDepartments() { - return this.page.getByLabel('Departments'); - } - - get inputDepartments() { - return this.fieldDepartments.getByRole('textbox'); - } - - get inputMonitors() { - return this.page.locator('[name="monitors"]'); - } - - get inputVisibility(): Locator { - return this.page.locator('button', { has: this.page.locator('select[name="visibility"]') }); - } - - get btnContextualbarClose(): Locator { - return this.page.locator('[data-qa="ContextualbarActionClose"]'); - } - - private findOption(name: string) { - return this.page.locator('#position-container').getByRole('option', { name, exact: true }); - } - - public findDepartmentsChipOption(name: string) { - return this.fieldDepartments.getByRole('option', { name, exact: true }); - } - - async selectDepartment(name: string) { - await this.inputDepartments.click(); - await this.inputDepartments.fill(name); - await this.findOption(name).click(); - await this.inputDepartments.click(); - } - - async selectMonitor(option: string) { - await this.inputMonitors.click(); - await this.findOption(option).click(); - await this.inputMonitors.click(); - } - - async selectVisibility(option: string) { - await this.inputVisibility.click(); - await this.page.locator(`li.rcx-option[data-key="${option}"]`).click(); - } - - get btnCreateUnit() { - return this.page.locator('header').locator('role=button[name="Create unit"]'); - } - - get contextualBar() { - return this.page.locator('div[role="dialog"][aria-labelledby="contextualbarTitle"]'); - } - - get btnSave() { - return this.contextualBar.locator('role=button[name="Save"]'); - } - - get btnCancel() { - return this.contextualBar.locator('role=button[name="Cancel"]'); - } - - get btnDelete() { - return this.contextualBar.locator('role=button[name="Delete"]'); - } - - btnDeleteByName(name: string) { - return this.page.locator(`button[data-qa-id="remove-unit-${name}"]`); - } - - get confirmDeleteModal() { - return this.page.locator('dialog[data-qa-id="units-confirm-delete-modal"]'); - } - - get btnConfirmDeleteModal() { - return this.confirmDeleteModal.locator('role=button[name="Delete"]'); - } -} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/index.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/index.ts new file mode 100644 index 0000000000000..3816f1d1dec34 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/index.ts @@ -0,0 +1,19 @@ +export * from './omnichannel-agents'; +export * from './omnichannel-departments'; +export * from './omnichannel-canned-responses'; +export * from './omnichannel-contact-center'; +export * from './omnichannel-livechat'; +export * from './omnichannel-livechat-appearance'; +export * from './omnichannel-livechat-embedded'; +export * from './omnichannel-manager'; +export * from './omnichannel-custom-fields'; +export * from './omnichannel-units'; +export * from './omnichannel-monitors'; +export * from './omnichannel-settings'; +export * from './omnichannel-business-hours'; +export * from './omnichannel-tags'; +export * from './omnichannel-transcript'; +export * from './omnichannel-triggers'; +export * from './omnichannel-priorities'; +export * from './omnichannel-reports'; +export * from './omnichannel-sla-policies'; diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-admin.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-admin.ts new file mode 100644 index 0000000000000..125b71d744736 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-admin.ts @@ -0,0 +1,46 @@ +import type { Locator, Page } from '@playwright/test'; + +import { expect } from '../../utils/test'; +import { OmnichannelSidebar, ToastMessages } from '../fragments'; +import { ConfirmDeleteModal } from '../fragments/modals'; + +export abstract class OmnichannelAdmin { + protected readonly page: Page; + + protected readonly toastMessage: ToastMessages; + + readonly sidebar: OmnichannelSidebar; + + readonly deleteModal: ConfirmDeleteModal; + + constructor(page: Page) { + this.page = page; + this.sidebar = new OmnichannelSidebar(page); + this.toastMessage = new ToastMessages(page); + this.deleteModal = new ConfirmDeleteModal(page.getByRole('dialog', { name: 'Are you sure?' })); + } + + get inputSearch() { + return this.page.getByRole('main').getByRole('textbox', { name: 'Search' }); + } + + get btnSaveChanges(): Locator { + return this.page.getByRole('button', { name: 'Save changes' }); + } + + getButtonByType(type: 'unit' | 'SLA policy' | 'tag' | 'trigger' | 'department' | 'custom field'): Locator { + return this.page.locator('header').getByRole('button', { name: `Create ${type}` }); + } + + async search(text: string) { + await this.inputSearch.fill(text); + } + + async clearSearch() { + await this.inputSearch.fill(''); + } + + waitForEmptyState() { + return expect(this.page.locator('h3 >> text="No results found"')).toBeVisible(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-agents.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-agents.ts new file mode 100644 index 0000000000000..b40141802759c --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-agents.ts @@ -0,0 +1,117 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +class OmnichannelEditAgentFlexTab extends FlexTab { + readonly listbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Edit User' })); + this.listbox = new Listbox(page); + } + + get inputMaxChats(): Locator { + return this.root.locator('input[name="maxNumberSimultaneousChat"]'); + } + + get inputDepartment(): Locator { + return this.root.getByLabel('Departments').getByRole('textbox'); + } + + getDepartmentOption(name: string) { + return this.listbox.getOption(name); + } + + async selectDepartment(name: string) { + await this.inputDepartment.click(); + await this.inputDepartment.fill(name); + await this.listbox.selectOption(name); + // TODO: This is necessary due to the PaginatedMultiSelectFiltered not closing the list when an option is selected nor when close is clicked. + // The line below can be removed once the component is adjusted in Fuselage + await this.root.click(); + } + + findSelectedDepartment(name: string) { + return this.root.getByLabel('Departments', { exact: true }).getByRole('option', { name }); + } + + private get inputStatus(): Locator { + return this.root.getByText('Status', { exact: true }); + } + + async selectStatus(status: string) { + await this.inputStatus.click(); + await this.listbox.selectOption(status); + } +} + +class OmnichannelAgentInfoFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'User Info' })); + } + + get btnEdit(): Locator { + return this.root.getByRole('button', { name: 'Edit', exact: true }); + } + + get btnRemove(): Locator { + return this.root.getByRole('button', { name: 'Remove', exact: true }); + } +} + +class OmnichannelAgentsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Agents' })); + } +} + +export class OmnichannelAgents extends OmnichannelAdmin { + readonly editAgent: OmnichannelEditAgentFlexTab; + + readonly agentInfo: OmnichannelAgentInfoFlexTab; + + readonly table: OmnichannelAgentsTable; + + readonly listbox: Listbox; + + constructor(page: Page) { + super(page); + this.editAgent = new OmnichannelEditAgentFlexTab(page); + this.agentInfo = new OmnichannelAgentInfoFlexTab(page); + this.table = new OmnichannelAgentsTable(page); + this.listbox = new Listbox(page); + } + + get inputUsername(): Locator { + return this.page.getByRole('textbox', { name: 'Username' }); + } + + get btnAddAgent(): Locator { + return this.page.getByRole('button', { name: 'Add agent', exact: true }); + } + + async deleteAgent(name: string) { + await this.search(name); + await this.table.findRowByName(name).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } + + get scrollContainer(): Locator { + return this.page.locator('#position-container').getByTestId('virtuoso-scroller'); + } + + scrollToListBottom() { + return this.scrollContainer.evaluate((el) => { + el.scrollTop = el.scrollHeight; + el.dispatchEvent(new Event('scroll')); + }); + } + + async selectUsername(username: string) { + await this.inputUsername.fill(username); + await this.listbox.selectOption(username); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-business-hours.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-business-hours.ts new file mode 100644 index 0000000000000..4cb327e3f661f --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-business-hours.ts @@ -0,0 +1,66 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +class OmnichannelBusinessHoursTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Business Hours' })); + } +} + +export class OmnichannelBusinessHours extends OmnichannelAdmin { + readonly table: OmnichannelBusinessHoursTable; + + readonly listbox: Listbox; + + constructor(page: Page) { + super(page); + this.table = new OmnichannelBusinessHoursTable(page); + this.listbox = new Listbox(page); + } + + get btnCreateBusinessHour(): Locator { + return this.page.locator('header').getByRole('button', { name: 'New', exact: true }); + } + + get btnSave(): Locator { + return this.page.getByRole('button', { name: 'Save', exact: true }); + } + + get btnBack(): Locator { + return this.page.locator('header').getByRole('button', { name: 'Back', exact: true }); + } + + get inputName(): Locator { + return this.page.getByRole('textbox', { name: 'Name', exact: true }); + } + + get fieldDepartment(): Locator { + return this.page.getByLabel('Departments', { exact: true }); + } + + get inputDepartments(): Locator { + return this.fieldDepartment.getByRole('textbox'); + } + + async deleteBusinessHour(name: string) { + await this.table.findRowByName(name).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } + + getCheckboxByLabel(name: string): Locator { + return this.page.locator('label', { has: this.page.getByRole('checkbox', { name }) }); + } + + findDepartmentsChipOption(name: string) { + return this.fieldDepartment.getByRole('option', { name, exact: true }); + } + + async selectDepartment(name: string) { + await this.inputDepartments.click(); + await this.inputDepartments.fill(name); + await this.listbox.selectOption(name); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-canned-responses.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-canned-responses.ts similarity index 93% rename from apps/meteor/tests/e2e/page-objects/omnichannel-canned-responses.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-canned-responses.ts index 4de383668ea7a..84e73566e2ef8 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-canned-responses.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-canned-responses.ts @@ -1,8 +1,8 @@ import type { Locator } from '@playwright/test'; -import { OmnichannelAdministration } from './omnichannel-administration'; +import { OmnichannelAdmin } from './omnichannel-admin'; -export class OmnichannelCannedResponses extends OmnichannelAdministration { +export class OmnichannelCannedResponses extends OmnichannelAdmin { get inputShortcut() { return this.page.getByRole('textbox', { name: 'Shortcut', exact: true }); } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/index.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/index.ts new file mode 100644 index 0000000000000..03b370997f6aa --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/index.ts @@ -0,0 +1,2 @@ +export * from './omnichannel-contact-center-chats'; +export * from './omnichannel-contact-center-contacts'; diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-chats.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-chats.ts new file mode 100644 index 0000000000000..6c2a7ca0793eb --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-chats.ts @@ -0,0 +1,179 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelContactCenter } from './omnichannel-contact-center'; +import { FlexTab } from '../../fragments/flextab'; +import { Listbox } from '../../fragments/listbox'; +import { OmnichannelConfirmRemoveChat } from '../../fragments/modals'; +import { Table } from '../../fragments/table'; + +class OmnichannelConversationFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Conversation' })); + } + + private get btnOpenChat(): Locator { + return this.root.getByRole('button', { name: 'Open chat' }); + } + + async openChat() { + await this.btnOpenChat.click(); + await this.waitForDismissal(); + } +} + +export class OmnichannelChatsFilters extends FlexTab { + readonly listbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Filters' })); + this.listbox = new Listbox(page); + } + + get inputFrom(): Locator { + return this.root.locator('input[name="from"]'); + } + + get inputTo(): Locator { + return this.root.locator('input[name="to"]'); + } + + get btnApply(): Locator { + return this.root.getByRole('button', { name: 'Apply' }); + } + + get inputServedBy(): Locator { + return this.root.getByLabel('Served By').locator('input'); + } + + get inputDepartment(): Locator { + return this.root.getByLabel('Department').locator('input'); + } + + get selectStatusContainer(): Locator { + return this.root.getByRole('button', { name: 'Status' }); + } + + get inputTags(): Locator { + return this.root.getByLabel('Tags').locator('input'); + } + + get inputUnits(): Locator { + return this.root.getByLabel('Units').locator('input'); + } + + get btnClearFilters(): Locator { + return this.root.getByRole('button', { name: 'Clear filters' }); + } + + async selectServedBy(option: string) { + await this.inputServedBy.click(); + await this.inputServedBy.fill(option); + await this.listbox.selectOption(option); + await this.btnApply.click(); + } + + async selectStatus(option: string) { + await this.selectStatusContainer.click(); + await this.listbox.selectOption(option); + await this.btnApply.click(); + } + + async selectDepartment(option: string) { + await this.inputDepartment.click(); + await this.inputDepartment.fill(option); + await this.listbox.selectOption(option); + await this.inputDepartment.click(); + await this.btnApply.click(); + } + + async selectTag(option: string) { + await this.inputTags.click(); + await this.inputTags.fill(option); + await this.listbox.selectOption(option); + await this.inputTags.click(); + await this.btnApply.click(); + } + + async removeTag(option: string) { + await this.inputTags.click(); + await this.listbox.selectOption(option); + await this.inputTags.click(); + await this.btnApply.click(); + } + + async selectUnit(unitName: string) { + await this.inputUnits.click(); + await this.inputUnits.fill(unitName); + await this.listbox.selectOption(unitName); + await this.btnApply.click(); + } + + async addTag(option: string) { + await this.inputTags.click(); + await this.listbox.selectOption(option); + await this.inputTags.click(); + } +} + +class OmnichannelContactCenterChatsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Omnichannel Contact Center Chats' })); + } + + btnRemoveByName(name: string): Locator { + return this.findRowByName(name).getByRole('button', { name: 'Remove' }); + } +} + +export class OmnichannelContactCenterChats extends OmnichannelContactCenter { + readonly filters: OmnichannelChatsFilters; + + readonly confirmRemoveChatModal: OmnichannelConfirmRemoveChat; + + readonly conversation: OmnichannelConversationFlexTab; + + readonly table: OmnichannelContactCenterChatsTable; + + constructor(page: Page) { + super(page); + this.filters = new OmnichannelChatsFilters(page); + this.confirmRemoveChatModal = new OmnichannelConfirmRemoveChat(page); + this.conversation = new OmnichannelConversationFlexTab(page); + this.table = new OmnichannelContactCenterChatsTable(page); + } + + async removeChatByName(name: string) { + await this.table.btnRemoveByName(name).click(); + await this.confirmRemoveChatModal.confirm(); + } + + async openChat(name: string) { + await this.table.findRowByName(name).click(); + await this.conversation.openChat(); + await this.page.locator('#main-content').waitFor(); + } + + get btnFilters(): Locator { + return this.page.getByRole('button', { name: 'Filters' }); + } + + btnStatusChip(name: string): Locator { + return this.page.getByRole('button', { name: `Status: ${name}` }); + } + + btnServedByChip(name: string): Locator { + return this.page.getByRole('button', { name: `Served by: ${name}` }); + } + + btnDepartmentChip(name: string): Locator { + return this.page.getByRole('button', { name: `Department: ${name}` }); + } + + btnSearchChip(name: string): Locator { + return this.page.getByRole('button', { name: `Text: ${name}` }); + } + + btnUnitsChip(name: string): Locator { + return this.page.getByRole('button', { name: `Units: ${name}` }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-contacts.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-contacts.ts new file mode 100644 index 0000000000000..00989c8510325 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center-contacts.ts @@ -0,0 +1,45 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelContactInfo } from '../omnichannel-info'; +import { OmnichannelContactCenter } from './omnichannel-contact-center'; +import { MenuMoreActions } from '../../fragments'; +import { OmnichannelEditContactFlexTab } from '../../fragments/edit-contact-flaxtab'; +import { OmnichannelDeleteContactModal } from '../../fragments/modals'; +import { Table } from '../../fragments/table'; + +class OmnichannelContactCenterContactsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Omnichannel Contact Center Contacts' })); + } +} + +export class OmnichannelContactCenterContacts extends OmnichannelContactCenter { + readonly contactInfo: OmnichannelContactInfo; + + readonly editContact: OmnichannelEditContactFlexTab; + + readonly table: OmnichannelContactCenterContactsTable; + + readonly deleteContactModal: OmnichannelDeleteContactModal; + + readonly menu: MenuMoreActions; + + constructor(page: Page) { + super(page); + this.contactInfo = new OmnichannelContactInfo(page); + this.editContact = new OmnichannelEditContactFlexTab(page); + this.table = new OmnichannelContactCenterContactsTable(page); + this.deleteContactModal = new OmnichannelDeleteContactModal(page); + this.menu = new MenuMoreActions(page); + } + + get btnNewContact(): Locator { + return this.page.getByRole('button', { name: 'New contact' }); + } + + async deleteContact(contactName: string) { + await this.table.findRowByName(contactName).getByRole('button', { name: 'More Actions' }).click(); + await this.menu.selectMenuItem('Delete'); + await this.deleteContactModal.waitForDisplay(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center.ts new file mode 100644 index 0000000000000..22eec38981e82 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-contact-center/omnichannel-contact-center.ts @@ -0,0 +1,13 @@ +import type { Locator } from '@playwright/test'; + +import { OmnichannelAdmin } from '../omnichannel-admin'; + +export abstract class OmnichannelContactCenter extends OmnichannelAdmin { + get tabContacts(): Locator { + return this.page.getByRole('tab', { name: 'Contacts' }); + } + + get tabChats(): Locator { + return this.page.getByRole('tab', { name: 'Chats' }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-custom-fields.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-custom-fields.ts new file mode 100644 index 0000000000000..ca9fcf7ad26d0 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-custom-fields.ts @@ -0,0 +1,50 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Table } from '../fragments/table'; + +class OmnichannelManageCustomFieldsFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Custom Field' })); + } + + get inputField(): Locator { + return this.root.getByRole('textbox', { name: 'Field', exact: true }); + } + + get inputLabel(): Locator { + return this.root.getByRole('textbox', { name: 'Label', exact: true }); + } + + get labelVisible(): Locator { + return this.root.getByText('Visible'); + } +} + +class OmnichannelCustomFieldsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Custom Fields' })); + } +} + +export class OmnichannelCustomFields extends OmnichannelAdmin { + readonly manageCustomFields: OmnichannelManageCustomFieldsFlexTab; + + readonly table: OmnichannelCustomFieldsTable; + + constructor(page: Page) { + super(page); + this.manageCustomFields = new OmnichannelManageCustomFieldsFlexTab(page); + this.table = new OmnichannelCustomFieldsTable(page); + } + + async createNew() { + await this.getButtonByType('custom field').click(); + } + + async deleteCustomField(fieldName: string) { + await this.table.findRowByName(fieldName).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-departments.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-departments.ts new file mode 100644 index 0000000000000..fea573cd2cc6d --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-departments.ts @@ -0,0 +1,134 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { Listbox } from '../fragments/listbox'; +import { OmnichannelUpsellDepartmentsModal, ConfirmDeleteDepartmentModal } from '../fragments/modals'; +import { Table } from '../fragments/table'; + +class OmnichannelDepartmentsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Departments' })); + } +} + +class OmnichannelDepartmentAgentsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Agents' })); + } +} + +export class OmnichannelDepartments extends OmnichannelAdmin { + readonly departmentsTable: OmnichannelDepartmentsTable; + + readonly agentsTable: OmnichannelDepartmentAgentsTable; + + readonly upsellDepartmentsModal: OmnichannelUpsellDepartmentsModal; + + readonly listbox: Listbox; + + override readonly deleteModal: ConfirmDeleteDepartmentModal; + + constructor(page: Page) { + super(page); + this.departmentsTable = new OmnichannelDepartmentsTable(page); + this.agentsTable = new OmnichannelDepartmentAgentsTable(page); + this.upsellDepartmentsModal = new OmnichannelUpsellDepartmentsModal(page); + this.listbox = new Listbox(page); + this.deleteModal = new ConfirmDeleteDepartmentModal(page); + } + + async createNew() { + await this.getButtonByType('department').click(); + } + + get labelEnabled() { + return this.page.locator('label', { hasText: 'Enabled' }); + } + + get inputName() { + return this.page.getByRole('textbox', { name: 'Name', exact: true }); + } + + get inputEmail() { + return this.page.getByRole('textbox', { name: 'Email', exact: true }); + } + + get inputConversationClosingTags() { + return this.page.getByRole('textbox', { name: 'Conversation closing tags', exact: true }); + } + + get btnAddTags() { + return this.page.getByText('Conversation closing tags', { exact: true }).locator('..').getByRole('button', { name: 'Add' }); + } + + get btnSave() { + return this.page.getByRole('button', { name: 'Save' }); + } + + get tabArchivedDepartments() { + return this.page.getByRole('tab', { name: 'Archived' }); + } + + getDepartmentMenuByName(name: string) { + return this.departmentsTable.findRowByName(name).getByRole('button', { name: 'Options' }); + } + + get menuEditOption() { + return this.listbox.getOption('Edit'); + } + + get menuDeleteOption() { + return this.listbox.getOption('Delete'); + } + + get menuArchiveOption() { + return this.listbox.getOption('Archive'); + } + + get menuUnarchiveOption() { + return this.listbox.getOption('Unarchive'); + } + + async archiveDepartmentByName(name: string) { + await this.getDepartmentMenuByName(name).click(); + await this.menuArchiveOption.click(); + await this.toastMessage.waitForDisplay(); + } + + get inputUnit(): Locator { + return this.page.getByLabel('Unit').getByRole('textbox', { name: 'Select an option' }); + } + + btnTag(tagName: string) { + return this.page.locator('button', { hasText: tagName }); + } + + errorMessage(message: string): Locator { + return this.page.locator(`[role="alert"] >> text="${message}"`); + } + + findOption(optionText: string) { + return this.listbox.getOption(optionText); + } + + async selectUnit(unitName: string) { + await this.inputUnit.click(); + await this.listbox.selectOption(unitName); + } + + get inputAgents() { + return this.page.getByRole('group', { name: 'Agents' }).getByRole('textbox'); + } + + get btnAddAgent() { + return this.page.getByRole('group', { name: 'Agents' }).getByRole('button', { name: 'Add', exact: true }); + } + + async createDepartment(departmentName: string, email: string) { + await this.labelEnabled.click(); + await this.inputName.fill(departmentName); + await this.inputEmail.fill(email); + await this.btnSave.click(); + await this.toastMessage.dismissToast(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-info.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-info.ts new file mode 100644 index 0000000000000..d911a81305d00 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-info.ts @@ -0,0 +1,46 @@ +import type { Locator, Page } from '@playwright/test'; + +import { FlexTab } from '../fragments/flextab'; +import { OmnichannelContactReviewModal } from '../fragments/modals'; + +export class OmnichannelContactInfo extends FlexTab { + readonly contactReviewModal: OmnichannelContactReviewModal; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Contact' })); + this.contactReviewModal = new OmnichannelContactReviewModal(page); + } + + get infoContactEmail(): Locator { + return this.root.getByRole('list', { name: 'Email' }).getByRole('listitem').first().locator('p'); + } + + get btnEdit(): Locator { + return this.root.locator('role=button[name="Edit"]'); + } + + get tabHistory(): Locator { + return this.root.getByRole('tab', { name: 'History' }); + } + + get historyItem(): Locator { + return this.root.getByRole('listitem').first(); + } + + get historyMessage(): Locator { + return this.root.getByRole('listitem').first(); + } + + get btnOpenChat(): Locator { + return this.root.getByRole('button', { name: 'Open chat' }); + } + + get btnSeeConflicts(): Locator { + return this.root.getByRole('button', { name: 'See conflicts' }); + } + + async solveConflict(field: string, value: string) { + await this.btnSeeConflicts.click(); + await this.contactReviewModal.solveConfirmation(field, value); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-appearance.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat-appearance.ts similarity index 81% rename from apps/meteor/tests/e2e/page-objects/omnichannel-livechat-appearance.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat-appearance.ts index c42c8363981f0..66ae39c3b72c7 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-appearance.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat-appearance.ts @@ -1,8 +1,8 @@ import type { Locator } from '@playwright/test'; -import { OmnichannelAdministration } from './omnichannel-administration'; +import { OmnichannelAdmin } from './omnichannel-admin'; -export class OmnichannelLivechatAppearance extends OmnichannelAdministration { +export class OmnichannelLivechatAppearance extends OmnichannelAdmin { get inputHideSystemMessages(): Locator { return this.page.locator('[name="Livechat_hide_system_messages"]'); } @@ -26,8 +26,4 @@ export class OmnichannelLivechatAppearance extends OmnichannelAdministration { findHideSystemMessageOption(option: string): Locator { return this.page.locator(`[role="option"][value="${option}"]`); } - - get btnSave(): Locator { - return this.page.locator('role=button[name="Save changes"]'); - } } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat-embedded.ts similarity index 100% rename from apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat-embedded.ts diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat.ts similarity index 99% rename from apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat.ts index 5fcf966bd0f91..12df33a2762b2 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-livechat.ts @@ -2,7 +2,7 @@ import fs from 'fs/promises'; import type { Page, Locator, APIResponse } from '@playwright/test'; -import { expect } from '../utils/test'; +import { expect } from '../../utils/test'; export class OmnichannelLiveChat { readonly page: Page; diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-manager.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-manager.ts new file mode 100644 index 0000000000000..7a68257bdb6bf --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-manager.ts @@ -0,0 +1,41 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +class OmnichannelManagersTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Managers' })); + } +} + +export class OmnichannelManager extends OmnichannelAdmin { + readonly table: OmnichannelManagersTable; + + readonly listbox: Listbox; + + constructor(page: Page) { + super(page); + this.table = new OmnichannelManagersTable(page); + this.listbox = new Listbox(page); + } + + get inputUsername(): Locator { + return this.page.getByRole('main').getByLabel('Username'); + } + + async selectUsername(username: string) { + await this.inputUsername.fill(username); + await this.listbox.selectOption(username); + } + + get btnAddManager(): Locator { + return this.page.getByRole('button', { name: 'Add manager' }); + } + + async removeManager(name: string) { + await this.table.findRowByName(name).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-monitors.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-monitors.ts new file mode 100644 index 0000000000000..4ebbaee051835 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-monitors.ts @@ -0,0 +1,50 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +class OmnichannelMonitorsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Monitors' })); + } +} + +export class OmnichannelMonitors extends OmnichannelAdmin { + readonly table: OmnichannelMonitorsTable; + + readonly listbox: Listbox; + + constructor(page: Page) { + super(page); + this.table = new OmnichannelMonitorsTable(page); + this.listbox = new Listbox(page); + } + + private get btnAddMonitor(): Locator { + return this.page.getByRole('button', { name: 'Add monitor' }); + } + + get inputMonitor(): Locator { + return this.page.locator('input[name="monitor"]'); + } + + private btnRemoveByName(name: string): Locator { + return this.table.findRowByName(name).getByRole('button', { name: 'Remove' }); + } + + private async selectMonitor(name: string) { + await this.inputMonitor.fill(name); + await this.listbox.selectOption(name); + } + + async removeMonitor(name: string) { + await this.btnRemoveByName(name).click(); + await this.deleteModal.confirmDelete(); + } + + async addMonitor(name: string) { + await this.selectMonitor(name); + await this.btnAddMonitor.click(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-priorities.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-priorities.ts new file mode 100644 index 0000000000000..d458c9f4f3970 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-priorities.ts @@ -0,0 +1,51 @@ +import type { Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { ToastMessages } from '../fragments'; +import { FlexTab } from '../fragments/flextab'; +import { OmnichannelResetPrioritiesModal } from '../fragments/modals'; +import { Table } from '../fragments/table'; + +class OmnichannelEditPriorityFlexTab extends FlexTab { + readonly toastMessage: ToastMessages; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'Priority' })); + this.toastMessage = new ToastMessages(page); + } +} + +class OmnichannelPrioritiesTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Priorities' })); + } +} + +export class OmnichannelPriorities extends OmnichannelAdmin { + readonly editPriority: OmnichannelEditPriorityFlexTab; + + readonly resetPrioritiesModal: OmnichannelResetPrioritiesModal; + + readonly table: OmnichannelPrioritiesTable; + + constructor(page: Page) { + super(page); + this.resetPrioritiesModal = new OmnichannelResetPrioritiesModal(page); + this.editPriority = new OmnichannelEditPriorityFlexTab(page); + this.table = new OmnichannelPrioritiesTable(page); + } + + get btnReset() { + return this.page.getByRole('button', { name: 'Reset' }); + } + + async resetPriorities() { + await this.btnReset.click(); + await this.resetPrioritiesModal.reset(); + await this.toastMessage.dismissToast(); + } + + findPriority(name: string) { + return this.table.findRowByName(name); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-reports.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-reports.ts similarity index 100% rename from apps/meteor/tests/e2e/page-objects/omnichannel-reports.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-reports.ts diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-settings.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-settings.ts similarity index 77% rename from apps/meteor/tests/e2e/page-objects/omnichannel-settings.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-settings.ts index 952959fda2cac..b658a9f7604b0 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-settings.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-settings.ts @@ -1,12 +1,8 @@ -import type { Locator, Page } from '@playwright/test'; +import type { Locator } from '@playwright/test'; -export class OmnichannelSettings { - protected readonly page: Page; - - constructor(page: Page) { - this.page = page; - } +import { OmnichannelAdmin } from './omnichannel-admin'; +export class OmnichannelSettings extends OmnichannelAdmin { get labelLivechatLogo(): Locator { return this.page.locator('//label[@title="Assets_livechat_widget_logo"]'); } @@ -30,8 +26,4 @@ export class OmnichannelSettings { get labelHideWatermark(): Locator { return this.page.locator('label').getByText('Hide "powered by Rocket.Chat"'); } - - get btnSave(): Locator { - return this.page.locator('role=button[name="Save changes"]'); - } } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-sla-policies.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-sla-policies.ts new file mode 100644 index 0000000000000..62a06fe2d75cf --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-sla-policies.ts @@ -0,0 +1,54 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Table } from '../fragments/table'; + +class OmnichannelManageSlaPolicyFlexTab extends FlexTab { + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'SLA Policy' })); + } + + get inputDescription(): Locator { + return this.root.getByRole('textbox', { name: 'Description' }); + } + + get inputEstimatedWaitTime(): Locator { + return this.root.locator('[name="dueTimeInMinutes"]'); + } +} + +class OmnichannelSlaPoliciesTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'SLA Policies' })); + } +} + +export class OmnichannelSlaPolicies extends OmnichannelAdmin { + readonly manageSlaPolicy: OmnichannelManageSlaPolicyFlexTab; + + readonly table: OmnichannelSlaPoliciesTable; + + constructor(page: Page) { + super(page); + this.manageSlaPolicy = new OmnichannelManageSlaPolicyFlexTab(page); + this.table = new OmnichannelSlaPoliciesTable(page); + } + + btnRemove(name: string) { + return this.table.findRowByName(name).getByRole('button', { name: 'Remove' }); + } + + async removeSLA(name: string) { + await this.btnRemove(name).click(); + await this.deleteModal.confirmDelete(); + } + + async createNew() { + await this.getButtonByType('SLA policy').click(); + } + + get txtEmptyState() { + return this.page.locator('div >> text="No results found"'); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-tags.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-tags.ts new file mode 100644 index 0000000000000..4bf0212e25aad --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-tags.ts @@ -0,0 +1,52 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +class OmnichannelEditTagFlexTab extends FlexTab { + readonly listbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'tag' })); + this.listbox = new Listbox(page); + } + + get inputDepartments(): Locator { + return this.root.getByLabel('Departments').getByRole('textbox'); + } + + async selectDepartment(name: string) { + await this.inputDepartments.click(); + await this.inputDepartments.fill(name); + await this.listbox.selectOption(name); + } +} + +class OmnichannelTagsTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Tags' })); + } +} + +export class OmnichannelTags extends OmnichannelAdmin { + readonly editTag: OmnichannelEditTagFlexTab; + + readonly table: OmnichannelTagsTable; + + constructor(page: Page) { + super(page); + this.editTag = new OmnichannelEditTagFlexTab(page); + this.table = new OmnichannelTagsTable(page); + } + + async createNew() { + await this.getButtonByType('tag').click(); + } + + async deleteTag(name: string) { + await this.table.findRowByName(name).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-transcript.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-transcript.ts similarity index 62% rename from apps/meteor/tests/e2e/page-objects/omnichannel-transcript.ts rename to apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-transcript.ts index 60b6179852ab1..a05a185849168 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-transcript.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-transcript.ts @@ -1,17 +1,8 @@ -import type { Locator, Page } from '@playwright/test'; +import type { Locator } from '@playwright/test'; -import { OmnichannelSidenav } from './fragments'; - -export class OmnichannelTranscript { - private readonly page: Page; - - readonly sidenav: OmnichannelSidenav; - - constructor(page: Page) { - this.page = page; - this.sidenav = new OmnichannelSidenav(page); - } +import { OmnichannelAdmin } from './omnichannel-admin'; +export class OmnichannelTranscript extends OmnichannelAdmin { get contactCenterChats(): Locator { return this.page.locator('//button[contains(.,"Chats")]'); } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-triggers.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-triggers.ts new file mode 100644 index 0000000000000..9619671a2c140 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-triggers.ts @@ -0,0 +1,127 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +type TriggerConditions = 'Visitor page URL' | 'Visitor time on site' | 'Chat opened by the visitor' | 'After guest registration'; + +class OmnichannelEditTriggerFlexTab extends FlexTab { + readonly listbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'trigger' })); + this.listbox = new Listbox(page); + } + + private get inputDescription(): Locator { + return this.root.getByRole('textbox', { name: 'Description', exact: true }); + } + + private get conditionLabel(): Locator { + return this.root.getByText('Condition', { exact: true }); + } + + private get senderLabel(): Locator { + return this.root.getByText('Sender', { exact: true }); + } + + private async selectCondition(condition: string) { + await this.conditionLabel.click(); + await this.listbox.selectOption(condition); + } + + private async selectSender(sender: 'queue' | 'custom') { + await this.senderLabel.click(); + await this.listbox.selectOption(sender); + } + + private get inputAgentName(): Locator { + return this.root.locator('input[name="actions.0.params.name"]'); + } + + private get inputConditionValue(): Locator { + return this.root.locator('input[name="conditions.0.value"]'); + } + + private get inputTriggerMessage(): Locator { + return this.root.locator('textarea[name="actions.0.params.msg"]'); + } + + async fillTriggerForm( + data: Partial<{ + name: string; + description: string; + condition: TriggerConditions; + conditionValue?: string | number; + sender: 'queue' | 'custom'; + agentName?: string; + triggerMessage: string; + }>, + ) { + data.name && (await this.inputName.fill(data.name)); + data.description && (await this.inputDescription.fill(data.description)); + data.condition && (await this.selectCondition(data.condition)); + + if (data.conditionValue) { + await this.inputConditionValue.fill(data.conditionValue.toString()); + } + + data.sender && (await this.selectSender(data.sender)); + if (data.sender === 'custom' && !data.agentName) { + throw new Error('A custom agent is required for this action'); + } else { + data.agentName && (await this.inputAgentName.fill(data.agentName)); + } + + data.triggerMessage && (await this.inputTriggerMessage.fill(data.triggerMessage)); + } +} + +class OmnichannelTriggersTable extends Table { + constructor(page: Page) { + super(page.getByRole('table', { name: 'Livechat Triggers' })); + } +} + +export class OmnichannelTriggers extends OmnichannelAdmin { + readonly editTrigger: OmnichannelEditTriggerFlexTab; + + readonly table: OmnichannelTriggersTable; + + constructor(page: Page) { + super(page); + this.editTrigger = new OmnichannelEditTriggerFlexTab(page); + this.table = new OmnichannelTriggersTable(page); + } + + async removeTrigger(name: string) { + await this.table.findRowByName(name).getByRole('button', { name: 'Remove' }).click(); + await this.deleteModal.confirmDelete(); + } + + public async createTrigger(triggersName: string, triggerMessage: string, condition: TriggerConditions, conditionValue?: number | string) { + await this.getButtonByType('trigger').click(); + await this.editTrigger.fillTriggerForm({ + name: triggersName, + description: 'Creating a fresh trigger', + condition, + conditionValue, + triggerMessage, + }); + await this.editTrigger.save(); + } + + public async updateTrigger(name: string, triggerMessage: string, condition: TriggerConditions = 'Chat opened by the visitor') { + await this.editTrigger.fillTriggerForm({ + name, + description: 'Updating the existing trigger', + condition, + sender: 'custom', + agentName: 'Rocket.cat', + triggerMessage, + }); + await this.editTrigger.save(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-units.ts b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-units.ts new file mode 100644 index 0000000000000..1ee38399ee639 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/omnichannel/omnichannel-units.ts @@ -0,0 +1,96 @@ +import type { Locator, Page } from '@playwright/test'; + +import { OmnichannelAdmin } from './omnichannel-admin'; +import { FlexTab } from '../fragments/flextab'; +import { Listbox } from '../fragments/listbox'; +import { Table } from '../fragments/table'; + +export class OmnichannelUnitFlexTab extends FlexTab { + readonly listbox: Listbox; + + constructor(page: Page) { + super(page.getByRole('dialog', { name: 'unit' })); + this.listbox = new Listbox(page); + } + + private get fieldDepartments() { + return this.root.getByLabel('Departments'); + } + + get inputDepartments() { + return this.fieldDepartments.getByRole('textbox'); + } + + private get fieldMonitors() { + return this.root.getByLabel('Monitors'); + } + + get inputMonitors() { + return this.fieldMonitors.getByRole('textbox'); + } + + get inputVisibility(): Locator { + return this.root.getByText('Visibility'); + } + + findDepartmentsChipOption(name: string) { + return this.fieldDepartments.getByRole('option', { name, exact: true }); + } + + findMonitorChipOption(name: string) { + return this.fieldMonitors.getByRole('option', { name, exact: true }); + } + + async selectDepartment(name: string) { + await this.inputDepartments.click(); + await this.inputDepartments.fill(name); + await this.listbox.selectOption(name); + await this.inputDepartments.click(); + } + + async selectMonitor(option: string) { + await this.inputMonitors.click(); + await this.listbox.selectOption(option); + await this.inputMonitors.click(); + } + + async removeMonitor(option: string) { + await this.findMonitorChipOption(option).click(); + } + + async selectVisibility(option: string) { + await this.inputVisibility.click(); + await this.listbox.selectOption(option); + } +} + +class OmnichannelUnitsTable extends Table { + constructor(page: Locator) { + super(page); + } + + deleteUnitByName(name: string) { + return this.findRowByName(name).getByRole('button', { name: 'Remove' }); + } +} + +export class OmnichannelUnits extends OmnichannelAdmin { + readonly manageUnit: OmnichannelUnitFlexTab; + + readonly table: OmnichannelUnitsTable; + + constructor(page: Page) { + super(page); + this.manageUnit = new OmnichannelUnitFlexTab(page); + this.table = new OmnichannelUnitsTable(page.getByRole('table', { name: 'Units' })); + } + + async createNew() { + await this.getButtonByType('unit').click(); + } + + async deleteUnit(name: string) { + await this.table.deleteUnitByName(name).click(); + await this.deleteModal.confirmDelete(); + } +} diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 5db49d7100676..e3ac97c6b6dc8 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -3903,6 +3903,7 @@ "Omnichannel_Agent": "Omnichannel Agent", "Omnichannel_Contact_Center": "Omnichannel Contact Center", "Omnichannel_Contact_Center_Chats": "Omnichannel Contact Center Chats", + "Omnichannel_Contact_Center_Contacts": "Omnichannel Contact Center Contacts", "Omnichannel_Description": "Set up Omnichannel to communicate with customers from one place, regardless of how they connect with you.", "Omnichannel_Directory": "Omnichannel Directory", "Omnichannel_External_Frame": "External Frame",