@chat21/chat21-web-widget 5.1.34 → 5.2.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 (191) hide show
  1. package/.angular-mcp-cache/package.json +1 -0
  2. package/.cursor/angular18-accessibility-auditor-skill.md +442 -0
  3. package/.cursor/mcp.json +15 -0
  4. package/.github/workflows/playwright.yml +27 -0
  5. package/CHANGELOG.md +25 -0
  6. package/Dockerfile +4 -5
  7. package/README.md +1 -1
  8. package/angular.json +21 -3
  9. package/docs/ACCESSIBILITY-STATEMENT.md +388 -0
  10. package/docs/TILEDESK_WIDGET_ACCESSIBILITY_ALIGNMENT.md +60 -0
  11. package/docs/TILEDESK_WIDGET_ACCESSIBILITY_STATEMENT_COMPLETE.md +386 -0
  12. package/env.sample +3 -2
  13. package/mocks/voice-websocket-mock/server.cjs +245 -0
  14. package/package.json +10 -3
  15. package/playwright.config.ts +41 -0
  16. package/src/app/app.component.html +2 -2
  17. package/src/app/app.component.scss +25 -14
  18. package/src/app/app.component.spec.ts +21 -6
  19. package/src/app/app.module.ts +13 -0
  20. package/src/app/component/conversation-detail/conversation/conversation.component.html +25 -11
  21. package/src/app/component/conversation-detail/conversation/conversation.component.scss +38 -0
  22. package/src/app/component/conversation-detail/conversation/conversation.component.spec.ts +644 -75
  23. package/src/app/component/conversation-detail/conversation/conversation.component.ts +70 -2
  24. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html +25 -13
  25. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.spec.ts +123 -5
  26. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.ts +1 -0
  27. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +23 -10
  28. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +18 -0
  29. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.spec.ts +241 -149
  30. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +8 -5
  31. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.spec.ts +53 -3
  32. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +203 -110
  33. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +212 -1
  34. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.spec.ts +458 -78
  35. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +288 -76
  36. package/src/app/component/conversation-detail/conversation-header/conversation-header.component.html +113 -53
  37. package/src/app/component/conversation-detail/conversation-header/conversation-header.component.scss +12 -4
  38. package/src/app/component/conversation-detail/conversation-header/conversation-header.component.spec.ts +274 -29
  39. package/src/app/component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component.html +23 -9
  40. package/src/app/component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component.spec.ts +80 -8
  41. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.html +29 -23
  42. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.spec.ts +185 -16
  43. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.ts +34 -14
  44. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.html +46 -0
  45. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.scss +83 -0
  46. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.ts +192 -0
  47. package/src/app/component/error-alert/error-alert.component.spec.ts +65 -5
  48. package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.html +16 -7
  49. package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.scss +21 -0
  50. package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.spec.ts +89 -7
  51. package/src/app/component/form/form-builder/form-builder.component.html +1 -1
  52. package/src/app/component/form/form-builder/form-builder.component.spec.ts +163 -21
  53. package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.html +8 -4
  54. package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.scss +10 -5
  55. package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.spec.ts +90 -16
  56. package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.ts +26 -0
  57. package/src/app/component/form/inputs/form-label/form-label.component.spec.ts +45 -11
  58. package/src/app/component/form/inputs/form-radio-button/form-radio-button.component.spec.ts +24 -6
  59. package/src/app/component/form/inputs/form-select/form-select.component.spec.ts +14 -5
  60. package/src/app/component/form/inputs/form-text/form-text.component.html +14 -12
  61. package/src/app/component/form/inputs/form-text/form-text.component.scss +11 -1
  62. package/src/app/component/form/inputs/form-text/form-text.component.spec.ts +113 -17
  63. package/src/app/component/form/inputs/form-text/form-text.component.ts +35 -3
  64. package/src/app/component/form/inputs/form-textarea/form-textarea.component.html +13 -11
  65. package/src/app/component/form/inputs/form-textarea/form-textarea.component.scss +6 -5
  66. package/src/app/component/form/inputs/form-textarea/form-textarea.component.spec.ts +149 -13
  67. package/src/app/component/form/inputs/form-textarea/form-textarea.component.ts +26 -0
  68. package/src/app/component/form/prechat-form/prechat-form.component.html +14 -11
  69. package/src/app/component/form/prechat-form/prechat-form.component.spec.ts +102 -10
  70. package/src/app/component/form/prechat-form/prechat-form.component.ts +8 -1
  71. package/src/app/component/form/prechat-form-test-mock.ts +35 -0
  72. package/src/app/component/home/home.component.html +38 -31
  73. package/src/app/component/home/home.component.scss +4 -2
  74. package/src/app/component/home/home.component.spec.ts +226 -11
  75. package/src/app/component/home-conversations/home-conversations.component.html +30 -26
  76. package/src/app/component/home-conversations/home-conversations.component.scss +3 -0
  77. package/src/app/component/home-conversations/home-conversations.component.spec.ts +212 -36
  78. package/src/app/component/last-message/last-message.component.html +15 -9
  79. package/src/app/component/last-message/last-message.component.scss +16 -2
  80. package/src/app/component/last-message/last-message.component.spec.ts +204 -23
  81. package/src/app/component/launcher-button/launcher-button.component.html +8 -13
  82. package/src/app/component/launcher-button/launcher-button.component.spec.ts +104 -8
  83. package/src/app/component/list-all-conversations/list-all-conversations.component.html +12 -17
  84. package/src/app/component/list-all-conversations/list-all-conversations.component.scss +2 -0
  85. package/src/app/component/list-conversations/list-conversations.component.html +22 -22
  86. package/src/app/component/menu-options/menu-options.component.html +30 -20
  87. package/src/app/component/menu-options/menu-options.component.spec.ts +125 -9
  88. package/src/app/component/message/audio/audio.component.html +13 -15
  89. package/src/app/component/message/audio/audio.component.spec.ts +140 -5
  90. package/src/app/component/message/audio/audio.component.ts +1 -5
  91. package/src/app/component/message/audio-sync/audio-sync.component.html +18 -0
  92. package/src/app/component/message/audio-sync/audio-sync.component.scss +65 -0
  93. package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +112 -0
  94. package/src/app/component/message/audio-sync/audio-sync.component.ts +714 -0
  95. package/src/app/component/message/avatar/avatar.component.html +2 -2
  96. package/src/app/component/message/avatar/avatar.component.spec.ts +99 -7
  97. package/src/app/component/message/bubble-message/bubble-message.component.html +41 -51
  98. package/src/app/component/message/bubble-message/bubble-message.component.scss +54 -1
  99. package/src/app/component/message/bubble-message/bubble-message.component.spec.ts +147 -57
  100. package/src/app/component/message/bubble-message/bubble-message.component.ts +95 -13
  101. package/src/app/component/message/buttons/action-button/action-button.component.html +3 -4
  102. package/src/app/component/message/buttons/action-button/action-button.component.spec.ts +49 -5
  103. package/src/app/component/message/buttons/link-button/link-button.component.scss +5 -8
  104. package/src/app/component/message/buttons/link-button/link-button.component.spec.ts +50 -5
  105. package/src/app/component/message/buttons/text-button/text-button.component.spec.ts +44 -5
  106. package/src/app/component/message/carousel/carousel.component.html +29 -16
  107. package/src/app/component/message/carousel/carousel.component.scss +20 -8
  108. package/src/app/component/message/carousel/carousel.component.spec.ts +80 -3
  109. package/src/app/component/message/carousel/carousel.component.ts +16 -0
  110. package/src/app/component/message/frame/frame.component.html +9 -4
  111. package/src/app/component/message/frame/frame.component.spec.ts +34 -15
  112. package/src/app/component/message/frame/frame.component.ts +7 -2
  113. package/src/app/component/message/html/html.component.html +1 -1
  114. package/src/app/component/message/html/html.component.scss +1 -1
  115. package/src/app/component/message/html/html.component.spec.ts +24 -7
  116. package/src/app/component/message/image/image.component.html +12 -10
  117. package/src/app/component/message/image/image.component.scss +16 -0
  118. package/src/app/component/message/image/image.component.spec.ts +101 -15
  119. package/src/app/component/message/image/image.component.ts +90 -51
  120. package/src/app/component/message/info-message/info-message.component.spec.ts +26 -14
  121. package/src/app/component/message/json-sources/json-sources.component.html +6 -5
  122. package/src/app/component/message/json-sources/json-sources.component.scss +26 -18
  123. package/src/app/component/message/json-sources/json-sources.component.ts +41 -0
  124. package/src/app/component/message/like-unlike/like-unlike.component.html +7 -9
  125. package/src/app/component/message/like-unlike/like-unlike.component.spec.ts +31 -3
  126. package/src/app/component/message/return-receipt/return-receipt.component.spec.ts +38 -17
  127. package/src/app/component/message/text/text.component.html +3 -3
  128. package/src/app/component/message/text/text.component.scss +80 -86
  129. package/src/app/component/message/text/text.component.spec.ts +106 -13
  130. package/src/app/component/message-attachment/message-attachment.component.spec.ts +134 -13
  131. package/src/app/component/selection-department/selection-department.component.html +21 -23
  132. package/src/app/component/selection-department/selection-department.component.spec.ts +159 -14
  133. package/src/app/component/selection-department/selection-department.component.ts +8 -1
  134. package/src/app/component/send-button/send-button.component.html +5 -13
  135. package/src/app/component/send-button/send-button.component.spec.ts +2 -2
  136. package/src/app/component/star-rating-widget/star-rating-widget.component.html +51 -81
  137. package/src/app/directives/tooltip.directive.spec.ts +8 -4
  138. package/src/app/modals/confirm-close/confirm-close.component.html +20 -8
  139. package/src/app/modals/confirm-close/confirm-close.component.scss +3 -0
  140. package/src/app/modals/confirm-close/confirm-close.component.spec.ts +13 -4
  141. package/src/app/modals/confirm-close/confirm-close.component.ts +8 -1
  142. package/src/app/pipe/html-entites-encode.pipe.spec.ts +35 -2
  143. package/src/app/pipe/marked.pipe.spec.ts +38 -2
  144. package/src/app/pipe/marked.pipe.ts +51 -41
  145. package/src/app/providers/app-config.service.ts +4 -2
  146. package/src/app/providers/brand.service.spec.ts +23 -2
  147. package/src/app/providers/brand.service.ts +1 -1
  148. package/src/app/providers/global-settings.service.spec.ts +1009 -14
  149. package/src/app/providers/global-settings.service.ts +40 -2
  150. package/src/app/providers/json-sources-parser.service.ts +13 -1
  151. package/src/app/providers/translator.service.ts +24 -7
  152. package/src/app/providers/tts-audio-playback-coordinator.service.spec.ts +116 -0
  153. package/src/app/providers/tts-audio-playback-coordinator.service.ts +122 -0
  154. package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +12 -0
  155. package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +156 -0
  156. package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +39 -0
  157. package/src/app/providers/voice/audio.types.ts +40 -0
  158. package/src/app/providers/voice/vad.service.spec.ts +28 -0
  159. package/src/app/providers/voice/vad.service.ts +70 -0
  160. package/src/app/providers/voice/voice-streaming.service.spec.ts +23 -0
  161. package/src/app/providers/voice/voice-streaming.service.ts +702 -0
  162. package/src/app/providers/voice/voice-streaming.types.ts +112 -0
  163. package/src/app/providers/voice/voice.service.spec.ts +227 -0
  164. package/src/app/providers/voice/voice.service.ts +969 -0
  165. package/src/app/sass/_variables.scss +2 -0
  166. package/src/app/sass/animations.scss +19 -1
  167. package/src/app/shims/onnxruntime-web-wasm.ts +4 -0
  168. package/src/app/utils/globals.ts +14 -0
  169. package/src/app/utils/utils-resources.ts +1 -1
  170. package/src/assets/i18n/en.json +128 -100
  171. package/src/assets/i18n/es.json +128 -100
  172. package/src/assets/i18n/fr.json +128 -100
  173. package/src/assets/i18n/it.json +128 -98
  174. package/src/assets/onnx/ort-wasm-simd-threaded.mjs +59 -0
  175. package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
  176. package/src/assets/sounds/keyboard.mp3 +0 -0
  177. package/src/assets/vad/silero_vad_legacy.onnx +0 -0
  178. package/src/assets/vad/vad.worklet.bundle.min.js +1 -0
  179. package/src/chat21-core/models/message.ts +2 -1
  180. package/src/chat21-core/providers/chat-manager.spec.ts +72 -0
  181. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +3 -2
  182. package/src/chat21-core/providers/firebase/firebase-init-service.ts +5 -5
  183. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +12 -0
  184. package/src/chat21-core/providers/scripts/script.service.spec.ts +12 -2
  185. package/src/chat21-core/utils/utils-message.ts +7 -0
  186. package/src/widget-config-template.json +3 -1
  187. package/src/widget-config.json +28 -27
  188. package/tests/widget-form-rich.spec.ts +67 -0
  189. package/tests/widget-index-dev-settings.spec.ts +52 -0
  190. package/tests/widget-twp-iframe.spec.ts +39 -0
  191. package/tsconfig.json +5 -0
@@ -0,0 +1,72 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { CustomLogger } from './logger/customLogger';
4
+ import { LoggerInstance } from './logger/loggerInstance';
5
+ import { ChatManager } from './chat-manager';
6
+ import { ArchivedConversationsHandlerService } from './abstract/archivedconversations-handler.service';
7
+ import { ConversationsHandlerService } from './abstract/conversations-handler.service';
8
+ import { ConversationHandlerService } from './abstract/conversation-handler.service';
9
+
10
+ describe('ChatManager', () => {
11
+ let convHandler: jasmine.SpyObj<ConversationsHandlerService>;
12
+ let archivedHandler: jasmine.SpyObj<ArchivedConversationsHandlerService>;
13
+
14
+ beforeEach(() => {
15
+ const ngxlogger = jasmine.createSpyObj('NGXLogger', ['log', 'trace', 'debug', 'warn', 'error', 'info']);
16
+ LoggerInstance.setInstance(new CustomLogger(ngxlogger));
17
+ convHandler = jasmine.createSpyObj('ConversationsHandlerService', ['dispose']);
18
+ archivedHandler = jasmine.createSpyObj('ArchivedConversationsHandlerService', ['dispose']);
19
+
20
+ TestBed.configureTestingModule({
21
+ providers: [
22
+ ChatManager,
23
+ { provide: ConversationsHandlerService, useValue: convHandler },
24
+ { provide: ArchivedConversationsHandlerService, useValue: archivedHandler },
25
+ ],
26
+ });
27
+ });
28
+
29
+ it('should initialize and track token and user', () => {
30
+ const mgr = TestBed.inject(ChatManager);
31
+
32
+ mgr.initialize();
33
+ expect(mgr.getOpenInfoConversation()).toBeTrue();
34
+
35
+ mgr.setTiledeskToken('tok');
36
+ expect(mgr.getTiledeskToken()).toBe('tok');
37
+
38
+ const user = { uid: 'u1' } as any;
39
+ mgr.setCurrentUser(user);
40
+ expect(mgr.getCurrentUser()).toBe(user);
41
+ });
42
+
43
+ it('startApp should emit on BSStart', () => {
44
+ const mgr = TestBed.inject(ChatManager);
45
+ const user = { uid: 'u1' } as any;
46
+ mgr.setCurrentUser(user);
47
+ mgr.startApp();
48
+ expect(mgr.BSStart.getValue()).toBe(user);
49
+ });
50
+
51
+ it('should add and find conversation handler', () => {
52
+ const mgr = TestBed.inject(ChatManager);
53
+ mgr.initialize();
54
+
55
+ const h = { conversationWith: 'cid-1' } as ConversationHandlerService;
56
+ mgr.addConversationHandler(h);
57
+
58
+ expect(mgr.getConversationHandlerByConversationId('cid-1')).toBe(h);
59
+ });
60
+
61
+ it('goOffLine should clear user and dispose handlers', () => {
62
+ const mgr = TestBed.inject(ChatManager);
63
+ mgr.initialize();
64
+ mgr.setArchivedConversationsHandler(archivedHandler);
65
+ mgr.setConversationsHandler(convHandler);
66
+ mgr.goOffLine();
67
+
68
+ expect(mgr.getCurrentUser()).toBeNull();
69
+ expect(convHandler.dispose).toHaveBeenCalled();
70
+ expect(archivedHandler.dispose).toHaveBeenCalled();
71
+ });
72
+ });
@@ -253,9 +253,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
253
253
  }
254
254
  }
255
255
 
256
-
257
256
 
258
-
259
257
  this.addRepalceMessageInArray(msg.uid, msg);
260
258
  this.messageAdded.next(msg);
261
259
  } else {
@@ -494,6 +492,9 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
494
492
  commands[i+1]? commands[i+1].time = 0 : null
495
493
  }
496
494
  }
495
+
496
+ command.message.isJustRecived = isJustRecived( that.startTime.getTime(), msg.timestamp );
497
+
497
498
  that.generateMessageObject(msg, command.message, function () {
498
499
  i += 1
499
500
  if (i < commands.length) {
@@ -14,7 +14,7 @@ import { Injectable } from '@angular/core';
14
14
  export class FirebaseInitService {
15
15
 
16
16
  public static firebaseInit: any;
17
-
17
+
18
18
  constructor() {
19
19
  }
20
20
 
@@ -22,10 +22,10 @@ export class FirebaseInitService {
22
22
  const { default: firebase} = await import("firebase/app");
23
23
  if(!FirebaseInitService.firebaseInit){
24
24
  if (!firebaseConfig || firebaseConfig.apiKey === 'CHANGEIT') {
25
- throw new Error('Firebase config is not defined. Please create your widget-config.json. See the Chat21-Web_widget Installation Page');
26
- }
27
- FirebaseInitService.firebaseInit = firebase.initializeApp(firebaseConfig);
25
+ throw new Error('Firebase config is not defined. Please create your widget-config-aws-stage.json. See the Chat21-Web_widget Installation Page');
26
+ }
27
+ FirebaseInitService.firebaseInit = firebase.initializeApp(firebaseConfig);
28
28
  }
29
29
  return FirebaseInitService.firebaseInit
30
30
  }
31
- }
31
+ }
@@ -273,6 +273,16 @@ export class MQTTConversationHandler extends ConversationHandlerService {
273
273
  if(isInfoMessage){
274
274
  this.messageInfo.next(msg)
275
275
  }
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
276
286
 
277
287
  if(isInfoMessage && hideInfoMessage(msg, this.showInfoMessage)){
278
288
  //if showBubbleInfoMessage array keys not includes msg.attributes.messagelabel['key'] exclude CURRENT INFO MESSAGE
@@ -492,6 +502,8 @@ export class MQTTConversationHandler extends ConversationHandlerService {
492
502
  }
493
503
  }
494
504
 
505
+ command.message.isJustRecived = isJustRecived( that.startTime.getTime(), msg.timestamp );
506
+
495
507
  that.generateMessageObject(msg, command.message, i, function () {
496
508
  i += 1
497
509
  if (i < commands.length) {
@@ -1,12 +1,22 @@
1
+ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
2
+ import { provideHttpClientTesting } from '@angular/common/http/testing';
1
3
  import { TestBed } from '@angular/core/testing';
2
4
 
3
5
  import { ScriptService } from './script.service';
4
6
 
5
7
  describe('ScriptService', () => {
6
- beforeEach(() => TestBed.configureTestingModule({}));
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({
10
+ providers: [
11
+ ScriptService,
12
+ provideHttpClient(withInterceptorsFromDi()),
13
+ provideHttpClientTesting(),
14
+ ],
15
+ });
16
+ });
7
17
 
8
18
  it('should be created', () => {
9
- const service: ScriptService = TestBed.get(ScriptService);
19
+ const service = TestBed.inject(ScriptService);
10
20
  expect(service).toBeTruthy();
11
21
  });
12
22
  });
@@ -50,6 +50,13 @@ export function isAudio(message: any) {
50
50
  return false;
51
51
  }
52
52
 
53
+ export function isAudioTTS(message: any) {
54
+ if (message && message.type && message.type === 'tts' && message.metadata && message.metadata.src && message.metadata.type.includes('audio') ) {
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+
53
60
  export function isJsonSources(message: any) {
54
61
  if (message && message.type && message.type === 'url_preview') {
55
62
  return true;
@@ -24,5 +24,7 @@
24
24
  "dashboardUrl": "${DASHBOARD_URL}",
25
25
  "authPersistence": "${AUTH_PERSISTENCE}",
26
26
  "enbedJs": "${ENBED_JS}",
27
- "brandSrc": "${BRAND_SRC}"
27
+ "brandSrc": "${BRAND_SRC}",
28
+ "voiceProxyWsUrl": "${VOICE_PROXY_WS_URL}",
29
+ "voiceProxyApiBaseUrl": "${VOICE_PROXY_API_BASE_URL}"
28
30
  }
@@ -1,29 +1,30 @@
1
1
  {
2
- "chatEngine": "mqtt",
3
- "uploadEngine": "native",
4
- "pushEngine":"none",
5
- "logLevel":"INFO",
6
- "remoteTranslationsUrl": "http://localhost:3000/",
7
- "firebaseConfig": {
8
- "apiKey": "CHANGEIT",
9
- "authDomain": "CHANGEIT",
10
- "databaseURL": "CHANGEIT",
11
- "projectId": "CHANGEIT",
12
- "storageBucket": "CHANGEIT",
13
- "messagingSenderId": "CHANGEIT",
14
- "appId": "CHANGEIT",
15
- "tenant": "CHANGEIT"
16
- },
17
- "chat21Config": {
18
- "appId": "tilechat",
19
- "MQTTendpoint": "ws://localhost:15675/ws",
20
- "APIendpoint": "http://localhost:8004/api"
21
- },
22
- "apiUrl": "http://localhost:3000/",
23
- "baseImageUrl": "http://localhost:3000/",
24
- "dashboardUrl": "http://localhost:4500/",
25
- "authPersistence": "LOCAL",
26
- "enbedJs": true,
27
- "brandSrc": "${BRAND_SRC}"
28
-
2
+ "chatEngine": "mqtt",
3
+ "uploadEngine": "native",
4
+ "pushEngine": "none",
5
+ "logLevel": "info" ,
6
+ "remoteTranslationsUrl": "http://localhost:3000/api/",
7
+ "firebaseConfig": {
8
+ "apiKey": "CHANGEIT",
9
+ "authDomain": "CHANGEIT.firebaseapp.com",
10
+ "databaseURL": "https://CHANGEIT.firebaseio.com",
11
+ "projectId": "CHANGEIT",
12
+ "storageBucket": "CHANGEIT.appspot.com",
13
+ "messagingSenderId": "CHANGEIT",
14
+ "appId": "",
15
+ "tenant": "tilechat"
16
+ },
17
+ "chat21Config": {
18
+ "appId": "tilechat",
19
+ "MQTTendpoint": "ws://localhost:15672/mqws/ws",
20
+ "APIendpoint": "http://localhost:3001/chatapi/api"
21
+ },
22
+ "apiUrl": "http://localhost:3000/api/",
23
+ "baseImageUrl": "http://localhost:3000/api/",
24
+ "dashboardUrl": "/dashboard/",
25
+ "authPersistence": "LOCAL",
26
+ "enbedJs": "true",
27
+ "brandSrc": "",
28
+ "voiceProxyWsBaseUrl": "ws://localhost:3000/ws/voice",
29
+ "voiceProxyApiBaseUrl": "http://localhost:3000/api"
29
30
  }
@@ -0,0 +1,67 @@
1
+ import { test, expect, type Page } from '@playwright/test';
2
+
3
+ const BASE_QUERY =
4
+ 'tiledesk_projectid=65c5f17ab4e95a0013a0181a&tiledesk_isLogEnabled=true&tiledesk_open=true';
5
+
6
+ function widgetFrame(page: Page) {
7
+ return page.frameLocator('#tiledeskiframe');
8
+ }
9
+
10
+ test.describe('Widget TWP — form / testi / allegati / reparti', () => {
11
+ test.beforeEach(({ page }) => {
12
+ page.setDefaultNavigationTimeout(120_000);
13
+ });
14
+
15
+ test('dopo nuova conversazione compare conversazione, prechat o selezione reparto', async ({ page }) => {
16
+ await page.goto(`/assets/twp/index.html?${BASE_QUERY}`);
17
+ await expect(page.locator('#tiledeskiframe')).toBeAttached({ timeout: 120_000 });
18
+ const w = widgetFrame(page);
19
+ await w.locator('#c21-app-list-conversations .c21-button-primary').first().click({ timeout: 120_000 });
20
+ await expect(
21
+ w.locator('chat-conversation, chat-selection-department, chat-prechat-form').first(),
22
+ ).toBeVisible({ timeout: 120_000 });
23
+ });
24
+
25
+ test('se compare la modale reparti, elenco pulsanti e click impostano flusso', async ({ page }) => {
26
+ await page.goto(`/assets/twp/index.html?${BASE_QUERY}`);
27
+ const w = widgetFrame(page);
28
+ await w.locator('#c21-app-list-conversations .c21-button-primary').first().click({ timeout: 120_000 });
29
+ const panel = w.locator('#chat21-selection-department');
30
+ try {
31
+ await panel.waitFor({ state: 'visible', timeout: 25_000 });
32
+ } catch {
33
+ test.skip();
34
+ }
35
+ await expect(panel).toHaveAttribute('role', 'dialog');
36
+ const deptButtons = panel.locator('.c21-button-department');
37
+ await expect(deptButtons.first()).toBeVisible();
38
+ const count = await deptButtons.count();
39
+ expect(count).toBeGreaterThan(0);
40
+ await deptButtons.first().click();
41
+ await expect(w.locator('chat-conversation').first()).toBeAttached({ timeout: 120_000 });
42
+ });
43
+
44
+ test('con prechat attivato da URL può comparire textarea o form (best-effort)', async ({ page }) => {
45
+ await page.goto(`/assets/twp/index.html?${BASE_QUERY}&tiledesk_preChatForm=true`);
46
+ const w = widgetFrame(page);
47
+ await w.locator('#c21-app-list-conversations .c21-button-primary').first().click({ timeout: 120_000 });
48
+ const prechat = w.locator('chat-prechat-form');
49
+ const textarea = w.locator('textarea#c21-prechat-notes, textarea.form-control, chat-form-textarea textarea');
50
+ await expect(prechat.or(textarea.first())).toBeVisible({ timeout: 120_000 });
51
+ });
52
+
53
+ test('messaggio in conversazione: area testo o bubble visibile nel frame', async ({ page }) => {
54
+ await page.goto(`/assets/twp/index.html?${BASE_QUERY}`);
55
+ const w = widgetFrame(page);
56
+ await w.locator('#c21-app-list-conversations .c21-button-primary').first().click({ timeout: 120_000 });
57
+ await expect(
58
+ w.locator('chat-conversation, chat-prechat-form, chat-selection-department').first(),
59
+ ).toBeVisible({ timeout: 120_000 });
60
+ const conv = w.locator('chat-conversation');
61
+ if (await conv.isVisible().catch(() => false)) {
62
+ await expect(
63
+ conv.locator('.message_innerhtml, chat-text, textarea, [contenteditable]').first(),
64
+ ).toBeVisible({ timeout: 60_000 });
65
+ }
66
+ });
67
+ });
@@ -0,0 +1,52 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ /**
4
+ * Pagina dev: campi testo + pulsante "Test this setting" chiamano onClick* e scrivono su window.tiledeskSettings.
5
+ * Verifica che i valori fake restino coerenti con quanto impostato nel codice inline della pagina.
6
+ */
7
+ test.describe('index-dev.html tiledeskSettings da input', () => {
8
+ test.beforeEach(({ page }) => {
9
+ page.setDefaultNavigationTimeout(120_000);
10
+ });
11
+
12
+ test('marginX / marginY / welcomeTitle aggiornano window.tiledeskSettings', async ({ page }) => {
13
+ await page.goto(
14
+ 'http://127.0.0.1:4203/assets/twp/index-dev.html?tiledesk_projectid=65c5f17ab4e95a0013a0181a&tiledesk_isLogEnabled=true',
15
+ );
16
+ const out = await page.evaluate(() => {
17
+ const mx = document.querySelector('#marginX') as HTMLInputElement;
18
+ const my = document.querySelector('#marginY') as HTMLInputElement;
19
+ const wt = document.querySelector('#welcomeTitle') as HTMLInputElement;
20
+ mx.value = '11px';
21
+ my.value = '22px';
22
+ wt.value = 'Titolo fake';
23
+ (window as any).onClickMarginX();
24
+ (window as any).onClickMarginY();
25
+ (window as any).onClickWelcomeTitle();
26
+ const s = (window as any).tiledeskSettings;
27
+ return { marginX: s.marginX, marginY: s.marginY, welcomeTitle: s.welcomeTitle };
28
+ });
29
+ expect(out.marginX).toBe('11px');
30
+ expect(out.marginY).toBe('22px');
31
+ expect(out.welcomeTitle).toBe('Titolo fake');
32
+ });
33
+
34
+ test('calloutTitle / widgetTitle / departmentID aggiornano tiledeskSettings', async ({ page }) => {
35
+ await page.goto(
36
+ 'http://127.0.0.1:4203/assets/twp/index-dev.html?tiledesk_projectid=65c5f17ab4e95a0013a0181a&tiledesk_isLogEnabled=true',
37
+ );
38
+ const out = await page.evaluate(() => {
39
+ (document.querySelector('#calloutTitle') as HTMLInputElement).value = 'Callout FAKE';
40
+ (document.querySelector('#widgetTitle') as HTMLInputElement).value = 'Widget FAKE';
41
+ (document.querySelector('#departmentID') as HTMLInputElement).value = 'dep-xyz';
42
+ (window as any).onClickCalloutTitle();
43
+ (window as any).onClickWidgetTitle();
44
+ (window as any).onClickDepartmentId();
45
+ const s = (window as any).tiledeskSettings;
46
+ return { calloutTitle: s.calloutTitle, widgetTitle: s.widgetTitle, departmentID: s.departmentID };
47
+ });
48
+ expect(out.calloutTitle).toBe('Callout FAKE');
49
+ expect(out.widgetTitle).toBe('Widget FAKE');
50
+ expect(out.departmentID).toBe('dep-xyz');
51
+ });
52
+ });
@@ -0,0 +1,39 @@
1
+ import { test, expect, type Page } from '@playwright/test';
2
+
3
+ /**
4
+ * Pagina host: `src/assets/twp/index.html` carica `launch.js` e crea `#tiledeskiframe`
5
+ * (vedi `src/launch.js`). L’app Angular gira nel frame; `tiledesk_open=true` viene letto
6
+ * dal parent via `GlobalSettingsService` (`tiledesk_open` → `globals.isOpen`).
7
+ */
8
+ const TWP_QUERY =
9
+ 'tiledesk_projectid=65c5f17ab4e95a0013a0181a&tiledesk_isLogEnabled=true&tiledesk_open=true';
10
+
11
+ function widgetFrame(page: Page) {
12
+ return page.frameLocator('#tiledeskiframe');
13
+ }
14
+
15
+ test.describe('Widget TWP (host + iframe)', () => {
16
+ test.beforeEach(({ page }) => {
17
+ page.setDefaultNavigationTimeout(120_000);
18
+ });
19
+
20
+ test('mostra home e lista conversazioni nel frame con widget già aperto', async ({ page }) => {
21
+ await page.goto(`/assets/twp/index.html?${TWP_QUERY}`);
22
+ await expect(page.locator('#tiledeskiframe')).toBeAttached({ timeout: 120_000 });
23
+ const w = widgetFrame(page);
24
+ await expect(w.locator('#chat21-home-component')).toBeVisible({ timeout: 120_000 });
25
+ await expect(w.locator('#c21-app-list-conversations')).toBeVisible();
26
+ });
27
+
28
+ test('click su CTA primaria apre conversazione, reparto o prechat', async ({ page }) => {
29
+ await page.goto(`/assets/twp/index.html?${TWP_QUERY}`);
30
+ await expect(page.locator('#tiledeskiframe')).toBeAttached({ timeout: 120_000 });
31
+ const w = widgetFrame(page);
32
+ const primary = w.locator('#c21-app-list-conversations .c21-button-primary').first();
33
+ await expect(primary).toBeVisible({ timeout: 120_000 });
34
+ await primary.click();
35
+ await expect(
36
+ w.locator('chat-conversation, chat-selection-department, chat-prechat-form').first(),
37
+ ).toBeVisible({ timeout: 120_000 });
38
+ });
39
+ });
package/tsconfig.json CHANGED
@@ -23,6 +23,11 @@
23
23
  "dom"
24
24
  ],
25
25
  "resolveJsonModule": true,
26
+ "paths": {
27
+ "onnxruntime-web/wasm": [
28
+ "src/app/shims/onnxruntime-web-wasm.ts"
29
+ ]
30
+ }
26
31
  },
27
32
  "skipLibCheck": true,
28
33
  "angularCompilerOptions": {