@nyaruka/temba-components 0.129.2 → 0.129.4

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 (773) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.github/workflows/build.yml +141 -8
  3. package/CHANGELOG.md +40 -0
  4. package/README.md +6 -0
  5. package/check-coverage.js +133 -0
  6. package/demo/data/flows/sample-flow.json +158 -128
  7. package/demo/field-config-demo.html +135 -0
  8. package/dist/temba-components.js +1750 -751
  9. package/dist/temba-components.js.map +1 -1
  10. package/docs/ActionEditor-Migration.md +118 -0
  11. package/generate-coverage-badge.sh +69 -0
  12. package/out-tsc/src/{vectoricon/index.js → Icons.js} +1 -1
  13. package/out-tsc/src/Icons.js.map +1 -0
  14. package/out-tsc/src/display/Alert.js.map +1 -0
  15. package/out-tsc/src/display/Anchor.js.map +1 -0
  16. package/out-tsc/src/display/Button.js.map +1 -0
  17. package/out-tsc/src/{charcount → display}/CharCount.js +159 -2
  18. package/out-tsc/src/display/CharCount.js.map +1 -0
  19. package/out-tsc/src/display/Chat.js.map +1 -0
  20. package/out-tsc/src/display/ContactName.js.map +1 -0
  21. package/out-tsc/src/display/ContactUrn.js.map +1 -0
  22. package/out-tsc/src/display/Dropdown.js.map +1 -0
  23. package/out-tsc/src/{vectoricon/VectorIcon.js → display/Icon.js} +2 -2
  24. package/out-tsc/src/display/Icon.js.map +1 -0
  25. package/out-tsc/src/display/Label.js.map +1 -0
  26. package/out-tsc/src/{leafletmap → display}/LeafletMap.js +16 -1
  27. package/out-tsc/src/display/LeafletMap.js.map +1 -0
  28. package/out-tsc/src/display/Lightbox.js.map +1 -0
  29. package/out-tsc/src/{loading → display}/Loading.js.map +1 -1
  30. package/out-tsc/src/{options → display}/Options.js.map +1 -1
  31. package/out-tsc/src/display/ProgressBar.js.map +1 -0
  32. package/out-tsc/src/display/TembaDate.js.map +1 -0
  33. package/out-tsc/src/display/TembaUser.js.map +1 -0
  34. package/out-tsc/src/display/Thumbnail.js.map +1 -0
  35. package/out-tsc/src/{tip → display}/Tip.js +1 -2
  36. package/out-tsc/src/display/Tip.js.map +1 -0
  37. package/out-tsc/src/display/Toast.js.map +1 -0
  38. package/out-tsc/src/display/sms/gsmsplitter.js.map +1 -0
  39. package/out-tsc/src/display/sms/gsmvalidator.js.map +1 -0
  40. package/out-tsc/src/display/sms/index.js.map +1 -0
  41. package/out-tsc/src/display/sms/unicodesplitter.js.map +1 -0
  42. package/out-tsc/src/events.js +2 -0
  43. package/out-tsc/src/events.js.map +1 -0
  44. package/out-tsc/src/excellent/ExcellentParser.js.map +1 -0
  45. package/out-tsc/src/excellent/helpers.js.map +1 -0
  46. package/out-tsc/src/flow/CanvasNode.js +861 -0
  47. package/out-tsc/src/flow/CanvasNode.js.map +1 -0
  48. package/out-tsc/src/flow/Editor.js +640 -143
  49. package/out-tsc/src/flow/Editor.js.map +1 -1
  50. package/out-tsc/src/flow/NodeEditor.js +1200 -0
  51. package/out-tsc/src/flow/NodeEditor.js.map +1 -0
  52. package/out-tsc/src/flow/Plumber.js +148 -74
  53. package/out-tsc/src/flow/Plumber.js.map +1 -1
  54. package/out-tsc/src/flow/StickyNote.js +153 -9
  55. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  56. package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
  57. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
  58. package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
  59. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
  60. package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
  61. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
  62. package/out-tsc/src/flow/actions/call_classifier.js +11 -0
  63. package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
  64. package/out-tsc/src/flow/actions/call_llm.js +11 -0
  65. package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
  66. package/out-tsc/src/flow/actions/call_resthook.js +11 -0
  67. package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
  68. package/out-tsc/src/flow/actions/call_webhook.js +122 -0
  69. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
  70. package/out-tsc/src/flow/actions/enter_flow.js +14 -0
  71. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  72. package/out-tsc/src/flow/actions/open_ticket.js +11 -0
  73. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
  74. package/out-tsc/src/flow/actions/play_audio.js +11 -0
  75. package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
  76. package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
  77. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
  78. package/out-tsc/src/flow/actions/request_optin.js +11 -0
  79. package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
  80. package/out-tsc/src/flow/actions/say_msg.js +11 -0
  81. package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
  82. package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
  83. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
  84. package/out-tsc/src/flow/actions/send_email.js +56 -0
  85. package/out-tsc/src/flow/actions/send_email.js.map +1 -0
  86. package/out-tsc/src/flow/actions/send_msg.js +55 -0
  87. package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
  88. package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
  89. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
  90. package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
  91. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
  92. package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
  93. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
  94. package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
  95. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
  96. package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
  97. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
  98. package/out-tsc/src/flow/actions/set_run_result.js +10 -0
  99. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
  100. package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
  101. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
  102. package/out-tsc/src/flow/actions/start_session.js +11 -0
  103. package/out-tsc/src/flow/actions/start_session.js.map +1 -0
  104. package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
  105. package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
  106. package/out-tsc/src/flow/config.js +88 -123
  107. package/out-tsc/src/flow/config.js.map +1 -1
  108. package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
  109. package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
  110. package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
  111. package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
  112. package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
  113. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
  114. package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
  115. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
  116. package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
  117. package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
  118. package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
  119. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
  120. package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
  121. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
  122. package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
  123. package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
  124. package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
  125. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
  126. package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
  127. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
  128. package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
  129. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  130. package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
  131. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
  132. package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
  133. package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
  134. package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
  135. package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
  136. package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
  137. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
  138. package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
  139. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
  140. package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
  141. package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
  142. package/out-tsc/src/flow/types.js +79 -0
  143. package/out-tsc/src/flow/types.js.map +1 -0
  144. package/out-tsc/src/flow/utils.js +65 -0
  145. package/out-tsc/src/flow/utils.js.map +1 -0
  146. package/out-tsc/src/form/ArrayEditor.js +199 -0
  147. package/out-tsc/src/form/ArrayEditor.js.map +1 -0
  148. package/out-tsc/src/form/BaseListEditor.js +128 -0
  149. package/out-tsc/src/form/BaseListEditor.js.map +1 -0
  150. package/out-tsc/src/{checkbox → form}/Checkbox.js +19 -4
  151. package/out-tsc/src/form/Checkbox.js.map +1 -0
  152. package/out-tsc/src/{colorpicker → form}/ColorPicker.js +1 -1
  153. package/out-tsc/src/form/ColorPicker.js.map +1 -0
  154. package/out-tsc/src/{completion → form}/Completion.js +8 -2
  155. package/out-tsc/src/form/Completion.js.map +1 -0
  156. package/out-tsc/src/{compose → form}/Compose.js +1 -1
  157. package/out-tsc/src/form/Compose.js.map +1 -0
  158. package/out-tsc/src/{contactsearch → form}/ContactSearch.js +2 -2
  159. package/out-tsc/src/form/ContactSearch.js.map +1 -0
  160. package/out-tsc/src/form/CroppieCSS.js.map +1 -0
  161. package/out-tsc/src/{datepicker → form}/DatePicker.js +1 -1
  162. package/out-tsc/src/form/DatePicker.js.map +1 -0
  163. package/out-tsc/src/{FormElement.js → form/FormElement.js} +1 -1
  164. package/out-tsc/src/form/FormElement.js.map +1 -0
  165. package/out-tsc/src/form/FormField.js +243 -0
  166. package/out-tsc/src/form/FormField.js.map +1 -0
  167. package/out-tsc/src/{imagepicker → form}/ImagePicker.js +2 -2
  168. package/out-tsc/src/form/ImagePicker.js.map +1 -0
  169. package/out-tsc/src/form/KeyValueEditor.js +223 -0
  170. package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
  171. package/out-tsc/src/{mediapicker → form}/MediaPicker.js +1 -1
  172. package/out-tsc/src/form/MediaPicker.js.map +1 -0
  173. package/out-tsc/src/form/RangePicker.js.map +1 -0
  174. package/out-tsc/src/{slider → form}/TembaSlider.js +1 -1
  175. package/out-tsc/src/form/TembaSlider.js.map +1 -0
  176. package/out-tsc/src/{templates → form}/TemplateEditor.js +1 -1
  177. package/out-tsc/src/form/TemplateEditor.js.map +1 -0
  178. package/out-tsc/src/{textinput → form}/TextInput.js +3 -3
  179. package/out-tsc/src/form/TextInput.js.map +1 -0
  180. package/out-tsc/src/{omnibox → form/select}/Omnibox.js +2 -2
  181. package/out-tsc/src/form/select/Omnibox.js.map +1 -0
  182. package/out-tsc/src/{select → form/select}/PopupSelect.js +1 -1
  183. package/out-tsc/src/form/select/PopupSelect.js.map +1 -0
  184. package/out-tsc/src/{select → form/select}/Select.js +157 -113
  185. package/out-tsc/src/form/select/Select.js.map +1 -0
  186. package/out-tsc/src/{select → form/select}/UserSelect.js +1 -1
  187. package/out-tsc/src/form/select/UserSelect.js.map +1 -0
  188. package/out-tsc/src/{select → form/select}/WorkspaceSelect.js +1 -1
  189. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -0
  190. package/out-tsc/src/interfaces.js +7 -0
  191. package/out-tsc/src/interfaces.js.map +1 -1
  192. package/out-tsc/src/layout/Dialog.js.map +1 -0
  193. package/out-tsc/src/layout/Mask.js.map +1 -0
  194. package/out-tsc/src/{dialog → layout}/Modax.js.map +1 -1
  195. package/out-tsc/src/layout/Resizer.js.map +1 -0
  196. package/out-tsc/src/layout/Tab.js.map +1 -0
  197. package/out-tsc/src/layout/TabPane.js.map +1 -0
  198. package/out-tsc/src/list/NotificationList.js +1 -1
  199. package/out-tsc/src/list/NotificationList.js.map +1 -1
  200. package/out-tsc/src/list/RunList.js +1 -1
  201. package/out-tsc/src/list/RunList.js.map +1 -1
  202. package/out-tsc/src/list/ShortcutList.js.map +1 -1
  203. package/out-tsc/src/list/TembaMenu.js +1 -1
  204. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  205. package/out-tsc/src/list/TicketList.js +1 -1
  206. package/out-tsc/src/list/TicketList.js.map +1 -1
  207. package/out-tsc/src/{aliaseditor → live}/AliasEditor.js +1 -1
  208. package/out-tsc/src/live/AliasEditor.js.map +1 -0
  209. package/out-tsc/src/{contacts → live}/ContactBadges.js +1 -1
  210. package/out-tsc/src/live/ContactBadges.js.map +1 -0
  211. package/out-tsc/src/{contacts → live}/ContactChat.js +80 -78
  212. package/out-tsc/src/live/ContactChat.js.map +1 -0
  213. package/out-tsc/src/{contacts → live}/ContactDetails.js +1 -1
  214. package/out-tsc/src/live/ContactDetails.js.map +1 -0
  215. package/out-tsc/src/{contacts → live}/ContactFieldEditor.js +2 -2
  216. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -0
  217. package/out-tsc/src/live/ContactFields.js.map +1 -0
  218. package/out-tsc/src/live/ContactNameFetch.js.map +1 -0
  219. package/out-tsc/src/{contacts → live}/ContactNotepad.js +1 -1
  220. package/out-tsc/src/{contacts → live}/ContactNotepad.js.map +1 -1
  221. package/out-tsc/src/{contacts → live}/ContactPending.js +1 -1
  222. package/out-tsc/src/live/ContactPending.js.map +1 -0
  223. package/out-tsc/src/live/ContactStoreElement.js.map +1 -0
  224. package/out-tsc/src/live/FieldManager.js.map +1 -0
  225. package/out-tsc/src/live/StartProgress.js.map +1 -0
  226. package/out-tsc/src/live/TembaChart.js.map +1 -0
  227. package/out-tsc/src/store/AppState.js +54 -24
  228. package/out-tsc/src/store/AppState.js.map +1 -1
  229. package/out-tsc/src/store/Store.js +1 -1
  230. package/out-tsc/src/store/Store.js.map +1 -1
  231. package/out-tsc/src/{utils/index.js → utils.js} +22 -1
  232. package/out-tsc/src/utils.js.map +1 -0
  233. package/out-tsc/src/webchat/WebChat.js +1 -1
  234. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  235. package/out-tsc/temba-components.js +2 -2
  236. package/out-tsc/temba-components.js.map +1 -1
  237. package/out-tsc/temba-modules.js +63 -56
  238. package/out-tsc/temba-modules.js.map +1 -1
  239. package/out-tsc/temba-webchat.js +2 -2
  240. package/out-tsc/temba-webchat.js.map +1 -1
  241. package/out-tsc/test/ActionHelper.js +116 -0
  242. package/out-tsc/test/ActionHelper.js.map +1 -0
  243. package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
  244. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
  245. package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
  246. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
  247. package/out-tsc/test/actions/send_email.test.js +160 -0
  248. package/out-tsc/test/actions/send_email.test.js.map +1 -0
  249. package/out-tsc/test/actions/send_msg.test.js +95 -0
  250. package/out-tsc/test/actions/send_msg.test.js.map +1 -0
  251. package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
  252. package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
  253. package/out-tsc/test/temba-alert.test.js +1 -1
  254. package/out-tsc/test/temba-alert.test.js.map +1 -1
  255. package/out-tsc/test/temba-appstate-language.test.js +90 -0
  256. package/out-tsc/test/temba-appstate-language.test.js.map +1 -1
  257. package/out-tsc/test/temba-charcount.test.js.map +1 -1
  258. package/out-tsc/test/temba-chart.test.js +1 -1
  259. package/out-tsc/test/temba-chart.test.js.map +1 -1
  260. package/out-tsc/test/temba-checkbox.test.js +1 -1
  261. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  262. package/out-tsc/test/temba-color-picker.test.js +1 -1
  263. package/out-tsc/test/temba-color-picker.test.js.map +1 -1
  264. package/out-tsc/test/temba-completion.test.js +1 -1
  265. package/out-tsc/test/temba-completion.test.js.map +1 -1
  266. package/out-tsc/test/temba-compose.test.js +1 -1
  267. package/out-tsc/test/temba-compose.test.js.map +1 -1
  268. package/out-tsc/test/temba-contact-badges.test.js +1 -1
  269. package/out-tsc/test/temba-contact-badges.test.js.map +1 -1
  270. package/out-tsc/test/temba-contact-chat.test.js +3 -1
  271. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  272. package/out-tsc/test/temba-contact-details.test.js +1 -1
  273. package/out-tsc/test/temba-contact-details.test.js.map +1 -1
  274. package/out-tsc/test/temba-contact-fields.test.js +1 -1
  275. package/out-tsc/test/temba-contact-fields.test.js.map +1 -1
  276. package/out-tsc/test/temba-contact-search.test.js +1 -1
  277. package/out-tsc/test/temba-contact-search.test.js.map +1 -1
  278. package/out-tsc/test/temba-date.test.js +5 -1
  279. package/out-tsc/test/temba-date.test.js.map +1 -1
  280. package/out-tsc/test/temba-datepicker.test.js +1 -1
  281. package/out-tsc/test/temba-datepicker.test.js.map +1 -1
  282. package/out-tsc/test/temba-dialog.test.js +1 -1
  283. package/out-tsc/test/temba-dialog.test.js.map +1 -1
  284. package/out-tsc/test/temba-dropdown.test.js +1 -1
  285. package/out-tsc/test/temba-dropdown.test.js.map +1 -1
  286. package/out-tsc/test/temba-excellent-helpers.test.js +316 -0
  287. package/out-tsc/test/temba-excellent-helpers.test.js.map +1 -0
  288. package/out-tsc/test/temba-field-config.test.js +133 -0
  289. package/out-tsc/test/temba-field-config.test.js.map +1 -0
  290. package/out-tsc/test/temba-field-manager.test.js.map +1 -1
  291. package/out-tsc/test/temba-flow-editor-node.test.js +426 -13
  292. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  293. package/out-tsc/test/temba-flow-editor.test.js +185 -0
  294. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  295. package/out-tsc/test/temba-flow-plumber-connections.test.js +113 -0
  296. package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -0
  297. package/out-tsc/test/temba-flow-plumber.test.js +73 -93
  298. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  299. package/out-tsc/test/temba-flow-self-routing.test.js +172 -0
  300. package/out-tsc/test/temba-flow-self-routing.test.js.map +1 -0
  301. package/out-tsc/test/temba-formfield.test.js.map +1 -1
  302. package/out-tsc/test/temba-icon.test.js +1 -1
  303. package/out-tsc/test/temba-icon.test.js.map +1 -1
  304. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  305. package/out-tsc/test/temba-label.test.js +1 -1
  306. package/out-tsc/test/temba-label.test.js.map +1 -1
  307. package/out-tsc/test/temba-lightbox.test.js +1 -1
  308. package/out-tsc/test/temba-lightbox.test.js.map +1 -1
  309. package/out-tsc/test/temba-markdown.test.js +127 -0
  310. package/out-tsc/test/temba-markdown.test.js.map +1 -0
  311. package/out-tsc/test/temba-menu.test.js +1 -1
  312. package/out-tsc/test/temba-menu.test.js.map +1 -1
  313. package/out-tsc/test/temba-modax.test.js +1 -1
  314. package/out-tsc/test/temba-modax.test.js.map +1 -1
  315. package/out-tsc/test/temba-modules.test.js +47 -0
  316. package/out-tsc/test/temba-modules.test.js.map +1 -0
  317. package/out-tsc/test/temba-node-editor.test.js +283 -0
  318. package/out-tsc/test/temba-node-editor.test.js.map +1 -0
  319. package/out-tsc/test/temba-omnibox.test.js +1 -1
  320. package/out-tsc/test/temba-omnibox.test.js.map +1 -1
  321. package/out-tsc/test/temba-options.test.js.map +1 -1
  322. package/out-tsc/test/temba-range-picker.test.js +9 -2
  323. package/out-tsc/test/temba-range-picker.test.js.map +1 -1
  324. package/out-tsc/test/temba-rapid-element.test.js +273 -0
  325. package/out-tsc/test/temba-rapid-element.test.js.map +1 -0
  326. package/out-tsc/test/temba-resize-element.test.js +85 -0
  327. package/out-tsc/test/temba-resize-element.test.js.map +1 -0
  328. package/out-tsc/test/temba-select.test.js +87 -2
  329. package/out-tsc/test/temba-select.test.js.map +1 -1
  330. package/out-tsc/test/temba-slider.test.js.map +1 -1
  331. package/out-tsc/test/temba-sticky-note.test.js +194 -0
  332. package/out-tsc/test/temba-sticky-note.test.js.map +1 -0
  333. package/out-tsc/test/temba-template-editor.test.js.map +1 -1
  334. package/out-tsc/test/temba-textinput.test.js +1 -1
  335. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  336. package/out-tsc/test/temba-tip.test.js +1 -1
  337. package/out-tsc/test/temba-tip.test.js.map +1 -1
  338. package/out-tsc/test/temba-toast.test.js +1 -1
  339. package/out-tsc/test/temba-toast.test.js.map +1 -1
  340. package/out-tsc/test/temba-utils-index.test.js +1 -1
  341. package/out-tsc/test/temba-utils-index.test.js.map +1 -1
  342. package/out-tsc/test/temba-utils-uuid.test.js +38 -0
  343. package/out-tsc/test/temba-utils-uuid.test.js.map +1 -0
  344. package/out-tsc/test/temba-webchat.test.js +28 -12
  345. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  346. package/out-tsc/test/utils.test.js +2 -6
  347. package/out-tsc/test/utils.test.js.map +1 -1
  348. package/package.json +18 -9
  349. package/rollup.components.mjs +1 -1
  350. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  351. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  352. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  353. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  354. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  355. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  356. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  357. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  358. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  359. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  360. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  361. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  362. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  363. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  364. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  365. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  366. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  367. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  368. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  369. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  370. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  371. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  372. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  373. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  374. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  375. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  376. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  377. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  378. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  379. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  380. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  381. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  382. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  383. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  384. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  385. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  386. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  387. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  388. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  389. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  390. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  391. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  392. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  393. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  394. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  395. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  396. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  397. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  398. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  399. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  400. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  401. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  402. package/screenshots/truth/datepicker/range-picker-all.png +0 -0
  403. package/screenshots/truth/datepicker/range-picker-button-states.png +0 -0
  404. package/screenshots/truth/datepicker/range-picker-default.png +0 -0
  405. package/screenshots/truth/datepicker/range-picker-editing-start.png +0 -0
  406. package/screenshots/truth/datepicker/range-picker-initial-values.png +0 -0
  407. package/screenshots/truth/datepicker/range-picker-week.png +0 -0
  408. package/screenshots/truth/datepicker/range-picker-year.png +0 -0
  409. package/screenshots/truth/editor/router.png +0 -0
  410. package/screenshots/truth/editor/send_msg.png +0 -0
  411. package/screenshots/truth/editor/set_contact_language.png +0 -0
  412. package/screenshots/truth/editor/set_contact_name.png +0 -0
  413. package/screenshots/truth/editor/set_run_result.png +0 -0
  414. package/screenshots/truth/editor/wait.png +0 -0
  415. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  416. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  417. package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
  418. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  419. package/screenshots/truth/sticky-note/blue-color.png +0 -0
  420. package/screenshots/truth/sticky-note/blue.png +0 -0
  421. package/screenshots/truth/sticky-note/color-picker-expanded.png +0 -0
  422. package/screenshots/truth/sticky-note/default.png +0 -0
  423. package/screenshots/truth/sticky-note/gray-color.png +0 -0
  424. package/screenshots/truth/sticky-note/gray.png +0 -0
  425. package/screenshots/truth/sticky-note/green-color.png +0 -0
  426. package/screenshots/truth/sticky-note/green.png +0 -0
  427. package/screenshots/truth/sticky-note/pink-color.png +0 -0
  428. package/screenshots/truth/sticky-note/pink.png +0 -0
  429. package/screenshots/truth/sticky-note/yellow-color.png +0 -0
  430. package/screenshots/truth/sticky-note/yellow.png +0 -0
  431. package/src/{charcount → display}/CharCount.ts +164 -2
  432. package/src/{vectoricon/VectorIcon.ts → display/Icon.ts} +1 -1
  433. package/src/{leafletmap → display}/LeafletMap.ts +19 -1
  434. package/src/{thumbnail → display}/Thumbnail.ts +1 -1
  435. package/src/{tip → display}/Tip.ts +1 -2
  436. package/src/events.ts +108 -0
  437. package/src/flow/CanvasNode.ts +1009 -0
  438. package/src/flow/Editor.ts +795 -169
  439. package/src/flow/NodeEditor.ts +1443 -0
  440. package/src/flow/Plumber.ts +177 -79
  441. package/src/flow/StickyNote.ts +165 -9
  442. package/src/flow/actions/add_contact_groups.ts +42 -0
  443. package/src/flow/actions/add_contact_urn.ts +17 -0
  444. package/src/flow/actions/add_input_labels.ts +12 -0
  445. package/src/flow/actions/call_classifier.ts +12 -0
  446. package/src/flow/actions/call_llm.ts +12 -0
  447. package/src/flow/actions/call_resthook.ts +12 -0
  448. package/src/flow/actions/call_webhook.ts +133 -0
  449. package/src/flow/actions/enter_flow.ts +15 -0
  450. package/src/flow/actions/open_ticket.ts +12 -0
  451. package/src/flow/actions/play_audio.ts +12 -0
  452. package/src/flow/actions/remove_contact_groups.ts +66 -0
  453. package/src/flow/actions/request_optin.ts +12 -0
  454. package/src/flow/actions/say_msg.ts +12 -0
  455. package/src/flow/actions/send_broadcast.ts +35 -0
  456. package/src/flow/actions/send_email.ts +60 -0
  457. package/src/flow/actions/send_msg.ts +58 -0
  458. package/src/flow/actions/set_contact_channel.ts +13 -0
  459. package/src/flow/actions/set_contact_field.ts +13 -0
  460. package/src/flow/actions/set_contact_language.ts +11 -0
  461. package/src/flow/actions/set_contact_name.ts +11 -0
  462. package/src/flow/actions/set_contact_status.ts +11 -0
  463. package/src/flow/actions/set_run_result.ts +11 -0
  464. package/src/flow/actions/split_by_expression_example.ts +88 -0
  465. package/src/flow/actions/start_session.ts +12 -0
  466. package/src/flow/actions/transfer_airtime.ts +12 -0
  467. package/src/flow/config.ts +93 -136
  468. package/src/flow/nodes/execute_actions.ts +5 -0
  469. package/src/flow/nodes/split_by_airtime.ts +9 -0
  470. package/src/flow/nodes/split_by_contact_field.ts +7 -0
  471. package/src/flow/nodes/split_by_expression.ts +7 -0
  472. package/src/flow/nodes/split_by_groups.ts +7 -0
  473. package/src/flow/nodes/split_by_random.ts +10 -0
  474. package/src/flow/nodes/split_by_run_result.ts +7 -0
  475. package/src/flow/nodes/split_by_scheme.ts +7 -0
  476. package/src/flow/nodes/split_by_subflow.ts +9 -0
  477. package/src/flow/nodes/split_by_webhook.ts +19 -0
  478. package/src/flow/nodes/wait_for_audio.ts +7 -0
  479. package/src/flow/nodes/wait_for_digits.ts +7 -0
  480. package/src/flow/nodes/wait_for_image.ts +7 -0
  481. package/src/flow/nodes/wait_for_location.ts +7 -0
  482. package/src/flow/nodes/wait_for_menu.ts +7 -0
  483. package/src/flow/nodes/wait_for_response.ts +7 -0
  484. package/src/flow/nodes/wait_for_video.ts +7 -0
  485. package/src/flow/types.ts +352 -0
  486. package/src/flow/utils.ts +76 -0
  487. package/src/form/ArrayEditor.ts +240 -0
  488. package/src/form/BaseListEditor.ts +177 -0
  489. package/src/{checkbox → form}/Checkbox.ts +24 -5
  490. package/src/{colorpicker → form}/ColorPicker.ts +2 -2
  491. package/src/{completion → form}/Completion.ts +9 -3
  492. package/src/{compose → form}/Compose.ts +7 -7
  493. package/src/{contactsearch → form}/ContactSearch.ts +6 -6
  494. package/src/{datepicker → form}/DatePicker.ts +1 -1
  495. package/src/{FormElement.ts → form/FormElement.ts} +1 -1
  496. package/src/form/FormField.ts +238 -0
  497. package/src/{imagepicker → form}/ImagePicker.ts +2 -2
  498. package/src/form/KeyValueEditor.ts +251 -0
  499. package/src/{mediapicker → form}/MediaPicker.ts +1 -1
  500. package/src/{slider → form}/TembaSlider.ts +1 -1
  501. package/src/{templates → form}/TemplateEditor.ts +2 -2
  502. package/src/{textinput → form}/TextInput.ts +5 -5
  503. package/src/{omnibox → form/select}/Omnibox.ts +2 -2
  504. package/src/{select → form/select}/PopupSelect.ts +1 -1
  505. package/src/{select → form/select}/Select.ts +207 -152
  506. package/src/{select → form/select}/UserSelect.ts +1 -1
  507. package/src/{select → form/select}/WorkspaceSelect.ts +1 -1
  508. package/src/interfaces.ts +8 -2
  509. package/src/{dialog → layout}/Dialog.ts +1 -1
  510. package/src/list/NotificationList.ts +2 -2
  511. package/src/list/RunList.ts +3 -3
  512. package/src/list/ShortcutList.ts +1 -1
  513. package/src/list/TembaMenu.ts +2 -2
  514. package/src/list/TicketList.ts +1 -1
  515. package/src/{aliaseditor → live}/AliasEditor.ts +3 -3
  516. package/src/{contacts → live}/ContactBadges.ts +1 -1
  517. package/src/{contacts → live}/ContactChat.ts +120 -104
  518. package/src/{contacts → live}/ContactDetails.ts +1 -1
  519. package/src/{contacts → live}/ContactFieldEditor.ts +4 -4
  520. package/src/{contacts → live}/ContactFields.ts +1 -1
  521. package/src/{contacts → live}/ContactNotepad.ts +1 -1
  522. package/src/{contacts → live}/ContactPending.ts +1 -1
  523. package/src/{chart → live}/TembaChart.ts +1 -1
  524. package/src/store/AppState.ts +75 -29
  525. package/src/store/Store.ts +1 -1
  526. package/src/store/flow-definition.d.ts +131 -1
  527. package/src/{utils/index.ts → utils.ts} +26 -10
  528. package/src/webchat/WebChat.ts +1 -1
  529. package/static/api/contacts.json +30 -0
  530. package/static/api/groups.json +4 -426
  531. package/static/api/locations.json +24 -0
  532. package/static/api/media.json +5 -0
  533. package/static/api/optins.json +16 -0
  534. package/static/api/orgs.json +13 -0
  535. package/static/api/topics.json +21 -0
  536. package/static/api/users.json +26 -0
  537. package/static/css/temba-components.css +4 -6
  538. package/svg.js +1 -4
  539. package/temba-components.ts +2 -2
  540. package/temba-modules.ts +63 -56
  541. package/temba-webchat.ts +2 -2
  542. package/test/ActionHelper.ts +142 -0
  543. package/test/actions/add_contact_groups.test.ts +89 -0
  544. package/test/actions/remove_contact_groups.test.ts +265 -0
  545. package/test/actions/send_email.test.ts +214 -0
  546. package/test/actions/send_msg.test.ts +130 -0
  547. package/test/temba-action-editing-integration.test.ts +240 -0
  548. package/test/temba-alert.test.ts +1 -1
  549. package/test/temba-appstate-language.test.ts +108 -0
  550. package/test/temba-charcount.test.ts +1 -1
  551. package/test/temba-chart.test.ts +1 -1
  552. package/test/temba-checkbox.test.ts +2 -2
  553. package/test/temba-color-picker.test.ts +1 -1
  554. package/test/temba-completion.test.ts +1 -1
  555. package/test/temba-compose.test.ts +1 -1
  556. package/test/temba-contact-badges.test.ts +1 -1
  557. package/test/temba-contact-chat.test.ts +6 -4
  558. package/test/temba-contact-details.test.ts +1 -1
  559. package/test/temba-contact-fields.test.ts +1 -1
  560. package/test/temba-contact-search.test.ts +2 -2
  561. package/test/temba-date.test.ts +8 -3
  562. package/test/temba-datepicker.test.ts +1 -1
  563. package/test/temba-dialog.test.ts +1 -1
  564. package/test/temba-dropdown.test.ts +1 -1
  565. package/test/temba-excellent-helpers.test.ts +417 -0
  566. package/test/temba-field-config.test.ts +152 -0
  567. package/test/temba-field-manager.test.ts +2 -2
  568. package/test/temba-flow-editor-node.test.ts +551 -16
  569. package/test/temba-flow-editor.test.ts +224 -0
  570. package/test/temba-flow-editor.test.ts.backup +563 -0
  571. package/test/temba-flow-plumber-connections.test.ts +142 -0
  572. package/test/temba-flow-plumber.test.ts +83 -120
  573. package/test/temba-flow-self-routing.test.ts +215 -0
  574. package/test/temba-formfield.test.ts +1 -1
  575. package/test/temba-icon.test.ts +1 -1
  576. package/test/temba-integration-markdown.test.ts +1 -1
  577. package/test/temba-label.test.ts +1 -1
  578. package/test/temba-lightbox.test.ts +1 -1
  579. package/test/temba-markdown.test.ts +162 -0
  580. package/test/temba-menu.test.ts +1 -1
  581. package/test/temba-modax.test.ts +2 -2
  582. package/test/temba-modules.test.ts +56 -0
  583. package/test/temba-node-editor.test.ts +353 -0
  584. package/test/temba-omnibox.test.ts +1 -1
  585. package/test/temba-options.test.ts +1 -1
  586. package/test/temba-range-picker.test.ts +17 -2
  587. package/test/temba-rapid-element.test.ts +341 -0
  588. package/test/temba-resize-element.test.ts +104 -0
  589. package/test/temba-select.test.ts +129 -2
  590. package/test/temba-slider.test.ts +1 -1
  591. package/test/temba-sticky-note.test.ts +281 -0
  592. package/test/temba-template-editor.test.ts +1 -1
  593. package/test/temba-textinput.test.ts +1 -1
  594. package/test/temba-tip.test.ts +1 -1
  595. package/test/temba-toast.test.ts +1 -1
  596. package/test/temba-utils-index.test.ts +1 -1
  597. package/test/temba-utils-index.test.ts.backup +1737 -0
  598. package/test/temba-utils-uuid.test.ts +48 -0
  599. package/test/temba-webchat.test.ts +30 -12
  600. package/test/utils.test.ts +5 -9
  601. package/test-assets/contacts/history.json +11 -33
  602. package/web-dev-server.config.mjs +35 -1
  603. package/demo/sticky-note-demo.html +0 -155
  604. package/out-tsc/src/FormElement.js.map +0 -1
  605. package/out-tsc/src/alert/Alert.js.map +0 -1
  606. package/out-tsc/src/aliaseditor/AliasEditor.js.map +0 -1
  607. package/out-tsc/src/anchor/Anchor.js.map +0 -1
  608. package/out-tsc/src/button/Button.js.map +0 -1
  609. package/out-tsc/src/charcount/CharCount.js.map +0 -1
  610. package/out-tsc/src/charcount/helpers.js +0 -159
  611. package/out-tsc/src/charcount/helpers.js.map +0 -1
  612. package/out-tsc/src/chart/TembaChart.js.map +0 -1
  613. package/out-tsc/src/chat/Chat.js.map +0 -1
  614. package/out-tsc/src/checkbox/Checkbox.js.map +0 -1
  615. package/out-tsc/src/colorpicker/ColorPicker.js.map +0 -1
  616. package/out-tsc/src/completion/Completion.js.map +0 -1
  617. package/out-tsc/src/completion/ExcellentParser.js.map +0 -1
  618. package/out-tsc/src/completion/helpers.js.map +0 -1
  619. package/out-tsc/src/compose/Compose.js.map +0 -1
  620. package/out-tsc/src/contacts/ContactBadges.js.map +0 -1
  621. package/out-tsc/src/contacts/ContactChat.js.map +0 -1
  622. package/out-tsc/src/contacts/ContactDetails.js.map +0 -1
  623. package/out-tsc/src/contacts/ContactFieldEditor.js.map +0 -1
  624. package/out-tsc/src/contacts/ContactFields.js.map +0 -1
  625. package/out-tsc/src/contacts/ContactName.js.map +0 -1
  626. package/out-tsc/src/contacts/ContactNameFetch.js.map +0 -1
  627. package/out-tsc/src/contacts/ContactPending.js.map +0 -1
  628. package/out-tsc/src/contacts/ContactStoreElement.js.map +0 -1
  629. package/out-tsc/src/contacts/ContactUrn.js.map +0 -1
  630. package/out-tsc/src/contacts/events.js +0 -65
  631. package/out-tsc/src/contacts/events.js.map +0 -1
  632. package/out-tsc/src/contacts/helpers.js +0 -77
  633. package/out-tsc/src/contacts/helpers.js.map +0 -1
  634. package/out-tsc/src/contactsearch/ContactSearch.js.map +0 -1
  635. package/out-tsc/src/date/TembaDate.js.map +0 -1
  636. package/out-tsc/src/datepicker/DatePicker.js.map +0 -1
  637. package/out-tsc/src/datepicker/RangePicker.js.map +0 -1
  638. package/out-tsc/src/dialog/Dialog.js.map +0 -1
  639. package/out-tsc/src/dropdown/Dropdown.js.map +0 -1
  640. package/out-tsc/src/fields/FieldManager.js.map +0 -1
  641. package/out-tsc/src/flow/EditorNode.js +0 -291
  642. package/out-tsc/src/flow/EditorNode.js.map +0 -1
  643. package/out-tsc/src/flow/render.js +0 -41
  644. package/out-tsc/src/flow/render.js.map +0 -1
  645. package/out-tsc/src/formfield/FormField.js +0 -144
  646. package/out-tsc/src/formfield/FormField.js.map +0 -1
  647. package/out-tsc/src/imagepicker/CroppieCSS.js.map +0 -1
  648. package/out-tsc/src/imagepicker/ImagePicker.js.map +0 -1
  649. package/out-tsc/src/label/Label.js.map +0 -1
  650. package/out-tsc/src/leafletmap/LeafletMap.js.map +0 -1
  651. package/out-tsc/src/leafletmap/helpers.js +0 -17
  652. package/out-tsc/src/leafletmap/helpers.js.map +0 -1
  653. package/out-tsc/src/lightbox/Lightbox.js.map +0 -1
  654. package/out-tsc/src/mask/Mask.js.map +0 -1
  655. package/out-tsc/src/mediapicker/MediaPicker.js.map +0 -1
  656. package/out-tsc/src/omnibox/Omnibox.js.map +0 -1
  657. package/out-tsc/src/options/helpers.js +0 -28
  658. package/out-tsc/src/options/helpers.js.map +0 -1
  659. package/out-tsc/src/progress/ProgressBar.js.map +0 -1
  660. package/out-tsc/src/progress/StartProgress.js.map +0 -1
  661. package/out-tsc/src/resizer/Resizer.js.map +0 -1
  662. package/out-tsc/src/select/PopupSelect.js.map +0 -1
  663. package/out-tsc/src/select/Select.js.map +0 -1
  664. package/out-tsc/src/select/UserSelect.js.map +0 -1
  665. package/out-tsc/src/select/WorkspaceSelect.js.map +0 -1
  666. package/out-tsc/src/select/helpers.js +0 -1
  667. package/out-tsc/src/select/helpers.js.map +0 -1
  668. package/out-tsc/src/shadowless/Shadowless.js +0 -33
  669. package/out-tsc/src/shadowless/Shadowless.js.map +0 -1
  670. package/out-tsc/src/slider/TembaSlider.js.map +0 -1
  671. package/out-tsc/src/sms/gsmsplitter.js.map +0 -1
  672. package/out-tsc/src/sms/gsmvalidator.js.map +0 -1
  673. package/out-tsc/src/sms/index.js.map +0 -1
  674. package/out-tsc/src/sms/unicodesplitter.js.map +0 -1
  675. package/out-tsc/src/tabpane/Tab.js.map +0 -1
  676. package/out-tsc/src/tabpane/TabPane.js.map +0 -1
  677. package/out-tsc/src/templates/TemplateEditor.js.map +0 -1
  678. package/out-tsc/src/textinput/TextInput.js.map +0 -1
  679. package/out-tsc/src/textinput/helpers.js +0 -12
  680. package/out-tsc/src/textinput/helpers.js.map +0 -1
  681. package/out-tsc/src/thumbnail/Thumbnail.js.map +0 -1
  682. package/out-tsc/src/tip/Tip.js.map +0 -1
  683. package/out-tsc/src/tip/helpers.js +0 -7
  684. package/out-tsc/src/tip/helpers.js.map +0 -1
  685. package/out-tsc/src/toast/Toast.js.map +0 -1
  686. package/out-tsc/src/user/TembaUser.js.map +0 -1
  687. package/out-tsc/src/utils/index.js.map +0 -1
  688. package/out-tsc/src/vectoricon/VectorIcon.js.map +0 -1
  689. package/out-tsc/src/vectoricon/index.js.map +0 -1
  690. package/out-tsc/test/temba-flow-render.test.js +0 -171
  691. package/out-tsc/test/temba-flow-render.test.js.map +0 -1
  692. package/src/charcount/helpers.ts +0 -162
  693. package/src/contacts/events.ts +0 -210
  694. package/src/contacts/helpers.ts +0 -103
  695. package/src/flow/EditorNode.ts +0 -318
  696. package/src/flow/render.ts +0 -56
  697. package/src/formfield/FormField.ts +0 -134
  698. package/src/leafletmap/helpers.ts +0 -18
  699. package/src/options/helpers.ts +0 -37
  700. package/src/select/helpers.ts +0 -0
  701. package/src/shadowless/Shadowless.ts +0 -32
  702. package/src/textinput/helpers.ts +0 -11
  703. package/src/tip/helpers.ts +0 -7
  704. package/test/temba-flow-render.test.ts +0 -220
  705. /package/out-tsc/src/{alert → display}/Alert.js +0 -0
  706. /package/out-tsc/src/{anchor → display}/Anchor.js +0 -0
  707. /package/out-tsc/src/{button → display}/Button.js +0 -0
  708. /package/out-tsc/src/{chat → display}/Chat.js +0 -0
  709. /package/out-tsc/src/{contacts → display}/ContactName.js +0 -0
  710. /package/out-tsc/src/{contacts → display}/ContactUrn.js +0 -0
  711. /package/out-tsc/src/{dropdown → display}/Dropdown.js +0 -0
  712. /package/out-tsc/src/{label → display}/Label.js +0 -0
  713. /package/out-tsc/src/{lightbox → display}/Lightbox.js +0 -0
  714. /package/out-tsc/src/{loading → display}/Loading.js +0 -0
  715. /package/out-tsc/src/{options → display}/Options.js +0 -0
  716. /package/out-tsc/src/{progress → display}/ProgressBar.js +0 -0
  717. /package/out-tsc/src/{date → display}/TembaDate.js +0 -0
  718. /package/out-tsc/src/{user → display}/TembaUser.js +0 -0
  719. /package/out-tsc/src/{thumbnail → display}/Thumbnail.js +0 -0
  720. /package/out-tsc/src/{toast → display}/Toast.js +0 -0
  721. /package/out-tsc/src/{sms → display/sms}/gsmsplitter.js +0 -0
  722. /package/out-tsc/src/{sms → display/sms}/gsmvalidator.js +0 -0
  723. /package/out-tsc/src/{sms → display/sms}/index.js +0 -0
  724. /package/out-tsc/src/{sms → display/sms}/unicodesplitter.js +0 -0
  725. /package/out-tsc/src/{completion → excellent}/ExcellentParser.js +0 -0
  726. /package/out-tsc/src/{completion → excellent}/helpers.js +0 -0
  727. /package/out-tsc/src/{imagepicker → form}/CroppieCSS.js +0 -0
  728. /package/out-tsc/src/{datepicker → form}/RangePicker.js +0 -0
  729. /package/out-tsc/src/{dialog → layout}/Dialog.js +0 -0
  730. /package/out-tsc/src/{mask → layout}/Mask.js +0 -0
  731. /package/out-tsc/src/{dialog → layout}/Modax.js +0 -0
  732. /package/out-tsc/src/{resizer → layout}/Resizer.js +0 -0
  733. /package/out-tsc/src/{tabpane → layout}/Tab.js +0 -0
  734. /package/out-tsc/src/{tabpane → layout}/TabPane.js +0 -0
  735. /package/out-tsc/src/{contacts → live}/ContactFields.js +0 -0
  736. /package/out-tsc/src/{contacts → live}/ContactNameFetch.js +0 -0
  737. /package/out-tsc/src/{contacts → live}/ContactStoreElement.js +0 -0
  738. /package/out-tsc/src/{fields → live}/FieldManager.js +0 -0
  739. /package/out-tsc/src/{progress → live}/StartProgress.js +0 -0
  740. /package/out-tsc/src/{chart → live}/TembaChart.js +0 -0
  741. /package/src/{vectoricon/index.ts → Icons.ts} +0 -0
  742. /package/src/{alert → display}/Alert.ts +0 -0
  743. /package/src/{anchor → display}/Anchor.ts +0 -0
  744. /package/src/{button → display}/Button.ts +0 -0
  745. /package/src/{chat → display}/Chat.ts +0 -0
  746. /package/src/{contacts → display}/ContactName.ts +0 -0
  747. /package/src/{contacts → display}/ContactUrn.ts +0 -0
  748. /package/src/{dropdown → display}/Dropdown.ts +0 -0
  749. /package/src/{label → display}/Label.ts +0 -0
  750. /package/src/{lightbox → display}/Lightbox.ts +0 -0
  751. /package/src/{loading → display}/Loading.ts +0 -0
  752. /package/src/{options → display}/Options.ts +0 -0
  753. /package/src/{progress → display}/ProgressBar.ts +0 -0
  754. /package/src/{date → display}/TembaDate.ts +0 -0
  755. /package/src/{user → display}/TembaUser.ts +0 -0
  756. /package/src/{toast → display}/Toast.ts +0 -0
  757. /package/src/{sms → display/sms}/gsmsplitter.ts +0 -0
  758. /package/src/{sms → display/sms}/gsmvalidator.ts +0 -0
  759. /package/src/{sms → display/sms}/index.ts +0 -0
  760. /package/src/{sms → display/sms}/unicodesplitter.ts +0 -0
  761. /package/src/{completion → excellent}/ExcellentParser.ts +0 -0
  762. /package/src/{completion → excellent}/helpers.ts +0 -0
  763. /package/src/{imagepicker → form}/CroppieCSS.ts +0 -0
  764. /package/src/{datepicker → form}/RangePicker.ts +0 -0
  765. /package/src/{mask → layout}/Mask.ts +0 -0
  766. /package/src/{dialog → layout}/Modax.ts +0 -0
  767. /package/src/{resizer → layout}/Resizer.ts +0 -0
  768. /package/src/{tabpane → layout}/Tab.ts +0 -0
  769. /package/src/{tabpane → layout}/TabPane.ts +0 -0
  770. /package/src/{contacts → live}/ContactNameFetch.ts +0 -0
  771. /package/src/{contacts → live}/ContactStoreElement.ts +0 -0
  772. /package/src/{fields → live}/FieldManager.ts +0 -0
  773. /package/src/{progress → live}/StartProgress.ts +0 -0
@@ -3,7 +3,6 @@ import { WebChat } from '../src/webchat/WebChat';
3
3
  import { assertScreenshot, getClip, getComponent, mockNow, mouseClickElement } from '../test/utils.test';
4
4
  import { expect, assert } from '@open-wc/testing';
5
5
  let clock;
6
- mockNow('2021-03-31T00:31:00.000-00:00');
7
6
  const TAG = 'temba-webchat';
8
7
  const getWebChat = async (attrs = {}) => {
9
8
  const webChat = (await getComponent(TAG, attrs, '', 400, 600));
@@ -22,12 +21,11 @@ class MockWebSocket {
22
21
  this.url = url;
23
22
  // Only auto-open if enabled
24
23
  if (this.autoOpen) {
25
- setTimeout(() => {
26
- this.readyState = 1; // OPEN
27
- if (this.onopen) {
28
- this.onopen(new Event('open'));
29
- }
30
- }, 0);
24
+ // Use synchronous execution instead of setTimeout to avoid clock advancing issues
25
+ this.readyState = 1; // OPEN
26
+ if (this.onopen) {
27
+ this.onopen(new Event('open'));
28
+ }
31
29
  }
32
30
  }
33
31
  send(data) {
@@ -64,7 +62,9 @@ describe('temba-webchat', () => {
64
62
  let mockWebSocket;
65
63
  let webSocketStub;
66
64
  let cookieStub;
65
+ let mockedNow;
67
66
  beforeEach(() => {
67
+ mockedNow = mockNow('2021-03-31T00:31:00.000-00:00');
68
68
  // Mock WebSocket
69
69
  originalWebSocket = window.WebSocket;
70
70
  webSocketStub = stub(window, 'WebSocket').callsFake((url) => {
@@ -74,12 +74,17 @@ describe('temba-webchat', () => {
74
74
  });
75
75
  // Mock document.cookie
76
76
  cookieStub = stub(document, 'cookie').value('');
77
- clock = useFakeTimers();
77
+ // Use fake timers but with a shorter timeout to avoid test hanging
78
+ clock = useFakeTimers({
79
+ shouldAdvanceTime: true,
80
+ advanceTimeDelta: 10
81
+ });
78
82
  });
79
83
  afterEach(() => {
80
84
  clock.restore();
81
85
  webSocketStub.restore();
82
86
  cookieStub.restore();
87
+ mockedNow.restore();
83
88
  window.WebSocket = originalWebSocket;
84
89
  });
85
90
  describe('Component Initialization', () => {
@@ -142,6 +147,7 @@ describe('temba-webchat', () => {
142
147
  expect(toggleElement).to.exist;
143
148
  await mouseClickElement(toggleElement);
144
149
  await webChat.updateComplete;
150
+ clock.tick(50);
145
151
  // Now it should be open and connecting
146
152
  expect(webChat.open).to.equal(true);
147
153
  expect(webChat.status).to.equal('connecting');
@@ -179,10 +185,12 @@ describe('temba-webchat', () => {
179
185
  expect(toggleElement).to.exist;
180
186
  await mouseClickElement(toggleElement);
181
187
  await webChat.updateComplete;
188
+ clock.tick(50);
182
189
  expect(webChat.open).to.equal(true);
183
190
  // Click toggle again
184
191
  await mouseClickElement(toggleElement);
185
192
  await webChat.updateComplete;
193
+ clock.tick(50);
186
194
  expect(webChat.open).to.equal(false);
187
195
  });
188
196
  it('toggles chat via close button', async () => {
@@ -217,12 +225,14 @@ describe('temba-webchat', () => {
217
225
  // Open chat - this should trigger socket connection
218
226
  webChat.open = true;
219
227
  await webChat.updateComplete;
228
+ clock.tick(50);
220
229
  expect(webChat.status).to.equal('connecting');
221
230
  expect(webSocketStub.called).to.be.true;
222
231
  expect(mockWebSocket.url).to.include('test-channel');
223
232
  // Now simulate the socket opening
224
233
  mockWebSocket.manualOpen();
225
234
  await webChat.updateComplete;
235
+ clock.tick(50);
226
236
  expect(webChat.status).to.equal('connected');
227
237
  });
228
238
  it('does not open socket if already connecting or connected', async () => {
@@ -248,7 +258,7 @@ describe('temba-webchat', () => {
248
258
  });
249
259
  webChat.open = true;
250
260
  await webChat.updateComplete;
251
- await clock.tick(0);
261
+ clock.tick(50);
252
262
  expect(mockWebSocket.url).to.equal('wss://localhost.textit.com/wc/connect/my-channel/');
253
263
  });
254
264
  it('includes urn in WebSocket URL when present', async () => {
@@ -258,7 +268,7 @@ describe('temba-webchat', () => {
258
268
  });
259
269
  webChat.open = true;
260
270
  await webChat.updateComplete;
261
- await clock.tick(0);
271
+ clock.tick(50);
262
272
  expect(mockWebSocket.url).to.equal('wss://localhost.textit.com/wc/connect/my-channel/?chat_id=chat-123');
263
273
  });
264
274
  it('sends start_chat command on socket open', async () => {
@@ -267,8 +277,11 @@ describe('temba-webchat', () => {
267
277
  });
268
278
  webChat.open = true;
269
279
  await webChat.updateComplete;
270
- await clock.tick(0);
271
- expect(mockWebSocket.sentMessages).to.have.length(1);
280
+ // Manually open the socket to trigger the start_chat command
281
+ mockWebSocket.manualOpen();
282
+ await webChat.updateComplete;
283
+ clock.tick(100);
284
+ expect(mockWebSocket.sentMessages.length).to.be.at.least(1);
272
285
  const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);
273
286
  expect(sentMessage.type).to.equal('start_chat');
274
287
  });
@@ -283,6 +296,7 @@ describe('temba-webchat', () => {
283
296
  await webChat.updateComplete;
284
297
  mockWebSocket.manualOpen();
285
298
  await webChat.updateComplete;
299
+ clock.tick(50);
286
300
  const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);
287
301
  expect(sentMessage.type).to.equal('start_chat');
288
302
  // The chat_id should be 'existing-chat-123' either from the urn property or cookie
@@ -294,9 +308,11 @@ describe('temba-webchat', () => {
294
308
  });
295
309
  webChat.open = true;
296
310
  await webChat.updateComplete;
311
+ clock.tick(50);
297
312
  expect(webChat.status).to.equal('connecting');
298
313
  mockWebSocket.close();
299
314
  await webChat.updateComplete;
315
+ clock.tick(50);
300
316
  expect(webChat.status).to.equal('disconnected');
301
317
  });
302
318
  it('handles socket error event', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"temba-webchat.test.js","sourceRoot":"","sources":["../../test/temba-webchat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { useFakeTimers, stub, SinonStub } from 'sinon';\nimport { WebChat } from '../src/webchat/WebChat';\nimport {\n assertScreenshot,\n getClip,\n getComponent,\n mockNow,\n mouseClickElement\n} from '../test/utils.test';\nimport { expect, assert } from '@open-wc/testing';\n\nlet clock: any;\nmockNow('2021-03-31T00:31:00.000-00:00');\n\nconst TAG = 'temba-webchat';\n\nconst getWebChat = async (attrs: any = {}) => {\n const webChat = (await getComponent(TAG, attrs, '', 400, 600)) as WebChat;\n\n return webChat;\n};\n\n// Mock WebSocket\nclass MockWebSocket {\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: CloseEvent) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public readyState: number = 0;\n public url: string;\n public sentMessages: string[] = [];\n public autoOpen: boolean = true;\n\n constructor(url: string) {\n this.url = url;\n // Only auto-open if enabled\n if (this.autoOpen) {\n setTimeout(() => {\n this.readyState = 1; // OPEN\n if (this.onopen) {\n this.onopen(new Event('open'));\n }\n }, 0);\n }\n }\n\n send(data: string) {\n this.sentMessages.push(data);\n }\n\n close() {\n this.readyState = 3; // CLOSED\n if (this.onclose) {\n this.onclose(new CloseEvent('close'));\n }\n }\n\n // Test helper to manually open connection\n manualOpen() {\n this.readyState = 1; // OPEN\n if (this.onopen) {\n this.onopen(new Event('open'));\n }\n }\n\n // Test helper to simulate incoming messages\n simulateMessage(data: any) {\n if (this.onmessage) {\n this.onmessage(\n new MessageEvent('message', { data: JSON.stringify(data) })\n );\n }\n }\n\n // Test helper to simulate errors\n simulateError() {\n if (this.onerror) {\n this.onerror(new Event('error'));\n }\n }\n}\n\ndescribe('temba-webchat', () => {\n let originalWebSocket: any;\n let mockWebSocket: MockWebSocket;\n let webSocketStub: SinonStub;\n let cookieStub: SinonStub;\n\n beforeEach(() => {\n // Mock WebSocket\n originalWebSocket = window.WebSocket;\n webSocketStub = stub(window, 'WebSocket').callsFake((url: string) => {\n mockWebSocket = new MockWebSocket(url);\n mockWebSocket.autoOpen = false; // Disable auto-open by default\n return mockWebSocket as any;\n });\n\n // Mock document.cookie\n cookieStub = stub(document, 'cookie').value('');\n\n clock = useFakeTimers();\n });\n\n afterEach(() => {\n clock.restore();\n webSocketStub.restore();\n cookieStub.restore();\n window.WebSocket = originalWebSocket;\n });\n\n describe('Component Initialization', () => {\n it('creates component with default properties', async () => {\n const webChat = await getWebChat();\n\n assert.instanceOf(webChat, WebChat);\n expect(webChat.open).to.equal(false);\n expect(webChat.status).to.equal('disconnected');\n expect(webChat.hasPendingText).to.equal(false);\n expect(webChat.messageGroups).to.deep.equal([]);\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('accepts channel and urn properties', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'test-urn-123'\n });\n\n expect(webChat.channel).to.equal('test-channel');\n expect(webChat.urn).to.equal('test-urn-123');\n });\n\n it('accepts host and activeUserAvatar properties', async () => {\n const webChat = await getWebChat({\n host: 'example.com',\n activeUserAvatar: 'https://example.com/avatar.jpg'\n });\n\n expect(webChat.host).to.equal('example.com');\n expect(webChat.activeUserAvatar).to.equal(\n 'https://example.com/avatar.jpg'\n );\n });\n\n it('initializes chat component on first update', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // Check that the chat component was initialized\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n });\n });\n\n describe('UI Rendering', () => {\n it('renders closed chat widget by default', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n await assertScreenshot('webchat/closed-widget', getClip(webChat));\n });\n\n it('renders opened chat widget', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n await assertScreenshot('webchat/opened-widget', getClip(webChat));\n });\n\n it('renders connecting state', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n expect(webChat.status).to.equal('disconnected');\n\n // Click to open the widget, which should trigger connecting state\n const toggleElement = webChat.shadowRoot.querySelector('.toggle');\n expect(toggleElement).to.exist;\n\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n\n // Now it should be open and connecting\n expect(webChat.open).to.equal(true);\n expect(webChat.status).to.equal('connecting');\n\n await assertScreenshot('webchat/connecting-state', getClip(webChat));\n });\n\n it('renders disconnected state with reconnect option', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n await assertScreenshot('webchat/disconnected-state', getClip(webChat));\n });\n\n it('renders connected state with input field', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n // the cursor is blinking, we need to account for it in our screenshot by making it transparent\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n expect(inputField).to.exist;\n inputField.style.caretColor = 'transparent';\n\n await assertScreenshot('webchat/connected-state', getClip(webChat));\n });\n });\n\n describe('Chat Toggle Functionality', () => {\n it('toggles chat open/closed', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n\n // Click the toggle element\n const toggleElement = webChat.shadowRoot.querySelector('.toggle');\n expect(toggleElement).to.exist;\n\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(true);\n\n // Click toggle again\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(false);\n });\n\n it('toggles chat via close button', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n expect(webChat.open).to.equal(true);\n\n // Click close button in header\n const closeButton = webChat.shadowRoot.querySelector('.close-button');\n expect(closeButton).to.exist;\n\n await mouseClickElement(closeButton);\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(false);\n });\n\n it('opens chat programmatically', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n\n webChat.openChat();\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(true);\n });\n });\n\n describe('Socket Connection Management', () => {\n it('opens socket when chat is opened', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.status).to.equal('disconnected');\n\n // Open chat - this should trigger socket connection\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n expect(webSocketStub.called).to.be.true;\n expect(mockWebSocket.url).to.include('test-channel');\n\n // Now simulate the socket opening\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connected');\n });\n\n it('does not open socket if already connecting or connected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // First connection\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n const firstCallCount = webSocketStub.callCount;\n\n // Try to connect again while connecting\n webChat.open = false;\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n // Should not create another socket\n expect(webSocketStub.callCount).to.equal(firstCallCount);\n });\n\n it('constructs correct WebSocket URL with channel', async () => {\n const webChat = await getWebChat({\n channel: 'my-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n expect(mockWebSocket.url).to.equal(\n 'wss://localhost.textit.com/wc/connect/my-channel/'\n );\n });\n\n it('includes urn in WebSocket URL when present', async () => {\n const webChat = await getWebChat({\n channel: 'my-channel',\n urn: 'chat-123'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n expect(mockWebSocket.url).to.equal(\n 'wss://localhost.textit.com/wc/connect/my-channel/?chat_id=chat-123'\n );\n });\n\n it('sends start_chat command on socket open', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n expect(mockWebSocket.sentMessages).to.have.length(1);\n const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);\n expect(sentMessage.type).to.equal('start_chat');\n });\n\n it('includes chat_id in start_chat command when urn is present', async () => {\n // Set the cookie directly in document.cookie\n cookieStub.value('temba-chat-urn=existing-chat-123');\n\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'existing-chat-123'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);\n expect(sentMessage.type).to.equal('start_chat');\n // The chat_id should be 'existing-chat-123' either from the urn property or cookie\n expect(sentMessage.chat_id).to.equal('existing-chat-123');\n });\n\n it('handles socket close event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n\n mockWebSocket.close();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('disconnected');\n });\n\n it('handles socket error event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n\n mockWebSocket.simulateError();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('disconnected');\n });\n\n it('reconnects when reconnect button is clicked', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n const reconnectButton = webChat.shadowRoot.querySelector('.reconnect');\n expect(reconnectButton).to.exist;\n\n await mouseClickElement(reconnectButton);\n await webChat.updateComplete;\n\n expect(webSocketStub.called).to.be.true;\n expect(webChat.status).to.equal('connecting');\n });\n });\n\n describe('Message Handling', () => {\n it('handles chat_started message', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connected');\n\n // Simulate chat_started message\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'new-chat-456'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('new-chat-456');\n expect(webChat.messageGroups).to.deep.equal([]);\n });\n\n it('handles chat_resumed message and fetches history', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate chat_resumed message\n mockWebSocket.simulateMessage({\n type: 'chat_resumed',\n chat_id: 'resumed-chat-789'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('resumed-chat-789');\n\n // Should have sent get_history command\n expect(mockWebSocket.sentMessages.length).to.be.greaterThan(1);\n const lastMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(lastMessage.type).to.equal('get_history');\n });\n\n it('handles chat_out message and sends ack', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Simulate incoming message\n mockWebSocket.simulateMessage({\n type: 'chat_out',\n msg_out: {\n id: 'msg-123',\n text: 'Hello from server',\n time: '2021-03-31T00:31:00.000Z',\n user: {\n id: 'user-1',\n name: 'Test User',\n email: 'test@example.com'\n }\n }\n });\n await webChat.updateComplete;\n\n // Should have sent ack\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const ackMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(ackMessage.type).to.equal('ack_chat');\n expect(ackMessage.msg_id).to.equal('msg-123');\n });\n\n it('handles history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate history response\n mockWebSocket.simulateMessage({\n type: 'history',\n history: [\n {\n msg_out: {\n id: 'msg-1',\n text: 'First message',\n time: '2021-03-31T00:30:00.000Z',\n user: { id: 'user-1', name: 'User', email: 'user@example.com' }\n }\n },\n {\n msg_in: {\n id: 'msg-2',\n text: 'Second message',\n time: '2021-03-31T00:30:30.000Z'\n }\n }\n ]\n });\n await webChat.updateComplete;\n\n // Should have updated beforeTime and unblocked history fetching\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('clears messages when chat_id changes', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'old-chat-123'\n });\n\n webChat.messageGroups = [['existing', 'messages']];\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate chat_started with different chat_id\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'new-chat-456'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('new-chat-456');\n expect(webChat.messageGroups).to.deep.equal([]);\n });\n\n it('keeps messages when chat_id is the same', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // First, simulate a chat_started to set the URN\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'same-chat-123'\n });\n await webChat.updateComplete;\n\n // Now set some messages\n webChat.messageGroups = [['existing', 'messages']];\n await webChat.updateComplete;\n\n // Simulate another chat_started with the same chat_id\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'same-chat-123'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('same-chat-123');\n expect(webChat.messageGroups).to.deep.equal([['existing', 'messages']]);\n });\n });\n\n describe('User Input and Message Sending', () => {\n it('updates hasPendingText on keyup', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n expect(inputField).to.exist;\n\n expect(webChat.hasPendingText).to.equal(false);\n\n // Simulate typing\n inputField.value = 'Hello';\n inputField.dispatchEvent(new KeyboardEvent('keydown', { key: 'h' }));\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(true);\n\n // Clear input\n inputField.value = '';\n inputField.dispatchEvent(\n new KeyboardEvent('keydown', { key: 'Backspace' })\n );\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('sends message on Enter key', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Ensure the socket is properly set\n expect(webChat.status).to.equal('connected');\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = 'Test message';\n webChat.hasPendingText = true;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Call handleKeyUp directly with Enter key event\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n\n // Should have sent message\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const sentMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(sentMessage.type).to.equal('send_msg');\n expect(sentMessage.text).to.equal('Test message');\n\n // input should be cleared and hasPendingText should be false\n expect(inputField.value).to.equal('');\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('sends message via send button click', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n\n inputField.value = 'Button click message';\n webChat.hasPendingText = true;\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // call sendPendingMessage directly since it's a private method called by click handler\n (webChat as any).sendPendingMessage();\n await webChat.updateComplete;\n\n // should have sent message\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const sentMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(sentMessage.type).to.equal('send_msg');\n expect(sentMessage.text).to.equal('Button click message');\n });\n\n it('focuses input when input panel is clicked', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputPanel = webChat.shadowRoot.querySelector('.input-panel');\n expect(inputPanel).to.exist;\n\n // Mock focus method\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n let focusCalled = false;\n inputField.focus = () => {\n focusCalled = true;\n };\n\n await mouseClickElement(inputPanel);\n\n expect(focusCalled).to.be.true;\n });\n\n it('does not send message when disconnected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n // Keep the status as disconnected - don't connect the socket\n expect(webChat.status).to.equal('disconnected');\n\n // Find input field - it might not exist in disconnected state\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n if (inputField) {\n inputField.value = 'Should not send';\n webChat.hasPendingText = true;\n\n // Try to send message by calling handleKeyUp\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n }\n\n // Should not have created any WebSocket connections\n expect(webSocketStub.called).to.be.false;\n });\n });\n\n describe('History Fetching', () => {\n it('fetches previous messages when requested', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Manually call fetchPreviousMessages\n webChat.fetchPreviousMessages();\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(true);\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n\n const historyRequest = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(historyRequest.type).to.equal('get_history');\n expect(historyRequest.before).to.exist;\n });\n\n it('does not fetch when already fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Try to fetch - should be blocked\n webChat.fetchPreviousMessages();\n await webChat.updateComplete;\n\n expect(mockWebSocket.sentMessages.length).to.equal(initialMessageCount);\n });\n\n it('completes fetch and unblocks history fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n webChat.fetchComplete();\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n });\n\n describe('Edge Cases and Additional Coverage', () => {\n it('handles keyup events that are not Enter', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = 'Some text';\n\n // Test with non-Enter key\n webChat.handleKeyUp({ key: 'a', target: inputField });\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(true);\n\n // Test with empty value\n inputField.value = '';\n webChat.handleKeyUp({ key: 'Backspace', target: inputField });\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('does not send message on Enter if no pending text', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = '';\n webChat.hasPendingText = false;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Try to send with Enter but no pending text\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n\n // Should not have sent any new messages\n expect(mockWebSocket.sentMessages.length).to.equal(initialMessageCount);\n });\n\n it('updates status when open changes from false to true', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.status).to.equal('disconnected');\n\n // Open the chat for the first time\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n expect(webSocketStub.called).to.be.true;\n });\n\n it('focuses input when status changes to connected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // Open chat to trigger connection\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n\n // Mock focus method before the input is rendered\n let focusCalled = false;\n const originalFocus = HTMLInputElement.prototype.focus;\n HTMLInputElement.prototype.focus = function () {\n focusCalled = true;\n };\n\n // Manually open socket to trigger status change to connected\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Restore original focus\n HTMLInputElement.prototype.focus = originalFocus;\n\n // Focus should have been called when status changed to connected\n expect(focusCalled).to.be.true;\n });\n\n it('handles focus input when input element does not exist', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n // Try to focus input when it might not exist\n (webChat as any).focusInput();\n\n // Should not throw an error\n expect(true).to.be.true;\n });\n\n it('handles empty history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate empty history response\n mockWebSocket.simulateMessage({\n type: 'history',\n history: []\n });\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('handles message with msg_in in history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate history response with msg_in first\n mockWebSocket.simulateMessage({\n type: 'history',\n history: [\n {\n msg_in: {\n id: 'msg-1',\n text: 'Incoming message',\n time: '2021-03-31T00:30:00.000Z'\n }\n }\n ]\n });\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('prevents event propagation on input panel click', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputPanel = webChat.shadowRoot.querySelector('.input-panel');\n expect(inputPanel).to.exist;\n\n let preventDefaultCalled = false;\n let stopPropagationCalled = false;\n\n const mockEvent = {\n preventDefault: () => {\n preventDefaultCalled = true;\n },\n stopPropagation: () => {\n stopPropagationCalled = true;\n }\n };\n\n (webChat as any).handleClickInputPanel(mockEvent);\n\n expect(preventDefaultCalled).to.be.true;\n expect(stopPropagationCalled).to.be.true;\n });\n\n it('handles unknown message types gracefully', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate unknown message type\n mockWebSocket.simulateMessage({\n type: 'unknown_message_type',\n data: 'some data'\n });\n await webChat.updateComplete;\n\n // Should not throw an error\n expect(true).to.be.true;\n });\n });\n\n describe('Integration with Chat Component', () => {\n it('listens to scroll threshold event for history fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Simulate scroll threshold event\n chatElement.dispatchEvent(new CustomEvent('temba-scroll-threshold'));\n await webChat.updateComplete;\n\n // Should have triggered history fetch\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const historyRequest = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(historyRequest.type).to.equal('get_history');\n });\n\n it('listens to fetch complete event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n\n // Simulate fetch complete event\n chatElement.dispatchEvent(new CustomEvent('temba-fetch-complete'));\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"temba-webchat.test.js","sourceRoot":"","sources":["../../test/temba-webchat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { useFakeTimers, stub, SinonStub } from 'sinon';\nimport { WebChat } from '../src/webchat/WebChat';\nimport {\n assertScreenshot,\n getClip,\n getComponent,\n mockNow,\n mouseClickElement\n} from '../test/utils.test';\nimport { expect, assert } from '@open-wc/testing';\n\nlet clock: any;\n\nconst TAG = 'temba-webchat';\n\nconst getWebChat = async (attrs: any = {}) => {\n const webChat = (await getComponent(TAG, attrs, '', 400, 600)) as WebChat;\n\n return webChat;\n};\n\n// Mock WebSocket\nclass MockWebSocket {\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: CloseEvent) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public readyState: number = 0;\n public url: string;\n public sentMessages: string[] = [];\n public autoOpen: boolean = true;\n\n constructor(url: string) {\n this.url = url;\n // Only auto-open if enabled\n if (this.autoOpen) {\n // Use synchronous execution instead of setTimeout to avoid clock advancing issues\n this.readyState = 1; // OPEN\n if (this.onopen) {\n this.onopen(new Event('open'));\n }\n }\n }\n\n send(data: string) {\n this.sentMessages.push(data);\n }\n\n close() {\n this.readyState = 3; // CLOSED\n if (this.onclose) {\n this.onclose(new CloseEvent('close'));\n }\n }\n\n // Test helper to manually open connection\n manualOpen() {\n this.readyState = 1; // OPEN\n if (this.onopen) {\n this.onopen(new Event('open'));\n }\n }\n\n // Test helper to simulate incoming messages\n simulateMessage(data: any) {\n if (this.onmessage) {\n this.onmessage(\n new MessageEvent('message', { data: JSON.stringify(data) })\n );\n }\n }\n\n // Test helper to simulate errors\n simulateError() {\n if (this.onerror) {\n this.onerror(new Event('error'));\n }\n }\n}\n\ndescribe('temba-webchat', () => {\n let originalWebSocket: any;\n let mockWebSocket: MockWebSocket;\n let webSocketStub: SinonStub;\n let cookieStub: SinonStub;\n let mockedNow: SinonStub;\n\n beforeEach(() => {\n mockedNow = mockNow('2021-03-31T00:31:00.000-00:00');\n\n // Mock WebSocket\n originalWebSocket = window.WebSocket;\n webSocketStub = stub(window, 'WebSocket').callsFake((url: string) => {\n mockWebSocket = new MockWebSocket(url);\n mockWebSocket.autoOpen = false; // Disable auto-open by default\n return mockWebSocket as any;\n });\n\n // Mock document.cookie\n cookieStub = stub(document, 'cookie').value('');\n\n // Use fake timers but with a shorter timeout to avoid test hanging\n clock = useFakeTimers({\n shouldAdvanceTime: true,\n advanceTimeDelta: 10\n });\n });\n\n afterEach(() => {\n clock.restore();\n webSocketStub.restore();\n cookieStub.restore();\n mockedNow.restore();\n window.WebSocket = originalWebSocket;\n });\n\n describe('Component Initialization', () => {\n it('creates component with default properties', async () => {\n const webChat = await getWebChat();\n\n assert.instanceOf(webChat, WebChat);\n expect(webChat.open).to.equal(false);\n expect(webChat.status).to.equal('disconnected');\n expect(webChat.hasPendingText).to.equal(false);\n expect(webChat.messageGroups).to.deep.equal([]);\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('accepts channel and urn properties', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'test-urn-123'\n });\n\n expect(webChat.channel).to.equal('test-channel');\n expect(webChat.urn).to.equal('test-urn-123');\n });\n\n it('accepts host and activeUserAvatar properties', async () => {\n const webChat = await getWebChat({\n host: 'example.com',\n activeUserAvatar: 'https://example.com/avatar.jpg'\n });\n\n expect(webChat.host).to.equal('example.com');\n expect(webChat.activeUserAvatar).to.equal(\n 'https://example.com/avatar.jpg'\n );\n });\n\n it('initializes chat component on first update', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // Check that the chat component was initialized\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n });\n });\n\n describe('UI Rendering', () => {\n it('renders closed chat widget by default', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n await assertScreenshot('webchat/closed-widget', getClip(webChat));\n });\n\n it('renders opened chat widget', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n await assertScreenshot('webchat/opened-widget', getClip(webChat));\n });\n\n it('renders connecting state', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n expect(webChat.status).to.equal('disconnected');\n\n // Click to open the widget, which should trigger connecting state\n const toggleElement = webChat.shadowRoot.querySelector('.toggle');\n expect(toggleElement).to.exist;\n\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n clock.tick(50);\n\n // Now it should be open and connecting\n expect(webChat.open).to.equal(true);\n expect(webChat.status).to.equal('connecting');\n\n await assertScreenshot('webchat/connecting-state', getClip(webChat));\n });\n\n it('renders disconnected state with reconnect option', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n await assertScreenshot('webchat/disconnected-state', getClip(webChat));\n });\n\n it('renders connected state with input field', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n // the cursor is blinking, we need to account for it in our screenshot by making it transparent\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n expect(inputField).to.exist;\n inputField.style.caretColor = 'transparent';\n\n await assertScreenshot('webchat/connected-state', getClip(webChat));\n });\n });\n\n describe('Chat Toggle Functionality', () => {\n it('toggles chat open/closed', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n\n // Click the toggle element\n const toggleElement = webChat.shadowRoot.querySelector('.toggle');\n expect(toggleElement).to.exist;\n\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.open).to.equal(true);\n\n // Click toggle again\n await mouseClickElement(toggleElement);\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.open).to.equal(false);\n });\n\n it('toggles chat via close button', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n expect(webChat.open).to.equal(true);\n\n // Click close button in header\n const closeButton = webChat.shadowRoot.querySelector('.close-button');\n expect(closeButton).to.exist;\n\n await mouseClickElement(closeButton);\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(false);\n });\n\n it('opens chat programmatically', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.open).to.equal(false);\n\n webChat.openChat();\n await webChat.updateComplete;\n\n expect(webChat.open).to.equal(true);\n });\n });\n\n describe('Socket Connection Management', () => {\n it('opens socket when chat is opened', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.status).to.equal('disconnected');\n\n // Open chat - this should trigger socket connection\n webChat.open = true;\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.status).to.equal('connecting');\n expect(webSocketStub.called).to.be.true;\n expect(mockWebSocket.url).to.include('test-channel');\n\n // Now simulate the socket opening\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.status).to.equal('connected');\n });\n\n it('does not open socket if already connecting or connected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // First connection\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n const firstCallCount = webSocketStub.callCount;\n\n // Try to connect again while connecting\n webChat.open = false;\n webChat.open = true;\n await webChat.updateComplete;\n await clock.tick(0);\n\n // Should not create another socket\n expect(webSocketStub.callCount).to.equal(firstCallCount);\n });\n\n it('constructs correct WebSocket URL with channel', async () => {\n const webChat = await getWebChat({\n channel: 'my-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(mockWebSocket.url).to.equal(\n 'wss://localhost.textit.com/wc/connect/my-channel/'\n );\n });\n\n it('includes urn in WebSocket URL when present', async () => {\n const webChat = await getWebChat({\n channel: 'my-channel',\n urn: 'chat-123'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(mockWebSocket.url).to.equal(\n 'wss://localhost.textit.com/wc/connect/my-channel/?chat_id=chat-123'\n );\n });\n\n it('sends start_chat command on socket open', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n // Manually open the socket to trigger the start_chat command\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n clock.tick(100);\n\n expect(mockWebSocket.sentMessages.length).to.be.at.least(1);\n const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);\n expect(sentMessage.type).to.equal('start_chat');\n });\n\n it('includes chat_id in start_chat command when urn is present', async () => {\n // Set the cookie directly in document.cookie\n cookieStub.value('temba-chat-urn=existing-chat-123');\n\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'existing-chat-123'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n clock.tick(50);\n\n const sentMessage = JSON.parse(mockWebSocket.sentMessages[0]);\n expect(sentMessage.type).to.equal('start_chat');\n // The chat_id should be 'existing-chat-123' either from the urn property or cookie\n expect(sentMessage.chat_id).to.equal('existing-chat-123');\n });\n\n it('handles socket close event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.status).to.equal('connecting');\n\n mockWebSocket.close();\n await webChat.updateComplete;\n clock.tick(50);\n\n expect(webChat.status).to.equal('disconnected');\n });\n\n it('handles socket error event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n\n mockWebSocket.simulateError();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('disconnected');\n });\n\n it('reconnects when reconnect button is clicked', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n const reconnectButton = webChat.shadowRoot.querySelector('.reconnect');\n expect(reconnectButton).to.exist;\n\n await mouseClickElement(reconnectButton);\n await webChat.updateComplete;\n\n expect(webSocketStub.called).to.be.true;\n expect(webChat.status).to.equal('connecting');\n });\n });\n\n describe('Message Handling', () => {\n it('handles chat_started message', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connected');\n\n // Simulate chat_started message\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'new-chat-456'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('new-chat-456');\n expect(webChat.messageGroups).to.deep.equal([]);\n });\n\n it('handles chat_resumed message and fetches history', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate chat_resumed message\n mockWebSocket.simulateMessage({\n type: 'chat_resumed',\n chat_id: 'resumed-chat-789'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('resumed-chat-789');\n\n // Should have sent get_history command\n expect(mockWebSocket.sentMessages.length).to.be.greaterThan(1);\n const lastMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(lastMessage.type).to.equal('get_history');\n });\n\n it('handles chat_out message and sends ack', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Simulate incoming message\n mockWebSocket.simulateMessage({\n type: 'chat_out',\n msg_out: {\n id: 'msg-123',\n text: 'Hello from server',\n time: '2021-03-31T00:31:00.000Z',\n user: {\n id: 'user-1',\n name: 'Test User',\n email: 'test@example.com'\n }\n }\n });\n await webChat.updateComplete;\n\n // Should have sent ack\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const ackMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(ackMessage.type).to.equal('ack_chat');\n expect(ackMessage.msg_id).to.equal('msg-123');\n });\n\n it('handles history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate history response\n mockWebSocket.simulateMessage({\n type: 'history',\n history: [\n {\n msg_out: {\n id: 'msg-1',\n text: 'First message',\n time: '2021-03-31T00:30:00.000Z',\n user: { id: 'user-1', name: 'User', email: 'user@example.com' }\n }\n },\n {\n msg_in: {\n id: 'msg-2',\n text: 'Second message',\n time: '2021-03-31T00:30:30.000Z'\n }\n }\n ]\n });\n await webChat.updateComplete;\n\n // Should have updated beforeTime and unblocked history fetching\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('clears messages when chat_id changes', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n urn: 'old-chat-123'\n });\n\n webChat.messageGroups = [['existing', 'messages']];\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate chat_started with different chat_id\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'new-chat-456'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('new-chat-456');\n expect(webChat.messageGroups).to.deep.equal([]);\n });\n\n it('keeps messages when chat_id is the same', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // First, simulate a chat_started to set the URN\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'same-chat-123'\n });\n await webChat.updateComplete;\n\n // Now set some messages\n webChat.messageGroups = [['existing', 'messages']];\n await webChat.updateComplete;\n\n // Simulate another chat_started with the same chat_id\n mockWebSocket.simulateMessage({\n type: 'chat_started',\n chat_id: 'same-chat-123'\n });\n await webChat.updateComplete;\n\n expect(webChat.urn).to.equal('same-chat-123');\n expect(webChat.messageGroups).to.deep.equal([['existing', 'messages']]);\n });\n });\n\n describe('User Input and Message Sending', () => {\n it('updates hasPendingText on keyup', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n expect(inputField).to.exist;\n\n expect(webChat.hasPendingText).to.equal(false);\n\n // Simulate typing\n inputField.value = 'Hello';\n inputField.dispatchEvent(new KeyboardEvent('keydown', { key: 'h' }));\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(true);\n\n // Clear input\n inputField.value = '';\n inputField.dispatchEvent(\n new KeyboardEvent('keydown', { key: 'Backspace' })\n );\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('sends message on Enter key', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Ensure the socket is properly set\n expect(webChat.status).to.equal('connected');\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = 'Test message';\n webChat.hasPendingText = true;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Call handleKeyUp directly with Enter key event\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n\n // Should have sent message\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const sentMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(sentMessage.type).to.equal('send_msg');\n expect(sentMessage.text).to.equal('Test message');\n\n // input should be cleared and hasPendingText should be false\n expect(inputField.value).to.equal('');\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('sends message via send button click', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n\n inputField.value = 'Button click message';\n webChat.hasPendingText = true;\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // call sendPendingMessage directly since it's a private method called by click handler\n (webChat as any).sendPendingMessage();\n await webChat.updateComplete;\n\n // should have sent message\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const sentMessage = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(sentMessage.type).to.equal('send_msg');\n expect(sentMessage.text).to.equal('Button click message');\n });\n\n it('focuses input when input panel is clicked', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputPanel = webChat.shadowRoot.querySelector('.input-panel');\n expect(inputPanel).to.exist;\n\n // Mock focus method\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n let focusCalled = false;\n inputField.focus = () => {\n focusCalled = true;\n };\n\n await mouseClickElement(inputPanel);\n\n expect(focusCalled).to.be.true;\n });\n\n it('does not send message when disconnected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true\n });\n\n // Keep the status as disconnected - don't connect the socket\n expect(webChat.status).to.equal('disconnected');\n\n // Find input field - it might not exist in disconnected state\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n if (inputField) {\n inputField.value = 'Should not send';\n webChat.hasPendingText = true;\n\n // Try to send message by calling handleKeyUp\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n }\n\n // Should not have created any WebSocket connections\n expect(webSocketStub.called).to.be.false;\n });\n });\n\n describe('History Fetching', () => {\n it('fetches previous messages when requested', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Manually call fetchPreviousMessages\n webChat.fetchPreviousMessages();\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(true);\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n\n const historyRequest = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(historyRequest.type).to.equal('get_history');\n expect(historyRequest.before).to.exist;\n });\n\n it('does not fetch when already fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Try to fetch - should be blocked\n webChat.fetchPreviousMessages();\n await webChat.updateComplete;\n\n expect(mockWebSocket.sentMessages.length).to.equal(initialMessageCount);\n });\n\n it('completes fetch and unblocks history fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n webChat.fetchComplete();\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n });\n\n describe('Edge Cases and Additional Coverage', () => {\n it('handles keyup events that are not Enter', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = 'Some text';\n\n // Test with non-Enter key\n webChat.handleKeyUp({ key: 'a', target: inputField });\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(true);\n\n // Test with empty value\n inputField.value = '';\n webChat.handleKeyUp({ key: 'Backspace', target: inputField });\n await webChat.updateComplete;\n\n expect(webChat.hasPendingText).to.equal(false);\n });\n\n it('does not send message on Enter if no pending text', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const inputField = webChat.shadowRoot.querySelector(\n '.input'\n ) as HTMLInputElement;\n inputField.value = '';\n webChat.hasPendingText = false;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Try to send with Enter but no pending text\n webChat.handleKeyUp({ key: 'Enter', target: inputField });\n await webChat.updateComplete;\n\n // Should not have sent any new messages\n expect(mockWebSocket.sentMessages.length).to.equal(initialMessageCount);\n });\n\n it('updates status when open changes from false to true', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n expect(webChat.status).to.equal('disconnected');\n\n // Open the chat for the first time\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n expect(webSocketStub.called).to.be.true;\n });\n\n it('focuses input when status changes to connected', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n // Open chat to trigger connection\n webChat.open = true;\n await webChat.updateComplete;\n\n expect(webChat.status).to.equal('connecting');\n\n // Mock focus method before the input is rendered\n let focusCalled = false;\n const originalFocus = HTMLInputElement.prototype.focus;\n HTMLInputElement.prototype.focus = function () {\n focusCalled = true;\n };\n\n // Manually open socket to trigger status change to connected\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Restore original focus\n HTMLInputElement.prototype.focus = originalFocus;\n\n // Focus should have been called when status changed to connected\n expect(focusCalled).to.be.true;\n });\n\n it('handles focus input when input element does not exist', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'disconnected'\n });\n\n // Try to focus input when it might not exist\n (webChat as any).focusInput();\n\n // Should not throw an error\n expect(true).to.be.true;\n });\n\n it('handles empty history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate empty history response\n mockWebSocket.simulateMessage({\n type: 'history',\n history: []\n });\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('handles message with msg_in in history response', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate history response with msg_in first\n mockWebSocket.simulateMessage({\n type: 'history',\n history: [\n {\n msg_in: {\n id: 'msg-1',\n text: 'Incoming message',\n time: '2021-03-31T00:30:00.000Z'\n }\n }\n ]\n });\n await webChat.updateComplete;\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n\n it('prevents event propagation on input panel click', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel',\n open: true,\n status: 'connected'\n });\n\n const inputPanel = webChat.shadowRoot.querySelector('.input-panel');\n expect(inputPanel).to.exist;\n\n let preventDefaultCalled = false;\n let stopPropagationCalled = false;\n\n const mockEvent = {\n preventDefault: () => {\n preventDefaultCalled = true;\n },\n stopPropagation: () => {\n stopPropagationCalled = true;\n }\n };\n\n (webChat as any).handleClickInputPanel(mockEvent);\n\n expect(preventDefaultCalled).to.be.true;\n expect(stopPropagationCalled).to.be.true;\n });\n\n it('handles unknown message types gracefully', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n // Simulate unknown message type\n mockWebSocket.simulateMessage({\n type: 'unknown_message_type',\n data: 'some data'\n });\n await webChat.updateComplete;\n\n // Should not throw an error\n expect(true).to.be.true;\n });\n });\n\n describe('Integration with Chat Component', () => {\n it('listens to scroll threshold event for history fetching', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.open = true;\n await webChat.updateComplete;\n mockWebSocket.manualOpen();\n await webChat.updateComplete;\n\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n\n const initialMessageCount = mockWebSocket.sentMessages.length;\n\n // Simulate scroll threshold event\n chatElement.dispatchEvent(new CustomEvent('temba-scroll-threshold'));\n await webChat.updateComplete;\n\n // Should have triggered history fetch\n expect(mockWebSocket.sentMessages.length).to.equal(\n initialMessageCount + 1\n );\n const historyRequest = JSON.parse(\n mockWebSocket.sentMessages[mockWebSocket.sentMessages.length - 1]\n );\n expect(historyRequest.type).to.equal('get_history');\n });\n\n it('listens to fetch complete event', async () => {\n const webChat = await getWebChat({\n channel: 'test-channel'\n });\n\n webChat.blockHistoryFetching = true;\n\n const chatElement = webChat.shadowRoot.querySelector('temba-chat');\n expect(chatElement).to.exist;\n\n // Simulate fetch complete event\n chatElement.dispatchEvent(new CustomEvent('temba-fetch-complete'));\n\n expect(webChat.blockHistoryFetching).to.equal(false);\n });\n });\n});\n"]}
@@ -2,7 +2,7 @@ import '../temba-modules';
2
2
  import { DateTime } from 'luxon';
3
3
  import { expect, fixture, html, assert, waitUntil } from '@open-wc/testing';
4
4
  import MouseHelper from './MouseHelper';
5
- import { replace, stub } from 'sinon';
5
+ import { stub } from 'sinon';
6
6
  const gets = [];
7
7
  let posts = [];
8
8
  let normalFetch;
@@ -205,11 +205,7 @@ export const loadStore = async () => {
205
205
  return store;
206
206
  };
207
207
  export const mockNow = (isodate) => {
208
- const now = DateTime.fromISO(isodate);
209
- // mock the current time
210
- replace(DateTime, 'now', () => {
211
- return now;
212
- });
208
+ return stub(DateTime, 'now').returns(DateTime.fromISO(isodate));
213
209
  };
214
210
  export const getOptions = (select) => {
215
211
  return select.shadowRoot.querySelector('temba-options[visible]');
@@ -1 +1 @@
1
- {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../test/utils.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAQjC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,WAAW,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAatC,MAAM,IAAI,GAAe,EAAE,CAAC;AAC5B,IAAI,KAAK,GAAe,EAAE,CAAC;AAC3B,IAAI,WAAW,CAAC;AAEhB,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;IAClC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,kBAAkB,CAAC,CAAC;IACpD,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAa,EAAE,EAAE,EAAE;IAC/C,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SACzB,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;QACpB,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACpC,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,GAAG,EACH,QAAa,EAAE,EACf,IAAI,GAAG,EAAE,EACT,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,CAAC,EACV,KAAK,GAAG,EAAE,EACV,EAAE;IACF,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,GAAG,CAAC;IAChE,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG;MACnB,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE;MACpC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE;MACvC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;GACrB,CAAC;IACF,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACjD,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,EAAE;IAChC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;QACpD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE;YACP,cAAc,EAAE,WAAW;YAC3B,GAAG,MAAM,CAAC,OAAO;SAClB;KACF,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,EAAE;IACpC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACpE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,MAAM,CAAC,OAAO;SAClB;KACF,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;IACpE,4CAA4C;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEpE,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,uCAAuC;YACvC,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,4BAA4B;IAC5B,OAAO,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,IAAI,EAAE;IAChB,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,GAAG,EAAE;IACR,MAAM,CAAC,KAAa,CAAC,OAAO,EAAE,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG;IAClB,oCAAoC,EAAE;QACpC,iDAAiD;KAClD;IACD,qCAAqC,EAAE;QACrC,kDAAkD;KACnD;IACD,oCAAoC,EAAE;QACpC,iDAAiD;KAClD;IACD,qCAAqC,EAAE;QACrC,kDAAkD;KACnD;IACD,4CAA4C,EAAE;QAC5C,uEAAuE;KACxE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE;IAC1B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,QAAgB,EAChB,IAAS,EACT,UAAe,EAAE,EACjB,MAAM,GAAG,KAAK,EACd,EAAE;IACF,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,QAAgB,EAChB,IAAS,EACT,UAAe,EAAE,EACjB,MAAM,GAAG,KAAK,EACd,EAAE;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,KAAK,GAAG,EAAE,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAU,EAAE,EAAE;IACxC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC;IACnE,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAChC,0BAA0B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CACzD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE;IACtC,OAAO,IAAI,OAAO,CAAC,UAAU,OAAO;QAClC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,SAAwB,EACxB,cAAsB,EAAE,EACxB,UAAkB,EAAE,EACL,EAAE;IACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,OAAO,CAAC,SAAS,EAAE,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC9C,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,QAAQ,EAAE,CAAC;IACb,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,2BAA2B,WAAW,cACpC,WAAW,GAAG,OAChB,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAgB,EAChB,IAAU,EACV,OAAoD,EACpD,EAAE;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,8EAA8E;IAC9E,MAAM,oBAAoB,GAAI,MAAc,CAAC,oBAAoB,CAAC;IAClE,MAAM,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnD,MAAM,OAAO,GAAW,EAAE,CAAC;IAE3B,IAAI,CAAC;QACH,MAAO,MAAc,CAAC,iBAAiB,CACrC,GAAG,QAAQ,MAAM,EACjB,IAAI,EACJ,OAAO,EACP,SAAS,CACV,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,OAAO,IACd,KAAK,CAAC,QAAQ;gBACZ,CAAC,CAAC,YAAY,KAAK,CAAC,QAAQ,YAAY,KAAK,CAAC,MAAM,EAAE;gBACtD,CAAC,CAAC,EACN,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACvD,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAgB,EAAE,EAAE;IAC1C,IAAI,IAAI,GAAQ,GAAG,CAAC,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC;IAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC;IAE3B,MAAM,OAAO,GAAG;QACd,CAAC;QACD,CAAC;QACD,KAAK;QACL,MAAM;QACN,MAAM,EAAE,CAAC,GAAG,MAAM;QAClB,KAAK,EAAE,CAAC,GAAG,KAAK;QAChB,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;KACR,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,GAA0B,EAAE,EAAE;IACpE,MAAM,MAAM,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;IAC3C,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAa,EAAE,EAAE,EAAE;IAC9C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SACtB,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SACjD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,QAAa,EAAE,EAAE,EAAE;IACtD,OAAO,IAAI,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;IAClC,MAAM,KAAK,GAAU,MAAM,OAAO,CAChC;;;;;;;OAOG,CACJ,CAAC;IACF,MAAM,KAAK,CAAC,mBAAmB,CAAC;IAChC,MAAM,KAAK,CAAC,mBAAmB,CAAC;IAEhC,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,EAAE;IACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,wBAAwB;IACxB,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAA4B,EAAW,EAAE;IAClE,OAAO,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,KAAU,EACV,MAA4B,EAC5B,KAAa,EACb,EAAE;;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,mFAAmF;IACnF,MAAM,cAAc,GAAG,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CACtD,uBAAuB,KAAK,IAAI,CACjC,CAAC;IACF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,gBAAgB,CACpB,GAAG,EAAE;;gBACH,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAC9C,uBAAuB,KAAK,IAAI,CACjC,CAAC;gBACF,OAAO,CAAC,CAAC,MAAM,CAAC;YAClB,CAAC,EACD,EAAE,EACF,EAAE,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,0BAA0B,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAC7C,uBAAuB,KAAK,IAAI,CACf,CAAC;IAEpB,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,OAAO,CAAC,cAAc,CAAC;IAC7B,MAAM,MAAM,CAAC,cAAc,CAAC;IAC5B,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;IAErB,WAAW,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,KAAU,EAAE,MAA4B,EAAE,EAAE;IAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACvE,SAAS,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpE,KAAK,CAAC,MAAM,EAAE,CAAC;IAEf,4CAA4C;IAC5C,MAAM,MAAM,CAAC,cAAc,CAAC;IAC5B,KAAK,CAAC,MAAM,EAAE,CAAC;IAEf,iDAAiD;IACjD,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAClB,KAAK,CAAC,MAAM,EAAE,CAAC;IAEf,mEAAmE;IACnE,yDAAyD;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,uFAAuF;YACvF,MAAM,gBAAgB,CACpB,GAAG,EAAE;gBACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAC7C,wBAAwB,CACzB,CAAC;gBACF,OAAO,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;YACxC,CAAC,EACD,EAAE,EACF,EAAE,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,6FAA6F;QAC/F,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,KAAU,EACV,MAA4B,EAC5B,GAAW,EACX,EAAE;IACF,MAAM,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEhC,6EAA6E;IAC7E,MAAM,MAAM,CAAC,cAAc,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,6DAA6D;IAE7E,MAAM,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAgB,EAAE;IAChE,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC;QACtB,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,CAAC;YACP,YAAY,EAAE,WAAW;YACzB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,OAAO,GAAG,CAAC;YACrB,GAAG,EAAE,MAAM,GAAG,CAAC;YACf,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI;SACE,CAAC;QAChB,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,OAAgB,EAChB,IAAa,EACb,WAA0B,EACX,EAAE;IACjB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,OAAO,CAAC,kBAAkB,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,MAAM,OAAO,CAAC,cAAc,CAAC;AAC/B,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAEF,uDAAuD;AACvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,MAA4B,EAC5B,KAAU,EACV,aAAqB,EACrB,cAAsB,EAAE,EACT,EAAE;IACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,OAAO,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC9B,kCAAkC;QAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;YACtE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,CAAC,cAAc,CAAC;QAC5B,KAAK,CAAC,MAAM,EAAE,CAAC;QAEf,2DAA2D;QAC3D,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;QAEhB,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qCAAqC,WAAW,cAC9C,WAAW,GAAG,EAChB,OAAO;QACL,YAAY,aAAa,iBAAiB,MAAM,CAAC,cAAc,CAAC,MAAM,IAAI;QAC1E,aAAa,MAAM,CAAC,QAAQ,EAAE,CACjC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import '../temba-modules';\nimport { DateTime } from 'luxon';\ninterface Clip {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nimport { expect, fixture, html, assert, waitUntil } from '@open-wc/testing';\nimport MouseHelper from './MouseHelper';\nimport { Store } from '../src/store/Store';\nimport { replace, stub } from 'sinon';\nimport { Select, SelectOption } from '../src/select/Select';\nimport { Options } from '../src/options/Options';\nimport { Attachment } from '../src/interfaces';\nimport { Compose } from '../src/compose/Compose';\n\nexport interface CodeMock {\n endpoint: RegExp;\n body: string;\n headers: any;\n status: string;\n}\n\nconst gets: CodeMock[] = [];\nlet posts: CodeMock[] = [];\nlet normalFetch;\n\nexport const showMouse = async () => {\n const mouse = await fixture(html`<mouse-helper />`);\n assert.instanceOf(mouse, MouseHelper);\n};\n\nexport const getAttributes = (attrs: any = {}) => {\n return `${Object.keys(attrs)\n .map((name: string) => {\n if (typeof attrs[name] === 'boolean' && attrs[name]) {\n return name;\n }\n return `${name}='${attrs[name]}'`;\n })\n .join(' ')}`;\n};\n\nexport const getComponent = async (\n tag,\n attrs: any = {},\n slot = '',\n width = 250,\n height = 0,\n style = ''\n) => {\n const spec = `<${tag} ${getAttributes(attrs)}>${slot}</${tag}>`;\n const parentNode = document.createElement('div');\n const styleAttribute = `\n ${width > 0 ? `width:${width}px;` : ``} \n ${height > 0 ? `height:${height}px;` : ``}\n ${style ? style : ``}\n `;\n parentNode.setAttribute('style', styleAttribute);\n return await fixture(spec, { parentNode });\n};\n\nconst createResponse = (mocked) => {\n const mockResponse = new window.Response(mocked.body, {\n status: mocked.status,\n headers: {\n 'Content-type': 'text/html',\n ...mocked.headers\n }\n });\n\n return Promise.resolve(mockResponse);\n};\n\nconst createJSONResponse = (mocked) => {\n const mockResponse = new window.Response(JSON.stringify(mocked.body), {\n status: mocked.status,\n headers: {\n 'Content-type': 'application/json',\n ...mocked.headers\n }\n });\n\n return Promise.resolve(mockResponse);\n};\n\nconst getResponse = (endpoint: string, options = { method: 'GET' }) => {\n // check if our path has been mocked in code\n const mocks = options.method === 'GET' ? gets : posts;\n const codeMock = mocks.find((mock) => mock.endpoint.test(endpoint));\n\n if (codeMock) {\n if (typeof codeMock.body === 'string') {\n // see if we are being mocked to a file\n if (codeMock.body.startsWith('/')) {\n endpoint = codeMock.body;\n } else {\n return createResponse(codeMock);\n }\n } else {\n return createJSONResponse(codeMock);\n }\n }\n // otherwise fetch over http\n return normalFetch(endpoint, options);\n};\n\nbefore(async () => {\n normalFetch = window.fetch;\n stub(window, 'fetch').callsFake(getResponse);\n await setViewport({ width: 1024, height: 768, deviceScaleFactor: 2 });\n});\n\nafter(() => {\n (window.fetch as any).restore();\n});\n\nconst mockMapping = {\n '/test-assets/api/users/admin1.json': [\n /\\/api\\/v2\\/users.json\\?email=admin1@nyaruka.com/\n ],\n '/test-assets/api/users/editor1.json': [\n /\\/api\\/v2\\/users.json\\?email=editor1@nyaruka.com/\n ],\n '/test-assets/api/users/agent1.json': [\n /\\/api\\/v2\\/users.json\\?email=agent1@nyaruka.com/\n ],\n '/test-assets/api/users/viewer1.json': [\n /\\/api\\/v2\\/users.json\\?email=viewer1@nyaruka.com/\n ],\n '/test-assets/contacts/contact-tickets.json': [\n /\\/api\\/v2\\/tickets.json\\?contact=24d64810-3315-4ff5-be85-48e3fe055bf9/\n ]\n};\n\nexport const mockAPI = () => {\n for (const key in mockMapping) {\n const urls = mockMapping[key];\n for (const url of urls) {\n mockGET(url, key);\n }\n }\n};\n\nexport const mockGET = (\n endpoint: RegExp,\n body: any,\n headers: any = {},\n status = '200'\n) => {\n gets.push({ endpoint, body, headers, status });\n};\n\nexport const mockPOST = (\n endpoint: RegExp,\n body: any,\n headers: any = {},\n status = '200'\n) => {\n posts.push({ endpoint, body, headers, status });\n};\n\nexport const clearMockPosts = () => {\n posts = [];\n};\n\nexport const checkTimers = (clock: any) => {\n expect(!!clock.timers).to.equal(true, 'Expected timers not found');\n expect(\n Object.keys(clock.timers).length,\n `Timers still to be run ${JSON.stringify(clock.timers)}`\n ).to.equal(0);\n};\n\nexport const delay = (millis: number) => {\n return new Promise(function (resolve) {\n window.setTimeout(resolve, millis);\n });\n};\n\n// Enhanced wait utility for more robust testing\nexport const waitForCondition = async (\n predicate: () => boolean,\n maxAttempts: number = 20,\n delayMs: number = 50\n): Promise<void> => {\n let attempts = 0;\n while (!predicate() && attempts < maxAttempts) {\n await delay(delayMs);\n attempts++;\n }\n if (!predicate()) {\n throw new Error(\n `Condition not met after ${maxAttempts} attempts (${\n maxAttempts * delayMs\n }ms)`\n );\n }\n};\n\nexport const assertScreenshot = async (\n filename: string,\n clip: Clip,\n waitFor?: { clock?: any; predicate?: () => boolean }\n) => {\n if (waitFor) {\n if (waitFor.clock) {\n waitFor.clock.restore();\n }\n await waitUntil(waitFor.predicate);\n }\n\n // detect if we're running in copilot's environment and use adaptive threshold\n const isCopilotEnvironment = (window as any).isCopilotEnvironment;\n const threshold = isCopilotEnvironment ? 1.0 : 0.1;\n const exclude: Clip[] = [];\n\n try {\n await (window as any).matchPageSnapshot(\n `${filename}.png`,\n clip,\n exclude,\n threshold\n );\n } catch (error) {\n if (error.message) {\n throw new Error(\n `${error.message} ${\n error.expected\n ? `Expected ${error.expected} but got ${error.actual}`\n : ''\n } ${error.files ? `\\n${error.files.join('\\n')}` : ''}`\n );\n }\n throw new Error(error);\n }\n};\n\nexport const getClip = (ele: HTMLElement) => {\n let clip: any = ele.getBoundingClientRect();\n if (!clip.width || !clip.height) {\n clip = ele.shadowRoot.firstElementChild.getBoundingClientRect();\n }\n\n const padding = 10;\n const width = clip.width + padding * 2;\n const height = clip.height + padding * 2;\n const y = clip.y - padding;\n const x = clip.x - padding;\n\n const newClip = {\n x,\n y,\n width,\n height,\n bottom: y + height,\n right: x + width,\n top: y,\n left: x\n };\n\n return newClip;\n};\n\nexport const mouseClickElement = async (ele: HTMLElement | Element) => {\n const bounds = ele.getBoundingClientRect();\n await mouseClick(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);\n};\n\nexport const getHTMLAttrs = (attrs: any = {}) => {\n return Object.keys(attrs)\n .map((name: string) => `${name}='${attrs[name]}'`)\n .join(' ');\n};\n\nexport const getHTML = (tag: string, attrs: any = {}) => {\n return `<${tag} ${getHTMLAttrs(attrs)}></${tag}>`;\n};\n\nexport const loadStore = async () => {\n const store: Store = await fixture(\n `<temba-store \n completion='/test-assets/store/editor.json'\n groups='/test-assets/store/groups.json'\n languages='/test-assets/store/languages.json'\n fields='/test-assets/store/fields.json'\n users='/test-assets/store/users.json'\n workspace='/test-assets/store/workspace.json'\n />`\n );\n await store.initialHttpComplete;\n await store.initialHttpComplete;\n\n return store;\n};\n\nexport const mockNow = (isodate: string) => {\n const now = DateTime.fromISO(isodate);\n // mock the current time\n replace(DateTime, 'now', () => {\n return now;\n });\n};\n\nexport const getOptions = (select: Select<SelectOption>): Options => {\n return select.shadowRoot.querySelector('temba-options[visible]');\n};\n\nexport const clickOption = async (\n clock: any,\n select: Select<SelectOption>,\n index: number\n) => {\n const options = getOptions(select);\n if (!options) {\n throw new Error('No options element found');\n }\n\n // Wait for the specific option to be available, but only if it's not already there\n const existingOption = options.shadowRoot?.querySelector(\n `[data-option-index=\"${index}\"]`\n );\n if (!existingOption) {\n try {\n await waitForCondition(\n () => {\n const option = options.shadowRoot?.querySelector(\n `[data-option-index=\"${index}\"]`\n );\n return !!option;\n },\n 10,\n 25\n );\n } catch (e) {\n throw new Error(`Option at index ${index} not found after waiting`);\n }\n }\n\n const option = options.shadowRoot.querySelector(\n `[data-option-index=\"${index}\"]`\n ) as HTMLDivElement;\n\n await mouseClickElement(option);\n await options.updateComplete;\n await select.updateComplete;\n await clock.runAll();\n\n checkTimers(clock);\n};\nexport const openSelect = async (clock: any, select: Select<SelectOption>) => {\n const container = select.shadowRoot.querySelector('.select-container');\n container.dispatchEvent(new MouseEvent('click', { bubbles: true }));\n\n clock.runAll();\n\n // add more explicit waiting and clock ticks\n await select.updateComplete;\n clock.runAll();\n\n // reduce wait time for options to become visible\n await waitFor(25);\n clock.runAll();\n\n // For non-endpoint selects, options might be immediately available\n // For endpoint selects, we need to wait for them to load\n const hasEndpoint = select.getAttribute('endpoint');\n if (hasEndpoint) {\n try {\n // Wait for options to be properly rendered and visible (but only for endpoint selects)\n await waitForCondition(\n () => {\n const options = select.shadowRoot.querySelector(\n 'temba-options[visible]'\n );\n return options && options.isConnected;\n },\n 10,\n 25\n );\n } catch (e) {\n // If condition fails, continue - some tests might not need options to be visible immediately\n }\n }\n};\n\nexport const openAndClick = async (\n clock: any,\n select: Select<SelectOption>,\n idx: number\n) => {\n await openSelect(clock, select);\n\n // Add this line to ensure proper timing when running as part of a test suite\n await select.updateComplete;\n clock.tick(25); // Reduced from 50 to give minimum time for options to render\n\n await clickOption(clock, select, idx);\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n\n// Helper for waiting for select pagination to complete\nexport const waitForSelectPagination = async (\n select: Select<SelectOption>,\n clock: any,\n expectedCount: number,\n maxAttempts: number = 30\n): Promise<void> => {\n let attempts = 0;\n while (attempts < maxAttempts) {\n // Ensure we're not still fetching\n if (!select.fetching && select.visibleOptions.length >= expectedCount) {\n return;\n }\n\n await select.updateComplete;\n clock.runAll();\n\n // Give more time between attempts for slow CI environments\n await delay(75);\n\n attempts++;\n }\n\n throw new Error(\n `Pagination did not complete after ${maxAttempts} attempts (${\n maxAttempts * 75\n }ms). ` +\n `Expected ${expectedCount} options, got ${select.visibleOptions.length}. ` +\n `Fetching: ${select.fetching}`\n );\n};\n"]}
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../test/utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import '../temba-modules';\nimport { DateTime } from 'luxon';\ninterface Clip {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nimport { expect, fixture, html, assert, waitUntil } from '@open-wc/testing';\nimport MouseHelper from './MouseHelper';\nimport { Store } from '../src/store/Store';\nimport { stub } from 'sinon';\nimport { Select, SelectOption } from '../src/form/select/Select';\nimport { Options } from '../src/display/Options';\nimport { Attachment } from '../src/interfaces';\nimport { Compose } from '../src/form/Compose';\n\nexport interface CodeMock {\n endpoint: RegExp;\n body: string;\n headers: any;\n status: string;\n}\n\nconst gets: CodeMock[] = [];\nlet posts: CodeMock[] = [];\nlet normalFetch;\n\nexport const showMouse = async () => {\n const mouse = await fixture(html`<mouse-helper />`);\n assert.instanceOf(mouse, MouseHelper);\n};\n\nexport const getAttributes = (attrs: any = {}) => {\n return `${Object.keys(attrs)\n .map((name: string) => {\n if (typeof attrs[name] === 'boolean' && attrs[name]) {\n return name;\n }\n return `${name}='${attrs[name]}'`;\n })\n .join(' ')}`;\n};\n\nexport const getComponent = async (\n tag,\n attrs: any = {},\n slot = '',\n width = 250,\n height = 0,\n style = ''\n) => {\n const spec = `<${tag} ${getAttributes(attrs)}>${slot}</${tag}>`;\n const parentNode = document.createElement('div');\n const styleAttribute = `\n ${width > 0 ? `width:${width}px;` : ``} \n ${height > 0 ? `height:${height}px;` : ``}\n ${style ? style : ``}\n `;\n parentNode.setAttribute('style', styleAttribute);\n return await fixture(spec, { parentNode });\n};\n\nconst createResponse = (mocked) => {\n const mockResponse = new window.Response(mocked.body, {\n status: mocked.status,\n headers: {\n 'Content-type': 'text/html',\n ...mocked.headers\n }\n });\n\n return Promise.resolve(mockResponse);\n};\n\nconst createJSONResponse = (mocked) => {\n const mockResponse = new window.Response(JSON.stringify(mocked.body), {\n status: mocked.status,\n headers: {\n 'Content-type': 'application/json',\n ...mocked.headers\n }\n });\n\n return Promise.resolve(mockResponse);\n};\n\nconst getResponse = (endpoint: string, options = { method: 'GET' }) => {\n // check if our path has been mocked in code\n const mocks = options.method === 'GET' ? gets : posts;\n const codeMock = mocks.find((mock) => mock.endpoint.test(endpoint));\n\n if (codeMock) {\n if (typeof codeMock.body === 'string') {\n // see if we are being mocked to a file\n if (codeMock.body.startsWith('/')) {\n endpoint = codeMock.body;\n } else {\n return createResponse(codeMock);\n }\n } else {\n return createJSONResponse(codeMock);\n }\n }\n // otherwise fetch over http\n return normalFetch(endpoint, options);\n};\n\nbefore(async () => {\n normalFetch = window.fetch;\n stub(window, 'fetch').callsFake(getResponse);\n await setViewport({ width: 1024, height: 768, deviceScaleFactor: 2 });\n});\n\nafter(() => {\n (window.fetch as any).restore();\n});\n\nconst mockMapping = {\n '/test-assets/api/users/admin1.json': [\n /\\/api\\/v2\\/users.json\\?email=admin1@nyaruka.com/\n ],\n '/test-assets/api/users/editor1.json': [\n /\\/api\\/v2\\/users.json\\?email=editor1@nyaruka.com/\n ],\n '/test-assets/api/users/agent1.json': [\n /\\/api\\/v2\\/users.json\\?email=agent1@nyaruka.com/\n ],\n '/test-assets/api/users/viewer1.json': [\n /\\/api\\/v2\\/users.json\\?email=viewer1@nyaruka.com/\n ],\n '/test-assets/contacts/contact-tickets.json': [\n /\\/api\\/v2\\/tickets.json\\?contact=24d64810-3315-4ff5-be85-48e3fe055bf9/\n ]\n};\n\nexport const mockAPI = () => {\n for (const key in mockMapping) {\n const urls = mockMapping[key];\n for (const url of urls) {\n mockGET(url, key);\n }\n }\n};\n\nexport const mockGET = (\n endpoint: RegExp,\n body: any,\n headers: any = {},\n status = '200'\n) => {\n gets.push({ endpoint, body, headers, status });\n};\n\nexport const mockPOST = (\n endpoint: RegExp,\n body: any,\n headers: any = {},\n status = '200'\n) => {\n posts.push({ endpoint, body, headers, status });\n};\n\nexport const clearMockPosts = () => {\n posts = [];\n};\n\nexport const checkTimers = (clock: any) => {\n expect(!!clock.timers).to.equal(true, 'Expected timers not found');\n expect(\n Object.keys(clock.timers).length,\n `Timers still to be run ${JSON.stringify(clock.timers)}`\n ).to.equal(0);\n};\n\nexport const delay = (millis: number) => {\n return new Promise(function (resolve) {\n window.setTimeout(resolve, millis);\n });\n};\n\n// Enhanced wait utility for more robust testing\nexport const waitForCondition = async (\n predicate: () => boolean,\n maxAttempts: number = 20,\n delayMs: number = 50\n): Promise<void> => {\n let attempts = 0;\n while (!predicate() && attempts < maxAttempts) {\n await delay(delayMs);\n attempts++;\n }\n if (!predicate()) {\n throw new Error(\n `Condition not met after ${maxAttempts} attempts (${\n maxAttempts * delayMs\n }ms)`\n );\n }\n};\n\nexport const assertScreenshot = async (\n filename: string,\n clip: Clip,\n waitFor?: { clock?: any; predicate?: () => boolean }\n) => {\n if (waitFor) {\n if (waitFor.clock) {\n waitFor.clock.restore();\n }\n await waitUntil(waitFor.predicate);\n }\n\n // detect if we're running in copilot's environment and use adaptive threshold\n const isCopilotEnvironment = (window as any).isCopilotEnvironment;\n const threshold = isCopilotEnvironment ? 1.0 : 0.1;\n const exclude: Clip[] = [];\n\n try {\n await (window as any).matchPageSnapshot(\n `${filename}.png`,\n clip,\n exclude,\n threshold\n );\n } catch (error) {\n if (error.message) {\n throw new Error(\n `${error.message} ${\n error.expected\n ? `Expected ${error.expected} but got ${error.actual}`\n : ''\n } ${error.files ? `\\n${error.files.join('\\n')}` : ''}`\n );\n }\n throw new Error(error);\n }\n};\n\nexport const getClip = (ele: HTMLElement) => {\n let clip: any = ele.getBoundingClientRect();\n if (!clip.width || !clip.height) {\n clip = ele.shadowRoot.firstElementChild.getBoundingClientRect();\n }\n\n const padding = 10;\n const width = clip.width + padding * 2;\n const height = clip.height + padding * 2;\n const y = clip.y - padding;\n const x = clip.x - padding;\n\n const newClip = {\n x,\n y,\n width,\n height,\n bottom: y + height,\n right: x + width,\n top: y,\n left: x\n };\n\n return newClip;\n};\n\nexport const mouseClickElement = async (ele: HTMLElement | Element) => {\n const bounds = ele.getBoundingClientRect();\n await mouseClick(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);\n};\n\nexport const getHTMLAttrs = (attrs: any = {}) => {\n return Object.keys(attrs)\n .map((name: string) => `${name}='${attrs[name]}'`)\n .join(' ');\n};\n\nexport const getHTML = (tag: string, attrs: any = {}) => {\n return `<${tag} ${getHTMLAttrs(attrs)}></${tag}>`;\n};\n\nexport const loadStore = async () => {\n const store: Store = await fixture(\n `<temba-store \n completion='/test-assets/store/editor.json'\n groups='/test-assets/store/groups.json'\n languages='/test-assets/store/languages.json'\n fields='/test-assets/store/fields.json'\n users='/test-assets/store/users.json'\n workspace='/test-assets/store/workspace.json'\n />`\n );\n await store.initialHttpComplete;\n await store.initialHttpComplete;\n\n return store;\n};\n\nexport const mockNow = (isodate: string) => {\n return stub(DateTime, 'now').returns(DateTime.fromISO(isodate));\n};\n\nexport const getOptions = (select: Select<SelectOption>): Options => {\n return select.shadowRoot.querySelector('temba-options[visible]');\n};\n\nexport const clickOption = async (\n clock: any,\n select: Select<SelectOption>,\n index: number\n) => {\n const options = getOptions(select);\n if (!options) {\n throw new Error('No options element found');\n }\n\n // Wait for the specific option to be available, but only if it's not already there\n const existingOption = options.shadowRoot?.querySelector(\n `[data-option-index=\"${index}\"]`\n );\n if (!existingOption) {\n try {\n await waitForCondition(\n () => {\n const option = options.shadowRoot?.querySelector(\n `[data-option-index=\"${index}\"]`\n );\n return !!option;\n },\n 10,\n 25\n );\n } catch (e) {\n throw new Error(`Option at index ${index} not found after waiting`);\n }\n }\n\n const option = options.shadowRoot.querySelector(\n `[data-option-index=\"${index}\"]`\n ) as HTMLDivElement;\n\n await mouseClickElement(option);\n await options.updateComplete;\n await select.updateComplete;\n await clock.runAll();\n\n checkTimers(clock);\n};\nexport const openSelect = async (clock: any, select: Select<SelectOption>) => {\n const container = select.shadowRoot.querySelector('.select-container');\n container.dispatchEvent(new MouseEvent('click', { bubbles: true }));\n\n clock.runAll();\n\n // add more explicit waiting and clock ticks\n await select.updateComplete;\n clock.runAll();\n\n // reduce wait time for options to become visible\n await waitFor(25);\n clock.runAll();\n\n // For non-endpoint selects, options might be immediately available\n // For endpoint selects, we need to wait for them to load\n const hasEndpoint = select.getAttribute('endpoint');\n if (hasEndpoint) {\n try {\n // Wait for options to be properly rendered and visible (but only for endpoint selects)\n await waitForCondition(\n () => {\n const options = select.shadowRoot.querySelector(\n 'temba-options[visible]'\n );\n return options && options.isConnected;\n },\n 10,\n 25\n );\n } catch (e) {\n // If condition fails, continue - some tests might not need options to be visible immediately\n }\n }\n};\n\nexport const openAndClick = async (\n clock: any,\n select: Select<SelectOption>,\n idx: number\n) => {\n await openSelect(clock, select);\n\n // Add this line to ensure proper timing when running as part of a test suite\n await select.updateComplete;\n clock.tick(25); // Reduced from 50 to give minimum time for options to render\n\n await clickOption(clock, select, idx);\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n\n// Helper for waiting for select pagination to complete\nexport const waitForSelectPagination = async (\n select: Select<SelectOption>,\n clock: any,\n expectedCount: number,\n maxAttempts: number = 30\n): Promise<void> => {\n let attempts = 0;\n while (attempts < maxAttempts) {\n // Ensure we're not still fetching\n if (!select.fetching && select.visibleOptions.length >= expectedCount) {\n return;\n }\n\n await select.updateComplete;\n clock.runAll();\n\n // Give more time between attempts for slow CI environments\n await delay(75);\n\n attempts++;\n }\n\n throw new Error(\n `Pagination did not complete after ${maxAttempts} attempts (${\n maxAttempts * 75\n }ms). ` +\n `Expected ${expectedCount} options, got ${select.visibleOptions.length}. ` +\n `Fetching: ${select.fetching}`\n );\n};\n"]}