Skip to content

Commit

Permalink
feat: Added new trigger condition after-guest-registration (#29785)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandernsilva committed Aug 30, 2023
1 parent 9e10de0 commit 04fe492
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 104 deletions.
6 changes: 6 additions & 0 deletions .changeset/eighty-kids-jog.md
@@ -0,0 +1,6 @@
---
'@rocket.chat/livechat': minor
'@rocket.chat/meteor': minor
---

Added new Omnichannel's trigger condition "After starting a chat".
22 changes: 17 additions & 5 deletions apps/meteor/client/views/omnichannel/triggers/TriggersForm.tsx
Expand Up @@ -62,6 +62,7 @@ const TriggersForm: FC<TriggersFormProps> = ({ values, handlers, className }) =>
['page-url', t('Visitor_page_URL')],
['time-on-site', t('Visitor_time_on_site')],
['chat-opened-by-visitor', t('Chat_opened_by_visitor')],
['after-guest-registration', t('After_guest_registration')],
],
[t],
);
Expand Down Expand Up @@ -167,11 +168,16 @@ const TriggersForm: FC<TriggersFormProps> = ({ values, handlers, className }) =>
<Field className={className}>
<Field.Label>{t('Condition')}</Field.Label>
<Field.Row>
<Select options={conditionOptions} value={conditionName} onChange={handleConditionName} />
<Select name='condition' options={conditionOptions} value={conditionName} onChange={handleConditionName} />
</Field.Row>
{conditionValuePlaceholder && (
<Field.Row>
<TextInput value={conditionValue} onChange={handleConditionValue} placeholder={conditionValuePlaceholder} />
<TextInput
name='conditionValue'
value={conditionValue}
onChange={handleConditionValue}
placeholder={conditionValuePlaceholder}
/>
</Field.Row>
)}
</Field>
Expand All @@ -181,15 +187,21 @@ const TriggersForm: FC<TriggersFormProps> = ({ values, handlers, className }) =>
<TextInput value={t('Send_a_message')} disabled />
</Field.Row>
<Field.Row>
<Select options={senderOptions} value={actionSender} onChange={handleActionSender} placeholder={t('Select_an_option')} />
<Select
name='sender'
options={senderOptions}
value={actionSender}
onChange={handleActionSender}
placeholder={t('Select_an_option')}
/>
</Field.Row>
{actionSender === 'custom' && (
<Field.Row>
<TextInput value={actionAgentName} onChange={handleActionAgentName} placeholder={t('Name_of_agent')} />
<TextInput name='agentName' value={actionAgentName} onChange={handleActionAgentName} placeholder={t('Name_of_agent')} />
</Field.Row>
)}
<Field.Row>
<TextAreaInput rows={3} value={actionMsg} onChange={handleActionMessage} placeholder={`${t('Message')}*`} />
<TextAreaInput name='triggerMessage' rows={3} value={actionMsg} onChange={handleActionMessage} placeholder={`${t('Message')}*`} />
</Field.Row>
<Field.Error>{msgError}</Field.Error>
</Field>
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Expand Up @@ -360,6 +360,7 @@
"Adult_images_are_not_allowed": "Adult images are not allowed",
"Aerospace_and_Defense": "Aerospace & Defense",
"After_OAuth2_authentication_users_will_be_redirected_to_this_URL": "After OAuth2 authentication, users will be redirected to an URL on this list. You can add one URL per line.",
"After_guest_registration": "After guest registration",
"Agent": "Agent",
"Agent_added": "Agent added",
"Agent_Info": "Agent Info",
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Expand Up @@ -325,6 +325,7 @@
"Adult_images_are_not_allowed": "Imagens com conteúdo adulto não são permitidas",
"Aerospace_and_Defense": "Aeroespacial e Defesa",
"After_OAuth2_authentication_users_will_be_redirected_to_this_URL": "Após a autenticação OAuth2, os usuários serão redirecionados para este URL. Você poderá adicionar um URL por linha.",
"After_guest_registration": "Após registro do convidado",
"Agent": "Agente",
"Agent_added": "Agente adicionado",
"Agent_Info": "Informações do agente",
Expand Down
143 changes: 113 additions & 30 deletions apps/meteor/tests/e2e/omnichannel/omnichannel-triggers.spec.ts
Expand Up @@ -6,7 +6,7 @@ import { Users } from '../fixtures/userStates';
import { OmnichannelLiveChat, HomeOmnichannel } from '../page-objects';
import { test, expect } from '../utils/test';

test.describe.serial('omnichannel-triggers', () => {
test.describe.serial('Omnichannel Triggers', () => {
let triggersName: string;
let triggerMessage: string;
let poLiveChat: OmnichannelLiveChat;
Expand All @@ -19,55 +19,138 @@ test.describe.serial('omnichannel-triggers', () => {
email: faker.internet.email(),
};
triggersName = faker.string.uuid();
triggerMessage = 'Welcome to Rocket.chat';
await Promise.all([
triggerMessage = 'This is a trigger message';
const requests = await Promise.all([
api.post('/livechat/users/agent', { username: 'user1' }),
api.post('/livechat/users/manager', { username: 'user1' }),
api.post('/settings/Livechat_clear_local_storage_when_chat_ended', { value: true }),
]);
requests.every((e) => expect(e.status()).toBe(200));

const { page } = await createAuxContext(browser, Users.user1);
const { page } = await createAuxContext(browser, Users.user1, '/omnichannel/triggers');
agent = { page, poHomeOmnichannel: new HomeOmnichannel(page) };

await page.goto('/omnichannel/triggers');
await page.locator('.main-content').waitFor();
});

test.beforeEach(async ({ page, api }) => {
poLiveChat = new OmnichannelLiveChat(page, api);
});

test.afterAll(async ({ api }) => {
await Promise.all([api.delete('/livechat/users/agent/user1'), api.delete('/livechat/users/manager/user1')]);
await Promise.all([
api.delete('/livechat/users/agent/user1'),
api.delete('/livechat/users/manager/user1'),
api.post('/settings/Livechat_clear_local_storage_when_chat_ended', { value: false }),
]);
await agent.page.close();
});

test('Triggers', async ({ page }) => {
test('trigger baseline', async ({ page }) => {
await page.goto('/livechat');
await poLiveChat.openLiveChat();

await test.step('expect to register visitor', async () => {
await expect(poLiveChat.btnChatNow).not.toBeVisible();
await poLiveChat.sendMessage(newUser, false);
});

await test.step('expect send a message as a visitor', async () => {
await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_user');
await poLiveChat.btnSendMessageToOnlineAgent.click();
await expect(poLiveChat.txtChatMessage('this_a_test_message_from_user')).toBeVisible();
});

await test.step('expect to finish this chat', async () => {
await poLiveChat.closeChat();
await expect(poLiveChat.txtHeaderTitle).toBeVisible();
});
});

test('create and edit trigger', async () => {
await test.step('expect create new trigger', async () => {
await agent.poHomeOmnichannel.triggers.createTrigger(triggersName, triggerMessage);
await expect(agent.poHomeOmnichannel.triggers.toastMessage).toBeVisible();
await agent.poHomeOmnichannel.triggers.btnCloseToastMessage.click();
});

await test.step('expect update trigger', async () => {
const newTriggerName = `edited-${triggersName}`;
await agent.poHomeOmnichannel.triggers.firstRowInTriggerTable(triggersName).click();
await agent.poHomeOmnichannel.triggers.updateTrigger(newTriggerName);
await expect(agent.poHomeOmnichannel.triggers.toastMessage).toBeVisible();
});
await test.step('expect triggers to be displaye on Livechat', async () => {
await test.step('Expect send a message as a visitor', async () => {
await page.goto('/livechat');
await poLiveChat.openLiveChat();
if (await page.locator('[type="button"] >> text="Chat now"').isVisible()) {
await page.locator('[type="button"] >> text="Chat now"').click();
}
await poLiveChat.sendMessage(newUser, false);
await expect(page.locator(`text=${triggerMessage} >> nth=0`)).toBeVisible();
await page.goBack();
});
});
await test.step('expect deleting trigger', async () => {
await agent.poHomeOmnichannel.triggers.btnDeletefirstRowInTable.click();
await agent.poHomeOmnichannel.triggers.btnModalRemove.click();
await expect(agent.poHomeOmnichannel.triggers.removeToastMessage).toBeVisible();
await agent.poHomeOmnichannel.triggers.updateTrigger(triggersName);
await agent.poHomeOmnichannel.triggers.btnCloseToastMessage.click();
});
});

test('trigger condition: chat opened by visitor', async ({ page }) => {
await test.step('expect to start conversation', async () => {
await page.goto('/livechat');
await poLiveChat.openLiveChat();
});

await test.step('expect trigger message before registration', async () => {
await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible();
});

await test.step('expect to register visitor', async () => {
await poLiveChat.btnChatNow.click();
await poLiveChat.sendMessage(newUser, false);
});

await test.step('expect trigger message after registration', async () => {
await expect(poLiveChat.txtChatMessage(triggerMessage)).not.toBeVisible();
});

await test.step('expect send a message as a visitor', async () => {
await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_user');
await poLiveChat.btnSendMessageToOnlineAgent.click();
await expect(poLiveChat.txtChatMessage('this_a_test_message_from_user')).toBeVisible();
});

await test.step('expect to finish this chat', async () => {
await poLiveChat.closeChat();
await expect(poLiveChat.txtHeaderTitle).toBeVisible();
});
});

test('trigger condition: after guest registration', async ({ page }) => {
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.btnCloseToastMessage.click();
await agent.page.waitForTimeout(500);
});

await test.step('expect to start conversation', async () => {
await page.goto('/livechat');
await poLiveChat.openLiveChat();
});

await test.step('expect not to have trigger message before registration', async () => {
await expect(poLiveChat.txtChatMessage(triggerMessage)).not.toBeVisible();
await expect(poLiveChat.btnChatNow).not.toBeVisible();
});

await test.step('expect to register visitor', async () => {
await poLiveChat.sendMessage(newUser, false);
});

await test.step('expect trigger message after registration', async () => {
await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible();
});

await test.step('expect send a message as a visitor', async () => {
await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_user');
await poLiveChat.btnSendMessageToOnlineAgent.click();
await expect(poLiveChat.txtChatMessage('this_a_test_message_from_user')).toBeVisible();
});

await test.step('expect to finish this chat', async () => {
await poLiveChat.closeChat();
await expect(poLiveChat.txtHeaderTitle).toBeVisible();
});
});

test('delete trigger', async () => {
await agent.poHomeOmnichannel.triggers.btnDeletefirstRowInTable.click();
await agent.poHomeOmnichannel.triggers.btnModalRemove.click();
await expect(agent.poHomeOmnichannel.triggers.removeToastMessage).toBeVisible();
});
});
31 changes: 31 additions & 0 deletions apps/meteor/tests/e2e/page-objects/omnichannel-livechat.ts
Expand Up @@ -11,6 +11,36 @@ export class OmnichannelLiveChat {
return this.page.locator(`role=button[name="${label}"]`);
}

get btnOptions(): Locator {
return this.page.locator(`button >> text="Options"`);
}

get btnCloseChat(): Locator {
return this.page.locator(`button >> text="Finish this chat"`);
}

get btnCloseChatConfirm(): Locator {
return this.page.locator(`button >> text="Yes"`);
}

get txtHeaderTitle(): Locator {
return this.page.locator('div >> text="Chat Finished"');
}

get btnChatNow(): Locator {
return this.page.locator('[type="button"] >> text="Chat now"');
}

txtChatMessage(message: string): Locator {
return this.page.locator(`text="${message}"`);
}

async closeChat(): Promise<void> {
await this.btnOptions.click();
await this.btnCloseChat.click();
await this.btnCloseChatConfirm.click();
}

async openLiveChat(): Promise<void> {
const { value: siteName } = await (await this.api.get('/settings/Site_Name')).json();
await this.btnOpenLiveChat(siteName).click();
Expand Down Expand Up @@ -62,5 +92,6 @@ export class OmnichannelLiveChat {
await this.textAreaMessage.type('any_message');
}
await this.btnSendMessage(buttonLabel).click();
await this.page.waitForSelector('[data-qa="livechat-composer"]');
}
}

0 comments on commit 04fe492

Please sign in to comment.