@servicetitan/titan-chatbot-ui-cypress 3.0.1 → 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.
Files changed (178) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/mocks/chatbot-api-client.mock.d.ts +0 -1
  7. package/dist/mocks/chatbot-api-client.mock.d.ts.map +1 -1
  8. package/dist/mocks/chatbot-api-client.mock.js +0 -6
  9. package/dist/mocks/chatbot-api-client.mock.js.map +1 -1
  10. package/dist/tests/index.d.ts +30 -0
  11. package/dist/tests/index.d.ts.map +1 -0
  12. package/dist/tests/index.js +30 -0
  13. package/dist/tests/index.js.map +1 -0
  14. package/dist/tests/titan-chat-ui/chat-error.shared-tests.d.ts +3 -0
  15. package/dist/tests/titan-chat-ui/chat-error.shared-tests.d.ts.map +1 -0
  16. package/dist/tests/titan-chat-ui/chat-error.shared-tests.js +138 -0
  17. package/dist/tests/titan-chat-ui/chat-error.shared-tests.js.map +1 -0
  18. package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.d.ts +7 -0
  19. package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.d.ts.map +1 -0
  20. package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.js +123 -0
  21. package/dist/tests/titan-chat-ui/chat-input-file.shared-tests.js.map +1 -0
  22. package/dist/tests/titan-chat-ui/chat-input.shared-tests.d.ts +3 -0
  23. package/dist/tests/titan-chat-ui/chat-input.shared-tests.d.ts.map +1 -0
  24. package/dist/tests/titan-chat-ui/chat-input.shared-tests.js +71 -0
  25. package/dist/tests/titan-chat-ui/chat-input.shared-tests.js.map +1 -0
  26. package/dist/tests/titan-chat-ui/chat-log.shared-tests.d.ts +9 -0
  27. package/dist/tests/titan-chat-ui/chat-log.shared-tests.d.ts.map +1 -0
  28. package/dist/tests/titan-chat-ui/chat-log.shared-tests.js +73 -0
  29. package/dist/tests/titan-chat-ui/chat-log.shared-tests.js.map +1 -0
  30. package/dist/tests/titan-chat-ui/chat-messages.shared-tests.d.ts +8 -0
  31. package/dist/tests/titan-chat-ui/chat-messages.shared-tests.d.ts.map +1 -0
  32. package/dist/tests/titan-chat-ui/chat-messages.shared-tests.js +118 -0
  33. package/dist/tests/titan-chat-ui/chat-messages.shared-tests.js.map +1 -0
  34. package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.d.ts +3 -0
  35. package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.d.ts.map +1 -0
  36. package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.js +110 -0
  37. package/dist/tests/titan-chat-ui/chat-notifications.shared-tests.js.map +1 -0
  38. package/dist/tests/titan-chat-ui/chat-timer.shared-tests.d.ts +3 -0
  39. package/dist/tests/titan-chat-ui/chat-timer.shared-tests.d.ts.map +1 -0
  40. package/dist/tests/titan-chat-ui/chat-timer.shared-tests.js +76 -0
  41. package/dist/tests/titan-chat-ui/chat-timer.shared-tests.js.map +1 -0
  42. package/dist/tests/titan-chat-ui/chat.shared-tests.d.ts +9 -0
  43. package/dist/tests/titan-chat-ui/chat.shared-tests.d.ts.map +1 -0
  44. package/dist/tests/titan-chat-ui/chat.shared-tests.js +111 -0
  45. package/dist/tests/titan-chat-ui/chat.shared-tests.js.map +1 -0
  46. package/dist/tests/titan-chat-ui/message-agent.shared-tests.d.ts +27 -0
  47. package/dist/tests/titan-chat-ui/message-agent.shared-tests.d.ts.map +1 -0
  48. package/dist/tests/titan-chat-ui/message-agent.shared-tests.js +67 -0
  49. package/dist/tests/titan-chat-ui/message-agent.shared-tests.js.map +1 -0
  50. package/dist/tests/titan-chat-ui/message-content-file.shared-tests.d.ts +10 -0
  51. package/dist/tests/titan-chat-ui/message-content-file.shared-tests.d.ts.map +1 -0
  52. package/dist/tests/titan-chat-ui/message-content-file.shared-tests.js +88 -0
  53. package/dist/tests/titan-chat-ui/message-content-file.shared-tests.js.map +1 -0
  54. package/dist/tests/titan-chat-ui/message-system.shared-tests.d.ts +16 -0
  55. package/dist/tests/titan-chat-ui/message-system.shared-tests.d.ts.map +1 -0
  56. package/dist/tests/titan-chat-ui/message-system.shared-tests.js +65 -0
  57. package/dist/tests/titan-chat-ui/message-system.shared-tests.js.map +1 -0
  58. package/dist/tests/titan-chat-ui/message-timeout.shared-tests.d.ts +8 -0
  59. package/dist/tests/titan-chat-ui/message-timeout.shared-tests.d.ts.map +1 -0
  60. package/dist/tests/titan-chat-ui/message-timeout.shared-tests.js +63 -0
  61. package/dist/tests/titan-chat-ui/message-timeout.shared-tests.js.map +1 -0
  62. package/dist/tests/titan-chat-ui/message-typing.shared-tests.d.ts +12 -0
  63. package/dist/tests/titan-chat-ui/message-typing.shared-tests.d.ts.map +1 -0
  64. package/dist/tests/titan-chat-ui/message-typing.shared-tests.js +46 -0
  65. package/dist/tests/titan-chat-ui/message-typing.shared-tests.js.map +1 -0
  66. package/dist/tests/titan-chat-ui/message-user.shared-tests.d.ts +10 -0
  67. package/dist/tests/titan-chat-ui/message-user.shared-tests.d.ts.map +1 -0
  68. package/dist/tests/titan-chat-ui/message-user.shared-tests.js +64 -0
  69. package/dist/tests/titan-chat-ui/message-user.shared-tests.js.map +1 -0
  70. package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.d.ts +7 -0
  71. package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.d.ts.map +1 -0
  72. package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.js +118 -0
  73. package/dist/tests/titan-chatbot-ui/chatbot-filters.shared-tests.js.map +1 -0
  74. package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.d.ts +9 -0
  75. package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.d.ts.map +1 -0
  76. package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.js +162 -0
  77. package/dist/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.js.map +1 -0
  78. package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.d.ts +15 -0
  79. package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.d.ts.map +1 -0
  80. package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.js +123 -0
  81. package/dist/tests/titan-chatbot-ui/chatbot-links.shared-tests.js.map +1 -0
  82. package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.d.ts +9 -0
  83. package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.d.ts.map +1 -0
  84. package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.js +84 -0
  85. package/dist/tests/titan-chatbot-ui/chatbot-live.shared-tests.js.map +1 -0
  86. package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.d.ts +8 -0
  87. package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.d.ts.map +1 -0
  88. package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.js +142 -0
  89. package/dist/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.js.map +1 -0
  90. package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.d.ts +8 -0
  91. package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.d.ts.map +1 -0
  92. package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.js +105 -0
  93. package/dist/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.js.map +1 -0
  94. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.d.ts +3 -0
  95. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.d.ts.map +1 -0
  96. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.js +86 -0
  97. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.js.map +1 -0
  98. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.d.ts +3 -0
  99. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.d.ts.map +1 -0
  100. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.js +143 -0
  101. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.js.map +1 -0
  102. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.d.ts +8 -0
  103. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.d.ts.map +1 -0
  104. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.js +200 -0
  105. package/dist/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.js.map +1 -0
  106. package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.d.ts +11 -0
  107. package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.d.ts.map +1 -0
  108. package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.js +81 -0
  109. package/dist/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.js.map +1 -0
  110. package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.d.ts +8 -0
  111. package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.d.ts.map +1 -0
  112. package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.js +60 -0
  113. package/dist/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.js.map +1 -0
  114. package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.d.ts +8 -0
  115. package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.d.ts.map +1 -0
  116. package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.js +77 -0
  117. package/dist/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.js.map +1 -0
  118. package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.d.ts +7 -0
  119. package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.d.ts.map +1 -0
  120. package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.js +130 -0
  121. package/dist/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.js.map +1 -0
  122. package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.d.ts +9 -0
  123. package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.d.ts.map +1 -0
  124. package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.js +157 -0
  125. package/dist/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.js.map +1 -0
  126. package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.d.ts +9 -0
  127. package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.d.ts.map +1 -0
  128. package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.js +114 -0
  129. package/dist/tests/titan-chatbot-ui/chatbot.shared-tests.js.map +1 -0
  130. package/dist/utils/chat-ui-selectors.d.ts +12 -0
  131. package/dist/utils/chat-ui-selectors.d.ts.map +1 -1
  132. package/dist/utils/chat-ui-selectors.js +24 -0
  133. package/dist/utils/chat-ui-selectors.js.map +1 -1
  134. package/dist/utils/test-utils-chatbot.d.ts +5 -0
  135. package/dist/utils/test-utils-chatbot.d.ts.map +1 -0
  136. package/dist/utils/test-utils-chatbot.js +55 -0
  137. package/dist/utils/test-utils-chatbot.js.map +1 -0
  138. package/dist/utils/test-utils.d.ts +6 -0
  139. package/dist/utils/test-utils.d.ts.map +1 -0
  140. package/dist/utils/test-utils.js +38 -0
  141. package/dist/utils/test-utils.js.map +1 -0
  142. package/package.json +10 -5
  143. package/src/index.ts +3 -0
  144. package/src/mocks/chatbot-api-client.mock.ts +0 -1
  145. package/src/tests/index.ts +30 -0
  146. package/src/tests/titan-chat-ui/chat-error.shared-tests.tsx +185 -0
  147. package/src/tests/titan-chat-ui/chat-input-file.shared-tests.tsx +182 -0
  148. package/src/tests/titan-chat-ui/chat-input.shared-tests.tsx +99 -0
  149. package/src/tests/titan-chat-ui/chat-log.shared-tests.tsx +117 -0
  150. package/src/tests/titan-chat-ui/chat-messages.shared-tests.tsx +156 -0
  151. package/src/tests/titan-chat-ui/chat-notifications.shared-tests.tsx +153 -0
  152. package/src/tests/titan-chat-ui/chat-timer.shared-tests.tsx +106 -0
  153. package/src/tests/titan-chat-ui/chat.shared-tests.tsx +158 -0
  154. package/src/tests/titan-chat-ui/message-agent.shared-tests.tsx +170 -0
  155. package/src/tests/titan-chat-ui/message-content-file.shared-tests.tsx +139 -0
  156. package/src/tests/titan-chat-ui/message-system.shared-tests.tsx +147 -0
  157. package/src/tests/titan-chat-ui/message-timeout.shared-tests.tsx +117 -0
  158. package/src/tests/titan-chat-ui/message-typing.shared-tests.tsx +92 -0
  159. package/src/tests/titan-chat-ui/message-user.shared-tests.tsx +138 -0
  160. package/src/tests/titan-chatbot-ui/chatbot-filters.shared-tests.tsx +164 -0
  161. package/src/tests/titan-chatbot-ui/chatbot-help-center.shared-tests.tsx +225 -0
  162. package/src/tests/titan-chatbot-ui/chatbot-links.shared-tests.tsx +189 -0
  163. package/src/tests/titan-chatbot-ui/chatbot-live.shared-tests.tsx +127 -0
  164. package/src/tests/titan-chatbot-ui/chatbot-message-answer-readonly.shared-tests.tsx +187 -0
  165. package/src/tests/titan-chatbot-ui/chatbot-message-answer.shared-tests.tsx +144 -0
  166. package/src/tests/titan-chatbot-ui/chatbot-message-feedback-form-guardrail.shared-tests.tsx +127 -0
  167. package/src/tests/titan-chatbot-ui/chatbot-message-feedback-form.shared-tests.tsx +198 -0
  168. package/src/tests/titan-chatbot-ui/chatbot-message-feedback-popover.shared-tests.tsx +285 -0
  169. package/src/tests/titan-chatbot-ui/chatbot-message-typing.shared-tests.tsx +112 -0
  170. package/src/tests/titan-chatbot-ui/chatbot-restart-dialog.shared-tests.tsx +91 -0
  171. package/src/tests/titan-chatbot-ui/chatbot-restart-link.shared-tests.tsx +116 -0
  172. package/src/tests/titan-chatbot-ui/chatbot-session-feedback-modal.shared-tests.tsx +182 -0
  173. package/src/tests/titan-chatbot-ui/chatbot-titan-chatbot.shared-tests.tsx +221 -0
  174. package/src/tests/titan-chatbot-ui/chatbot.shared-tests.tsx +158 -0
  175. package/src/utils/chat-ui-selectors.ts +24 -0
  176. package/src/utils/test-utils-chatbot.tsx +73 -0
  177. package/src/utils/test-utils.tsx +52 -0
  178. package/tsconfig.tsbuildinfo +1 -1
@@ -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
+ 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 MessageTimeoutProps {
14
+ onResume: () => void;
15
+ onReset: () => void;
16
+ }
17
+
18
+ export function runMessageTimeoutSharedTests(MessageTimeoutComponent: FC<MessageTimeoutProps>) {
19
+ let container: Container;
20
+ let chatUiStore: IChatUiStore;
21
+ let chatUiBackendStore: IChatUiBackendStore;
22
+
23
+ beforeEach(() => {
24
+ container = testInitContainer();
25
+ chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
26
+ chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
27
+ cy.viewport(800, 800);
28
+ });
29
+
30
+ const render = (onResume?: () => void, onReset?: () => void, onAfterInit?: () => void) =>
31
+ cy
32
+ .wrap(null)
33
+ .then(() =>
34
+ testRenderWrapper(
35
+ chatUiStore,
36
+ chatUiBackendStore,
37
+ <MessageTimeoutComponent
38
+ onResume={onResume ?? cy.spy().as('onResume')}
39
+ onReset={onReset ?? cy.spy().as('onReset')}
40
+ />,
41
+ onAfterInit
42
+ )
43
+ );
44
+
45
+ it('should render timeout message with proper text content', () => {
46
+ render();
47
+
48
+ ChatUiSelectors.chatMessageTimeout.should('be.visible');
49
+ ChatUiSelectors.chatMessageTimeout.should('contain.text', 'Your session has timed out.');
50
+ ChatUiSelectors.chatMessageTimeout.should(
51
+ 'contain.text',
52
+ 'Would you like to resume it or start a new one?'
53
+ );
54
+ });
55
+
56
+ it('should render resume and reset links', () => {
57
+ render();
58
+
59
+ ChatUiSelectors.chatMessageTimeoutResume
60
+ .should('be.visible')
61
+ .should('contain.text', 'Continue session');
62
+
63
+ ChatUiSelectors.chatMessageTimeoutReset
64
+ .should('be.visible')
65
+ .should('contain.text', 'Start new session');
66
+ });
67
+
68
+ it('should call onResume when continue session link is clicked', () => {
69
+ const onResume = cy.spy().as('onResume');
70
+ render(onResume);
71
+
72
+ ChatUiSelectors.chatMessageTimeoutResume.click();
73
+ cy.get('@onResume').should('have.been.calledOnce');
74
+ });
75
+
76
+ it('should call onReset when start new session link is clicked', () => {
77
+ const onReset = cy.spy().as('onReset');
78
+ render(undefined, onReset);
79
+
80
+ ChatUiSelectors.chatMessageTimeoutReset.click();
81
+ cy.get('@onReset').should('have.been.calledOnce');
82
+ });
83
+
84
+ it('should handle both callbacks being provided', () => {
85
+ const onResume = cy.spy().as('onResume');
86
+ const onReset = cy.spy().as('onReset');
87
+ render(onResume, onReset);
88
+
89
+ ChatUiSelectors.chatMessageTimeoutResume.click();
90
+ cy.get('@onResume').should('have.been.calledOnce');
91
+ cy.get('@onReset').should('not.have.been.called');
92
+
93
+ ChatUiSelectors.chatMessageTimeoutReset.click();
94
+ cy.get('@onReset').should('have.been.calledOnce');
95
+ cy.get('@onResume').should('have.been.calledOnce');
96
+ });
97
+
98
+ it('should have proper data-cy attributes', () => {
99
+ render();
100
+
101
+ ChatUiSelectors.chatMessageTimeout.should(
102
+ 'have.attr',
103
+ 'data-cy',
104
+ 'titan-chat-message-timeout'
105
+ );
106
+ ChatUiSelectors.chatMessageTimeoutResume.should(
107
+ 'have.attr',
108
+ 'data-cy',
109
+ 'titan-chat-message-timeout-resume'
110
+ );
111
+ ChatUiSelectors.chatMessageTimeoutReset.should(
112
+ 'have.attr',
113
+ 'data-cy',
114
+ 'titan-chat-message-timeout-reset'
115
+ );
116
+ });
117
+ }
@@ -0,0 +1,92 @@
1
+ import { Container } from '@servicetitan/react-ioc';
2
+ import {
3
+ CHAT_UI_BACKEND_STORE_TOKEN,
4
+ CHAT_UI_STORE_TOKEN,
5
+ ChatParticipantIcon,
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 MessageTypingProps {
15
+ avatar: {
16
+ name: string;
17
+ icon: ChatParticipantIcon;
18
+ className?: string;
19
+ };
20
+ }
21
+
22
+ export function runMessageTypingSharedTests(MessageTypingComponent: FC<MessageTypingProps>) {
23
+ let container: Container;
24
+ let chatUiStore: IChatUiStore;
25
+ let chatUiBackendStore: IChatUiBackendStore;
26
+
27
+ beforeEach(() => {
28
+ container = testInitContainer();
29
+ chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
30
+ chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
31
+ cy.viewport(800, 800);
32
+ });
33
+
34
+ const render = (icon: ChatParticipantIcon, onAfterInit?: () => void) =>
35
+ cy.wrap(null).then(() =>
36
+ testRenderWrapper(
37
+ chatUiStore,
38
+ chatUiBackendStore,
39
+ <MessageTypingComponent
40
+ avatar={{
41
+ name: 'Test User Name',
42
+ icon,
43
+ className: 'custom-class',
44
+ }}
45
+ />,
46
+ onAfterInit
47
+ )
48
+ );
49
+
50
+ it('should render typing message with proper structure', () => {
51
+ render(ChatParticipantIcon.Bot);
52
+
53
+ ChatUiSelectors.chatMessageTyping.should('be.visible').children().should('have.length', 2);
54
+ ChatUiSelectors.chatMessageTypingDots.should('be.visible');
55
+ });
56
+
57
+ it('should render typing message with user icon', () => {
58
+ render(ChatParticipantIcon.Initials);
59
+
60
+ ChatUiSelectors.chatMessageTyping.should('be.visible');
61
+ ChatUiSelectors.chatMessageTypingDots.should('be.visible');
62
+ });
63
+
64
+ it('should render typing message with agent icon', () => {
65
+ render(ChatParticipantIcon.Bot);
66
+
67
+ ChatUiSelectors.chatMessageTyping.should('be.visible');
68
+ ChatUiSelectors.chatMessageTypingDots.should('be.visible');
69
+ });
70
+
71
+ it('should render typing message with empty icon', () => {
72
+ render(ChatParticipantIcon.Empty);
73
+
74
+ ChatUiSelectors.chatMessageTyping.should('be.visible');
75
+ ChatUiSelectors.chatMessageTypingDots.should('be.visible');
76
+ });
77
+
78
+ it('should have proper data-cy attributes', () => {
79
+ render(ChatParticipantIcon.Bot);
80
+
81
+ ChatUiSelectors.chatMessageTyping.should(
82
+ 'have.attr',
83
+ 'data-cy',
84
+ 'titan-chat-message-typing'
85
+ );
86
+ ChatUiSelectors.chatMessageTypingDots.should(
87
+ 'have.attr',
88
+ 'data-cy',
89
+ 'titan-chat-message-typing-dots'
90
+ );
91
+ });
92
+ }
@@ -0,0 +1,138 @@
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, ReactNode } from 'react';
10
+ import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
11
+ import { testInitContainer, testRenderWrapper } from '../../utils/test-utils';
12
+
13
+ interface MessageUserProps {
14
+ children?: ReactNode;
15
+ messageFooter?: ReactNode;
16
+ isError?: boolean;
17
+ className?: string;
18
+ }
19
+
20
+ export function runMessageUserSharedTests(
21
+ MessageUserComponent: FC<MessageUserProps>,
22
+ TextComponent: FC<any>
23
+ ) {
24
+ let container: Container;
25
+ let chatUiStore: IChatUiStore;
26
+ let chatUiBackendStore: IChatUiBackendStore;
27
+
28
+ beforeEach(() => {
29
+ container = testInitContainer();
30
+ chatUiStore = container.get<IChatUiStore>(CHAT_UI_STORE_TOKEN);
31
+ chatUiBackendStore = container.get<ChatUiBackendEchoStore>(CHAT_UI_BACKEND_STORE_TOKEN);
32
+ cy.viewport(800, 800);
33
+ });
34
+
35
+ const render = (
36
+ children?: ReactNode,
37
+ messageFooter?: ReactNode,
38
+ isError?: boolean,
39
+ className?: string,
40
+ onAfterInit?: () => void
41
+ ) =>
42
+ cy.wrap(null).then(() =>
43
+ testRenderWrapper(
44
+ chatUiStore,
45
+ chatUiBackendStore,
46
+ <MessageUserComponent
47
+ messageFooter={messageFooter}
48
+ isError={isError}
49
+ className={className}
50
+ >
51
+ {children}
52
+ </MessageUserComponent>,
53
+ onAfterInit
54
+ )
55
+ );
56
+
57
+ it('should render user message with basic content', () => {
58
+ render(<TextComponent data-cy="content">message user content</TextComponent>);
59
+
60
+ ChatUiSelectors.chatMessageUser.should('be.visible');
61
+ ChatUiSelectors.chatMessageContent
62
+ .should('be.visible')
63
+ .should('contain.text', 'message user content');
64
+ });
65
+
66
+ it('should render user message with long text content', () => {
67
+ const longText = 'message user content '.repeat(100).trim();
68
+ render(<TextComponent data-cy="content">{longText}</TextComponent>);
69
+
70
+ ChatUiSelectors.chatMessageContent.should('be.visible').should('contain.text', longText);
71
+ });
72
+
73
+ it('should render user message with footer', () => {
74
+ render(
75
+ <TextComponent data-cy="content">message user content</TextComponent>,
76
+ <TextComponent>message user footer</TextComponent>
77
+ );
78
+
79
+ ChatUiSelectors.chatMessageFooter.should('be.visible');
80
+ ChatUiSelectors.chatMessageFooter.should('contain.text', 'message user footer');
81
+ });
82
+
83
+ it('should render user message with error state', () => {
84
+ render(
85
+ <TextComponent data-cy="content">error message content</TextComponent>,
86
+ undefined,
87
+ true
88
+ );
89
+
90
+ ChatUiSelectors.chatMessageUser.should('be.visible');
91
+ ChatUiSelectors.chatMessageContent.should('be.visible');
92
+ });
93
+
94
+ it('should render user message with custom className', () => {
95
+ render(
96
+ <TextComponent data-cy="content">message content</TextComponent>,
97
+ undefined,
98
+ false,
99
+ 'custom-message-class'
100
+ );
101
+
102
+ ChatUiSelectors.chatMessageUser.should('be.visible');
103
+ ChatUiSelectors.chatMessageUser.should('have.class', 'custom-message-class');
104
+ });
105
+
106
+ it('should not render footer when messageFooter is not provided', () => {
107
+ render(<TextComponent data-cy="content">message without footer</TextComponent>);
108
+
109
+ ChatUiSelectors.chatMessageUser.should('be.visible');
110
+ ChatUiSelectors.chatMessageFooter.should('not.exist');
111
+ });
112
+
113
+ it('should have proper data-cy attributes for testing', () => {
114
+ render(<TextComponent data-cy="content">test message</TextComponent>);
115
+
116
+ ChatUiSelectors.chatMessageUser.should('have.attr', 'data-cy', 'titan-chat-message-user');
117
+ ChatUiSelectors.chatMessageContent.should(
118
+ 'have.attr',
119
+ 'data-cy',
120
+ 'titan-chat-message-content'
121
+ );
122
+ });
123
+
124
+ it('should render both content and footer when both are provided', () => {
125
+ render(
126
+ <TextComponent data-cy="content">message content</TextComponent>,
127
+ <TextComponent data-cy="footer">message footer</TextComponent>
128
+ );
129
+
130
+ ChatUiSelectors.chatMessageUser.should('be.visible');
131
+ ChatUiSelectors.chatMessageContent
132
+ .should('be.visible')
133
+ .should('contain.text', 'message content');
134
+ ChatUiSelectors.chatMessageFooter
135
+ .should('be.visible')
136
+ .should('contain.text', 'message footer');
137
+ });
138
+ }
@@ -0,0 +1,164 @@
1
+ import { Container } from '@servicetitan/react-ioc';
2
+ import {
3
+ CHATBOT_API_CLIENT,
4
+ CHATBOT_UI_STORE_TOKEN,
5
+ ChatbotUiStore,
6
+ IChatbotUiStore,
7
+ ModelsMocks,
8
+ } from '@servicetitan/titan-chatbot-api';
9
+ import { FC, ReactElement } from 'react';
10
+ import { CypressMocks, testInitContainerChatbot, testRenderWrapperChatbot } from '../..';
11
+ import { ChatUiSelectors } from '../../utils/chat-ui-selectors';
12
+
13
+ interface IChatFiltersProps {
14
+ className?: string;
15
+ }
16
+
17
+ export function runChatbotFiltersSharedTests(
18
+ ChatFiltersComponent: FC<IChatFiltersProps>,
19
+ wrapperComponent?: (component: ReactElement) => ReactElement
20
+ ) {
21
+ let container: Container;
22
+ let api: CypressMocks.ChatbotApiClientMock;
23
+ let chatbotUiStore: IChatbotUiStore;
24
+
25
+ const filter = (index: number) => ChatUiSelectors.chatbotFilterButton.eq(index);
26
+ const filterOptions = (index: number) =>
27
+ ChatUiSelectors.chatbotFilterOptions.then($options =>
28
+ ChatUiSelectors.chatbotFilterOptions.eq($options.length === 1 ? 0 : index)
29
+ );
30
+ const filterContent = (index: number) => {
31
+ const selector = `[data-cy="${ChatUiSelectors.cy.chatbotFilterContent}"], [data-anvil-component="Popover"]`;
32
+ return cy
33
+ .get(selector)
34
+ .then($options => cy.get(selector).eq($options.length === 1 ? 0 : index));
35
+ };
36
+
37
+ const mockApiClient = () => {
38
+ api.postSession = cy.stub().resolves(ModelsMocks.mockSession());
39
+ api.getOptions = cy.stub().resolves(ModelsMocks.mockFrontendModel());
40
+ };
41
+
42
+ beforeEach(() => {
43
+ container = testInitContainerChatbot();
44
+ api = container.get<CypressMocks.ChatbotApiClientMock>(CHATBOT_API_CLIENT);
45
+ chatbotUiStore = container.get<ChatbotUiStore>(CHATBOT_UI_STORE_TOKEN);
46
+ mockApiClient();
47
+ cy.viewport(550, 800);
48
+ });
49
+
50
+ const render = (className?: string, onAfterInit?: () => void) => {
51
+ return cy.wrap(null).then(() => {
52
+ const component = (
53
+ <div
54
+ style={{
55
+ position: 'absolute',
56
+ bottom: '2rem',
57
+ left: '2rem',
58
+ width: 'calc(100% - 4rem)',
59
+ }}
60
+ >
61
+ <ChatFiltersComponent className={className} />
62
+ </div>
63
+ );
64
+ const wrappedComponent = wrapperComponent ? wrapperComponent(component) : component;
65
+
66
+ return testRenderWrapperChatbot(container, wrappedComponent, onAfterInit);
67
+ });
68
+ };
69
+
70
+ it('should render filters container when filters are available', () => {
71
+ render().then(() => {
72
+ chatbotUiStore.setFilters(ModelsMocks.mockFrontendModel());
73
+ });
74
+
75
+ ChatUiSelectors.chatbotFilters.should('be.visible');
76
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 1);
77
+ });
78
+
79
+ it('should not render anything when no filters are available', () => {
80
+ render().then(() => {
81
+ chatbotUiStore.setFilters(ModelsMocks.mockFrontendModelEmpty());
82
+ });
83
+
84
+ ChatUiSelectors.chatbotFilters.should('not.exist');
85
+ });
86
+
87
+ it('should apply custom className to filters container', () => {
88
+ const customClass = 'custom-filters-class';
89
+
90
+ render(customClass).then(() => {
91
+ chatbotUiStore.setFilters(ModelsMocks.mockFrontendModel());
92
+ });
93
+
94
+ ChatUiSelectors.chatbotFilters.should('have.class', customClass);
95
+ });
96
+
97
+ it('should cascade filters 1', () => {
98
+ render().then(() => {
99
+ chatbotUiStore.setFilters(ModelsMocks.mockFrontendModel());
100
+ });
101
+
102
+ filter(0).click();
103
+ filterOptions(0).within(() => {
104
+ cy.contains('Knowledge Base').should('be.visible');
105
+ cy.contains('Jarvis').should('be.visible').click();
106
+ });
107
+
108
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 2);
109
+ filter(0).should('contain.text', 'Sources');
110
+ filter(1).should('contain.text', 'Content Types').click();
111
+ filterOptions(1).within(() => {
112
+ cy.contains('Xxx').should('be.visible').click();
113
+ cy.contains('Yyy').should('be.visible').click();
114
+ cy.contains('Release Notes').should('be.visible').click();
115
+ });
116
+
117
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 2);
118
+ filter(0).should('contain.text', 'Sources1');
119
+ filter(1).should('contain.text', 'Content Types3');
120
+ });
121
+
122
+ it('should cascade filters 2', () => {
123
+ render().then(() => {
124
+ chatbotUiStore.setFilters(ModelsMocks.mockFrontendModel());
125
+ });
126
+
127
+ filter(0).click();
128
+ filterOptions(0).within(() => {
129
+ cy.contains('Knowledge Base').should('be.visible').click();
130
+ cy.contains('Jarvis').should('be.visible').click();
131
+ });
132
+
133
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 3);
134
+ filter(0).should('contain.text', 'Sources');
135
+ filter(1).should('contain.text', 'Content Types').click();
136
+ filter(2).should('contain.text', 'Product Areas');
137
+ filterOptions(1).within(() => {
138
+ cy.contains('Xxx').should('be.visible').click();
139
+ cy.contains('Yyy').should('be.visible').click();
140
+ cy.contains('FAQ').should('be.visible').click();
141
+ cy.contains('How To').should('be.visible').click();
142
+ cy.contains('Release Notes').should('be.visible').click();
143
+ });
144
+
145
+ filter(2).should('contain.text', 'Product Areas').click();
146
+ filterOptions(2).within(() => {
147
+ cy.contains('Call Booking').should('be.visible').click();
148
+ cy.contains('Marketing').should('be.visible').click();
149
+ cy.contains('Marketing Pro').should('be.visible').click();
150
+ });
151
+
152
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 3);
153
+ filter(0).should('contain.text', 'Sources2');
154
+ filter(1).should('contain.text', 'Content Types5');
155
+ filter(2).should('contain.text', 'Product Areas3');
156
+
157
+ filter(0).click();
158
+ filterContent(0).within(() => {
159
+ ChatUiSelectors.chatbotFilterNone.click();
160
+ });
161
+
162
+ ChatUiSelectors.chatbotFilterButton.should('have.length', 1);
163
+ });
164
+ }