@nyaruka/temba-components 0.129.10 → 0.130.0

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 (316) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/demo/components/flow/example.html +5 -1
  3. package/demo/data/flows/sample-flow.json +217 -113
  4. package/dist/temba-components.js +310 -356
  5. package/dist/temba-components.js.map +1 -1
  6. package/out-tsc/src/events.js.map +1 -1
  7. package/out-tsc/src/flow/CanvasNode.js +3 -35
  8. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  9. package/out-tsc/src/flow/Editor.js +9 -6
  10. package/out-tsc/src/flow/Editor.js.map +1 -1
  11. package/out-tsc/src/flow/NodeEditor.js +44 -11
  12. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  13. package/out-tsc/src/flow/actions/add_contact_groups.js +1 -1
  14. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  15. package/out-tsc/src/flow/actions/add_contact_urn.js +1 -1
  16. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
  17. package/out-tsc/src/flow/actions/add_input_labels.js +1 -1
  18. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  19. package/out-tsc/src/flow/actions/remove_contact_groups.js +1 -1
  20. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  21. package/out-tsc/src/flow/actions/send_email.js +9 -0
  22. package/out-tsc/src/flow/actions/send_email.js.map +1 -1
  23. package/out-tsc/src/flow/actions/send_msg.js +7 -8
  24. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  25. package/out-tsc/src/flow/actions/set_contact_channel.js +25 -4
  26. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  27. package/out-tsc/src/flow/actions/set_contact_field.js +51 -1
  28. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
  29. package/out-tsc/src/flow/actions/set_contact_language.js +70 -2
  30. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
  31. package/out-tsc/src/flow/actions/set_contact_name.js +27 -2
  32. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
  33. package/out-tsc/src/flow/actions/set_contact_status.js +32 -2
  34. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  35. package/out-tsc/src/flow/actions/set_run_result.js +13 -11
  36. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  37. package/out-tsc/src/flow/actions/split_by_expression_example.js +4 -4
  38. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -1
  39. package/out-tsc/src/flow/config.js +2 -8
  40. package/out-tsc/src/flow/config.js.map +1 -1
  41. package/out-tsc/src/flow/forms/index.js +2 -0
  42. package/out-tsc/src/flow/forms/index.js.map +1 -0
  43. package/out-tsc/src/flow/nodes/split_by_llm.js +101 -0
  44. package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -0
  45. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +4 -89
  46. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  47. package/out-tsc/src/flow/nodes/split_by_random.js +117 -0
  48. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  49. package/out-tsc/src/flow/nodes/split_by_subflow.js +123 -3
  50. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
  51. package/out-tsc/src/flow/nodes/split_by_ticket.js +114 -13
  52. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -1
  53. package/out-tsc/src/flow/nodes/split_by_webhook.js +158 -12
  54. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -1
  55. package/out-tsc/src/flow/types.js.map +1 -1
  56. package/out-tsc/src/form/ArrayEditor.js +9 -25
  57. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  58. package/out-tsc/src/form/FieldRenderer.js +6 -64
  59. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  60. package/out-tsc/src/form/select/Select.js +29 -58
  61. package/out-tsc/src/form/select/Select.js.map +1 -1
  62. package/out-tsc/src/live/ContactChat.js +48 -66
  63. package/out-tsc/src/live/ContactChat.js.map +1 -1
  64. package/out-tsc/src/utils.js +118 -0
  65. package/out-tsc/src/utils.js.map +1 -1
  66. package/out-tsc/test/nodes/split_by_llm.test.js +174 -0
  67. package/out-tsc/test/nodes/split_by_llm.test.js.map +1 -0
  68. package/out-tsc/test/nodes/split_by_random.test.js +0 -6
  69. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -1
  70. package/out-tsc/test/temba-field-renderer.test.js +6 -3
  71. package/out-tsc/test/temba-field-renderer.test.js.map +1 -1
  72. package/out-tsc/test/utils.test.js +18 -0
  73. package/out-tsc/test/utils.test.js.map +1 -1
  74. package/package.json +1 -1
  75. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  76. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  77. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  78. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  79. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  80. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  81. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  82. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  83. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  84. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  85. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  86. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  87. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  88. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  89. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  90. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  91. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  92. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  93. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  94. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  95. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  96. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  97. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  98. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  99. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  100. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  101. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  102. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  103. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  104. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  105. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  106. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  107. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  108. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  109. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  110. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  111. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  112. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  113. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  114. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  115. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  116. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  117. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  118. package/screenshots/truth/checkbox/checkbox-whitespace-label-no-background-hover.png +0 -0
  119. package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
  120. package/screenshots/truth/checkbox/checked.png +0 -0
  121. package/screenshots/truth/checkbox/default.png +0 -0
  122. package/screenshots/truth/colorpicker/default.png +0 -0
  123. package/screenshots/truth/colorpicker/focused.png +0 -0
  124. package/screenshots/truth/colorpicker/initialized.png +0 -0
  125. package/screenshots/truth/colorpicker/selected.png +0 -0
  126. package/screenshots/truth/compose/attachments-tab.png +0 -0
  127. package/screenshots/truth/compose/attachments-with-files.png +0 -0
  128. package/screenshots/truth/compose/intial-text.png +0 -0
  129. package/screenshots/truth/compose/no-counter.png +0 -0
  130. package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
  131. package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
  132. package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
  133. package/screenshots/truth/contacts/chat-failure.png +0 -0
  134. package/screenshots/truth/contacts/chat-for-active-contact.png +0 -0
  135. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  136. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  137. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  138. package/screenshots/truth/counter/summary.png +0 -0
  139. package/screenshots/truth/counter/text.png +0 -0
  140. package/screenshots/truth/counter/unicode-variables.png +0 -0
  141. package/screenshots/truth/counter/unicode.png +0 -0
  142. package/screenshots/truth/counter/variable.png +0 -0
  143. package/screenshots/truth/datepicker/date-truncated-time.png +0 -0
  144. package/screenshots/truth/datepicker/date.png +0 -0
  145. package/screenshots/truth/datepicker/initial-timezone.png +0 -0
  146. package/screenshots/truth/datepicker/range-picker-editing-start.png +0 -0
  147. package/screenshots/truth/datepicker/updated-keyboard-date.png +0 -0
  148. package/screenshots/truth/dialog/focused.png +0 -0
  149. package/screenshots/truth/dropdown/right-edge-collision.png +0 -0
  150. package/screenshots/truth/editor/router.png +0 -0
  151. package/screenshots/truth/editor/send_msg.png +0 -0
  152. package/screenshots/truth/editor/set_contact_language.png +0 -0
  153. package/screenshots/truth/editor/set_contact_name.png +0 -0
  154. package/screenshots/truth/editor/set_run_result.png +0 -0
  155. package/screenshots/truth/editor/wait.png +0 -0
  156. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  157. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  158. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  159. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  160. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  161. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  162. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  163. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  164. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  165. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  166. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  167. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  168. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  169. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  170. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  171. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  172. package/screenshots/truth/list/fields-dragging.png +0 -0
  173. package/screenshots/truth/list/fields-filtered.png +0 -0
  174. package/screenshots/truth/list/fields-hovered.png +0 -0
  175. package/screenshots/truth/list/fields.png +0 -0
  176. package/screenshots/truth/list/items-selected.png +0 -0
  177. package/screenshots/truth/list/items-updated.png +0 -0
  178. package/screenshots/truth/list/items.png +0 -0
  179. package/screenshots/truth/menu/menu-focused-with items.png +0 -0
  180. package/screenshots/truth/menu/menu-refresh-1.png +0 -0
  181. package/screenshots/truth/menu/menu-refresh-2.png +0 -0
  182. package/screenshots/truth/menu/menu-submenu.png +0 -0
  183. package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
  184. package/screenshots/truth/menu/menu-tasks.png +0 -0
  185. package/screenshots/truth/message-editor/autogrow-initial-content.png +0 -0
  186. package/screenshots/truth/message-editor/default.png +0 -0
  187. package/screenshots/truth/message-editor/drag-highlight.png +0 -0
  188. package/screenshots/truth/message-editor/filtered-attachments.png +0 -0
  189. package/screenshots/truth/message-editor/with-completion.png +0 -0
  190. package/screenshots/truth/message-editor/with-properties.png +0 -0
  191. package/screenshots/truth/modax/form.png +0 -0
  192. package/screenshots/truth/modax/simple.png +0 -0
  193. package/screenshots/truth/nodes/split_by_llm/editor/information-extraction.png +0 -0
  194. package/screenshots/truth/nodes/split_by_llm/editor/sentiment-analysis.png +0 -0
  195. package/screenshots/truth/nodes/split_by_llm/editor/summarization.png +0 -0
  196. package/screenshots/truth/nodes/split_by_llm/editor/translation-task.png +0 -0
  197. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  198. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  199. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  200. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  201. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  202. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  203. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  204. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  205. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  206. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  207. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  208. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  209. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  210. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  211. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  212. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  213. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  214. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  215. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  216. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  217. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  218. package/screenshots/truth/omnibox/selected.png +0 -0
  219. package/screenshots/truth/options/block.png +0 -0
  220. package/screenshots/truth/run-list/basic.png +0 -0
  221. package/screenshots/truth/select/disabled-multi-selection.png +0 -0
  222. package/screenshots/truth/select/disabled-selection.png +0 -0
  223. package/screenshots/truth/select/disabled.png +0 -0
  224. package/screenshots/truth/select/embedded.png +0 -0
  225. package/screenshots/truth/select/empty-options.png +0 -0
  226. package/screenshots/truth/select/expression-selected.png +0 -0
  227. package/screenshots/truth/select/expressions.png +0 -0
  228. package/screenshots/truth/select/functions.png +0 -0
  229. package/screenshots/truth/select/local-options.png +0 -0
  230. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  231. package/screenshots/truth/select/multiple-initial-values.png +0 -0
  232. package/screenshots/truth/select/remote-options.png +0 -0
  233. package/screenshots/truth/select/search-enabled.png +0 -0
  234. package/screenshots/truth/select/search-multi-no-matches.png +0 -0
  235. package/screenshots/truth/select/search-selected-focus.png +0 -0
  236. package/screenshots/truth/select/search-selected.png +0 -0
  237. package/screenshots/truth/select/search-with-selected.png +0 -0
  238. package/screenshots/truth/select/searching.png +0 -0
  239. package/screenshots/truth/select/selected-multi-maxitems-reached.png +0 -0
  240. package/screenshots/truth/select/selected-multi.png +0 -0
  241. package/screenshots/truth/select/selected-single.png +0 -0
  242. package/screenshots/truth/select/selection-clearable.png +0 -0
  243. package/screenshots/truth/select/static-initial-value.png +0 -0
  244. package/screenshots/truth/select/static-initial-via-selected.png +0 -0
  245. package/screenshots/truth/select/truncated-selection.png +0 -0
  246. package/screenshots/truth/select/with-placeholder.png +0 -0
  247. package/screenshots/truth/select/without-placeholder.png +0 -0
  248. package/screenshots/truth/slider/update-slider-on-circle-dragged.png +0 -0
  249. package/screenshots/truth/templates/default.png +0 -0
  250. package/screenshots/truth/templates/unapproved.png +0 -0
  251. package/screenshots/truth/textinput/autogrow-initial.png +0 -0
  252. package/screenshots/truth/textinput/input-disabled.png +0 -0
  253. package/screenshots/truth/textinput/input-focused.png +0 -0
  254. package/screenshots/truth/textinput/input-form.png +0 -0
  255. package/screenshots/truth/textinput/input-inserted.png +0 -0
  256. package/screenshots/truth/textinput/input-placeholder.png +0 -0
  257. package/screenshots/truth/textinput/input-updated.png +0 -0
  258. package/screenshots/truth/textinput/input.png +0 -0
  259. package/screenshots/truth/textinput/textarea-focused.png +0 -0
  260. package/screenshots/truth/textinput/textarea.png +0 -0
  261. package/src/events.ts +4 -2
  262. package/src/flow/CanvasNode.ts +2 -39
  263. package/src/flow/Editor.ts +6 -3
  264. package/src/flow/NodeEditor.ts +54 -13
  265. package/src/flow/actions/add_contact_groups.ts +1 -1
  266. package/src/flow/actions/add_contact_urn.ts +1 -1
  267. package/src/flow/actions/add_input_labels.ts +1 -1
  268. package/src/flow/actions/remove_contact_groups.ts +1 -1
  269. package/src/flow/actions/send_email.ts +11 -1
  270. package/src/flow/actions/send_msg.ts +20 -11
  271. package/src/flow/actions/set_contact_channel.ts +28 -5
  272. package/src/flow/actions/set_contact_field.ts +56 -2
  273. package/src/flow/actions/set_contact_language.ts +74 -3
  274. package/src/flow/actions/set_contact_name.ts +31 -3
  275. package/src/flow/actions/set_contact_status.ts +36 -3
  276. package/src/flow/actions/set_run_result.ts +13 -15
  277. package/src/flow/actions/split_by_expression_example.ts +4 -4
  278. package/src/flow/config.ts +2 -8
  279. package/src/flow/forms/index.ts +1 -0
  280. package/src/flow/nodes/split_by_llm.ts +119 -0
  281. package/src/flow/nodes/split_by_llm_categorize.ts +13 -116
  282. package/src/flow/nodes/split_by_random.ts +148 -0
  283. package/src/flow/nodes/split_by_subflow.ts +153 -3
  284. package/src/flow/nodes/split_by_ticket.ts +134 -12
  285. package/src/flow/nodes/split_by_webhook.ts +185 -12
  286. package/src/flow/types.ts +2 -1
  287. package/src/form/ArrayEditor.ts +6 -20
  288. package/src/form/FieldRenderer.ts +6 -65
  289. package/src/form/select/Select.ts +34 -66
  290. package/src/live/ContactChat.ts +56 -58
  291. package/src/store/flow-definition.d.ts +8 -2
  292. package/src/utils.ts +196 -0
  293. package/static/api/fields.json +93 -1208
  294. package/static/api/workspace.json +23 -0
  295. package/test/nodes/split_by_llm.test.ts +232 -0
  296. package/test/nodes/split_by_random.test.ts +0 -7
  297. package/test/temba-field-renderer.test.ts +26 -13
  298. package/test/utils.test.ts +20 -0
  299. package/test-assets/style.css +36 -234
  300. package/web-dev-server.config.mjs +28 -0
  301. package/web-test-runner.config.mjs +38 -1
  302. package/out-tsc/src/flow/actions/call_llm.js +0 -64
  303. package/out-tsc/src/flow/actions/call_llm.js.map +0 -1
  304. package/out-tsc/src/flow/actions/call_webhook.js +0 -131
  305. package/out-tsc/src/flow/actions/call_webhook.js.map +0 -1
  306. package/out-tsc/src/flow/actions/enter_flow.js +0 -14
  307. package/out-tsc/src/flow/actions/enter_flow.js.map +0 -1
  308. package/out-tsc/src/flow/actions/open_ticket.js +0 -73
  309. package/out-tsc/src/flow/actions/open_ticket.js.map +0 -1
  310. package/out-tsc/test/actions/call_llm.test.js +0 -103
  311. package/out-tsc/test/actions/call_llm.test.js.map +0 -1
  312. package/src/flow/actions/call_llm.ts +0 -66
  313. package/src/flow/actions/call_webhook.ts +0 -143
  314. package/src/flow/actions/enter_flow.ts +0 -15
  315. package/src/flow/actions/open_ticket.ts +0 -83
  316. package/test/actions/call_llm.test.ts +0 -137
@@ -1 +1 @@
1
- {"version":3,"file":"temba-field-renderer.test.js","sourceRoot":"","sources":["../../test/temba-field-renderer.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { FieldRenderer } from '../src/form/FieldRenderer';\nimport {\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n KeyValueFieldConfig,\n MessageEditorFieldConfig\n} from '../src/flow/types';\nimport { assertScreenshot, getClip } from './utils.test';\n\ndescribe('FieldRenderer', () => {\n describe('text fields', () => {\n it('should render text field with label', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Website URL',\n placeholder: 'Enter URL'\n };\n\n const template = FieldRenderer.renderField(\n 'url',\n config,\n 'https://example.com',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render evaluated text field with completion', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Dynamic URL',\n evaluated: true,\n placeholder: 'Enter URL with expressions'\n };\n\n const template = FieldRenderer.renderField(\n 'url',\n config,\n 'https://api.com/@contact.name',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-evaluated',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render text field without label for ArrayEditor context', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Item Name',\n placeholder: 'Enter name'\n };\n\n const template = FieldRenderer.renderField(\n 'name',\n config,\n 'Sample Item',\n {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 300px; padding: 10px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-no-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render text field with errors', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Email Address',\n placeholder: 'Enter email'\n };\n\n const template = FieldRenderer.renderField(\n 'email',\n config,\n 'invalid-email',\n {\n errors: ['Invalid email format', 'Email is required'],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-with-errors',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('textarea fields', () => {\n it('should render textarea with label', async () => {\n const config: TextareaFieldConfig = {\n type: 'textarea',\n label: 'Description',\n placeholder: 'Enter description',\n rows: 4\n };\n\n const template = FieldRenderer.renderField(\n 'description',\n config,\n 'This is a sample description\\nwith multiple lines',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/textarea-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render evaluated textarea with completion', async () => {\n const config: TextareaFieldConfig = {\n type: 'textarea',\n label: 'Message Template',\n evaluated: true,\n placeholder: 'Enter message with expressions',\n rows: 3\n };\n\n const template = FieldRenderer.renderField(\n 'message',\n config,\n 'Hello @contact.name,\\nYour order is ready!',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/textarea-evaluated',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('select fields', () => {\n it('should render select field with label', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Country',\n options: ['United States', 'Canada', 'United Kingdom', 'Australia'],\n searchable: true\n };\n\n const template = FieldRenderer.renderField('country', config, 'Canada', {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render multi-select field', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Skills',\n options: ['JavaScript', 'Python', 'TypeScript', 'React', 'Node.js'],\n multi: true,\n tags: true\n };\n\n const template = FieldRenderer.renderField(\n 'skills',\n config,\n ['JavaScript', 'TypeScript'],\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-multi',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render select field without label for ArrayEditor context', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Status',\n options: ['Active', 'Inactive', 'Pending']\n };\n\n const template = FieldRenderer.renderField('status', config, 'Active', {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 200px; padding: 10px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-no-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('checkbox fields', () => {\n it('should render checkbox with label', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Accept Terms and Conditions'\n };\n\n const template = FieldRenderer.renderField('accept', config, true, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-checked',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render unchecked checkbox', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Subscribe to newsletter'\n };\n\n const template = FieldRenderer.renderField('subscribe', config, false, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-unchecked',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render checkbox with errors', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Agree to terms',\n required: true\n };\n\n const template = FieldRenderer.renderField('terms', config, false, {\n errors: ['You must accept the terms to continue'],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-with-errors',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('key-value fields', () => {\n it('should render key-value field with label', async () => {\n const config: KeyValueFieldConfig = {\n type: 'key-value',\n label: 'HTTP Headers',\n keyPlaceholder: 'Header name',\n valuePlaceholder: 'Header value'\n };\n\n const template = FieldRenderer.renderField(\n 'headers',\n config,\n [\n { key: 'Content-Type', value: 'application/json' },\n { key: 'Authorization', value: 'Bearer token123' }\n ],\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 500px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/key-value-with-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('message-editor fields', () => {\n it('should render message-editor with label', async () => {\n const config: MessageEditorFieldConfig = {\n type: 'message-editor',\n label: 'Email Message',\n placeholder: 'Enter your message...',\n minHeight: 120\n };\n\n const template = FieldRenderer.renderField(\n 'message',\n config,\n 'Hello! This is a test message.',\n {\n errors: [],\n showLabel: true,\n onChange: () => {},\n additionalData: { attachments: [] }\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 500px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/message-editor-with-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('field consistency', () => {\n it('should render the same field type consistently between contexts', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Product Name',\n placeholder: 'Enter product name'\n };\n\n // NodeEditor context (with label)\n const nodeEditorTemplate = FieldRenderer.renderField(\n 'product',\n config,\n 'iPhone 15',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n // ArrayEditor context (without label)\n const arrayEditorTemplate = FieldRenderer.renderField(\n 'product',\n config,\n 'iPhone 15',\n {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n }\n );\n\n const nodeContainer = await fixture(html`<div\n style=\"width: 400px; padding: 20px; border: 1px solid #ddd; margin: 10px;\"\n >\n <h3 style=\"margin: 0 0 10px 0; font-size: 14px; color: #666;\">\n NodeEditor Context\n </h3>\n ${nodeEditorTemplate}\n </div>`);\n\n const arrayContainer = await fixture(html`<div\n style=\"width: 400px; padding: 20px; border: 1px solid #ddd; margin: 10px;\"\n >\n <h3 style=\"margin: 0 0 10px 0; font-size: 14px; color: #666;\">\n ArrayEditor Context\n </h3>\n ${arrayEditorTemplate}\n </div>`);\n\n const combinedContainer = await fixture(html`<div\n style=\"display: flex; flex-direction: column; width: 420px;\"\n >\n ${nodeContainer} ${arrayContainer}\n </div>`);\n\n await assertScreenshot(\n 'field-renderer/context-comparison',\n getClip(combinedContainer as HTMLElement)\n );\n });\n });\n\n describe('error handling', () => {\n it('should handle all field types without throwing errors', () => {\n const configs = [\n { type: 'text', label: 'Text' } as TextFieldConfig,\n { type: 'textarea', label: 'Textarea' } as TextareaFieldConfig,\n { type: 'select', label: 'Select', options: [] } as SelectFieldConfig,\n { type: 'checkbox', label: 'Checkbox' },\n { type: 'key-value', label: 'KeyValue' },\n { type: 'array', label: 'Array', itemConfig: {} },\n { type: 'message-editor', label: 'MessageEditor' }\n ];\n\n configs.forEach((config, index) => {\n expect(() => {\n FieldRenderer.renderField(`field${index}`, config as any, null, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n }).to.not.throw;\n });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"temba-field-renderer.test.js","sourceRoot":"","sources":["../../test/temba-field-renderer.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { FieldRenderer } from '../src/form/FieldRenderer';\nimport {\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n KeyValueFieldConfig,\n MessageEditorFieldConfig\n} from '../src/flow/types';\nimport { assertScreenshot, getClip } from './utils.test';\n\ndescribe('FieldRenderer', () => {\n describe('text fields', () => {\n it('should render text field with label', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Website URL',\n placeholder: 'Enter URL'\n };\n\n const template = FieldRenderer.renderField(\n 'url',\n config,\n 'https://example.com',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render evaluated text field with completion', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Dynamic URL',\n evaluated: true,\n placeholder: 'Enter URL with expressions'\n };\n\n const template = FieldRenderer.renderField(\n 'url',\n config,\n 'https://api.com/@contact.name',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-evaluated',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render text field without label for ArrayEditor context', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Item Name',\n placeholder: 'Enter name'\n };\n\n const template = FieldRenderer.renderField(\n 'name',\n config,\n 'Sample Item',\n {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 300px; padding: 10px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-no-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render text field with errors', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Email Address',\n placeholder: 'Enter email'\n };\n\n const template = FieldRenderer.renderField(\n 'email',\n config,\n 'invalid-email',\n {\n errors: ['Invalid email format', 'Email is required'],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/text-with-errors',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('textarea fields', () => {\n it('should render textarea with label', async () => {\n const config: TextareaFieldConfig = {\n type: 'textarea',\n label: 'Description',\n placeholder: 'Enter description',\n rows: 4\n };\n\n const template = FieldRenderer.renderField(\n 'description',\n config,\n 'This is a sample description\\nwith multiple lines',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/textarea-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render evaluated textarea with completion', async () => {\n const config: TextareaFieldConfig = {\n type: 'textarea',\n label: 'Message Template',\n evaluated: true,\n placeholder: 'Enter message with expressions',\n rows: 3\n };\n\n const template = FieldRenderer.renderField(\n 'message',\n config,\n 'Hello @contact.name,\\nYour order is ready!',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/textarea-evaluated',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('select fields', () => {\n it('should render select field with label', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Country',\n options: ['United States', 'Canada', 'United Kingdom', 'Australia'],\n searchable: true\n };\n\n const template = FieldRenderer.renderField(\n 'country',\n config,\n [{ name: 'Canada', value: 'Canada' }],\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-with-label',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render multi-select field', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Skills',\n options: ['JavaScript', 'Python', 'TypeScript', 'React', 'Node.js'],\n multi: true,\n tags: true\n };\n\n const template = FieldRenderer.renderField(\n 'skills',\n config,\n [\n { name: 'JavaScript', value: 'JavaScript' },\n { name: 'TypeScript', value: 'TypeScript' }\n ],\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-multi',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render select field without label for ArrayEditor context', async () => {\n const config: SelectFieldConfig = {\n type: 'select',\n label: 'Status',\n options: ['Active', 'Inactive', 'Pending']\n };\n\n const template = FieldRenderer.renderField(\n 'status',\n config,\n [{ name: 'Active', value: 'Active' }],\n {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 200px; padding: 10px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/select-no-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('checkbox fields', () => {\n it('should render checkbox with label', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Accept Terms and Conditions'\n };\n\n const template = FieldRenderer.renderField('accept', config, true, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-checked',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render unchecked checkbox', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Subscribe to newsletter'\n };\n\n const template = FieldRenderer.renderField('subscribe', config, false, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-unchecked',\n getClip(container as HTMLElement)\n );\n });\n\n it('should render checkbox with errors', async () => {\n const config: CheckboxFieldConfig = {\n type: 'checkbox',\n label: 'Agree to terms',\n required: true\n };\n\n const template = FieldRenderer.renderField('terms', config, false, {\n errors: ['You must accept the terms to continue'],\n showLabel: true,\n onChange: () => {}\n });\n\n const container = await fixture(\n html`<div style=\"width: 400px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/checkbox-with-errors',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('key-value fields', () => {\n it('should render key-value field with label', async () => {\n const config: KeyValueFieldConfig = {\n type: 'key-value',\n label: 'HTTP Headers',\n keyPlaceholder: 'Header name',\n valuePlaceholder: 'Header value'\n };\n\n const template = FieldRenderer.renderField(\n 'headers',\n config,\n [\n { key: 'Content-Type', value: 'application/json' },\n { key: 'Authorization', value: 'Bearer token123' }\n ],\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 500px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/key-value-with-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('message-editor fields', () => {\n it('should render message-editor with label', async () => {\n const config: MessageEditorFieldConfig = {\n type: 'message-editor',\n label: 'Email Message',\n placeholder: 'Enter your message...',\n minHeight: 120\n };\n\n const template = FieldRenderer.renderField(\n 'message',\n config,\n 'Hello! This is a test message.',\n {\n errors: [],\n showLabel: true,\n onChange: () => {},\n additionalData: { attachments: [] }\n }\n );\n\n const container = await fixture(\n html`<div style=\"width: 500px; padding: 20px;\">${template}</div>`\n );\n await assertScreenshot(\n 'field-renderer/message-editor-with-label',\n getClip(container as HTMLElement)\n );\n });\n });\n\n describe('field consistency', () => {\n it('should render the same field type consistently between contexts', async () => {\n const config: TextFieldConfig = {\n type: 'text',\n label: 'Product Name',\n placeholder: 'Enter product name'\n };\n\n // NodeEditor context (with label)\n const nodeEditorTemplate = FieldRenderer.renderField(\n 'product',\n config,\n 'iPhone 15',\n {\n errors: [],\n showLabel: true,\n onChange: () => {}\n }\n );\n\n // ArrayEditor context (without label)\n const arrayEditorTemplate = FieldRenderer.renderField(\n 'product',\n config,\n 'iPhone 15',\n {\n errors: [],\n showLabel: false,\n flavor: 'small',\n extraClasses: 'form-control',\n onChange: () => {}\n }\n );\n\n const nodeContainer = await fixture(html`<div\n style=\"width: 400px; padding: 20px; border: 1px solid #ddd; margin: 10px;\"\n >\n <h3 style=\"margin: 0 0 10px 0; font-size: 14px; color: #666;\">\n NodeEditor Context\n </h3>\n ${nodeEditorTemplate}\n </div>`);\n\n const arrayContainer = await fixture(html`<div\n style=\"width: 400px; padding: 20px; border: 1px solid #ddd; margin: 10px;\"\n >\n <h3 style=\"margin: 0 0 10px 0; font-size: 14px; color: #666;\">\n ArrayEditor Context\n </h3>\n ${arrayEditorTemplate}\n </div>`);\n\n const combinedContainer = await fixture(html`<div\n style=\"display: flex; flex-direction: column; width: 420px;\"\n >\n ${nodeContainer} ${arrayContainer}\n </div>`);\n\n await assertScreenshot(\n 'field-renderer/context-comparison',\n getClip(combinedContainer as HTMLElement)\n );\n });\n });\n\n describe('error handling', () => {\n it('should handle all field types without throwing errors', () => {\n const configs = [\n { type: 'text', label: 'Text' } as TextFieldConfig,\n { type: 'textarea', label: 'Textarea' } as TextareaFieldConfig,\n { type: 'select', label: 'Select', options: [] } as SelectFieldConfig,\n { type: 'checkbox', label: 'Checkbox' },\n { type: 'key-value', label: 'KeyValue' },\n { type: 'array', label: 'Array', itemConfig: {} },\n { type: 'message-editor', label: 'MessageEditor' }\n ];\n\n configs.forEach((config, index) => {\n expect(() => {\n FieldRenderer.renderField(`field${index}`, config as any, null, {\n errors: [],\n showLabel: true,\n onChange: () => {}\n });\n }).to.not.throw;\n });\n });\n });\n});\n"]}
@@ -104,6 +104,24 @@ export const mockAPI = () => {
104
104
  mockGET(url, key);
105
105
  }
106
106
  }
107
+ // Add mock data for contact form endpoints
108
+ mockGET(/\/api\/v2\/channels\.json/, {
109
+ results: [
110
+ { uuid: 'chan-1', name: 'WhatsApp Channel' },
111
+ { uuid: 'chan-2', name: 'Telegram Channel' },
112
+ { uuid: 'chan-3', name: 'SMS Channel' },
113
+ { uuid: 'chan-4', name: 'Facebook Messenger' }
114
+ ]
115
+ });
116
+ mockGET(/\/api\/v2\/languages\.json/, {
117
+ results: [
118
+ { iso: 'eng', name: 'English' },
119
+ { iso: 'spa', name: 'Spanish' },
120
+ { iso: 'fra', name: 'French' },
121
+ { iso: 'por', name: 'Portuguese' },
122
+ { iso: 'deu', name: 'German' }
123
+ ]
124
+ });
107
125
  };
108
126
  export const mockGET = (endpoint, body, headers = {}, status = '200') => {
109
127
  gets.push({ endpoint, body, headers, status });
@@ -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 } 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"]}
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 // Add mock data for contact form endpoints\n mockGET(/\\/api\\/v2\\/channels\\.json/, {\n results: [\n { uuid: 'chan-1', name: 'WhatsApp Channel' },\n { uuid: 'chan-2', name: 'Telegram Channel' },\n { uuid: 'chan-3', name: 'SMS Channel' },\n { uuid: 'chan-4', name: 'Facebook Messenger' }\n ]\n });\n\n mockGET(/\\/api\\/v2\\/languages\\.json/, {\n results: [\n { iso: 'eng', name: 'English' },\n { iso: 'spa', name: 'Spanish' },\n { iso: 'fra', name: 'French' },\n { iso: 'por', name: 'Portuguese' },\n { iso: 'deu', name: 'German' }\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.10",
3
+ "version": "0.130.0",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file