@nyaruka/temba-components 0.131.3 → 0.133.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.
- package/CHANGELOG.md +22 -0
- package/demo/components/flow/example.html +1 -0
- package/demo/static/css/tailwind.css +30019 -0
- package/dist/temba-components.js +449 -417
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +26 -6
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +4 -4
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +124 -58
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +89 -40
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeTypeSelector.js +8 -2
- package/out-tsc/src/flow/NodeTypeSelector.js.map +1 -1
- package/out-tsc/src/flow/config.js +17 -4
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +2 -2
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_run_result.js +6 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/layout/FloatingWindow.js +1 -2
- package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +1 -0
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +3 -2
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +105 -69
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/store/AppState.js +39 -1
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/utils.js +3 -3
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +6 -5
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_run_result.test.js +83 -0
- package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
- package/out-tsc/test/temba-backwards-compatibility.test.js +30 -0
- package/out-tsc/test/temba-backwards-compatibility.test.js.map +1 -0
- package/out-tsc/test/temba-contact-chat.test.js +28 -13
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-floating-window.test.js +0 -2
- package/out-tsc/test/temba-floating-window.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-node.test.js +109 -0
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-localization.test.js +24 -5
- package/out-tsc/test/temba-localization.test.js.map +1 -1
- package/out-tsc/test/temba-node-type-selector.test.js +70 -3
- package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
- package/out-tsc/test/temba-utils-uuid.test.js +45 -1
- package/out-tsc/test/temba-utils-uuid.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +3 -3
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/screenshots/truth/floating-tab/default.png +0 -0
- package/screenshots/truth/floating-tab/gray.png +0 -0
- package/screenshots/truth/floating-tab/green.png +0 -0
- package/screenshots/truth/floating-tab/hover.png +0 -0
- package/screenshots/truth/floating-tab/purple.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/src/display/Chat.ts +29 -7
- package/src/display/FloatingTab.ts +4 -4
- package/src/events.ts +1 -4
- package/src/flow/CanvasNode.ts +130 -57
- package/src/flow/Editor.ts +107 -40
- package/src/flow/NodeTypeSelector.ts +7 -1
- package/src/flow/config.ts +22 -4
- package/src/flow/nodes/split_by_llm_categorize.ts +2 -8
- package/src/flow/nodes/split_by_run_result.ts +7 -0
- package/src/flow/types.ts +2 -0
- package/src/layout/FloatingWindow.ts +1 -3
- package/src/list/ContentMenu.ts +1 -0
- package/src/list/SortableList.ts +3 -2
- package/src/live/ContactChat.ts +112 -78
- package/src/store/AppState.ts +53 -1
- package/src/utils.ts +3 -3
- package/test/ActionHelper.ts +13 -5
- package/test/actions/send_broadcast.test.ts +2 -1
- package/test/nodes/split_by_run_result.test.ts +99 -0
- package/test/temba-backwards-compatibility.test.ts +37 -0
- package/test/temba-contact-chat.test.ts +28 -13
- package/test/temba-floating-window.test.ts +0 -2
- package/test/temba-flow-editor-node.test.ts +129 -0
- package/test/temba-localization.test.ts +29 -5
- package/test/temba-node-type-selector.test.ts +89 -3
- package/test/temba-utils-uuid.test.ts +61 -1
- package/test/utils.test.ts +8 -3
- package/test-assets/contacts/history.json +22 -9
- package/web-test-runner.config.mjs +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-localization.test.js","sourceRoot":"","sources":["../../test/temba-localization.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { Editor } from '../src/flow/Editor';\nimport { NodeEditor } from '../src/flow/NodeEditor';\nimport { SendMsg, FlowDefinition } from '../src/store/flow-definition';\nimport { zustand } from '../src/store/AppState';\nimport { send_msg } from '../src/flow/actions/send_msg';\nimport '../temba-modules';\n\ndescribe('Localization Editing', () => {\n let editor: Editor;\n let storeElement: HTMLElement;\n\n const languageNames: Record<string, string> = {\n eng: 'English',\n fra: 'French',\n esp: 'Spanish'\n };\n\n const buildCategoryFlowDefinition = (\n localization: Record<string, any> = {}\n ): FlowDefinition => ({\n uuid: 'category-flow',\n name: 'Category Flow',\n language: 'eng',\n type: 'messaging',\n revision: 1,\n spec_version: '14.3',\n localization,\n nodes: [\n {\n uuid: 'split-node',\n actions: [],\n exits: [\n { uuid: 'split-exit-1', destination_uuid: null },\n { uuid: 'split-exit-2', destination_uuid: null }\n ],\n router: {\n type: 'random',\n categories: [\n {\n uuid: 'cat-1',\n name: 'First bucket',\n exit_uuid: 'split-exit-1'\n },\n {\n uuid: 'cat-2',\n name: 'Second bucket',\n exit_uuid: 'split-exit-2'\n }\n ]\n }\n }\n ],\n _ui: {\n nodes: {\n 'split-node': {\n position: { left: 0, top: 0 },\n type: 'split_by_random'\n }\n },\n languages: []\n }\n });\n\n const openLocalizationWindow = async (\n flowEditor: Editor\n ): Promise<HTMLElement> => {\n const tab = flowEditor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await flowEditor.updateComplete;\n return flowEditor.querySelector('#localization-window') as HTMLElement;\n };\n\n before(() => {\n storeElement = document.createElement('temba-store');\n (storeElement as any).getLanguageName = (code: string) =>\n languageNames[code];\n document.body.appendChild(storeElement);\n });\n\n after(() => {\n storeElement?.remove();\n });\n\n afterEach(() => {\n editor?.remove();\n });\n\n beforeEach(async () => {\n // Create a flow definition with localization data\n const flowDefinition: FlowDefinition = {\n uuid: 'test-flow',\n name: 'Test Flow',\n language: 'eng',\n type: 'messaging',\n revision: 1,\n spec_version: '14.3',\n localization: {\n esp: {\n 'action-1': {\n text: ['Hola mundo'],\n quick_replies: ['Sí', 'No']\n }\n }\n },\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n } as SendMsg\n ],\n exits: [{ uuid: 'exit-1' }]\n }\n ],\n _ui: {\n nodes: {\n 'node-1': {\n position: { left: 100, top: 100 }\n }\n },\n languages: []\n }\n };\n\n // Initialize store with flow definition\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n await editor.updateComplete;\n });\n\n it('should render localization floating tab when translations exist', () => {\n const tab = editor.querySelector('#localization-tab');\n expect(tab).to.exist;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n expect(windowEl).to.exist;\n expect(windowEl.hidden).to.be.true;\n });\n\n it('should open localization window with translation languages excluding base', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n expect(windowEl.hidden).to.be.false;\n\n const select = windowEl.querySelector('temba-select') as any;\n expect(select).to.exist;\n expect(select.values[0].value).to.equal('fra');\n\n const options = windowEl.querySelectorAll('temba-option');\n expect(options.length).to.equal(2);\n const optionLabels = Array.from(options).map((opt: Element) =>\n opt.getAttribute('name')\n );\n expect(optionLabels).to.include('French');\n expect(optionLabels).to.include('Spanish');\n expect(optionLabels).to.not.include('English');\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('fra');\n\n const summary = windowEl.querySelector('.localization-progress-summary');\n expect(summary?.textContent.trim()).to.equal('0 of 1 items translated');\n\n const progress = windowEl.querySelector('temba-progress') as any;\n expect(progress).to.exist;\n expect(progress.current).to.equal(0);\n expect(progress.total).to.equal(1);\n expect(progress.animated).to.be.false;\n });\n\n it('should toggle translation settings and persist include categories preference', async () => {\n await openLocalizationWindow(editor);\n\n const toggle = editor.querySelector(\n '.translation-settings-toggle'\n ) as HTMLElement;\n expect(toggle).to.exist;\n\n toggle.dispatchEvent(new Event('click', { bubbles: true }));\n await editor.updateComplete;\n\n const checkbox = editor.querySelector(\n '#translation-settings-panel temba-checkbox'\n ) as any;\n expect(checkbox).to.exist;\n expect(Boolean(checkbox.checked)).to.be.false;\n\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n await editor.updateComplete;\n\n const filters = zustand.getState().flowDefinition._ui.translation_filters;\n expect(filters?.categories).to.be.true;\n });\n\n it('should allow toggling translation languages within the window', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window');\n const select = windowEl.querySelector('temba-select') as any;\n expect(select).to.exist;\n\n select.values = [{ name: 'Spanish', value: 'esp' }];\n select.dispatchEvent(new CustomEvent('change', { bubbles: true }));\n await editor.updateComplete;\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('esp');\n const summary = windowEl.querySelector('.localization-progress-summary');\n expect(summary?.textContent.trim()).to.equal('All items are translated.');\n });\n\n it('should include category translations when include categories is enabled', async () => {\n editor?.remove();\n\n const categoryFlowDefinition: FlowDefinition =\n buildCategoryFlowDefinition();\n\n zustand.getState().setFlowContents({\n definition: categoryFlowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n await editor.updateComplete;\n\n await openLocalizationWindow(editor);\n\n let summary = editor\n .querySelector('.localization-progress-summary')\n .textContent.trim();\n expect(summary).to.equal(\n 'Add content or enable more options to start translating.'\n );\n\n const toggle = editor.querySelector(\n '.translation-settings-toggle'\n ) as HTMLElement;\n toggle.dispatchEvent(new Event('click', { bubbles: true }));\n await editor.updateComplete;\n\n const checkbox = editor.querySelector(\n 'temba-checkbox[name=\"include-categories\"]'\n ) as any;\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n await editor.updateComplete;\n\n summary = editor\n .querySelector('.localization-progress-summary')\n .textContent.trim();\n expect(summary).to.equal('0 of 2 items translated');\n });\n\n it('should remove category localization when translation is cleared', async () => {\n editor?.remove();\n editor = null;\n\n const flowDefinition = buildCategoryFlowDefinition({\n fra: {\n 'cat-1': { name: ['Premier choix'] },\n 'cat-2': { name: ['Deuxième choix'] }\n }\n });\n\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n zustand.getState().setLanguageCode('fra');\n\n const state = zustand.getState();\n const node = state.flowDefinition.nodes[0];\n const nodeUI = state.flowDefinition._ui.nodes[node.uuid];\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor\n .node=${node}\n .nodeUI=${nodeUI}\n .isOpen=${true}\n ></temba-node-editor>\n `);\n await nodeEditor.updateComplete;\n\n const formData = (nodeEditor as any).formData;\n formData.categories['cat-1'].localizedName = '';\n\n (nodeEditor as any).handleSave();\n\n const localization =\n zustand.getState().flowDefinition.localization?.fra || {};\n expect(localization['cat-1']).to.be.undefined;\n expect(localization['cat-2']).to.deep.equal({ name: ['Deuxième choix'] });\n\n nodeEditor.remove();\n });\n\n it('should remove empty localization entries when all category translations are cleared', async () => {\n editor?.remove();\n editor = null;\n\n const flowDefinition = buildCategoryFlowDefinition({\n fra: {\n 'cat-1': { name: ['Premier choix'] }\n }\n });\n\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n zustand.getState().setLanguageCode('fra');\n\n const state = zustand.getState();\n const node = state.flowDefinition.nodes[0];\n const nodeUI = state.flowDefinition._ui.nodes[node.uuid];\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor\n .node=${node}\n .nodeUI=${nodeUI}\n .isOpen=${true}\n ></temba-node-editor>\n `);\n await nodeEditor.updateComplete;\n\n const formData = (nodeEditor as any).formData;\n formData.categories['cat-1'].localizedName = '';\n\n (nodeEditor as any).handleSave();\n\n const localization = zustand.getState().flowDefinition.localization;\n expect(localization).to.be.undefined;\n\n nodeEditor.remove();\n });\n\n it('should open auto translate dialog when clicking auto translate', async () => {\n await openLocalizationWindow(editor);\n\n const autoTranslateButton = editor.querySelector(\n '.auto-translate-button'\n ) as HTMLButtonElement;\n expect(autoTranslateButton.disabled).to.be.false;\n\n autoTranslateButton.click();\n await editor.updateComplete;\n\n expect((editor as any).autoTranslateDialogOpen).to.be.true;\n const dialog = editor.querySelector(\n 'temba-dialog[header=\"Auto translate\"]'\n );\n const modelSelect = dialog?.querySelector(\n '.auto-translate-model-select'\n ) as HTMLElement;\n expect(modelSelect).to.exist;\n expect(modelSelect.getAttribute('endpoint')).to.equal(\n '/api/internal/llms.json'\n );\n });\n\n it('should return to base language when window closes', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n windowEl.close();\n await editor.updateComplete;\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('eng');\n expect(windowEl.hidden).to.be.true;\n });\n\n it('should load base language values when in English', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = send_msg.toFormData(action);\n\n expect(formData.text).to.equal('Hello world');\n expect(formData.quick_replies).to.have.lengthOf(2);\n expect(formData.quick_replies[0].value).to.equal('Yes');\n expect(formData.quick_replies[1].value).to.equal('No');\n });\n\n it('should load localized values when in Spanish', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const localization = {\n text: ['Hola mundo'],\n quick_replies: ['Sí', 'No']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola mundo');\n expect(formData.quick_replies).to.have.lengthOf(2);\n expect(formData.quick_replies[0].value).to.equal('Sí');\n expect(formData.quick_replies[1].value).to.equal('No');\n });\n\n it('should fall back to base language if no localization exists', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const localization = {}; // Empty localization\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n // Should show base language values (but empty since localization is empty)\n expect(formData.text).to.equal('');\n expect(formData.quick_replies).to.be.undefined;\n });\n\n it('should convert form data to localization format', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Bonjour le monde',\n quick_replies: [\n { name: 'Oui', value: 'Oui' },\n { name: 'Non', value: 'Non' }\n ]\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n expect(localization.text).to.deep.equal(['Bonjour le monde']);\n expect(localization.quick_replies).to.deep.equal(['Oui', 'Non']);\n });\n\n it('should not include unchanged values in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Hello world', // Same as base\n quick_replies: [\n { name: 'Yes', value: 'Yes' },\n { name: 'No', value: 'No' }\n ] // Same as base\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n // should not include unchanged values\n expect(localization.text).to.be.undefined;\n expect(localization.quick_replies).to.be.undefined;\n });\n\n it('should include language name in dialog header when translating', async () => {\n // Switch to Spanish\n zustand.getState().setLanguageCode('esp');\n\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: []\n };\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor .action=${action} .isOpen=${true}> </temba-node-editor>\n `);\n\n await nodeEditor.updateComplete;\n\n // Check dialog header\n const dialog = nodeEditor.shadowRoot.querySelector('temba-dialog');\n expect(dialog).to.exist;\n expect(dialog.getAttribute('header')).to.equal('Spanish - Send Message');\n });\n\n it('should handle attachments in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello',\n attachments: ['image/jpeg:http://example.com/image.jpg']\n };\n\n const localization = {\n text: ['Hola'],\n attachments: ['image/jpeg:http://example.com/imagen.jpg']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola');\n expect(formData.attachments).to.have.lengthOf(1);\n expect(formData.attachments[0]).to.equal(\n 'image/jpeg:http://example.com/imagen.jpg'\n );\n });\n\n it('should handle runtime attachments in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello',\n attachments: ['image:@fields.profile_pic']\n };\n\n const localization = {\n text: ['Hola'],\n attachments: ['image:@fields.foto_perfil']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola');\n expect(formData.runtime_attachments).to.have.lengthOf(1);\n expect(formData.runtime_attachments[0].expression).to.equal(\n '@fields.foto_perfil'\n );\n });\n\n it('should identify localizable fields', () => {\n expect(send_msg.localizable).to.exist;\n expect(send_msg.localizable).to.include('text');\n expect(send_msg.localizable).to.include('quick_replies');\n expect(send_msg.localizable).to.include('attachments');\n });\n\n it('should save empty localization when all values match base', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: []\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Hello world' // Same as base, so shouldn't be saved\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n // empty localization when nothing changed\n expect(Object.keys(localization)).to.have.lengthOf(0);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"temba-localization.test.js","sourceRoot":"","sources":["../../test/temba-localization.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { Editor } from '../src/flow/Editor';\nimport { NodeEditor } from '../src/flow/NodeEditor';\nimport { SendMsg, FlowDefinition } from '../src/store/flow-definition';\nimport { zustand } from '../src/store/AppState';\nimport { send_msg } from '../src/flow/actions/send_msg';\nimport '../temba-modules';\n\ndescribe('Localization Editing', () => {\n let editor: Editor;\n let storeElement: HTMLElement;\n\n const languageNames: Record<string, string> = {\n eng: 'English',\n fra: 'French',\n spa: 'Spanish'\n };\n\n const setupWorkspace = () => {\n zustand.setState({\n workspace: {\n uuid: 'test-workspace',\n name: 'Test Workspace',\n languages: ['eng', 'fra', 'spa'],\n primary_language: 'eng',\n timezone: 'UTC',\n date_style: 'day_first',\n country: 'US',\n anon: false\n }\n });\n };\n\n const buildCategoryFlowDefinition = (\n localization: Record<string, any> = {}\n ): FlowDefinition => ({\n uuid: 'category-flow',\n name: 'Category Flow',\n language: 'eng',\n type: 'messaging',\n revision: 1,\n spec_version: '14.3',\n localization,\n nodes: [\n {\n uuid: 'split-node',\n actions: [],\n exits: [\n { uuid: 'split-exit-1', destination_uuid: null },\n { uuid: 'split-exit-2', destination_uuid: null }\n ],\n router: {\n type: 'random',\n categories: [\n {\n uuid: 'cat-1',\n name: 'First bucket',\n exit_uuid: 'split-exit-1'\n },\n {\n uuid: 'cat-2',\n name: 'Second bucket',\n exit_uuid: 'split-exit-2'\n }\n ]\n }\n }\n ],\n _ui: {\n nodes: {\n 'split-node': {\n position: { left: 0, top: 0 },\n type: 'split_by_random'\n }\n },\n languages: []\n }\n });\n\n const openLocalizationWindow = async (\n flowEditor: Editor\n ): Promise<HTMLElement> => {\n const tab = flowEditor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await flowEditor.updateComplete;\n return flowEditor.querySelector('#localization-window') as HTMLElement;\n };\n\n before(() => {\n storeElement = document.createElement('temba-store');\n (storeElement as any).getLanguageName = (code: string) =>\n languageNames[code];\n document.body.appendChild(storeElement);\n });\n\n after(() => {\n storeElement?.remove();\n });\n\n afterEach(() => {\n editor?.remove();\n });\n\n beforeEach(async () => {\n // Set workspace with languages\n setupWorkspace();\n\n // Create a flow definition with localization data\n const flowDefinition: FlowDefinition = {\n uuid: 'test-flow',\n name: 'Test Flow',\n language: 'eng',\n type: 'messaging',\n revision: 1,\n spec_version: '14.3',\n localization: {\n spa: {\n 'action-1': {\n text: ['Hola mundo'],\n quick_replies: ['Sí', 'No']\n }\n }\n },\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n } as SendMsg\n ],\n exits: [{ uuid: 'exit-1' }]\n }\n ],\n _ui: {\n nodes: {\n 'node-1': {\n position: { left: 100, top: 100 }\n }\n },\n languages: []\n }\n };\n\n // Initialize store with flow definition\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n await editor.updateComplete;\n });\n\n it('should render localization floating tab when translations exist', () => {\n const tab = editor.querySelector('#localization-tab');\n expect(tab).to.exist;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n expect(windowEl).to.exist;\n expect(windowEl.hidden).to.be.true;\n });\n\n it('should open localization window with translation languages excluding base', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n expect(windowEl.hidden).to.be.false;\n\n const select = windowEl.querySelector('temba-select') as any;\n expect(select).to.exist;\n expect(select.values[0].value).to.equal('fra');\n\n const options = windowEl.querySelectorAll('temba-option');\n expect(options.length).to.equal(2);\n const optionLabels = Array.from(options).map((opt: Element) =>\n opt.getAttribute('name')\n );\n expect(optionLabels).to.include('French');\n expect(optionLabels).to.include('Spanish');\n expect(optionLabels).to.not.include('English');\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('fra');\n\n const summary = windowEl.querySelector('.localization-progress-summary');\n expect(summary?.textContent.trim()).to.equal('0 of 1 items translated');\n\n const progress = windowEl.querySelector('temba-progress') as any;\n expect(progress).to.exist;\n expect(progress.current).to.equal(0);\n expect(progress.total).to.equal(1);\n expect(progress.animated).to.be.false;\n });\n\n it('should toggle translation settings and persist include categories preference', async () => {\n await openLocalizationWindow(editor);\n\n const toggle = editor.querySelector(\n '.translation-settings-toggle'\n ) as HTMLElement;\n expect(toggle).to.exist;\n\n toggle.dispatchEvent(new Event('click', { bubbles: true }));\n await editor.updateComplete;\n\n const checkbox = editor.querySelector(\n '#translation-settings-panel temba-checkbox'\n ) as any;\n expect(checkbox).to.exist;\n expect(Boolean(checkbox.checked)).to.be.false;\n\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n await editor.updateComplete;\n\n const filters = zustand.getState().flowDefinition._ui.translation_filters;\n expect(filters?.categories).to.be.true;\n });\n\n it('should allow toggling translation languages within the window', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window');\n const select = windowEl.querySelector('temba-select') as any;\n expect(select).to.exist;\n\n select.values = [{ name: 'Spanish', value: 'spa' }];\n select.dispatchEvent(new CustomEvent('change', { bubbles: true }));\n await editor.updateComplete;\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('spa');\n const summary = windowEl.querySelector('.localization-progress-summary');\n expect(summary?.textContent.trim()).to.equal('All items are translated.');\n });\n\n it('should include category translations when include categories is enabled', async () => {\n editor?.remove();\n\n setupWorkspace();\n\n const categoryFlowDefinition: FlowDefinition =\n buildCategoryFlowDefinition();\n\n zustand.getState().setFlowContents({\n definition: categoryFlowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n await editor.updateComplete;\n\n await openLocalizationWindow(editor);\n\n let summary = editor\n .querySelector('.localization-progress-summary')\n .textContent.trim();\n expect(summary).to.equal(\n 'Add content or enable more options to start translating.'\n );\n\n const toggle = editor.querySelector(\n '.translation-settings-toggle'\n ) as HTMLElement;\n toggle.dispatchEvent(new Event('click', { bubbles: true }));\n await editor.updateComplete;\n\n const checkbox = editor.querySelector(\n 'temba-checkbox[name=\"include-categories\"]'\n ) as any;\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n await editor.updateComplete;\n\n summary = editor\n .querySelector('.localization-progress-summary')\n .textContent.trim();\n expect(summary).to.equal('0 of 2 items translated');\n });\n\n it('should remove category localization when translation is cleared', async () => {\n editor?.remove();\n editor = null;\n\n setupWorkspace();\n\n const flowDefinition = buildCategoryFlowDefinition({\n fra: {\n 'cat-1': { name: ['Premier choix'] },\n 'cat-2': { name: ['Deuxième choix'] }\n }\n });\n\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n zustand.getState().setLanguageCode('fra');\n\n const state = zustand.getState();\n const node = state.flowDefinition.nodes[0];\n const nodeUI = state.flowDefinition._ui.nodes[node.uuid];\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor\n .node=${node}\n .nodeUI=${nodeUI}\n .isOpen=${true}\n ></temba-node-editor>\n `);\n await nodeEditor.updateComplete;\n\n const formData = (nodeEditor as any).formData;\n formData.categories['cat-1'].localizedName = '';\n\n (nodeEditor as any).handleSave();\n\n const localization =\n zustand.getState().flowDefinition.localization?.fra || {};\n expect(localization['cat-1']).to.be.undefined;\n expect(localization['cat-2']).to.deep.equal({ name: ['Deuxième choix'] });\n\n nodeEditor.remove();\n });\n\n it('should remove empty localization entries when all category translations are cleared', async () => {\n editor?.remove();\n editor = null;\n\n setupWorkspace();\n\n const flowDefinition = buildCategoryFlowDefinition({\n fra: {\n 'cat-1': { name: ['Premier choix'] }\n }\n });\n\n zustand.getState().setFlowContents({\n definition: flowDefinition,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 2 },\n locals: []\n }\n });\n zustand.getState().setLanguageCode('fra');\n\n const state = zustand.getState();\n const node = state.flowDefinition.nodes[0];\n const nodeUI = state.flowDefinition._ui.nodes[node.uuid];\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor\n .node=${node}\n .nodeUI=${nodeUI}\n .isOpen=${true}\n ></temba-node-editor>\n `);\n await nodeEditor.updateComplete;\n\n const formData = (nodeEditor as any).formData;\n formData.categories['cat-1'].localizedName = '';\n\n (nodeEditor as any).handleSave();\n\n const localization = zustand.getState().flowDefinition.localization;\n expect(localization).to.be.undefined;\n\n nodeEditor.remove();\n });\n\n it('should open auto translate dialog when clicking auto translate', async () => {\n await openLocalizationWindow(editor);\n\n const autoTranslateButton = editor.querySelector(\n '.auto-translate-button'\n ) as HTMLButtonElement;\n expect(autoTranslateButton.disabled).to.be.false;\n\n autoTranslateButton.click();\n await editor.updateComplete;\n\n expect((editor as any).autoTranslateDialogOpen).to.be.true;\n const dialog = editor.querySelector(\n 'temba-dialog[header=\"Auto translate\"]'\n );\n const modelSelect = dialog?.querySelector(\n '.auto-translate-model-select'\n ) as HTMLElement;\n expect(modelSelect).to.exist;\n expect(modelSelect.getAttribute('endpoint')).to.equal(\n '/api/internal/llms.json'\n );\n });\n\n it('should return to base language when window closes', async () => {\n const tab = editor.querySelector('#localization-tab');\n tab.dispatchEvent(\n new CustomEvent('temba-button-clicked', { bubbles: true })\n );\n await editor.updateComplete;\n\n const windowEl = editor.querySelector('#localization-window') as any;\n windowEl.close();\n await editor.updateComplete;\n\n const state = zustand.getState();\n expect(state.languageCode).to.equal('eng');\n expect(windowEl.hidden).to.be.true;\n });\n\n it('should load base language values when in English', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = send_msg.toFormData(action);\n\n expect(formData.text).to.equal('Hello world');\n expect(formData.quick_replies).to.have.lengthOf(2);\n expect(formData.quick_replies[0].value).to.equal('Yes');\n expect(formData.quick_replies[1].value).to.equal('No');\n });\n\n it('should load localized values when in Spanish', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const localization = {\n text: ['Hola mundo'],\n quick_replies: ['Sí', 'No']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola mundo');\n expect(formData.quick_replies).to.have.lengthOf(2);\n expect(formData.quick_replies[0].value).to.equal('Sí');\n expect(formData.quick_replies[1].value).to.equal('No');\n });\n\n it('should fall back to base language if no localization exists', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const localization = {}; // Empty localization\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n // Should show base language values (but empty since localization is empty)\n expect(formData.text).to.equal('');\n expect(formData.quick_replies).to.be.undefined;\n });\n\n it('should convert form data to localization format', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Bonjour le monde',\n quick_replies: [\n { name: 'Oui', value: 'Oui' },\n { name: 'Non', value: 'Non' }\n ]\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n expect(localization.text).to.deep.equal(['Bonjour le monde']);\n expect(localization.quick_replies).to.deep.equal(['Oui', 'Non']);\n });\n\n it('should not include unchanged values in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: ['Yes', 'No']\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Hello world', // Same as base\n quick_replies: [\n { name: 'Yes', value: 'Yes' },\n { name: 'No', value: 'No' }\n ] // Same as base\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n // should not include unchanged values\n expect(localization.text).to.be.undefined;\n expect(localization.quick_replies).to.be.undefined;\n });\n\n it('should include language name in dialog header when translating', async () => {\n // Switch to Spanish\n zustand.getState().setLanguageCode('spa');\n\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: []\n };\n\n const nodeEditor: NodeEditor = await fixture(html`\n <temba-node-editor .action=${action} .isOpen=${true}> </temba-node-editor>\n `);\n\n await nodeEditor.updateComplete;\n\n // Check dialog header\n const dialog = nodeEditor.shadowRoot.querySelector('temba-dialog');\n expect(dialog).to.exist;\n expect(dialog.getAttribute('header')).to.equal('Spanish - Send Message');\n });\n\n it('should handle attachments in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello',\n attachments: ['image/jpeg:http://example.com/image.jpg']\n };\n\n const localization = {\n text: ['Hola'],\n attachments: ['image/jpeg:http://example.com/imagen.jpg']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola');\n expect(formData.attachments).to.have.lengthOf(1);\n expect(formData.attachments[0]).to.equal(\n 'image/jpeg:http://example.com/imagen.jpg'\n );\n });\n\n it('should handle runtime attachments in localization', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello',\n attachments: ['image:@fields.profile_pic']\n };\n\n const localization = {\n text: ['Hola'],\n attachments: ['image:@fields.foto_perfil']\n };\n\n const formData = send_msg.toLocalizationFormData(action, localization);\n\n expect(formData.text).to.equal('Hola');\n expect(formData.runtime_attachments).to.have.lengthOf(1);\n expect(formData.runtime_attachments[0].expression).to.equal(\n '@fields.foto_perfil'\n );\n });\n\n it('should identify localizable fields', () => {\n expect(send_msg.localizable).to.exist;\n expect(send_msg.localizable).to.include('text');\n expect(send_msg.localizable).to.include('quick_replies');\n expect(send_msg.localizable).to.include('attachments');\n });\n\n it('should save empty localization when all values match base', () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-1',\n text: 'Hello world',\n quick_replies: []\n };\n\n const formData = {\n uuid: 'action-1',\n text: 'Hello world' // Same as base, so shouldn't be saved\n };\n\n const localization = send_msg.fromLocalizationFormData(formData, action);\n\n // empty localization when nothing changed\n expect(Object.keys(localization)).to.have.lengthOf(0);\n });\n});\n"]}
|
|
@@ -179,8 +179,9 @@ describe('temba-node-type-selector', () => {
|
|
|
179
179
|
// get all node item titles
|
|
180
180
|
const nodeItems = (_a = selector.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.node-item-title');
|
|
181
181
|
const titles = Array.from(nodeItems || []).map((item) => { var _a; return (_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim(); });
|
|
182
|
-
//
|
|
183
|
-
|
|
182
|
+
// split_by_llm_categorize (Split by AI) is filtered out for old editor compatibility
|
|
183
|
+
// so it should NOT appear even when AI feature is enabled
|
|
184
|
+
expect(titles).to.not.include('Split by AI');
|
|
184
185
|
});
|
|
185
186
|
it('filters by features - without AI feature, AI splits are hidden', async () => {
|
|
186
187
|
var _a;
|
|
@@ -193,7 +194,8 @@ describe('temba-node-type-selector', () => {
|
|
|
193
194
|
// get all node item titles
|
|
194
195
|
const nodeItems = (_a = selector.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.node-item-title');
|
|
195
196
|
const titles = Array.from(nodeItems || []).map((item) => { var _a; return (_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim(); });
|
|
196
|
-
// without ai feature, should not have Split by AI
|
|
197
|
+
// without ai feature, should not have Call AI or Split by AI
|
|
198
|
+
expect(titles).to.not.include('Call AI');
|
|
197
199
|
expect(titles).to.not.include('Split by AI');
|
|
198
200
|
});
|
|
199
201
|
it('filters by features - airtime feature enables airtime actions', async () => {
|
|
@@ -261,5 +263,70 @@ describe('temba-node-type-selector', () => {
|
|
|
261
263
|
const isAvailableVoice = selector.isConfigAvailable(configWithUndefinedFlowTypes);
|
|
262
264
|
expect(isAvailableVoice).to.be.true;
|
|
263
265
|
});
|
|
266
|
+
describe('alias filtering', () => {
|
|
267
|
+
it('should not show split_by_run_result twice when aliases exist', async () => {
|
|
268
|
+
const selector = await createSelector();
|
|
269
|
+
selector.show('split', { x: 100, y: 100 });
|
|
270
|
+
await selector.updateComplete;
|
|
271
|
+
// Get all the node items rendered in the selector
|
|
272
|
+
const nodeItems = selector.shadowRoot.querySelectorAll('.node-item');
|
|
273
|
+
// Count how many times "Split by Result" appears
|
|
274
|
+
let splitByResultCount = 0;
|
|
275
|
+
nodeItems.forEach((item) => {
|
|
276
|
+
var _a;
|
|
277
|
+
const title = item.querySelector('.node-item-title');
|
|
278
|
+
if ((_a = title === null || title === void 0 ? void 0 : title.textContent) === null || _a === void 0 ? void 0 : _a.includes('Split by Result')) {
|
|
279
|
+
splitByResultCount++;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
// Should only appear once, not twice
|
|
283
|
+
expect(splitByResultCount).to.equal(1);
|
|
284
|
+
});
|
|
285
|
+
it('should not show split_by_run_result_delimited type in the selector', async () => {
|
|
286
|
+
const selector = await createSelector();
|
|
287
|
+
selector.show('split', { x: 100, y: 100 });
|
|
288
|
+
await selector.updateComplete;
|
|
289
|
+
// Get all the node items and check their data-type attributes
|
|
290
|
+
const nodeItems = selector.shadowRoot.querySelectorAll('.node-item');
|
|
291
|
+
let foundDelimitedType = false;
|
|
292
|
+
nodeItems.forEach((item) => {
|
|
293
|
+
const typeAttr = item.getAttribute('data-type');
|
|
294
|
+
if (typeAttr === 'split_by_run_result_delimited') {
|
|
295
|
+
foundDelimitedType = true;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
expect(foundDelimitedType).to.be.false;
|
|
299
|
+
});
|
|
300
|
+
it('should not show split_by_llm_categorize in split mode', async () => {
|
|
301
|
+
const selector = await createSelector();
|
|
302
|
+
selector.show('split', { x: 100, y: 100 });
|
|
303
|
+
await selector.updateComplete;
|
|
304
|
+
// Get all the node items and check their data-type attributes
|
|
305
|
+
const nodeItems = selector.shadowRoot.querySelectorAll('.node-item');
|
|
306
|
+
let foundLLMCategorize = false;
|
|
307
|
+
nodeItems.forEach((item) => {
|
|
308
|
+
const typeAttr = item.getAttribute('data-type');
|
|
309
|
+
if (typeAttr === 'split_by_llm_categorize') {
|
|
310
|
+
foundLLMCategorize = true;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
expect(foundLLMCategorize).to.be.false;
|
|
314
|
+
});
|
|
315
|
+
it('should not show split_by_llm_categorize in action mode', async () => {
|
|
316
|
+
const selector = await createSelector();
|
|
317
|
+
selector.show('action', { x: 100, y: 100 });
|
|
318
|
+
await selector.updateComplete;
|
|
319
|
+
// Get all the node items and check their data-type attributes
|
|
320
|
+
const nodeItems = selector.shadowRoot.querySelectorAll('.node-item');
|
|
321
|
+
let foundLLMCategorize = false;
|
|
322
|
+
nodeItems.forEach((item) => {
|
|
323
|
+
const typeAttr = item.getAttribute('data-type');
|
|
324
|
+
if (typeAttr === 'split_by_llm_categorize') {
|
|
325
|
+
foundLLMCategorize = true;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
expect(foundLLMCategorize).to.be.false;
|
|
329
|
+
});
|
|
330
|
+
});
|
|
264
331
|
});
|
|
265
332
|
//# sourceMappingURL=temba-node-type-selector.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-node-type-selector.test.js","sourceRoot":"","sources":["../../test/temba-node-type-selector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvE,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,MAAM,SAAS,GAAG,CAAC,MAAM,YAAY,CACnC,0BAA0B,EAC1B,EAAE,EACF,EAAE,EACF,GAAG,EACH,GAAG,CACJ,CAAqB,CAAC;QACvB,MAAM,SAAS,CAAC,cAAc,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC9C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAElC,6CAA6C;QAC7C,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;;QACvD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QAExC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CAAC,SAAS,CAAgB,CAAC;QAC5E,MAAM,gBAAgB,CAAC,gCAAgC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;;QACtD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QAExC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,MAAM,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CAAC,SAAS,CAAgB,CAAC;QAC5E,MAAM,gBAAgB,CAAC,+BAA+B,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;;QACpD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,KAAK,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CAAC,YAAY,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAExD,4BAA4B;QAC5B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;;QAClD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,KAAK,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CAAC,YAAY,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAEtD,4BAA4B;QAC5B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAEjC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;;QAC9C,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,OAAO,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CAChD,UAAU,CACI,CAAC;QACjB,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;;QACpD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,YAAY,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CACrD,cAAc,CACA,CAAC;QACjB,YAAY,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;;QAC/D,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,eAAe,GAAG,IAAI,CAAC;QAE3B,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,CAAC,KAAU,EAAE,EAAE;YAC1D,cAAc,GAAG,IAAI,CAAC;YACtB,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,aAAa,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,aAAa,CACtD,YAAY,CACE,CAAC;QACjB,aAAa,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;;QACxF,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC5B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,oDAAoD;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;;QAC9F,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,yDAAyD;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;;QACxF,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,6CAA6C;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;;QAC1F,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC5B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,+CAA+C;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAEnD,8DAA8D;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;;QAClE,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,QAAQ,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,2CAA2C;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;;QAC9E,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,kDAAkD;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;;QAC7E,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,QAAQ,CAAC,QAAQ,GAAG,CAAC,SAAS,CAAC,CAAC;QAChC,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,iDAAiD;QACjD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;;QACzF,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAA,QAAQ,CAAC,UAAU,0CAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,WACtD,OAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAA,EAAA,CACzB,CAAC;QAEF,wDAAwD;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QAExC,sEAAsE;QACtE,MAAM,wBAAwB,GAAG;YAC/B,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,aAAa;YACnB,SAAS,EAAE,EAAE,CAAC,8CAA8C;SAC7D,CAAC;QAEF,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,+CAA+C;QAC/C,MAAM,WAAW,GAAI,QAAgB,CAAC,iBAAiB,CACrD,wBAAwB,CACzB,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAEhC,yDAAyD;QACzD,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC5B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,gBAAgB,GAAI,QAAgB,CAAC,iBAAiB,CAC1D,wBAAwB,CACzB,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;QAExC,mEAAmE;QACnE,MAAM,4BAA4B,GAAG;YACnC,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,aAAa;YACnB,uDAAuD;SACxD,CAAC;QAEF,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC9B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,WAAW,GAAI,QAAgB,CAAC,iBAAiB,CACrD,4BAA4B,CAC7B,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAE/B,wDAAwD;QACxD,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC5B,MAAM,QAAQ,CAAC,cAAc,CAAC;QAE9B,MAAM,gBAAgB,GAAI,QAAgB,CAAC,iBAAiB,CAC1D,4BAA4B,CAC7B,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect, assert } from '@open-wc/testing';\nimport { NodeTypeSelector } from '../src/flow/NodeTypeSelector';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\n\ndescribe('temba-node-type-selector', () => {\n const createSelector = async () => {\n const component = (await getComponent(\n 'temba-node-type-selector',\n {},\n '',\n 700,\n 600\n )) as NodeTypeSelector;\n await component.updateComplete;\n return component;\n };\n\n it('can be created', async () => {\n const selector = await createSelector();\n assert.instanceOf(selector, NodeTypeSelector);\n expect(selector.open).to.be.false;\n });\n\n it('is not visible when closed', async () => {\n const selector = await createSelector();\n expect(selector.open).to.be.false;\n\n // component should not be in DOM when closed\n expect(selector.hasAttribute('open')).to.be.false;\n });\n\n it('shows dialog when opened in action mode', async () => {\n const selector = await createSelector();\n\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n expect(selector.mode).to.equal('action');\n expect(selector.hasAttribute('open')).to.be.true;\n\n const dialog = selector.shadowRoot?.querySelector('.dialog') as HTMLElement;\n await assertScreenshot('node-type-selector/action-mode', getClip(dialog));\n });\n\n it('shows dialog when opened in split mode', async () => {\n const selector = await createSelector();\n\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n expect(selector.mode).to.equal('split');\n\n const dialog = selector.shadowRoot?.querySelector('.dialog') as HTMLElement;\n await assertScreenshot('node-type-selector/split-mode', getClip(dialog));\n });\n\n it('displays action types in action mode', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const title = selector.shadowRoot?.querySelector('.header h2');\n expect(title?.textContent).to.equal('Select an Action');\n\n // verify we have node items\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item');\n expect(nodeItems?.length).to.be.greaterThan(0);\n });\n\n it('displays split types in split mode', async () => {\n const selector = await createSelector();\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const title = selector.shadowRoot?.querySelector('.header h2');\n expect(title?.textContent).to.equal('Select a Split');\n\n // verify we have node items\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item');\n expect(nodeItems?.length).to.be.greaterThan(0);\n });\n\n it('closes when close() is called', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n\n selector.close();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('closes when overlay is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const overlay = selector.shadowRoot?.querySelector(\n '.overlay'\n ) as HTMLElement;\n overlay.click();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('closes when cancel button is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const cancelButton = selector.shadowRoot?.querySelector(\n 'temba-button'\n ) as HTMLElement;\n cancelButton.click();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('fires selection event when node type is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n let selectionFired = false;\n let selectionDetail = null;\n\n selector.addEventListener('temba-selection', (event: any) => {\n selectionFired = true;\n selectionDetail = event.detail;\n });\n\n // click on first node item\n const firstNodeItem = selector.shadowRoot?.querySelector(\n '.node-item'\n ) as HTMLElement;\n firstNodeItem.click();\n await selector.updateComplete;\n\n expect(selectionFired).to.be.true;\n expect(selectionDetail).to.have.property('nodeType');\n expect(selectionDetail).to.have.property('position');\n expect(selectionDetail.position).to.deep.equal({ x: 100, y: 100 });\n expect(selector.open).to.be.false;\n });\n\n it('filters actions by flow type - voice flow should show voice-only actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'voice';\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // voice flow should have Say Message and Play Audio\n expect(titles).to.include('Say Message');\n expect(titles).to.include('Play Audio');\n });\n\n it('filters actions by flow type - message flow should not show voice-only actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // message flow should not have Say Message or Play Audio\n expect(titles).to.not.include('Say Message');\n expect(titles).to.not.include('Play Audio');\n });\n\n it('filters splits by flow type - message flow should show wait for response', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // message flow should have Wait for Response\n expect(titles).to.include('Wait for Response');\n });\n\n it('filters splits by flow type - voice flow should not show wait for response', async () => {\n const selector = await createSelector();\n selector.flowType = 'voice';\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // voice flow should not have Wait for Response\n expect(titles).to.not.include('Wait for Response');\n\n // but should have Wait for Digits and Wait for Menu Selection\n expect(titles).to.include('Wait for Digits');\n expect(titles).to.include('Wait for Menu Selection');\n });\n\n it('filters by features - AI feature enables AI splits', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = ['ai'];\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // with ai feature, should have Split by AI\n expect(titles).to.include('Split by AI');\n });\n\n it('filters by features - without AI feature, AI splits are hidden', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = [];\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // without ai feature, should not have Split by AI\n expect(titles).to.not.include('Split by AI');\n });\n\n it('filters by features - airtime feature enables airtime actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = ['airtime'];\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // with airtime feature, should have Send Airtime\n expect(titles).to.include('Send Airtime');\n });\n\n it('filters by features - without airtime feature, airtime actions are hidden', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = [];\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // without airtime feature, should not have Send Airtime\n expect(titles).to.not.include('Send Airtime');\n });\n\n it('hides actions/nodes with empty flowTypes array from selector', async () => {\n const selector = await createSelector();\n\n // test that isConfigAvailable returns false for empty flowTypes array\n const configWithEmptyFlowTypes = {\n name: 'Test Action',\n type: 'test_action',\n flowTypes: [] // empty array should hide from all flow types\n };\n\n selector.flowType = 'message';\n await selector.updateComplete;\n\n // call private method via any to test behavior\n const isAvailable = (selector as any).isConfigAvailable(\n configWithEmptyFlowTypes\n );\n expect(isAvailable).to.be.false;\n\n // test with different flow types - should still be false\n selector.flowType = 'voice';\n await selector.updateComplete;\n\n const isAvailableVoice = (selector as any).isConfigAvailable(\n configWithEmptyFlowTypes\n );\n expect(isAvailableVoice).to.be.false;\n });\n\n it('shows actions/nodes with undefined flowTypes for all flow types', async () => {\n const selector = await createSelector();\n\n // test that isConfigAvailable returns true for undefined flowTypes\n const configWithUndefinedFlowTypes = {\n name: 'Test Action',\n type: 'test_action'\n // flowTypes is undefined - should be available for all\n };\n\n selector.flowType = 'message';\n await selector.updateComplete;\n\n const isAvailable = (selector as any).isConfigAvailable(\n configWithUndefinedFlowTypes\n );\n expect(isAvailable).to.be.true;\n\n // test with different flow types - should still be true\n selector.flowType = 'voice';\n await selector.updateComplete;\n\n const isAvailableVoice = (selector as any).isConfigAvailable(\n configWithUndefinedFlowTypes\n );\n expect(isAvailableVoice).to.be.true;\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"temba-node-type-selector.test.js","sourceRoot":"","sources":["../../test/temba-node-type-selector.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, assert } from '@open-wc/testing';\nimport { NodeTypeSelector } from '../src/flow/NodeTypeSelector';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\n\ndescribe('temba-node-type-selector', () => {\n const createSelector = async () => {\n const component = (await getComponent(\n 'temba-node-type-selector',\n {},\n '',\n 700,\n 600\n )) as NodeTypeSelector;\n await component.updateComplete;\n return component;\n };\n\n it('can be created', async () => {\n const selector = await createSelector();\n assert.instanceOf(selector, NodeTypeSelector);\n expect(selector.open).to.be.false;\n });\n\n it('is not visible when closed', async () => {\n const selector = await createSelector();\n expect(selector.open).to.be.false;\n\n // component should not be in DOM when closed\n expect(selector.hasAttribute('open')).to.be.false;\n });\n\n it('shows dialog when opened in action mode', async () => {\n const selector = await createSelector();\n\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n expect(selector.mode).to.equal('action');\n expect(selector.hasAttribute('open')).to.be.true;\n\n const dialog = selector.shadowRoot?.querySelector('.dialog') as HTMLElement;\n await assertScreenshot('node-type-selector/action-mode', getClip(dialog));\n });\n\n it('shows dialog when opened in split mode', async () => {\n const selector = await createSelector();\n\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n expect(selector.mode).to.equal('split');\n\n const dialog = selector.shadowRoot?.querySelector('.dialog') as HTMLElement;\n await assertScreenshot('node-type-selector/split-mode', getClip(dialog));\n });\n\n it('displays action types in action mode', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const title = selector.shadowRoot?.querySelector('.header h2');\n expect(title?.textContent).to.equal('Select an Action');\n\n // verify we have node items\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item');\n expect(nodeItems?.length).to.be.greaterThan(0);\n });\n\n it('displays split types in split mode', async () => {\n const selector = await createSelector();\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const title = selector.shadowRoot?.querySelector('.header h2');\n expect(title?.textContent).to.equal('Select a Split');\n\n // verify we have node items\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item');\n expect(nodeItems?.length).to.be.greaterThan(0);\n });\n\n it('closes when close() is called', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n expect(selector.open).to.be.true;\n\n selector.close();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('closes when overlay is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const overlay = selector.shadowRoot?.querySelector(\n '.overlay'\n ) as HTMLElement;\n overlay.click();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('closes when cancel button is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n const cancelButton = selector.shadowRoot?.querySelector(\n 'temba-button'\n ) as HTMLElement;\n cancelButton.click();\n await selector.updateComplete;\n\n expect(selector.open).to.be.false;\n });\n\n it('fires selection event when node type is clicked', async () => {\n const selector = await createSelector();\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n let selectionFired = false;\n let selectionDetail = null;\n\n selector.addEventListener('temba-selection', (event: any) => {\n selectionFired = true;\n selectionDetail = event.detail;\n });\n\n // click on first node item\n const firstNodeItem = selector.shadowRoot?.querySelector(\n '.node-item'\n ) as HTMLElement;\n firstNodeItem.click();\n await selector.updateComplete;\n\n expect(selectionFired).to.be.true;\n expect(selectionDetail).to.have.property('nodeType');\n expect(selectionDetail).to.have.property('position');\n expect(selectionDetail.position).to.deep.equal({ x: 100, y: 100 });\n expect(selector.open).to.be.false;\n });\n\n it('filters actions by flow type - voice flow should show voice-only actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'voice';\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // voice flow should have Say Message and Play Audio\n expect(titles).to.include('Say Message');\n expect(titles).to.include('Play Audio');\n });\n\n it('filters actions by flow type - message flow should not show voice-only actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // message flow should not have Say Message or Play Audio\n expect(titles).to.not.include('Say Message');\n expect(titles).to.not.include('Play Audio');\n });\n\n it('filters splits by flow type - message flow should show wait for response', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // message flow should have Wait for Response\n expect(titles).to.include('Wait for Response');\n });\n\n it('filters splits by flow type - voice flow should not show wait for response', async () => {\n const selector = await createSelector();\n selector.flowType = 'voice';\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // voice flow should not have Wait for Response\n expect(titles).to.not.include('Wait for Response');\n\n // but should have Wait for Digits and Wait for Menu Selection\n expect(titles).to.include('Wait for Digits');\n expect(titles).to.include('Wait for Menu Selection');\n });\n\n it('filters by features - AI feature enables AI splits', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = ['ai'];\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // split_by_llm_categorize (Split by AI) is filtered out for old editor compatibility\n // so it should NOT appear even when AI feature is enabled\n expect(titles).to.not.include('Split by AI');\n });\n\n it('filters by features - without AI feature, AI splits are hidden', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = [];\n await selector.updateComplete;\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // without ai feature, should not have Call AI or Split by AI\n expect(titles).to.not.include('Call AI');\n expect(titles).to.not.include('Split by AI');\n });\n\n it('filters by features - airtime feature enables airtime actions', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = ['airtime'];\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // with airtime feature, should have Send Airtime\n expect(titles).to.include('Send Airtime');\n });\n\n it('filters by features - without airtime feature, airtime actions are hidden', async () => {\n const selector = await createSelector();\n selector.flowType = 'message';\n selector.features = [];\n await selector.updateComplete;\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // get all node item titles\n const nodeItems = selector.shadowRoot?.querySelectorAll('.node-item-title');\n const titles = Array.from(nodeItems || []).map((item) =>\n item.textContent?.trim()\n );\n\n // without airtime feature, should not have Send Airtime\n expect(titles).to.not.include('Send Airtime');\n });\n\n it('hides actions/nodes with empty flowTypes array from selector', async () => {\n const selector = await createSelector();\n\n // test that isConfigAvailable returns false for empty flowTypes array\n const configWithEmptyFlowTypes = {\n name: 'Test Action',\n type: 'test_action',\n flowTypes: [] // empty array should hide from all flow types\n };\n\n selector.flowType = 'message';\n await selector.updateComplete;\n\n // call private method via any to test behavior\n const isAvailable = (selector as any).isConfigAvailable(\n configWithEmptyFlowTypes\n );\n expect(isAvailable).to.be.false;\n\n // test with different flow types - should still be false\n selector.flowType = 'voice';\n await selector.updateComplete;\n\n const isAvailableVoice = (selector as any).isConfigAvailable(\n configWithEmptyFlowTypes\n );\n expect(isAvailableVoice).to.be.false;\n });\n\n it('shows actions/nodes with undefined flowTypes for all flow types', async () => {\n const selector = await createSelector();\n\n // test that isConfigAvailable returns true for undefined flowTypes\n const configWithUndefinedFlowTypes = {\n name: 'Test Action',\n type: 'test_action'\n // flowTypes is undefined - should be available for all\n };\n\n selector.flowType = 'message';\n await selector.updateComplete;\n\n const isAvailable = (selector as any).isConfigAvailable(\n configWithUndefinedFlowTypes\n );\n expect(isAvailable).to.be.true;\n\n // test with different flow types - should still be true\n selector.flowType = 'voice';\n await selector.updateComplete;\n\n const isAvailableVoice = (selector as any).isConfigAvailable(\n configWithUndefinedFlowTypes\n );\n expect(isAvailableVoice).to.be.true;\n });\n\n describe('alias filtering', () => {\n it('should not show split_by_run_result twice when aliases exist', async () => {\n const selector = await createSelector();\n\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // Get all the node items rendered in the selector\n const nodeItems = selector.shadowRoot!.querySelectorAll('.node-item');\n\n // Count how many times \"Split by Result\" appears\n let splitByResultCount = 0;\n nodeItems.forEach((item) => {\n const title = item.querySelector('.node-item-title');\n if (title?.textContent?.includes('Split by Result')) {\n splitByResultCount++;\n }\n });\n\n // Should only appear once, not twice\n expect(splitByResultCount).to.equal(1);\n });\n\n it('should not show split_by_run_result_delimited type in the selector', async () => {\n const selector = await createSelector();\n\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // Get all the node items and check their data-type attributes\n const nodeItems = selector.shadowRoot!.querySelectorAll('.node-item');\n\n let foundDelimitedType = false;\n nodeItems.forEach((item) => {\n const typeAttr = item.getAttribute('data-type');\n if (typeAttr === 'split_by_run_result_delimited') {\n foundDelimitedType = true;\n }\n });\n\n expect(foundDelimitedType).to.be.false;\n });\n\n it('should not show split_by_llm_categorize in split mode', async () => {\n const selector = await createSelector();\n\n selector.show('split', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // Get all the node items and check their data-type attributes\n const nodeItems = selector.shadowRoot!.querySelectorAll('.node-item');\n\n let foundLLMCategorize = false;\n nodeItems.forEach((item) => {\n const typeAttr = item.getAttribute('data-type');\n if (typeAttr === 'split_by_llm_categorize') {\n foundLLMCategorize = true;\n }\n });\n\n expect(foundLLMCategorize).to.be.false;\n });\n\n it('should not show split_by_llm_categorize in action mode', async () => {\n const selector = await createSelector();\n\n selector.show('action', { x: 100, y: 100 });\n await selector.updateComplete;\n\n // Get all the node items and check their data-type attributes\n const nodeItems = selector.shadowRoot!.querySelectorAll('.node-item');\n\n let foundLLMCategorize = false;\n nodeItems.forEach((item) => {\n const typeAttr = item.getAttribute('data-type');\n if (typeAttr === 'split_by_llm_categorize') {\n foundLLMCategorize = true;\n }\n });\n\n expect(foundLLMCategorize).to.be.false;\n });\n });\n});\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert } from '@open-wc/testing';
|
|
2
|
-
import { generateUUID } from '../src/utils';
|
|
2
|
+
import { generateUUID, generateUUIDv7 } from '../src/utils';
|
|
3
3
|
describe('UUID Generation', () => {
|
|
4
4
|
it('generates a valid UUID v4 format', () => {
|
|
5
5
|
const uuid = generateUUID();
|
|
@@ -34,5 +34,49 @@ describe('UUID Generation', () => {
|
|
|
34
34
|
// All should be unique
|
|
35
35
|
assert.equal(uuids.size, count, 'All generated UUIDs should be unique');
|
|
36
36
|
});
|
|
37
|
+
it('generates a valid UUID v7 format', () => {
|
|
38
|
+
const uuid = generateUUIDv7();
|
|
39
|
+
// check that it's a string
|
|
40
|
+
assert.isString(uuid);
|
|
41
|
+
// check UUID v7 format: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx
|
|
42
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
43
|
+
assert.match(uuid, uuidPattern, 'Should match UUID v7 format');
|
|
44
|
+
// check length
|
|
45
|
+
assert.equal(uuid.length, 36);
|
|
46
|
+
// check that it contains hyphens in the right places
|
|
47
|
+
assert.equal(uuid[8], '-');
|
|
48
|
+
assert.equal(uuid[13], '-');
|
|
49
|
+
assert.equal(uuid[18], '-');
|
|
50
|
+
assert.equal(uuid[23], '-');
|
|
51
|
+
});
|
|
52
|
+
it('generates unique UUIDs v7', () => {
|
|
53
|
+
const uuid1 = generateUUIDv7();
|
|
54
|
+
const uuid2 = generateUUIDv7();
|
|
55
|
+
const uuid3 = generateUUIDv7();
|
|
56
|
+
// all should be different
|
|
57
|
+
assert.notEqual(uuid1, uuid2);
|
|
58
|
+
assert.notEqual(uuid2, uuid3);
|
|
59
|
+
assert.notEqual(uuid1, uuid3);
|
|
60
|
+
});
|
|
61
|
+
it('generates time-ordered UUIDs v7', () => {
|
|
62
|
+
const uuid1 = generateUUIDv7();
|
|
63
|
+
// small delay to ensure different timestamp
|
|
64
|
+
const delayPromise = new Promise((resolve) => setTimeout(resolve, 5));
|
|
65
|
+
return delayPromise.then(() => {
|
|
66
|
+
const uuid2 = generateUUIDv7();
|
|
67
|
+
// uuid v7 should be sortable by timestamp
|
|
68
|
+
// the first uuid should come before the second when compared as strings
|
|
69
|
+
assert.isTrue(uuid1 < uuid2, 'Earlier UUID should be lexicographically smaller');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it('generates many unique UUIDs v7', () => {
|
|
73
|
+
const uuids = new Set();
|
|
74
|
+
const count = 1000;
|
|
75
|
+
for (let i = 0; i < count; i++) {
|
|
76
|
+
uuids.add(generateUUIDv7());
|
|
77
|
+
}
|
|
78
|
+
// all should be unique
|
|
79
|
+
assert.equal(uuids.size, count, 'All generated UUIDs should be unique');
|
|
80
|
+
});
|
|
37
81
|
});
|
|
38
82
|
//# sourceMappingURL=temba-utils-uuid.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-utils-uuid.test.js","sourceRoot":"","sources":["../../test/temba-utils-uuid.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"temba-utils-uuid.test.js","sourceRoot":"","sources":["../../test/temba-utils-uuid.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@open-wc/testing';\nimport { generateUUID, generateUUIDv7 } from '../src/utils';\n\ndescribe('UUID Generation', () => {\n it('generates a valid UUID v4 format', () => {\n const uuid = generateUUID();\n\n // Check that it's a string\n assert.isString(uuid);\n\n // Check UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n const uuidPattern =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n assert.match(uuid, uuidPattern, 'Should match UUID v4 format');\n\n // Check length\n assert.equal(uuid.length, 36);\n\n // Check that it contains hyphens in the right places\n assert.equal(uuid[8], '-');\n assert.equal(uuid[13], '-');\n assert.equal(uuid[18], '-');\n assert.equal(uuid[23], '-');\n });\n\n it('generates unique UUIDs', () => {\n const uuid1 = generateUUID();\n const uuid2 = generateUUID();\n const uuid3 = generateUUID();\n\n // All should be different\n assert.notEqual(uuid1, uuid2);\n assert.notEqual(uuid2, uuid3);\n assert.notEqual(uuid1, uuid3);\n });\n\n it('generates many unique UUIDs', () => {\n const uuids = new Set();\n const count = 1000;\n\n for (let i = 0; i < count; i++) {\n uuids.add(generateUUID());\n }\n\n // All should be unique\n assert.equal(uuids.size, count, 'All generated UUIDs should be unique');\n });\n\n it('generates a valid UUID v7 format', () => {\n const uuid = generateUUIDv7();\n\n // check that it's a string\n assert.isString(uuid);\n\n // check UUID v7 format: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx\n const uuidPattern =\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n assert.match(uuid, uuidPattern, 'Should match UUID v7 format');\n\n // check length\n assert.equal(uuid.length, 36);\n\n // check that it contains hyphens in the right places\n assert.equal(uuid[8], '-');\n assert.equal(uuid[13], '-');\n assert.equal(uuid[18], '-');\n assert.equal(uuid[23], '-');\n });\n\n it('generates unique UUIDs v7', () => {\n const uuid1 = generateUUIDv7();\n const uuid2 = generateUUIDv7();\n const uuid3 = generateUUIDv7();\n\n // all should be different\n assert.notEqual(uuid1, uuid2);\n assert.notEqual(uuid2, uuid3);\n assert.notEqual(uuid1, uuid3);\n });\n\n it('generates time-ordered UUIDs v7', () => {\n const uuid1 = generateUUIDv7();\n // small delay to ensure different timestamp\n const delayPromise = new Promise((resolve) => setTimeout(resolve, 5));\n return delayPromise.then(() => {\n const uuid2 = generateUUIDv7();\n\n // uuid v7 should be sortable by timestamp\n // the first uuid should come before the second when compared as strings\n assert.isTrue(\n uuid1 < uuid2,\n 'Earlier UUID should be lexicographically smaller'\n );\n });\n });\n\n it('generates many unique UUIDs v7', () => {\n const uuids = new Set();\n const count = 1000;\n\n for (let i = 0; i < count; i++) {\n uuids.add(generateUUIDv7());\n }\n\n // all should be unique\n assert.equal(uuids.size, count, 'All generated UUIDs should be unique');\n });\n});\n"]}
|
|
@@ -5,7 +5,7 @@ import { expect, fixture, html, assert } from '@open-wc/testing';
|
|
|
5
5
|
const style = document.createElement('style');
|
|
6
6
|
style.textContent = `
|
|
7
7
|
* {
|
|
8
|
-
--transition-
|
|
8
|
+
--transition-speed: 0ms !important;
|
|
9
9
|
}
|
|
10
10
|
`;
|
|
11
11
|
document.head.appendChild(style);
|
|
@@ -170,13 +170,13 @@ export const waitForCondition = async (predicate, maxAttempts = 20, delayMs = 50
|
|
|
170
170
|
throw new Error(`Condition not met after ${maxAttempts} attempts (${maxAttempts * delayMs}ms)`);
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
|
-
export const assertScreenshot = async (filename, clip) => {
|
|
173
|
+
export const assertScreenshot = async (filename, clip, waitForNetwork = false) => {
|
|
174
174
|
// detect if we're running in copilot's environment and use adaptive threshold
|
|
175
175
|
const isCopilotEnvironment = window.isCopilotEnvironment;
|
|
176
176
|
const threshold = isCopilotEnvironment ? 1.0 : 0.1;
|
|
177
177
|
const exclude = [];
|
|
178
178
|
try {
|
|
179
|
-
await window.matchPageSnapshot(`${filename}.png`, clip, exclude, threshold);
|
|
179
|
+
await window.matchPageSnapshot(`${filename}.png`, clip, exclude, threshold, waitForNetwork);
|
|
180
180
|
}
|
|
181
181
|
catch (error) {
|
|
182
182
|
if (error.message) {
|