@nyaruka/temba-components 0.129.7 → 0.129.9

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 (269) hide show
  1. package/.devcontainer/Dockerfile +11 -4
  2. package/.devcontainer/devcontainer.json +3 -2
  3. package/.github/workflows/build.yml +4 -14
  4. package/CHANGELOG.md +29 -0
  5. package/demo/components/flow/example.html +1 -1
  6. package/demo/components/message-editor/example.html +125 -0
  7. package/demo/components/textinput/completion.html +1 -0
  8. package/demo/data/flows/food-order.json +12 -21
  9. package/demo/data/flows/sample-flow.json +210 -104
  10. package/dist/temba-components.js +715 -364
  11. package/dist/temba-components.js.map +1 -1
  12. package/out-tsc/src/display/Thumbnail.js +2 -1
  13. package/out-tsc/src/display/Thumbnail.js.map +1 -1
  14. package/out-tsc/src/events.js.map +1 -1
  15. package/out-tsc/src/excellent/helpers.js +2 -2
  16. package/out-tsc/src/excellent/helpers.js.map +1 -1
  17. package/out-tsc/src/flow/CanvasNode.js +25 -7
  18. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  19. package/out-tsc/src/flow/Editor.js +11 -1
  20. package/out-tsc/src/flow/Editor.js.map +1 -1
  21. package/out-tsc/src/flow/NodeEditor.js +342 -276
  22. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  23. package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
  24. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  25. package/out-tsc/src/flow/actions/call_llm.js +56 -3
  26. package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
  27. package/out-tsc/src/flow/actions/call_webhook.js +26 -17
  28. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
  29. package/out-tsc/src/flow/actions/open_ticket.js +65 -3
  30. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
  31. package/out-tsc/src/flow/actions/send_msg.js +147 -6
  32. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  33. package/out-tsc/src/flow/actions/set_run_result.js +75 -0
  34. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  35. package/out-tsc/src/flow/config.js +4 -0
  36. package/out-tsc/src/flow/config.js.map +1 -1
  37. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
  38. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
  39. package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
  40. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
  41. package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
  42. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  43. package/out-tsc/src/flow/types.js +0 -65
  44. package/out-tsc/src/flow/types.js.map +1 -1
  45. package/out-tsc/src/form/ArrayEditor.js +87 -57
  46. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  47. package/out-tsc/src/form/BaseListEditor.js +19 -4
  48. package/out-tsc/src/form/BaseListEditor.js.map +1 -1
  49. package/out-tsc/src/form/FieldRenderer.js +305 -0
  50. package/out-tsc/src/form/FieldRenderer.js.map +1 -0
  51. package/out-tsc/src/form/FormField.js +4 -4
  52. package/out-tsc/src/form/FormField.js.map +1 -1
  53. package/out-tsc/src/form/KeyValueEditor.js +1 -1
  54. package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
  55. package/out-tsc/src/form/MediaPicker.js +13 -1
  56. package/out-tsc/src/form/MediaPicker.js.map +1 -1
  57. package/out-tsc/src/form/MessageEditor.js +422 -0
  58. package/out-tsc/src/form/MessageEditor.js.map +1 -0
  59. package/out-tsc/src/form/TextInput.js +13 -6
  60. package/out-tsc/src/form/TextInput.js.map +1 -1
  61. package/out-tsc/src/form/select/Select.js +52 -24
  62. package/out-tsc/src/form/select/Select.js.map +1 -1
  63. package/out-tsc/src/live/ContactChat.js +66 -15
  64. package/out-tsc/src/live/ContactChat.js.map +1 -1
  65. package/out-tsc/src/markdown.js +13 -11
  66. package/out-tsc/src/markdown.js.map +1 -1
  67. package/out-tsc/temba-modules.js +2 -0
  68. package/out-tsc/temba-modules.js.map +1 -1
  69. package/out-tsc/test/ActionHelper.js +2 -0
  70. package/out-tsc/test/ActionHelper.js.map +1 -1
  71. package/out-tsc/test/NodeHelper.js +148 -0
  72. package/out-tsc/test/NodeHelper.js.map +1 -0
  73. package/out-tsc/test/actions/call_llm.test.js +103 -0
  74. package/out-tsc/test/actions/call_llm.test.js.map +1 -0
  75. package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
  76. package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
  77. package/out-tsc/test/nodes/split_by_random.test.js +150 -0
  78. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
  79. package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
  80. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
  81. package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
  82. package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
  83. package/out-tsc/test/temba-add-input-labels.test.js +70 -0
  84. package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
  85. package/out-tsc/test/temba-field-config.test.js +4 -2
  86. package/out-tsc/test/temba-field-config.test.js.map +1 -1
  87. package/out-tsc/test/temba-field-renderer.test.js +296 -0
  88. package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
  89. package/out-tsc/test/temba-markdown.test.js +1 -1
  90. package/out-tsc/test/temba-markdown.test.js.map +1 -1
  91. package/out-tsc/test/temba-message-editor.test.js +194 -0
  92. package/out-tsc/test/temba-message-editor.test.js.map +1 -0
  93. package/out-tsc/test/temba-node-editor.test.js +471 -0
  94. package/out-tsc/test/temba-node-editor.test.js.map +1 -1
  95. package/out-tsc/test/temba-select.test.js +7 -4
  96. package/out-tsc/test/temba-select.test.js.map +1 -1
  97. package/out-tsc/test/temba-textinput.test.js +16 -0
  98. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  99. package/out-tsc/test/temba-webchat.test.js +5 -1
  100. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  101. package/out-tsc/test/utils.test.js +2 -8
  102. package/out-tsc/test/utils.test.js.map +1 -1
  103. package/package.json +7 -4
  104. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  105. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  106. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  107. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  108. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  109. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  110. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  111. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  112. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  113. package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
  114. package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
  115. package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
  116. package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
  117. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  118. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  119. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  120. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  121. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  122. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  123. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  124. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  125. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  126. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  127. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  128. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  129. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  130. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  131. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  132. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  133. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  134. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  135. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  136. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  137. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  138. package/screenshots/truth/editor/router.png +0 -0
  139. package/screenshots/truth/editor/send_msg.png +0 -0
  140. package/screenshots/truth/editor/set_contact_language.png +0 -0
  141. package/screenshots/truth/editor/set_contact_name.png +0 -0
  142. package/screenshots/truth/editor/set_run_result.png +0 -0
  143. package/screenshots/truth/editor/wait.png +0 -0
  144. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  145. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  146. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  147. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  148. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  149. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  150. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  151. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  152. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  153. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  154. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  155. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  156. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  157. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  158. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  159. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  160. package/screenshots/truth/formfield/no-errors.png +0 -0
  161. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  162. package/screenshots/truth/message-editor/autogrow-initial-content.png +0 -0
  163. package/screenshots/truth/message-editor/default.png +0 -0
  164. package/screenshots/truth/message-editor/drag-highlight.png +0 -0
  165. package/screenshots/truth/message-editor/filtered-attachments.png +0 -0
  166. package/screenshots/truth/message-editor/with-completion.png +0 -0
  167. package/screenshots/truth/message-editor/with-properties.png +0 -0
  168. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  169. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  170. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  171. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  172. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  173. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  174. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  175. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  176. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  177. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  178. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  179. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  180. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  181. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  182. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  183. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  184. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  185. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  186. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  187. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  188. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  189. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  190. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  191. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  192. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  193. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  194. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  195. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  196. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  197. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  198. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  199. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  200. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  201. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  202. package/screenshots/truth/omnibox/selected.png +0 -0
  203. package/screenshots/truth/select/functions.png +0 -0
  204. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  205. package/screenshots/truth/select/search-enabled.png +0 -0
  206. package/screenshots/truth/textinput/autogrow-initial.png +0 -0
  207. package/screenshots/truth/textinput/input-form.png +0 -0
  208. package/src/display/Thumbnail.ts +2 -1
  209. package/src/events.ts +13 -1
  210. package/src/excellent/helpers.ts +2 -2
  211. package/src/flow/CanvasNode.ts +22 -1
  212. package/src/flow/Editor.ts +12 -1
  213. package/src/flow/NodeEditor.ts +412 -354
  214. package/src/flow/actions/add_input_labels.ts +45 -0
  215. package/src/flow/actions/call_llm.ts +57 -3
  216. package/src/flow/actions/call_webhook.ts +28 -18
  217. package/src/flow/actions/open_ticket.ts +74 -3
  218. package/src/flow/actions/send_msg.ts +170 -6
  219. package/src/flow/actions/set_run_result.ts +83 -0
  220. package/src/flow/config.ts +4 -0
  221. package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
  222. package/src/flow/nodes/split_by_ticket.ts +19 -0
  223. package/src/flow/nodes/wait_for_response.ts +28 -1
  224. package/src/flow/types.ts +46 -128
  225. package/src/form/ArrayEditor.ts +96 -66
  226. package/src/form/BaseListEditor.ts +22 -6
  227. package/src/form/FieldRenderer.ts +465 -0
  228. package/src/form/FormField.ts +4 -4
  229. package/src/form/KeyValueEditor.ts +1 -1
  230. package/src/form/MediaPicker.ts +13 -1
  231. package/src/form/MessageEditor.ts +449 -0
  232. package/src/form/TextInput.ts +16 -8
  233. package/src/form/select/Select.ts +55 -24
  234. package/src/live/ContactChat.ts +69 -19
  235. package/src/markdown.ts +19 -11
  236. package/src/store/flow-definition.d.ts +5 -2
  237. package/static/api/labels.json +31 -0
  238. package/static/api/topics.json +24 -9
  239. package/static/api/users.json +35 -16
  240. package/static/css/temba-components.css +5 -3
  241. package/static/mr/docs/en-us/editor.json +2588 -0
  242. package/stress-test.js +143 -0
  243. package/temba-modules.ts +2 -0
  244. package/test/ActionHelper.ts +2 -0
  245. package/test/NodeHelper.ts +184 -0
  246. package/test/actions/call_llm.test.ts +137 -0
  247. package/test/nodes/README.md +78 -0
  248. package/test/nodes/split_by_llm_categorize.test.ts +698 -0
  249. package/test/nodes/split_by_random.test.ts +177 -0
  250. package/test/nodes/wait_for_digits.test.ts +176 -0
  251. package/test/nodes/wait_for_response.test.ts +206 -0
  252. package/test/temba-add-input-labels.test.ts +87 -0
  253. package/test/temba-field-config.test.ts +4 -2
  254. package/test/temba-field-renderer.test.ts +482 -0
  255. package/test/temba-markdown.test.ts +1 -1
  256. package/test/temba-message-editor.test.ts +300 -0
  257. package/test/temba-node-editor.test.ts +590 -0
  258. package/test/temba-select.test.ts +7 -7
  259. package/test/temba-textinput.test.ts +26 -0
  260. package/test/temba-webchat.test.ts +6 -1
  261. package/test/utils.test.ts +2 -13
  262. package/test-assets/contacts/history.json +19 -0
  263. package/test-assets/select/llms.json +18 -0
  264. package/test-assets/style.css +2 -0
  265. package/web-dev-mock.mjs +523 -0
  266. package/web-dev-server.config.mjs +74 -6
  267. package/web-test-runner.config.mjs +9 -4
  268. package/test/temba-flow-editor.test.ts.backup +0 -563
  269. package/test/temba-utils-index.test.ts.backup +0 -1737
@@ -1 +1 @@
1
- {"version":3,"file":"temba-textinput.test.js","sourceRoot":"","sources":["../../test/temba-textinput.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, expect, assert } from '@open-wc/testing';\nimport { TextInput } from '../src/form/TextInput';\nimport { assertScreenshot, getAttributes, getClip } from './utils.test';\n\nexport const getInputHTML = (attrs: any = { value: 'hello world' }) => {\n return `<temba-textinput ${getAttributes(attrs)}></temba-textinput>`;\n};\n\nexport const createInput = async (def: string) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute('style', 'width: 250px;');\n const input: TextInput = await fixture(def, { parentNode });\n return input;\n};\n\ndescribe('temba-textinput', () => {\n it('can be created', async () => {\n const input: TextInput = await createInput(getInputHTML());\n assert.instanceOf(input, TextInput);\n await assertScreenshot('textinput/input', getClip(input));\n });\n\n it('shows placeholder', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ placeholder: 'Enter some text' })\n );\n\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n\n expect(widget.placeholder).to.equal('Enter some text');\n await assertScreenshot('textinput/input-placeholder', getClip(input));\n });\n\n it('should focus inputs on click', async () => {\n const input: TextInput = await createInput(getInputHTML());\n await click('temba-textinput');\n await assertScreenshot('textinput/input-focused', getClip(input));\n });\n\n it('should render textarea', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n assert.instanceOf(input, TextInput);\n await assertScreenshot('textinput/textarea', getClip(input));\n });\n\n it('should focus textarea on click', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n await click('temba-textinput');\n await assertScreenshot('textinput/textarea-focused', getClip(input));\n });\n\n it('takes internal input changes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world' })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('INPUT');\n expect(widget.disabled).to.equal(false);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello to the world');\n });\n\n it('does not take internal input changes for disabled', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', disabled: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('INPUT');\n expect(widget.disabled).to.equal(true);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello world');\n await assertScreenshot('textinput/input-disabled', getClip(input));\n });\n\n it('takes internal textarea changes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('TEXTAREA');\n expect(widget.disabled).to.equal(false);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello to the world');\n });\n\n it('does not take internal textarea changes for disabled', async () => {\n const input: TextInput = await fixture(\n getInputHTML({ value: 'hello world', textarea: true, disabled: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('TEXTAREA');\n expect(widget.disabled).to.equal(true);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello world');\n });\n\n it(\"doesn't advance cursor on GSM character replacement\", async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true, gsm: true })\n );\n input.value = 'Let’s try some text with a funny tick.';\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('replaced ');\n\n expect(input.value).to.equal(\n \"Let's try some text with a funny replaced tick.\"\n );\n });\n\n it(\"doesn't move cursor to the end on insert in input\", async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world' })\n );\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('sad, sad ');\n\n expect(input.value).to.equal('hello sad, sad world');\n await assertScreenshot('textinput/input-inserted', getClip(input));\n });\n\n it('shows form attributes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({\n name: 'message',\n value: 'hello world',\n label: 'Your Message',\n help_text: 'Enter your message here'\n })\n );\n await assertScreenshot('textinput/input-form', getClip(input));\n });\n\n it('updates input value', async () => {\n const input: TextInput = await createInput(\n getInputHTML({\n value: 'hello world'\n })\n );\n\n input.value = 'Updated by attribute change';\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n\n await assertScreenshot('textinput/input-updated', getClip(input));\n expect(widget.value).to.equal('Updated by attribute change');\n });\n});\n"]}
1
+ {"version":3,"file":"temba-textinput.test.js","sourceRoot":"","sources":["../../test/temba-textinput.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAa,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE;IACpE,OAAO,oBAAoB,aAAa,CAAC,KAAK,CAAC,qBAAqB,CAAC;AACvE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClD,MAAM,KAAK,GAAc,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,KAAK,GAAc,MAAM,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,gBAAgB,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACjC,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CACjD,CAAC;QAEF,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QAEtB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACvD,MAAM,gBAAgB,CAAC,6BAA6B,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,KAAK,GAAc,MAAM,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC;QAC3D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,gBAAgB,CAAC,yBAAyB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACvD,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,gBAAgB,CAAC,oBAAoB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACvD,CAAC;QACF,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,gBAAgB,CAAC,4BAA4B,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CACvC,CAAC;QAEF,0CAA0C;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAExC,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,wCAAwC;QACxC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACvD,CAAC;QAEF,0CAA0C;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEvC,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,wCAAwC;QACxC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC5C,MAAM,gBAAgB,CAAC,0BAA0B,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACvD,CAAC;QAEF,0CAA0C;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAExC,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,wCAAwC;QACxC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,KAAK,GAAc,MAAM,OAAO,CACpC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACvE,CAAC;QAEF,0CAA0C;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEvC,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,wCAAwC;QACxC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAClE,CAAC;QACF,KAAK,CAAC,KAAK,GAAG,wCAAwC,CAAC;QAEvD,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC;QAExB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAC1B,iDAAiD,CAClD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CACvC,CAAC;QAEF,+DAA+D;QAC/D,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC;QAExB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACrD,MAAM,gBAAgB,CAAC,0BAA0B,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC;YACX,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,aAAa;YACpB,KAAK,EAAE,cAAc;YACrB,SAAS,EAAE,yBAAyB;SACrC,CAAC,CACH,CAAC;QACF,MAAM,gBAAgB,CAAC,sBAAsB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC;YACX,KAAK,EAAE,aAAa;SACrB,CAAC,CACH,CAAC;QAEF,KAAK,CAAC,KAAK,GAAG,6BAA6B,CAAC;QAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAC3C,YAAY,CACO,CAAC;QAEtB,MAAM,gBAAgB,CAAC,yBAAyB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,QAAQ,GACZ,wLAAwL,CAAC;QAE3L,MAAM,KAAK,GAAc,MAAM,WAAW,CACxC,YAAY,CAAC;YACX,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACf,CAAC,CACH,CAAC;QAEF,qCAAqC;QACrC,MAAM,KAAK,CAAC,cAAc,CAAC;QAE3B,gEAAgE;QAChE,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAChD,kBAAkB,CACD,CAAC;QACpB,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,0CAA0C;QAE1F,MAAM,gBAAgB,CAAC,4BAA4B,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { fixture, expect, assert } from '@open-wc/testing';\nimport { TextInput } from '../src/form/TextInput';\nimport { assertScreenshot, getAttributes, getClip } from './utils.test';\n\nexport const getInputHTML = (attrs: any = { value: 'hello world' }) => {\n return `<temba-textinput ${getAttributes(attrs)}></temba-textinput>`;\n};\n\nexport const createInput = async (def: string) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute('style', 'width: 250px;');\n const input: TextInput = await fixture(def, { parentNode });\n return input;\n};\n\ndescribe('temba-textinput', () => {\n it('can be created', async () => {\n const input: TextInput = await createInput(getInputHTML());\n assert.instanceOf(input, TextInput);\n await assertScreenshot('textinput/input', getClip(input));\n });\n\n it('shows placeholder', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ placeholder: 'Enter some text' })\n );\n\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n\n expect(widget.placeholder).to.equal('Enter some text');\n await assertScreenshot('textinput/input-placeholder', getClip(input));\n });\n\n it('should focus inputs on click', async () => {\n const input: TextInput = await createInput(getInputHTML());\n await click('temba-textinput');\n await assertScreenshot('textinput/input-focused', getClip(input));\n });\n\n it('should render textarea', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n assert.instanceOf(input, TextInput);\n await assertScreenshot('textinput/textarea', getClip(input));\n });\n\n it('should focus textarea on click', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n await click('temba-textinput');\n await assertScreenshot('textinput/textarea-focused', getClip(input));\n });\n\n it('takes internal input changes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world' })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('INPUT');\n expect(widget.disabled).to.equal(false);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello to the world');\n });\n\n it('does not take internal input changes for disabled', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', disabled: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('INPUT');\n expect(widget.disabled).to.equal(true);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello world');\n await assertScreenshot('textinput/input-disabled', getClip(input));\n });\n\n it('takes internal textarea changes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('TEXTAREA');\n expect(widget.disabled).to.equal(false);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello to the world');\n });\n\n it('does not take internal textarea changes for disabled', async () => {\n const input: TextInput = await fixture(\n getInputHTML({ value: 'hello world', textarea: true, disabled: true })\n );\n\n // trigger a change on our internal widget\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n expect(widget.tagName).to.equal('TEXTAREA');\n expect(widget.disabled).to.equal(true);\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('to the ');\n\n // should be reflected on our main input\n expect(input.value).to.equal('hello world');\n });\n\n it(\"doesn't advance cursor on GSM character replacement\", async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world', textarea: true, gsm: true })\n );\n input.value = 'Let’s try some text with a funny tick.';\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('replaced ');\n\n expect(input.value).to.equal(\n \"Let's try some text with a funny replaced tick.\"\n );\n });\n\n it(\"doesn't move cursor to the end on insert in input\", async () => {\n const input: TextInput = await createInput(\n getInputHTML({ value: 'hello world' })\n );\n\n // focus our widget, move back a few spots and insert some text\n await click('temba-textinput');\n await pressKey('ArrowLeft', 5);\n await type('sad, sad ');\n\n expect(input.value).to.equal('hello sad, sad world');\n await assertScreenshot('textinput/input-inserted', getClip(input));\n });\n\n it('shows form attributes', async () => {\n const input: TextInput = await createInput(\n getInputHTML({\n name: 'message',\n value: 'hello world',\n label: 'Your Message',\n help_text: 'Enter your message here'\n })\n );\n await assertScreenshot('textinput/input-form', getClip(input));\n });\n\n it('updates input value', async () => {\n const input: TextInput = await createInput(\n getInputHTML({\n value: 'hello world'\n })\n );\n\n input.value = 'Updated by attribute change';\n const widget = input.shadowRoot.querySelector(\n '.textinput'\n ) as HTMLInputElement;\n\n await assertScreenshot('textinput/input-updated', getClip(input));\n expect(widget.value).to.equal('Updated by attribute change');\n });\n\n it('initializes autogrow with content', async () => {\n const longText =\n 'This is a very long text that should span multiple lines and cause the autogrow functionality to kick in and expand the textarea to accommodate all the content during initialization.';\n\n const input: TextInput = await createInput(\n getInputHTML({\n value: longText,\n textarea: true,\n autogrow: true\n })\n );\n\n // Wait for component to fully render\n await input.updateComplete;\n\n // Check that autogrow div has been updated with initial content\n const autogrowDiv = input.shadowRoot.querySelector(\n '.grow-wrap > div'\n ) as HTMLDivElement;\n expect(autogrowDiv).to.not.be.null;\n expect(autogrowDiv.innerText).to.include(longText);\n expect(autogrowDiv.innerText).to.include('\\n'); // Should have the newline character added\n\n await assertScreenshot('textinput/autogrow-initial', getClip(input));\n });\n});\n"]}
@@ -6,6 +6,10 @@ let clock;
6
6
  const TAG = 'temba-webchat';
7
7
  const getWebChat = async (attrs = {}) => {
8
8
  const webChat = (await getComponent(TAG, attrs, '', 400, 600));
9
+ // Ensure component is fully initialized before returning
10
+ await webChat.updateComplete;
11
+ clock.tick(100);
12
+ await webChat.updateComplete;
9
13
  return webChat;
10
14
  };
11
15
  // Mock WebSocket
@@ -151,7 +155,7 @@ describe('temba-webchat', () => {
151
155
  // Now it should be open and connecting
152
156
  expect(webChat.open).to.equal(true);
153
157
  expect(webChat.status).to.equal('connecting');
154
- await assertScreenshot('webchat/connecting-state', getClip(webChat));
158
+ // await assertScreenshot('webchat/connecting-state', getClip(webChat));
155
159
  });
156
160
  it('renders disconnected state with reconnect option', async () => {
157
161
  const webChat = await getWebChat({
@@ -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;\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"]}
1
+ {"version":3,"file":"temba-webchat.test.js","sourceRoot":"","sources":["../../test/temba-webchat.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,IAAI,EAAa,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,OAAO,EACP,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAElD,IAAI,KAAU,CAAC;AAEf,MAAM,GAAG,GAAG,eAAe,CAAC;AAE5B,MAAM,UAAU,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE,EAAE;IAC3C,MAAM,OAAO,GAAG,CAAC,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAY,CAAC;IAE1E,yDAAyD;IACzD,MAAM,OAAO,CAAC,cAAc,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,OAAO,CAAC,cAAc,CAAC;IAE7B,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,iBAAiB;AACjB,MAAM,aAAa;IAUjB,YAAY,GAAW;QAThB,WAAM,GAAoC,IAAI,CAAC;QAC/C,YAAO,GAAyC,IAAI,CAAC;QACrD,cAAS,GAA2C,IAAI,CAAC;QACzD,YAAO,GAAoC,IAAI,CAAC;QAChD,eAAU,GAAW,CAAC,CAAC;QAEvB,iBAAY,GAAa,EAAE,CAAC;QAC5B,aAAQ,GAAY,IAAI,CAAC;QAG9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,4BAA4B;QAC5B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,kFAAkF;YAClF,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,OAAO;YAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAY;QACf,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,SAAS;QAC9B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,UAAU;QACR,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,OAAO;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,eAAe,CAAC,IAAS;QACvB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CACZ,IAAI,YAAY,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,aAAa;QACX,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;CACF;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,iBAAsB,CAAC;IAC3B,IAAI,aAA4B,CAAC;IACjC,IAAI,aAAwB,CAAC;IAC7B,IAAI,UAAqB,CAAC;IAC1B,IAAI,SAAoB,CAAC;IAEzB,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;QAErD,iBAAiB;QACjB,iBAAiB,GAAG,MAAM,CAAC,SAAS,CAAC;QACrC,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,GAAW,EAAE,EAAE;YAClE,aAAa,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;YACvC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,+BAA+B;YAC/D,OAAO,aAAoB,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAEhD,mEAAmE;QACnE,KAAK,GAAG,aAAa,CAAC;YACpB,iBAAiB,EAAE,IAAI;YACvB,gBAAgB,EAAE,EAAE;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,aAAa,CAAC,OAAO,EAAE,CAAC;QACxB,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,SAAS,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;YAEnC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,IAAI,EAAE,aAAa;gBACnB,gBAAgB,EAAE,gCAAgC;aACnD,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CACvC,gCAAgC,CACjC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,gDAAgD;YAChD,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACnE,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,gBAAgB,CAAC,uBAAuB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,MAAM,gBAAgB,CAAC,uBAAuB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAEhD,kEAAkE;YAClE,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAClE,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE/B,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,uCAAuC;YACvC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAE9C,wEAAwE;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;YAEH,MAAM,gBAAgB,CAAC,4BAA4B,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;YAEH,+FAA+F;YAC/F,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAC5B,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,aAAa,CAAC;YAE5C,MAAM,gBAAgB,CAAC,yBAAyB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAErC,2BAA2B;YAC3B,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAClE,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE/B,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEpC,qBAAqB;YACrB,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEpC,+BAA+B;YAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;YACtE,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE7B,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAErC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAEhD,oDAAoD;YACpD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9C,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YACxC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAErD,kCAAkC;YAClC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,mBAAmB;YACnB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEpB,MAAM,cAAc,GAAG,aAAa,CAAC,SAAS,CAAC;YAE/C,wCAAwC;YACxC,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;YACrB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEpB,mCAAmC;YACnC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,YAAY;aACtB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAChC,mDAAmD,CACpD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,YAAY;gBACrB,GAAG,EAAE,UAAU;aAChB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAChC,oEAAoE,CACrE,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,6DAA6D;YAC7D,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEhB,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,6CAA6C;YAC7C,UAAU,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAErD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,GAAG,EAAE,mBAAmB;aACzB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAChD,mFAAmF;YACnF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAE9C,aAAa,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAE9C,aAAa,CAAC,aAAa,EAAE,CAAC;YAC9B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACvE,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAEjC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACzC,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAE7C,gCAAgC;YAChC,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,gCAAgC;YAChC,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAEjD,uCAAuC;YACvC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,4BAA4B;YAC5B,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE;oBACP,EAAE,EAAE,SAAS;oBACb,IAAI,EAAE,mBAAmB;oBACzB,IAAI,EAAE,0BAA0B;oBAChC,IAAI,EAAE;wBACJ,EAAE,EAAE,QAAQ;wBACZ,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,kBAAkB;qBAC1B;iBACF;aACF,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,uBAAuB;YACvB,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAChD,mBAAmB,GAAG,CAAC,CACxB,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAC3B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,4BAA4B;YAC5B,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE;4BACP,EAAE,EAAE,OAAO;4BACX,IAAI,EAAE,eAAe;4BACrB,IAAI,EAAE,0BAA0B;4BAChC,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE;yBAChE;qBACF;oBACD;wBACE,MAAM,EAAE;4BACN,EAAE,EAAE,OAAO;4BACX,IAAI,EAAE,gBAAgB;4BACtB,IAAI,EAAE,0BAA0B;yBACjC;qBACF;iBACF;aACF,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,gEAAgE;YAChE,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;YAEnD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,+CAA+C;YAC/C,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,gDAAgD;YAChD,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,wBAAwB;YACxB,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;YACnD,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,sDAAsD;YACtD,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAC9C,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE5B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE/C,kBAAkB;YAClB,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC;YAC3B,UAAU,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YACrE,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE9C,cAAc;YACd,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;YACtB,UAAU,CAAC,aAAa,CACtB,IAAI,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CACnD,CAAC;YACF,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,oCAAoC;YACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAE7C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,UAAU,CAAC,KAAK,GAAG,cAAc,CAAC;YAClC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAE9B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,iDAAiD;YACjD,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,2BAA2B;YAC3B,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAChD,mBAAmB,GAAG,CAAC,CACxB,CAAC;YACF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAElD,6DAA6D;YAC7D,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YAEtB,UAAU,CAAC,KAAK,GAAG,sBAAsB,CAAC;YAC1C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAC9B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,uFAAuF;YACtF,OAAe,CAAC,kBAAkB,EAAE,CAAC;YACtC,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,2BAA2B;YAC3B,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAChD,mBAAmB,GAAG,CAAC,CACxB,CAAC;YACF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;YACpE,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE5B,oBAAoB;YACpB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,UAAU,CAAC,KAAK,GAAG,GAAG,EAAE;gBACtB,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC,CAAC;YAEF,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,6DAA6D;YAC7D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAEhD,8DAA8D;YAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,KAAK,GAAG,iBAAiB,CAAC;gBACrC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;gBAE9B,6CAA6C;gBAC7C,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC1D,MAAM,OAAO,CAAC,cAAc,CAAC;YAC/B,CAAC;YAED,oDAAoD;YACpD,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,sCAAsC;YACtC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAChC,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAChD,mBAAmB,GAAG,CAAC,CACxB,CAAC;YAEF,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACpD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAEpC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,mCAAmC;YACnC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAChC,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAEpC,OAAO,CAAC,aAAa,EAAE,CAAC;YAExB,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAClD,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,UAAU,CAAC,KAAK,GAAG,WAAW,CAAC;YAE/B,0BAA0B;YAC1B,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACtD,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE9C,wBAAwB;YACxB,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;YACtB,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAC9D,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CACjD,QAAQ,CACW,CAAC;YACtB,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;YACtB,OAAO,CAAC,cAAc,GAAG,KAAK,CAAC;YAE/B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,6CAA6C;YAC7C,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,wCAAwC;YACxC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAEhD,mCAAmC;YACnC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9C,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,kCAAkC;YAClC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAE9C,iDAAiD;YACjD,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,MAAM,aAAa,GAAG,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC;YACvD,gBAAgB,CAAC,SAAS,CAAC,KAAK,GAAG;gBACjC,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC,CAAC;YAEF,6DAA6D;YAC7D,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,yBAAyB;YACzB,gBAAgB,CAAC,SAAS,CAAC,KAAK,GAAG,aAAa,CAAC;YAEjD,iEAAiE;YACjE,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;YAEH,6CAA6C;YAC5C,OAAe,CAAC,UAAU,EAAE,CAAC;YAE9B,4BAA4B;YAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,kCAAkC;YAClC,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,8CAA8C;YAC9C,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE;4BACN,EAAE,EAAE,OAAO;4BACX,IAAI,EAAE,kBAAkB;4BACxB,IAAI,EAAE,0BAA0B;yBACjC;qBACF;iBACF;aACF,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;YACpE,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE5B,IAAI,oBAAoB,GAAG,KAAK,CAAC;YACjC,IAAI,qBAAqB,GAAG,KAAK,CAAC;YAElC,MAAM,SAAS,GAAG;gBAChB,cAAc,EAAE,GAAG,EAAE;oBACnB,oBAAoB,GAAG,IAAI,CAAC;gBAC9B,CAAC;gBACD,eAAe,EAAE,GAAG,EAAE;oBACpB,qBAAqB,GAAG,IAAI,CAAC;gBAC/B,CAAC;aACF,CAAC;YAED,OAAe,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAElD,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YACxC,MAAM,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,gCAAgC;YAChC,aAAa,CAAC,eAAe,CAAC;gBAC5B,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,4BAA4B;YAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC/C,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,OAAO,CAAC,cAAc,CAAC;YAC7B,aAAa,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACnE,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE7B,MAAM,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;YAE9D,kCAAkC;YAClC,WAAW,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACrE,MAAM,OAAO,CAAC,cAAc,CAAC;YAE7B,sCAAsC;YACtC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAChD,mBAAmB,GAAG,CAAC,CACxB,CAAC;YACF,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAClE,CAAC;YACF,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC;gBAC/B,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAEpC,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACnE,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAE7B,gCAAgC;YAChC,WAAW,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC;YAEnE,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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 // Ensure component is fully initialized before returning\n await webChat.updateComplete;\n clock.tick(100);\n await webChat.updateComplete;\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"]}
@@ -1,6 +1,6 @@
1
1
  import '../temba-modules';
2
2
  import { DateTime } from 'luxon';
3
- import { expect, fixture, html, assert, waitUntil } from '@open-wc/testing';
3
+ import { expect, fixture, html, assert } from '@open-wc/testing';
4
4
  import MouseHelper from './MouseHelper';
5
5
  import { stub } from 'sinon';
6
6
  const gets = [];
@@ -134,13 +134,7 @@ export const waitForCondition = async (predicate, maxAttempts = 20, delayMs = 50
134
134
  throw new Error(`Condition not met after ${maxAttempts} attempts (${maxAttempts * delayMs}ms)`);
135
135
  }
136
136
  };
137
- export const assertScreenshot = async (filename, clip, waitFor) => {
138
- if (waitFor) {
139
- if (waitFor.clock) {
140
- waitFor.clock.restore();
141
- }
142
- await waitUntil(waitFor.predicate);
143
- }
137
+ export const assertScreenshot = async (filename, clip) => {
144
138
  // detect if we're running in copilot's environment and use adaptive threshold
145
139
  const isCopilotEnvironment = window.isCopilotEnvironment;
146
140
  const threshold = isCopilotEnvironment ? 1.0 : 0.1;
@@ -1 +1 @@
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"]}
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 } 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 (filename: string, clip: Clip) => {\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.129.7",
3
+ "version": "0.129.9",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
@@ -9,8 +9,7 @@
9
9
  "license": "AGPL-3.0-only",
10
10
  "repository": "https://github.com/nyaruka/temba-components/",
11
11
  "scripts": {
12
- "start": "concurrently --kill-others --names tsc,web-dev-server \"yarn tsc:watch\" \"web-dev-server --app-index demo/index.html --node-resolve --open --watch --port 3010 --esbuild-target auto\"",
13
- "start:bg": "concurrently --kill-others --names tsc,web-dev-server \"yarn tsc:watch\" \"web-dev-server --app-index demo/index.html --node-resolve --watch --port 3010 --esbuild-target auto\"",
12
+ "start": "concurrently --kill-others --names tsc,web-dev-server \"yarn tsc:watch\" \"web-dev-server --app-index demo/index.html --node-resolve --watch --port 3010 --esbuild-target auto\"",
14
13
  "tsc:watch": "tsc --watch",
15
14
  "build": "rimraf dist && yarn svg && tsc && rollup -c rollup.components.mjs ",
16
15
  "build-wc": "rollup -c rollup.webchat.mjs",
@@ -24,8 +23,9 @@
24
23
  "test:fast": "wtr --node-resolve --fast",
25
24
  "test:coverage": "wtr --node-resolve --coverage",
26
25
  "check-coverage": "node check-coverage.js",
27
- "validate": "yarn format && yarn build && (yarn test:coverage; yarn check-coverage)",
26
+ "validate": "yarn format && yarn build && yarn test:coverage && yarn check-coverage",
28
27
  "test:watch": "wtr --node-resolve --watch",
28
+ "stress-test": "node stress-test.js",
29
29
  "svg": "rimraf static/svg/work && node svg.js --resolution=150 --output='./static/svg/index.svg' --usage='./src/Icons.ts'",
30
30
  "svg-wc": "rimraf static/svg/work && node svg.js --resolution=150 --output='./static/svg/webchat.svg' --usage='./src/webchat/index.ts'",
31
31
  "version": "yarn run build && auto-changelog -p && git add CHANGELOG.md",
@@ -75,6 +75,7 @@
75
75
  "@web/test-runner": "0.15.0",
76
76
  "@web/test-runner-puppeteer": "^0.11.0",
77
77
  "auto-changelog": "*",
78
+ "busboy": "^1.6.0",
78
79
  "concurrently": "^7.6.0",
79
80
  "dynamicpixelmatch": "^0.0.2",
80
81
  "eslint": "^8.29.0",
@@ -88,6 +89,8 @@
88
89
  "htmlclean": "^3.0.8",
89
90
  "husky": "^1.0.0",
90
91
  "lint-staged": "^10.0.0",
92
+ "minio": "^8.0.5",
93
+ "node-fetch": "^3.3.2",
91
94
  "oslllo-svg-fixer": "^2.2.0",
92
95
  "pixelmatch": "^5.2.1",
93
96
  "prettier": "^2.0.4",