@servicetitan/titan-chatbot-ui-cypress 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/tests/index.d.ts +30 -0
- package/dist/tests/index.d.ts.map +1 -0
- package/dist/tests/index.js +30 -0
- package/dist/tests/index.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-error.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chat-ui/chat-error.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-error.shared-tests.js +138 -0
- package/dist/tests/titan-chat-ui/chat-error.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.d.ts +7 -0
- package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.js +123 -0
- package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-input.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chat-ui/chat-input.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-input.shared-tests.js +71 -0
- package/dist/tests/titan-chat-ui/chat-input.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-log.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chat-ui/chat-log.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-log.shared-tests.js +73 -0
- package/dist/tests/titan-chat-ui/chat-log.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-messages.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chat-ui/chat-messages.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-messages.shared-tests.js +118 -0
- package/dist/tests/titan-chat-ui/chat-messages.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.js +110 -0
- package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat-timer.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chat-ui/chat-timer.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat-timer.shared-tests.js +76 -0
- package/dist/tests/titan-chat-ui/chat-timer.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/chat.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chat-ui/chat.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/chat.shared-tests.js +111 -0
- package/dist/tests/titan-chat-ui/chat.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-agent.shared-tests.d.ts +27 -0
- package/dist/tests/titan-chat-ui/message-agent.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-agent.shared-tests.js +67 -0
- package/dist/tests/titan-chat-ui/message-agent.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-content-file.shared-tests.d.ts +10 -0
- package/dist/tests/titan-chat-ui/message-content-file.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-content-file.shared-tests.js +88 -0
- package/dist/tests/titan-chat-ui/message-content-file.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-system.shared-tests.d.ts +16 -0
- package/dist/tests/titan-chat-ui/message-system.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-system.shared-tests.js +65 -0
- package/dist/tests/titan-chat-ui/message-system.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-timeout.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chat-ui/message-timeout.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-timeout.shared-tests.js +63 -0
- package/dist/tests/titan-chat-ui/message-timeout.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-typing.shared-tests.d.ts +12 -0
- package/dist/tests/titan-chat-ui/message-typing.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-typing.shared-tests.js +46 -0
- package/dist/tests/titan-chat-ui/message-typing.shared-tests.js.map +1 -0
- package/dist/tests/titan-chat-ui/message-user.shared-tests.d.ts +10 -0
- package/dist/tests/titan-chat-ui/message-user.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chat-ui/message-user.shared-tests.js +64 -0
- package/dist/tests/titan-chat-ui/message-user.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.d.ts +7 -0
- package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.js +118 -0
- package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.js +162 -0
- package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.d.ts +15 -0
- package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.js +123 -0
- package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.js +84 -0
- package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.js +142 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.js +105 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.js +86 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.d.ts +3 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.js +143 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.js +200 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.d.ts +11 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.js +81 -0
- package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.js +60 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.d.ts +8 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.js +77 -0
- package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.d.ts +7 -0
- package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.js +130 -0
- package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.js +157 -0
- package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.js.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.d.ts +9 -0
- package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.d.ts.map +1 -0
- package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.js +114 -0
- package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.js.map +1 -0
- package/dist/utils/chat-ui-selectors.d.ts +12 -0
- package/dist/utils/chat-ui-selectors.d.ts.map +1 -1
- package/dist/utils/chat-ui-selectors.js +24 -0
- package/dist/utils/chat-ui-selectors.js.map +1 -1
- package/dist/utils/test-utils-chatbot.d.ts +5 -0
- package/dist/utils/test-utils-chatbot.d.ts.map +1 -0
- package/dist/utils/test-utils-chatbot.js +55 -0
- package/dist/utils/test-utils-chatbot.js.map +1 -0
- package/dist/utils/test-utils.d.ts +6 -0
- package/dist/utils/test-utils.d.ts.map +1 -0
- package/dist/utils/test-utils.js +38 -0
- package/dist/utils/test-utils.js.map +1 -0
- package/package.json +10 -5
- package/src/index.ts +3 -0
- package/src/tests/index.ts +30 -0
- package/src/tests/titan-chat-ui/chat-error.shared-tests.tsx +185 -0
- package/src/tests/titan-chat-ui/chat-input-file.shared-tests.tsx +182 -0
- package/src/tests/titan-chat-ui/chat-input.shared-tests.tsx +99 -0
- package/src/tests/titan-chat-ui/chat-log.shared-tests.tsx +117 -0
- package/src/tests/titan-chat-ui/chat-messages.shared-tests.tsx +156 -0
- package/src/tests/titan-chat-ui/chat-notifications.shared-tests.tsx +153 -0
- package/src/tests/titan-chat-ui/chat-timer.shared-tests.tsx +106 -0
- package/src/tests/titan-chat-ui/chat.shared-tests.tsx +158 -0
- package/src/tests/titan-chat-ui/message-agent.shared-tests.tsx +170 -0
- package/src/tests/titan-chat-ui/message-content-file.shared-tests.tsx +139 -0
- package/src/tests/titan-chat-ui/message-system.shared-tests.tsx +147 -0
- package/src/tests/titan-chat-ui/message-timeout.shared-tests.tsx +117 -0
- package/src/tests/titan-chat-ui/message-typing.shared-tests.tsx +92 -0
- package/src/tests/titan-chat-ui/message-user.shared-tests.tsx +138 -0
- package/src/tests/titan-chatbot-ui/chatbot-filters.shared-tests.tsx +164 -0
- package/src/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.tsx +225 -0
- package/src/tests/titan-chatbot-ui/chatbot-links.shared-tests.tsx +189 -0
- package/src/tests/titan-chatbot-ui/chatbot-live.shared-tests.tsx +127 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.tsx +187 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.tsx +144 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.tsx +127 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.tsx +198 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.tsx +285 -0
- package/src/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.tsx +112 -0
- package/src/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.tsx +91 -0
- package/src/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.tsx +116 -0
- package/src/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.tsx +182 -0
- package/src/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.tsx +221 -0
- package/src/tests/titan-chatbot-ui/chatbot.shared-tests.tsx +158 -0
- package/src/utils/chat-ui-selectors.ts +24 -0
- package/src/utils/test-utils-chatbot.tsx +73 -0
- package/src/utils/test-utils.tsx +52 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Container } from '@servicetitan/react-ioc';
|
|
2
|
+
import {
|
|
3
|
+
CHAT_UI_BACKEND_STORE_TOKEN,
|
|
4
|
+
CHAT_UI_STORE_TOKEN,
|
|
5
|
+
ChatUiBackendEchoStore,
|
|
6
|
+
IChatUiBackendStore,
|
|
7
|
+
IChatUiStore,
|
|
8
|
+
} from '@servicetitan/titan-chat-ui-common';
|
|
9
|
+
import { FC } from 'react';
|
|
10
|
+
import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
|
|
11
|
+
import { testInitContainer, testRenderWrapper } from '../../utils/test-utils';
|
|
12
|
+
|
|
13
|
+
export function runChatErrorSharedTests(ChatErrorComponent: FC) {
|
|
14
|
+
let container: Container;
|
|
15
|
+
let chatUiStore: IChatUiStore;
|
|
16
|
+
let chatUiBackendStore: IChatUiBackendStore;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
container = testInitContainer();
|
|
20
|
+
chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
|
|
21
|
+
chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
|
|
22
|
+
cy.viewport(800, 800);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const render = (onAfterInit?: () => void) =>
|
|
26
|
+
cy
|
|
27
|
+
.wrap(null)
|
|
28
|
+
.then(() =>
|
|
29
|
+
testRenderWrapper(
|
|
30
|
+
chatUiStore,
|
|
31
|
+
chatUiBackendStore,
|
|
32
|
+
<ChatErrorComponent />,
|
|
33
|
+
onAfterInit
|
|
34
|
+
)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
it('should render', () => {
|
|
38
|
+
render(() => {
|
|
39
|
+
cy.spy(chatUiStore, 'recover').as('recoverSpy');
|
|
40
|
+
chatUiStore.setError(
|
|
41
|
+
'Custom error message Custom error message Custom error message Custom error message Custom error message Custom error message Custom error message',
|
|
42
|
+
{
|
|
43
|
+
title: 'Custom error title',
|
|
44
|
+
recoverStrategy: {
|
|
45
|
+
recoverButtonTitle: 'Recover button',
|
|
46
|
+
},
|
|
47
|
+
data: { customData: 'Custom data' },
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
ChatUiSelectors.chatError.should('contain.text', 'Custom error title');
|
|
53
|
+
ChatUiSelectors.chatErrorText.should(
|
|
54
|
+
'have.text',
|
|
55
|
+
'Custom error message Custom error message Custom error message Custom error message Custom error message Custom error message Custom error message'
|
|
56
|
+
);
|
|
57
|
+
ChatUiSelectors.chatErrorRecover.should('have.text', 'Recover button').click();
|
|
58
|
+
cy.get('@recoverSpy').should('have.been.calledOnce');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should not render when no error is set', () => {
|
|
62
|
+
render();
|
|
63
|
+
ChatUiSelectors.chatError.should('not.exist');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should render error without recover button when no recover strategy is provided', () => {
|
|
67
|
+
render(() => {
|
|
68
|
+
chatUiStore.setError('Error without recovery', {
|
|
69
|
+
title: 'Non-recoverable error',
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
ChatUiSelectors.chatError.should('be.visible');
|
|
74
|
+
ChatUiSelectors.chatError.should('contain.text', 'Non-recoverable error');
|
|
75
|
+
ChatUiSelectors.chatErrorText.should('have.text', 'Error without recovery');
|
|
76
|
+
ChatUiSelectors.chatErrorRecover.should('not.exist');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should render with default title when no title is provided', () => {
|
|
80
|
+
render(() => {
|
|
81
|
+
chatUiStore.setError('Error message without title');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
ChatUiSelectors.chatError.should('be.visible');
|
|
85
|
+
ChatUiSelectors.chatErrorText.should('have.text', 'Error message without title');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should handle multiline error messages correctly', () => {
|
|
89
|
+
render(() => {
|
|
90
|
+
chatUiStore.setError('First line\nSecond line\nThird line', {
|
|
91
|
+
title: 'Multiline Error',
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
ChatUiSelectors.chatError.should('be.visible');
|
|
96
|
+
ChatUiSelectors.chatError.should('contain.text', 'Multiline Error');
|
|
97
|
+
ChatUiSelectors.chatErrorText.should('contain.text', 'First line');
|
|
98
|
+
ChatUiSelectors.chatErrorText.should('contain.text', 'Second line');
|
|
99
|
+
ChatUiSelectors.chatErrorText.should('contain.text', 'Third line');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should update error content when error changes', () => {
|
|
103
|
+
render(() => {
|
|
104
|
+
chatUiStore.setError('First error', { title: 'First Title' });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
ChatUiSelectors.chatError.should('contain.text', 'First Title');
|
|
108
|
+
ChatUiSelectors.chatErrorText.should('have.text', 'First error');
|
|
109
|
+
|
|
110
|
+
cy.then(() => {
|
|
111
|
+
chatUiStore.setError('Second error', { title: 'Second Title' });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
ChatUiSelectors.chatError.should('contain.text', 'Second Title');
|
|
115
|
+
ChatUiSelectors.chatErrorText.should('have.text', 'Second error');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should hide error when error is cleared', () => {
|
|
119
|
+
render(() => {
|
|
120
|
+
chatUiStore.setError('Temporary error', { title: 'Error' });
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
ChatUiSelectors.chatError.should('be.visible');
|
|
124
|
+
|
|
125
|
+
cy.then(() => {
|
|
126
|
+
chatUiStore.resetError(chatUiStore.status);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
ChatUiSelectors.chatError.should('not.exist');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should call recover method when recover button is clicked multiple times', () => {
|
|
133
|
+
render(() => {
|
|
134
|
+
cy.spy(chatUiStore, 'recover').as('recoverSpy');
|
|
135
|
+
chatUiStore.setError('Recoverable error', {
|
|
136
|
+
title: 'Connection Error',
|
|
137
|
+
recoverStrategy: {
|
|
138
|
+
recoverButtonTitle: 'Retry Connection',
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
ChatUiSelectors.chatErrorRecover.should('have.text', 'Retry Connection');
|
|
144
|
+
ChatUiSelectors.chatErrorRecover.click();
|
|
145
|
+
cy.get('@recoverSpy').should('have.been.calledOnce');
|
|
146
|
+
|
|
147
|
+
ChatUiSelectors.chatErrorRecover.click();
|
|
148
|
+
cy.get('@recoverSpy').should('have.been.calledTwice');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should render with custom recover button text', () => {
|
|
152
|
+
render(() => {
|
|
153
|
+
chatUiStore.setError('Network timeout', {
|
|
154
|
+
title: 'Connection Failed',
|
|
155
|
+
recoverStrategy: {
|
|
156
|
+
recoverButtonTitle: 'Try Again Now',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
ChatUiSelectors.chatErrorRecover.should('have.text', 'Try Again Now');
|
|
162
|
+
ChatUiSelectors.chatErrorRecover.should('be.visible');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should maintain error data when provided', () => {
|
|
166
|
+
render(() => {
|
|
167
|
+
chatUiStore.setError('Error with data', {
|
|
168
|
+
title: 'Data Error',
|
|
169
|
+
data: { errorCode: 500, timestamp: '2023-10-01' },
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
ChatUiSelectors.chatError.should('be.visible');
|
|
174
|
+
ChatUiSelectors.chatError.should('contain.text', 'Data Error');
|
|
175
|
+
ChatUiSelectors.chatErrorText.should('have.text', 'Error with data');
|
|
176
|
+
|
|
177
|
+
// Verify the error data is accessible through the store
|
|
178
|
+
cy.then(() => {
|
|
179
|
+
expect(chatUiStore.error?.data).to.deep.equal({
|
|
180
|
+
errorCode: 500,
|
|
181
|
+
timestamp: '2023-10-01',
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Container } from '@servicetitan/react-ioc';
|
|
2
|
+
import {
|
|
3
|
+
CHAT_UI_BACKEND_STORE_TOKEN,
|
|
4
|
+
CHAT_UI_STORE_TOKEN,
|
|
5
|
+
ChatUiBackendEchoStore,
|
|
6
|
+
IChatUiBackendStore,
|
|
7
|
+
IChatUiStore,
|
|
8
|
+
} from '@servicetitan/titan-chat-ui-common';
|
|
9
|
+
import { FC } from 'react';
|
|
10
|
+
import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
|
|
11
|
+
import { testInitContainer, testRenderWrapper } from '../../utils/test-utils';
|
|
12
|
+
|
|
13
|
+
interface ChatInputFileSharedTestsOptions {
|
|
14
|
+
isAnvil2?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function runChatInputFileSharedTests(
|
|
18
|
+
ChatInputFileComponent: FC,
|
|
19
|
+
options: ChatInputFileSharedTestsOptions = {}
|
|
20
|
+
) {
|
|
21
|
+
let container: Container;
|
|
22
|
+
let chatUiStore: IChatUiStore;
|
|
23
|
+
let chatUiBackendStore: IChatUiBackendStore;
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
container = testInitContainer();
|
|
27
|
+
chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
|
|
28
|
+
chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
|
|
29
|
+
cy.viewport(800, 800);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const render = (onAfterInit?: () => void) =>
|
|
33
|
+
cy
|
|
34
|
+
.wrap(null)
|
|
35
|
+
.then(() =>
|
|
36
|
+
testRenderWrapper(
|
|
37
|
+
chatUiStore,
|
|
38
|
+
chatUiBackendStore,
|
|
39
|
+
<ChatInputFileComponent />,
|
|
40
|
+
onAfterInit
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const selectFile = (fileName: string, mimeType = 'text/plain', contents = '') => {
|
|
45
|
+
cy.get('input[type="file"]').selectFile(
|
|
46
|
+
{
|
|
47
|
+
contents: Cypress.Buffer.from(contents),
|
|
48
|
+
fileName,
|
|
49
|
+
mimeType,
|
|
50
|
+
lastModified: Date.now(),
|
|
51
|
+
},
|
|
52
|
+
{ force: true }
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
it('should render the upload button when no file is selected', () => {
|
|
57
|
+
render(() => {
|
|
58
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
ChatUiSelectors.chatUploadFile.should('be.visible');
|
|
62
|
+
|
|
63
|
+
if (options.isAnvil2) {
|
|
64
|
+
cy.contains('e.g. Screenshot of issue').should('be.visible');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should not render when file picker is disabled', () => {
|
|
69
|
+
render(() => {
|
|
70
|
+
chatUiStore.setFilePickerEnabled(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
ChatUiSelectors.chatUploadFile.should('not.exist');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should display the file name and action buttons after selecting a file', () => {
|
|
77
|
+
render(() => {
|
|
78
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const fileName = 'test-image.png';
|
|
82
|
+
selectFile(fileName);
|
|
83
|
+
|
|
84
|
+
// Verify the file name is displayed
|
|
85
|
+
ChatUiSelectors.chatUploadFile.should('be.visible').and('contain', fileName);
|
|
86
|
+
if (options.isAnvil2) {
|
|
87
|
+
ChatUiSelectors.chatUploadFileEdit.should('be.visible');
|
|
88
|
+
ChatUiSelectors.chatUploadFileDelete.should('be.visible');
|
|
89
|
+
ChatUiSelectors.chatUploadFileBtn.should('not.exist');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Verify the store received the file
|
|
93
|
+
cy.wrap(chatUiStore).its('file.displayName').should('eq', fileName);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (options.isAnvil2) {
|
|
97
|
+
it('should allow replacing an already selected file', () => {
|
|
98
|
+
const initialFileName = 'test-image.png';
|
|
99
|
+
const newFileName = 'another-document.pdf';
|
|
100
|
+
|
|
101
|
+
render(() => {
|
|
102
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
selectFile(initialFileName);
|
|
106
|
+
ChatUiSelectors.chatUploadFileName.should('be.visible').and('contain', initialFileName);
|
|
107
|
+
cy.wrap(chatUiStore).its('file.displayName').should('eq', initialFileName);
|
|
108
|
+
|
|
109
|
+
selectFile(newFileName, 'application/pdf');
|
|
110
|
+
ChatUiSelectors.chatUploadFileName.should('be.visible').and('contain', newFileName);
|
|
111
|
+
cy.wrap(chatUiStore).its('file.displayName').should('eq', newFileName);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should allow deleting a selected file', () => {
|
|
115
|
+
const fileName = 'test-image.png';
|
|
116
|
+
|
|
117
|
+
render(() => {
|
|
118
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
selectFile(fileName);
|
|
122
|
+
|
|
123
|
+
// Verify the file name is displayed
|
|
124
|
+
ChatUiSelectors.chatUploadFileName.should('be.visible').and('contain', fileName);
|
|
125
|
+
|
|
126
|
+
// Click the delete button
|
|
127
|
+
ChatUiSelectors.chatUploadFileDelete.click();
|
|
128
|
+
|
|
129
|
+
// Verify the file input is reset
|
|
130
|
+
ChatUiSelectors.chatUploadFile.should('be.visible');
|
|
131
|
+
ChatUiSelectors.chatUploadFileName.should('not.exist');
|
|
132
|
+
ChatUiSelectors.chatUploadFileEdit.should('not.exist');
|
|
133
|
+
ChatUiSelectors.chatUploadFileDelete.should('not.exist');
|
|
134
|
+
|
|
135
|
+
// Verify the store no longer has a file
|
|
136
|
+
cy.wrap(chatUiStore).its('file').should('be.undefined');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should handle file selection with different file types', () => {
|
|
140
|
+
render(() => {
|
|
141
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Test PDF file
|
|
145
|
+
const pdfFileName = 'test-document.pdf';
|
|
146
|
+
selectFile(pdfFileName, 'application/pdf', 'test file content');
|
|
147
|
+
|
|
148
|
+
ChatUiSelectors.chatUploadFileName.should('contain', pdfFileName);
|
|
149
|
+
cy.wrap(chatUiStore).its('file.displayName').should('eq', pdfFileName);
|
|
150
|
+
|
|
151
|
+
// Replace with image file
|
|
152
|
+
const imageFileName = 'test-image.jpg';
|
|
153
|
+
selectFile(imageFileName, 'image/jpeg');
|
|
154
|
+
|
|
155
|
+
ChatUiSelectors.chatUploadFileName.should('contain', imageFileName);
|
|
156
|
+
cy.wrap(chatUiStore).its('file.displayName').should('eq', imageFileName);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should maintain file picker state during interactions', () => {
|
|
160
|
+
render(() => {
|
|
161
|
+
chatUiStore.setFilePickerEnabled(true);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const fileName = 'test-file.txt';
|
|
165
|
+
selectFile(fileName);
|
|
166
|
+
|
|
167
|
+
// Verify file is selected
|
|
168
|
+
ChatUiSelectors.chatUploadFileName.should('be.visible').and('contain', fileName);
|
|
169
|
+
|
|
170
|
+
// Edit button should be visible and functional
|
|
171
|
+
ChatUiSelectors.chatUploadFileEdit.should('be.visible');
|
|
172
|
+
|
|
173
|
+
// Delete and re-upload
|
|
174
|
+
ChatUiSelectors.chatUploadFileDelete.click();
|
|
175
|
+
ChatUiSelectors.chatUploadFile.should('be.visible');
|
|
176
|
+
|
|
177
|
+
// Select file again
|
|
178
|
+
selectFile(fileName);
|
|
179
|
+
ChatUiSelectors.chatUploadFileName.should('be.visible').and('contain', fileName);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Container } from '@servicetitan/react-ioc';
|
|
2
|
+
import {
|
|
3
|
+
CHAT_UI_BACKEND_STORE_TOKEN,
|
|
4
|
+
CHAT_UI_STORE_TOKEN,
|
|
5
|
+
ChatUiBackendEchoStore,
|
|
6
|
+
IChatUiBackendStore,
|
|
7
|
+
IChatUiStore,
|
|
8
|
+
} from '@servicetitan/titan-chat-ui-common';
|
|
9
|
+
import { FC } from 'react';
|
|
10
|
+
import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
|
|
11
|
+
import { testInitContainer, testRenderWrapper } from '../../utils/test-utils';
|
|
12
|
+
|
|
13
|
+
export function runChatInputSharedTests(ChatInputComponent: FC) {
|
|
14
|
+
let container: Container;
|
|
15
|
+
let chatUiStore: IChatUiStore;
|
|
16
|
+
let chatUiBackendStore: IChatUiBackendStore;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
container = testInitContainer();
|
|
20
|
+
chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
|
|
21
|
+
chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
|
|
22
|
+
cy.viewport(800, 800);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const render = (onAfterInit?: () => void) =>
|
|
26
|
+
cy
|
|
27
|
+
.wrap(null)
|
|
28
|
+
.then(() =>
|
|
29
|
+
testRenderWrapper(
|
|
30
|
+
chatUiStore,
|
|
31
|
+
chatUiBackendStore,
|
|
32
|
+
<ChatInputComponent />,
|
|
33
|
+
onAfterInit
|
|
34
|
+
)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
it('should render chat input', () => {
|
|
38
|
+
render();
|
|
39
|
+
ChatUiSelectors.chatInput.should('be.visible');
|
|
40
|
+
ChatUiSelectors.chatSend.should('be.visible');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should send message when send button is clicked', () => {
|
|
44
|
+
render(() => {
|
|
45
|
+
cy.spy(chatUiStore, 'sendMessageText').as('sendMessageSpy');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const text = 'Hello, world! '.repeat(30).trim();
|
|
49
|
+
ChatUiSelectors.chatInput.type(text, { delay: 0 });
|
|
50
|
+
cy.wait(1);
|
|
51
|
+
ChatUiSelectors.chatInput.should('have.value', text);
|
|
52
|
+
ChatUiSelectors.chatSend.click();
|
|
53
|
+
ChatUiSelectors.chatInput.should('have.value', '');
|
|
54
|
+
cy.get('@sendMessageSpy').should('have.been.calledWith', text);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should send message when Enter key is pressed', () => {
|
|
58
|
+
render(() => {
|
|
59
|
+
cy.spy(chatUiStore, 'sendMessageText').as('sendMessageSpy');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const text = 'Test message with Enter key';
|
|
63
|
+
ChatUiSelectors.chatInput.type(text, { delay: 0 });
|
|
64
|
+
cy.wait(1);
|
|
65
|
+
ChatUiSelectors.chatInput.type('{enter}');
|
|
66
|
+
ChatUiSelectors.chatInput.should('have.value', '');
|
|
67
|
+
cy.get('@sendMessageSpy').should('have.been.calledWith', text);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should not send empty message', () => {
|
|
71
|
+
render(() => {
|
|
72
|
+
cy.spy(chatUiStore, 'sendMessageText').as('sendMessageSpy');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
ChatUiSelectors.chatInput.type(' ', { delay: 0 });
|
|
76
|
+
cy.wait(1);
|
|
77
|
+
ChatUiSelectors.chatSend.click();
|
|
78
|
+
cy.get('@sendMessageSpy').should('not.have.been.called');
|
|
79
|
+
ChatUiSelectors.chatInput.should('have.value', ' ');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should handle long text input', () => {
|
|
83
|
+
render();
|
|
84
|
+
|
|
85
|
+
const longText = 'This is a very long message that exceeds normal length. '.repeat(50);
|
|
86
|
+
ChatUiSelectors.chatInput.type(longText, { delay: 0 });
|
|
87
|
+
ChatUiSelectors.chatInput.should('have.value', longText);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should disable send button when input is empty', () => {
|
|
91
|
+
render();
|
|
92
|
+
|
|
93
|
+
ChatUiSelectors.chatSend.should('be.disabled');
|
|
94
|
+
ChatUiSelectors.chatInput.type('Some text', { delay: 0 });
|
|
95
|
+
ChatUiSelectors.chatSend.should('not.be.disabled');
|
|
96
|
+
ChatUiSelectors.chatInput.clear();
|
|
97
|
+
ChatUiSelectors.chatSend.should('be.disabled');
|
|
98
|
+
});
|
|
99
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Container } from '@servicetitan/react-ioc';
|
|
2
|
+
import {
|
|
3
|
+
CHAT_UI_BACKEND_STORE_TOKEN,
|
|
4
|
+
CHAT_UI_STORE_TOKEN,
|
|
5
|
+
ChatCustomizations,
|
|
6
|
+
ChatUiBackendEchoStore,
|
|
7
|
+
IChatUiBackendStore,
|
|
8
|
+
IChatUiStore,
|
|
9
|
+
} from '@servicetitan/titan-chat-ui-common';
|
|
10
|
+
import { FC } from 'react';
|
|
11
|
+
import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
|
|
12
|
+
import { testInitContainer, testRenderWrapper } from '../../utils/test-utils';
|
|
13
|
+
|
|
14
|
+
interface ChatLogProps {
|
|
15
|
+
className?: string;
|
|
16
|
+
customizations?: ChatCustomizations;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function runChatLogSharedTests(ChatLogComponent: FC<ChatLogProps>) {
|
|
20
|
+
let container: Container;
|
|
21
|
+
let chatUiStore: IChatUiStore;
|
|
22
|
+
let chatUiBackendStore: IChatUiBackendStore;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
container = testInitContainer();
|
|
26
|
+
chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
|
|
27
|
+
chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
|
|
28
|
+
cy.viewport(800, 800);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const render = (
|
|
32
|
+
className?: string,
|
|
33
|
+
customizations?: ChatCustomizations,
|
|
34
|
+
onAfterInit?: () => void
|
|
35
|
+
) =>
|
|
36
|
+
cy
|
|
37
|
+
.wrap(null)
|
|
38
|
+
.then(() =>
|
|
39
|
+
testRenderWrapper(
|
|
40
|
+
chatUiStore,
|
|
41
|
+
chatUiBackendStore,
|
|
42
|
+
<ChatLogComponent className={className} customizations={customizations} />,
|
|
43
|
+
onAfterInit
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
it('should render chat log with titan-chat data-cy attribute', () => {
|
|
48
|
+
render();
|
|
49
|
+
|
|
50
|
+
ChatUiSelectors.chat.should('be.visible');
|
|
51
|
+
ChatUiSelectors.chatMessages.should('exist');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should apply custom className', () => {
|
|
55
|
+
const customClass = 'custom-chat-class';
|
|
56
|
+
render(customClass);
|
|
57
|
+
|
|
58
|
+
ChatUiSelectors.chat.should('have.class', customClass);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should set customization context on mount', () => {
|
|
62
|
+
const customizations: ChatCustomizations = {
|
|
63
|
+
input: {
|
|
64
|
+
isDisabled: true,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
render(undefined, customizations);
|
|
69
|
+
|
|
70
|
+
ChatUiSelectors.chat.should('be.visible');
|
|
71
|
+
cy.wait(1).then(() => {
|
|
72
|
+
expect(chatUiStore.customizations).to.deep.equal(customizations);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should display messages from store', () => {
|
|
77
|
+
render(undefined, undefined, () => {
|
|
78
|
+
chatUiStore.addMessage(true, 'Hello from agent');
|
|
79
|
+
chatUiStore.addMessage(false, 'Hello from user');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
ChatUiSelectors.chatMessage.should('have.length', 3); // 1st message is the welcome message
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should show typing indicator when agent is typing', () => {
|
|
86
|
+
render(undefined, undefined, () => {
|
|
87
|
+
chatUiStore.setAgentTyping(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
ChatUiSelectors.chatMessageTyping.should('be.visible');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should hide typing indicator when agent is not typing', () => {
|
|
94
|
+
render(undefined, undefined, () => {
|
|
95
|
+
chatUiStore.setAgentTyping(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
ChatUiSelectors.chatMessageTyping.should('not.exist');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should update customization context when customizations prop changes', () => {
|
|
102
|
+
const initialCustomizations: ChatCustomizations = {
|
|
103
|
+
input: {
|
|
104
|
+
isDisabled: false,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
render(undefined, initialCustomizations);
|
|
109
|
+
|
|
110
|
+
cy.get('[data-cy="titan-chat"]').should('be.visible');
|
|
111
|
+
|
|
112
|
+
// Verify initial customizations are set
|
|
113
|
+
cy.wrap(null).then(() => {
|
|
114
|
+
expect(chatUiStore.customizations).to.deep.equal(initialCustomizations);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|