@nyaruka/temba-components 0.132.0 → 0.134.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 +31 -1
- package/demo/components/flow/example.html +1 -0
- package/demo/components/webchat/example.html +1 -1
- package/demo/static/css/tailwind.css +30019 -0
- package/dist/locales/es.js +5 -5
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +5 -5
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/locale-codes.js +2 -11
- package/dist/locales/locale-codes.js.map +1 -1
- package/dist/locales/pt.js +5 -5
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +555 -476
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +248 -95
- 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/display/TembaUser.js +3 -3
- package/out-tsc/src/display/TembaUser.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +132 -58
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +183 -58
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/utils.js +141 -0
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/interfaces.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 +184 -205
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/locales/es.js +5 -5
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +5 -5
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/locale-codes.js +2 -11
- package/out-tsc/src/locales/locale-codes.js.map +1 -1
- package/out-tsc/src/locales/pt.js +5 -5
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/store/AppState.js +34 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/store/Store.js +5 -5
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/utils.js +3 -3
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +22 -9
- package/out-tsc/src/webchat/WebChat.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 +9 -4
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +1 -1
- 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-collision.test.js +673 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +195 -0
- package/out-tsc/test/temba-flow-editor-node.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 +2 -2
- 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 +331 -135
- package/src/display/FloatingTab.ts +4 -4
- package/src/display/TembaUser.ts +3 -2
- package/src/events.ts +12 -12
- package/src/flow/CanvasNode.ts +140 -57
- package/src/flow/Editor.ts +240 -58
- package/src/flow/utils.ts +207 -1
- package/src/interfaces.ts +7 -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 +195 -221
- package/src/locales/es.ts +13 -18
- package/src/locales/fr.ts +13 -18
- package/src/locales/locale-codes.ts +2 -11
- package/src/locales/pt.ts +13 -18
- package/src/store/AppState.ts +43 -0
- package/src/store/Store.ts +5 -5
- package/src/utils.ts +3 -3
- package/src/webchat/WebChat.ts +24 -10
- package/test/ActionHelper.ts +13 -5
- package/test/actions/send_broadcast.test.ts +4 -2
- package/test/temba-contact-chat.test.ts +1 -1
- package/test/temba-floating-window.test.ts +0 -2
- package/test/temba-flow-collision.test.ts +833 -0
- package/test/temba-flow-editor-node.test.ts +224 -0
- package/test/temba-utils-uuid.test.ts +61 -1
- package/test/utils.test.ts +7 -2
- package/test-assets/contacts/history.json +22 -9
- package/web-test-runner.config.mjs +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionHelper.js","sourceRoot":"","sources":["../../test/ActionHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACrB,YAAoB,YAAiB,EAAU,UAAkB;QAA7C,iBAAY,GAAZ,YAAY,CAAK;QAAU,eAAU,GAAV,UAAU,CAAQ;IAAG,CAAC;IAErE;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,MAAS;QAClC,MAAM,IAAI,GAAS;YACjB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,KAAK,EAAE,EAAE;SACV,CAAC;QAEF,MAAM,cAAc,GAAG;YACrB,KAAK,EAAE,CAAC,IAAI,CAAC;YACb,GAAG,EAAE;gBACH,KAAK,EAAE;oBACL,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBACX,IAAI,EAAE,iBAAiB;wBACvB,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;qBAChC;iBACF;aACF;SACF,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAA;;;;KAIjC,CAAC,CAAW,CAAC;QAEb,MAAc,CAAC,UAAU,GAAG,cAAc,CAAC;QAC3C,MAAc,CAAC,UAAU,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACzD,MAAM,MAAM,CAAC,cAAc,CAAC;QAE5B,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAgB,CAAC;QACxE,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAE1B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,MAAS;QACpC,MAAM,UAAU,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAA;mCACP,MAAM,YAAY,IAAI;KACpD,CAAC,CAAgB,CAAC;QAEnB,MAAO,UAAkB,CAAC,cAAc,CAAC;QACzC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAE5B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAClC,EAAe,EACf,cAAsB;
|
|
1
|
+
{"version":3,"file":"ActionHelper.js","sourceRoot":"","sources":["../../test/ActionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, expect } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Action, Node } from '../src/store/flow-definition';\nimport { assertScreenshot, getClip } from './utils.test';\nimport { Editor } from '../src/flow/Editor';\nimport '../temba-modules';\n\n/**\n * Generic action test framework\n * Tests the complete action lifecycle: render → edit → save → validate\n *\n * For node configuration testing, see NodeHelper.ts\n */\nexport class ActionTest<T extends Action> {\n constructor(private actionConfig: any, private actionName: string) {}\n\n /**\n * Renders an action in the flow editor and returns the flow node\n */\n private async renderAction(action: T): Promise<HTMLElement> {\n const node: Node = {\n uuid: 'test-node',\n actions: [action],\n exits: []\n };\n\n const mockDefinition = {\n nodes: [node],\n _ui: {\n nodes: {\n [node.uuid]: {\n type: 'execute_actions',\n position: { left: 50, top: 50 }\n }\n }\n }\n };\n\n const editor = (await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `)) as Editor;\n\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 400, height: 300 };\n await editor.updateComplete;\n\n const flowNode = editor.querySelector('temba-flow-node') as HTMLElement;\n expect(flowNode).to.exist;\n\n return flowNode;\n }\n\n /**\n * Opens the node editor for an action and returns the editor element\n */\n private async openNodeEditor(action: T): Promise<HTMLElement> {\n const nodeEditor = (await fixture(html`\n <temba-node-editor .action=${action} .isOpen=${true}></temba-node-editor>\n `)) as HTMLElement;\n\n await (nodeEditor as any).updateComplete;\n expect(nodeEditor).to.exist;\n\n return nodeEditor;\n }\n\n /**\n * Takes a screenshot of the dialog container within a node editor\n */\n private async assertDialogScreenshot(\n el: HTMLElement,\n screenshotName: string,\n waitForNetwork: boolean = false\n ) {\n const dialog = el.shadowRoot\n .querySelector('temba-dialog')\n .shadowRoot.querySelector('.dialog-container') as HTMLElement;\n await assertScreenshot(screenshotName, getClip(dialog), waitForNetwork);\n }\n\n /**\n * Complete test for an action configuration\n * 1. Renders the action in a flow node (with screenshot)\n * 2. Opens the node editor (with screenshot)\n * 3. Simulates save and validates round-trip conversion\n * @param waitForNetwork - If true, waits longer for network idle (useful for slow loading resources)\n */\n async testAction(\n action: T,\n testName: string,\n waitForNetwork: boolean = false\n ) {\n it(`${testName}`, async () => {\n // Step 1: Render action in flow node\n const flowNode = await this.renderAction(action);\n expect(flowNode.querySelector('.body')).to.exist;\n await assertScreenshot(\n `actions/${this.actionName}/render/${testName}`,\n getClip(flowNode),\n waitForNetwork\n );\n\n // Step 2: Open node editor\n const nodeEditor = await this.openNodeEditor(action);\n await this.assertDialogScreenshot(\n nodeEditor,\n `actions/${this.actionName}/editor/${testName}`,\n waitForNetwork\n );\n\n // Step 3: Test round-trip conversion (simulates save workflow)\n if (this.actionConfig.toFormData && this.actionConfig.fromFormData) {\n const formData = this.actionConfig.toFormData(action);\n const convertedAction = this.actionConfig.fromFormData(formData) as T;\n\n // Validate the round trip worked\n expect(convertedAction.uuid).to.equal(action.uuid);\n expect(convertedAction.type).to.equal(action.type);\n\n // Validate the form data\n if (this.actionConfig.validate) {\n const validation = this.actionConfig.validate(formData);\n expect(validation.valid).to.be.true;\n }\n }\n });\n }\n\n /**\n * Run basic property tests\n */\n testBasicProperties() {\n it('has correct basic properties', () => {\n expect(this.actionConfig.name).to.be.a('string');\n expect(this.actionConfig.group).to.exist;\n\n // toFormData and fromFormData are optional - only needed for complex data transformations\n if (this.actionConfig.toFormData) {\n expect(this.actionConfig.toFormData).to.be.a('function');\n }\n if (this.actionConfig.fromFormData) {\n expect(this.actionConfig.fromFormData).to.be.a('function');\n }\n\n if (this.actionConfig.validate) {\n expect(this.actionConfig.validate).to.be.a('function');\n }\n });\n }\n}\n"]}
|
|
@@ -47,17 +47,22 @@ describe('send_broadcast action config', () => {
|
|
|
47
47
|
groups: [{ uuid: 'group-1', name: 'Newsletter Subscribers' }],
|
|
48
48
|
contacts: []
|
|
49
49
|
}, 'multiline-text');
|
|
50
|
-
|
|
50
|
+
/* TODO: flaky test having to do with attachment render times
|
|
51
|
+
helper.testAction(
|
|
52
|
+
{
|
|
51
53
|
uuid: 'test-action-5',
|
|
52
54
|
type: 'send_broadcast',
|
|
53
55
|
text: 'Broadcast with attachments',
|
|
54
56
|
groups: [{ uuid: 'group-1', name: 'Members' }],
|
|
55
57
|
contacts: [],
|
|
56
58
|
attachments: [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
'image/jpeg:https://example.com/photo.jpg',
|
|
60
|
+
'application/pdf:https://example.com/document.pdf'
|
|
59
61
|
]
|
|
60
|
-
|
|
62
|
+
} as SendBroadcast,
|
|
63
|
+
'with-attachments',
|
|
64
|
+
true
|
|
65
|
+
);*/
|
|
61
66
|
helper.testAction({
|
|
62
67
|
uuid: 'test-action-6',
|
|
63
68
|
type: 'send_broadcast',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send_broadcast.test.js","sourceRoot":"","sources":["../../../test/actions/send_broadcast.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { send_broadcast } from '../../src/flow/actions/send_broadcast';\nimport { SendBroadcast } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the send_broadcast action configuration.\n */\ndescribe('send_broadcast action config', () => {\n const helper = new ActionTest(send_broadcast, 'send_broadcast');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(send_broadcast.name).to.equal('Send Broadcast');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'send_broadcast',\n text: 'Important announcement for all subscribers!',\n groups: [\n { uuid: 'group-1', name: 'Subscribers' },\n { uuid: 'group-2', name: 'VIP Members' }\n ],\n contacts: []\n } as SendBroadcast,\n 'groups-only'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'send_broadcast',\n text: 'Personal message to specific contacts.',\n groups: [],\n contacts: [\n { uuid: 'contact-1', name: 'Alice Johnson' },\n { uuid: 'contact-2', name: 'Bob Smith' }\n ]\n } as SendBroadcast,\n 'contacts-only'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'send_broadcast',\n text: 'Urgent update for everyone!',\n groups: [{ uuid: 'group-1', name: 'All Members' }],\n contacts: [{ uuid: 'contact-1', name: 'Admin' }]\n } as SendBroadcast,\n 'groups-and-contacts'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'send_broadcast',\n text: 'Multi-line broadcast message.\\n\\nThis is the second paragraph.\\n\\nAnd the third.',\n groups: [{ uuid: 'group-1', name: 'Newsletter Subscribers' }],\n contacts: []\n } as SendBroadcast,\n 'multiline-text'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'send_broadcast',\n text: 'Broadcast with attachments',\n groups: [{ uuid: 'group-1', name: 'Members' }],\n contacts: [],\n attachments: [\n 'image/jpeg:https://example.com/photo.jpg',\n 'application/pdf:https://example.com/document.pdf'\n ]\n } as SendBroadcast,\n 'with-attachments'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-6',\n type: 'send_broadcast',\n text: 'Message to many groups',\n groups: [\n { uuid: 'group-1', name: 'Group A' },\n { uuid: 'group-2', name: 'Group B' },\n { uuid: 'group-3', name: 'Group C' },\n { uuid: 'group-4', name: 'Group D' }\n ],\n contacts: []\n } as SendBroadcast,\n 'many-groups'\n );\n });\n\n describe('form data conversion', () => {\n it('converts action to form data correctly', () => {\n const action: SendBroadcast = {\n uuid: 'test-uuid',\n type: 'send_broadcast',\n text: 'Test message',\n groups: [{ uuid: 'group-1', name: 'Test Group' }],\n contacts: [{ uuid: 'contact-1', name: 'Test Contact' }],\n attachments: ['image/jpeg:test.jpg']\n };\n\n const formData = send_broadcast.toFormData(action);\n\n expect(formData.uuid).to.equal('test-uuid');\n expect(formData.text).to.equal('Test message');\n expect(formData.recipients).to.have.lengthOf(2);\n expect(formData.attachments).to.deep.equal(['image/jpeg:test.jpg']);\n });\n\n it('converts form data to action correctly with contacts only', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'contact-1', name: 'Contact 1' },\n { uuid: 'contact-2', name: 'Contact 2' }\n ],\n text: 'Test message',\n attachments: []\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.uuid).to.equal('test-uuid');\n expect(action.type).to.equal('send_broadcast');\n expect(action.text).to.equal('Test message');\n expect(action.contacts).to.have.lengthOf(2);\n expect(action.groups).to.have.lengthOf(0);\n expect(action.attachments).to.be.undefined;\n });\n\n it('converts form data to action correctly with groups only', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'group-1', name: 'Group 1', group: true },\n { uuid: 'group-2', name: 'Group 2', group: true }\n ],\n text: 'Test message',\n attachments: []\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.contacts).to.have.lengthOf(0);\n expect(action.groups).to.have.lengthOf(2);\n });\n\n it('converts form data to action correctly with mixed recipients', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'contact-1', name: 'Contact 1' },\n { uuid: 'group-1', name: 'Group 1', group: true }\n ],\n text: 'Test message',\n attachments: ['image/jpeg:test.jpg']\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.contacts).to.have.lengthOf(1);\n expect(action.groups).to.have.lengthOf(1);\n expect(action.attachments).to.deep.equal(['image/jpeg:test.jpg']);\n });\n\n it('sanitizes text by trimming whitespace', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [{ uuid: 'contact-1', name: 'Test Contact' }],\n text: ' Test message \\n '\n };\n\n send_broadcast.sanitize(formData);\n\n expect(formData.text).to.equal('Test message');\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"send_broadcast.test.js","sourceRoot":"","sources":["../../../test/actions/send_broadcast.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { send_broadcast } from '../../src/flow/actions/send_broadcast';\nimport { SendBroadcast } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the send_broadcast action configuration.\n */\ndescribe('send_broadcast action config', () => {\n const helper = new ActionTest(send_broadcast, 'send_broadcast');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(send_broadcast.name).to.equal('Send Broadcast');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'send_broadcast',\n text: 'Important announcement for all subscribers!',\n groups: [\n { uuid: 'group-1', name: 'Subscribers' },\n { uuid: 'group-2', name: 'VIP Members' }\n ],\n contacts: []\n } as SendBroadcast,\n 'groups-only'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'send_broadcast',\n text: 'Personal message to specific contacts.',\n groups: [],\n contacts: [\n { uuid: 'contact-1', name: 'Alice Johnson' },\n { uuid: 'contact-2', name: 'Bob Smith' }\n ]\n } as SendBroadcast,\n 'contacts-only'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'send_broadcast',\n text: 'Urgent update for everyone!',\n groups: [{ uuid: 'group-1', name: 'All Members' }],\n contacts: [{ uuid: 'contact-1', name: 'Admin' }]\n } as SendBroadcast,\n 'groups-and-contacts'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'send_broadcast',\n text: 'Multi-line broadcast message.\\n\\nThis is the second paragraph.\\n\\nAnd the third.',\n groups: [{ uuid: 'group-1', name: 'Newsletter Subscribers' }],\n contacts: []\n } as SendBroadcast,\n 'multiline-text'\n );\n\n /* TODO: flaky test having to do with attachment render times\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'send_broadcast',\n text: 'Broadcast with attachments',\n groups: [{ uuid: 'group-1', name: 'Members' }],\n contacts: [],\n attachments: [\n 'image/jpeg:https://example.com/photo.jpg',\n 'application/pdf:https://example.com/document.pdf'\n ]\n } as SendBroadcast,\n 'with-attachments',\n true\n );*/\n\n helper.testAction(\n {\n uuid: 'test-action-6',\n type: 'send_broadcast',\n text: 'Message to many groups',\n groups: [\n { uuid: 'group-1', name: 'Group A' },\n { uuid: 'group-2', name: 'Group B' },\n { uuid: 'group-3', name: 'Group C' },\n { uuid: 'group-4', name: 'Group D' }\n ],\n contacts: []\n } as SendBroadcast,\n 'many-groups'\n );\n });\n\n describe('form data conversion', () => {\n it('converts action to form data correctly', () => {\n const action: SendBroadcast = {\n uuid: 'test-uuid',\n type: 'send_broadcast',\n text: 'Test message',\n groups: [{ uuid: 'group-1', name: 'Test Group' }],\n contacts: [{ uuid: 'contact-1', name: 'Test Contact' }],\n attachments: ['image/jpeg:test.jpg']\n };\n\n const formData = send_broadcast.toFormData(action);\n\n expect(formData.uuid).to.equal('test-uuid');\n expect(formData.text).to.equal('Test message');\n expect(formData.recipients).to.have.lengthOf(2);\n expect(formData.attachments).to.deep.equal(['image/jpeg:test.jpg']);\n });\n\n it('converts form data to action correctly with contacts only', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'contact-1', name: 'Contact 1' },\n { uuid: 'contact-2', name: 'Contact 2' }\n ],\n text: 'Test message',\n attachments: []\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.uuid).to.equal('test-uuid');\n expect(action.type).to.equal('send_broadcast');\n expect(action.text).to.equal('Test message');\n expect(action.contacts).to.have.lengthOf(2);\n expect(action.groups).to.have.lengthOf(0);\n expect(action.attachments).to.be.undefined;\n });\n\n it('converts form data to action correctly with groups only', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'group-1', name: 'Group 1', group: true },\n { uuid: 'group-2', name: 'Group 2', group: true }\n ],\n text: 'Test message',\n attachments: []\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.contacts).to.have.lengthOf(0);\n expect(action.groups).to.have.lengthOf(2);\n });\n\n it('converts form data to action correctly with mixed recipients', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [\n { uuid: 'contact-1', name: 'Contact 1' },\n { uuid: 'group-1', name: 'Group 1', group: true }\n ],\n text: 'Test message',\n attachments: ['image/jpeg:test.jpg']\n };\n\n const action = send_broadcast.fromFormData(formData) as SendBroadcast;\n\n expect(action.contacts).to.have.lengthOf(1);\n expect(action.groups).to.have.lengthOf(1);\n expect(action.attachments).to.deep.equal(['image/jpeg:test.jpg']);\n });\n\n it('sanitizes text by trimming whitespace', () => {\n const formData = {\n uuid: 'test-uuid',\n recipients: [{ uuid: 'contact-1', name: 'Test Contact' }],\n text: ' Test message \\n '\n };\n\n send_broadcast.sanitize(formData);\n\n expect(formData.text).to.equal('Test message');\n });\n });\n});\n"]}
|
|
@@ -26,7 +26,7 @@ describe('temba-contact-chat', () => {
|
|
|
26
26
|
beforeEach(() => {
|
|
27
27
|
mockedNow = mockNow('2021-03-31T00:31:00.000-00:00');
|
|
28
28
|
clearMockPosts();
|
|
29
|
-
mockGET(/\/contact\/
|
|
29
|
+
mockGET(/\/contact\/chat\/contact-.*/, '/test-assets/contacts/history.json');
|
|
30
30
|
mockGET(/\/api\/v2\/users\.json\?email=admin1%40nyaruka\.com/, '/test-assets/api/users/admin1.json');
|
|
31
31
|
mockAPI();
|
|
32
32
|
clock = useFakeTimers();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-contact-chat.test.js","sourceRoot":"","sources":["../../test/temba-contact-chat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { SinonStub, useFakeTimers } from 'sinon';\nimport { Compose } from '../src/form/Compose';\nimport { ContactChat } from '../src/live/ContactChat';\nimport { Attachment, CustomEventType } from '../src/interfaces';\nimport {\n assertScreenshot,\n clearMockPosts,\n getClip,\n getComponent,\n getValidAttachments,\n getValidText,\n loadStore,\n mockAPI,\n mockGET,\n mockNow,\n mockPOST,\n updateComponent\n} from '../test/utils.test';\n\nimport { expect, oneEvent } from '@open-wc/testing';\n\nlet clock: any;\n\nconst TAG = 'temba-contact-chat';\nconst getContactChat = async (attrs: any = {}) => {\n attrs['endpoint'] = '/test-assets/contacts/';\n // add some sizes and styles to force our chat history to scroll\n const chat = (await getComponent(\n TAG,\n attrs,\n '',\n 500,\n 500,\n 'display:flex;flex-direction:column;flex-grow:1;min-height:0;'\n )) as ContactChat;\n\n // TODO: this should be waiting for an event instead\n await waitFor(100);\n await clock.tick(0);\n return chat;\n};\n\nconst getResponseSuccessFiles = (attachments: Attachment[]) => {\n const response_attachments = attachments.map((attachment) => {\n return { content_type: attachment.content_type, url: attachment.url };\n });\n return response_attachments;\n};\n\ndescribe('temba-contact-chat', () => {\n let mockedNow: SinonStub;\n // map requests for contact history to our static files\n // we'll just us the same historylist for everybody for now\n beforeEach(() => {\n mockedNow = mockNow('2021-03-31T00:31:00.000-00:00');\n clearMockPosts();\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n\n mockGET(\n /\\/api\\/v2\\/users\\.json\\?email=admin1%40nyaruka\\.com/,\n '/test-assets/api/users/admin1.json'\n );\n\n mockAPI();\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n mockedNow.restore();\n });\n\n // temporarily disabled as it's too flaky in CI\n xit('show history and show chatbox if contact is active', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n\n await assertScreenshot('contacts/chat-for-active-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is archived', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-barack-archived'\n });\n\n await assertScreenshot('contacts/chat-for-archived-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is blocked', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-michelle-blocked'\n });\n\n await assertScreenshot('contacts/chat-for-blocked-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is stopped', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-tim-stopped'\n });\n\n await assertScreenshot('contacts/chat-for-stopped-contact', getClip(chat));\n });\n\n it('sends text without attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n await updateComponent(compose, text);\n\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text: text,\n attachments: []\n }\n }\n };\n mockPOST(/contact\\/chat\\/contact-dave-active\\//, response_body);\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', text, true, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-sends-text-only', getClip(chat));\n });\n\n it('sends attachments without text', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const attachments = getValidAttachments();\n await updateComponent(compose, null, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text: '',\n attachments: response_attachments\n }\n }\n };\n const response_headers = {};\n const response_status = '200';\n mockPOST(\n /contact\\/chat\\/contact-dave-active\\//,\n response_body,\n response_headers,\n response_status\n );\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-attachments-only',\n getClip(chat)\n );\n });\n\n it('sends text with attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n const attachments = getValidAttachments();\n await updateComponent(compose, text, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text,\n attachments: response_attachments\n }\n }\n };\n mockPOST(/contact\\/chat\\/contact-dave-active\\//, response_body);\n\n // press enter\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-text-and-attachments',\n getClip(chat)\n );\n });\n\n it('shows failure message with retry', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n await updateComponent(compose, getValidText(), getValidAttachments());\n\n const response_body = {};\n const response_headers = {};\n const response_status = '500';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-failure', getClip(chat));\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"temba-contact-chat.test.js","sourceRoot":"","sources":["../../test/temba-contact-chat.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAO,EAAc,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,QAAQ,EACR,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpD,IAAI,KAAU,CAAC;AAEf,MAAM,GAAG,GAAG,oBAAoB,CAAC;AACjC,MAAM,cAAc,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE,EAAE;IAC/C,KAAK,CAAC,UAAU,CAAC,GAAG,wBAAwB,CAAC;IAC7C,gEAAgE;IAChE,MAAM,IAAI,GAAG,CAAC,MAAM,YAAY,CAC9B,GAAG,EACH,KAAK,EACL,EAAE,EACF,GAAG,EACH,GAAG,EACH,8DAA8D,CAC/D,CAAgB,CAAC;IAElB,oDAAoD;IACpD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,WAAyB,EAAE,EAAE;IAC5D,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAC1D,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;IACH,OAAO,oBAAoB,CAAC;AAC9B,CAAC,CAAC;AAEF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,SAAoB,CAAC;IACzB,uDAAuD;IACvD,2DAA2D;IAC3D,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACrD,cAAc,EAAE,CAAC;QACjB,OAAO,CACL,6BAA6B,EAC7B,oCAAoC,CACrC,CAAC;QAEF,OAAO,CACL,qDAAqD,EACrD,oCAAoC,CACrC,CAAC;QAEF,OAAO,EAAE,CAAC;QACV,KAAK,GAAG,aAAa,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,SAAS,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,GAAG,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACnE,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QAEH,MAAM,gBAAgB,CAAC,kCAAkC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,yBAAyB;SACnC,CAAC,CAAC;QAEH,MAAM,gBAAgB,CAAC,oCAAoC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,0BAA0B;SACpC,CAAC,CAAC;QAEH,MAAM,gBAAgB,CAAC,mCAAmC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QAEH,MAAM,gBAAgB,CAAC,mCAAmC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAErC,MAAM,aAAa,GAAG;YACpB,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,eAAe,EAAE;gBAC/D,GAAG,EAAE;oBACH,IAAI,EAAE,IAAI;oBACV,WAAW,EAAE,EAAE;iBAChB;aACF;SACF,CAAC;QACF,QAAQ,CAAC,sCAAsC,EAAE,aAAa,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,QAAQ,CAAC,kCAAkC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAEhC,MAAM,gBAAgB,CAAC,+BAA+B,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;QAC1C,MAAM,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAClD,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG;YACpB,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,eAAe,EAAE;gBAC/D,GAAG,EAAE;oBACH,IAAI,EAAE,EAAE;oBACR,WAAW,EAAE,oBAAoB;iBAClC;aACF;SACF,CAAC;QACF,MAAM,gBAAgB,GAAG,EAAE,CAAC;QAC5B,MAAM,eAAe,GAAG,KAAK,CAAC;QAC9B,QAAQ,CACN,sCAAsC,EACtC,aAAa,EACb,gBAAgB,EAChB,eAAe,CAChB,CAAC;QAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,QAAQ,CAAC,kCAAkC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAEhC,MAAM,gBAAgB,CACpB,sCAAsC,EACtC,OAAO,CAAC,IAAI,CAAC,CACd,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;QAC1C,MAAM,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAClD,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG;YACpB,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,eAAe,EAAE;gBAC/D,GAAG,EAAE;oBACH,IAAI;oBACJ,WAAW,EAAE,oBAAoB;iBAClC;aACF;SACF,CAAC;QACF,QAAQ,CAAC,sCAAsC,EAAE,aAAa,CAAC,CAAC;QAEhE,cAAc;QACd,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,QAAQ,CAAC,kCAAkC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAEhC,MAAM,gBAAgB,CACpB,0CAA0C,EAC1C,OAAO,CAAC,IAAI,CAAC,CACd,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,+CAA+C;QAC/C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAgB,MAAM,cAAc,CAAC;YAC7C,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,MAAM,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAEtE,MAAM,aAAa,GAAG,EAAE,CAAC;QACzB,MAAM,gBAAgB,GAAG,EAAE,CAAC;QAC5B,MAAM,eAAe,GAAG,KAAK,CAAC;QAC9B,QAAQ,CACN,yBAAyB,EACzB,aAAa,EACb,gBAAgB,EAChB,eAAe,CAChB,CAAC;QAEF,QAAQ;QACR,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,QAAQ,CAAC,kCAAkC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAEhC,MAAM,gBAAgB,CAAC,uBAAuB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { SinonStub, useFakeTimers } from 'sinon';\nimport { Compose } from '../src/form/Compose';\nimport { ContactChat } from '../src/live/ContactChat';\nimport { Attachment, CustomEventType } from '../src/interfaces';\nimport {\n assertScreenshot,\n clearMockPosts,\n getClip,\n getComponent,\n getValidAttachments,\n getValidText,\n loadStore,\n mockAPI,\n mockGET,\n mockNow,\n mockPOST,\n updateComponent\n} from '../test/utils.test';\n\nimport { expect, oneEvent } from '@open-wc/testing';\n\nlet clock: any;\n\nconst TAG = 'temba-contact-chat';\nconst getContactChat = async (attrs: any = {}) => {\n attrs['endpoint'] = '/test-assets/contacts/';\n // add some sizes and styles to force our chat history to scroll\n const chat = (await getComponent(\n TAG,\n attrs,\n '',\n 500,\n 500,\n 'display:flex;flex-direction:column;flex-grow:1;min-height:0;'\n )) as ContactChat;\n\n // TODO: this should be waiting for an event instead\n await waitFor(100);\n await clock.tick(0);\n return chat;\n};\n\nconst getResponseSuccessFiles = (attachments: Attachment[]) => {\n const response_attachments = attachments.map((attachment) => {\n return { content_type: attachment.content_type, url: attachment.url };\n });\n return response_attachments;\n};\n\ndescribe('temba-contact-chat', () => {\n let mockedNow: SinonStub;\n // map requests for contact history to our static files\n // we'll just us the same historylist for everybody for now\n beforeEach(() => {\n mockedNow = mockNow('2021-03-31T00:31:00.000-00:00');\n clearMockPosts();\n mockGET(\n /\\/contact\\/chat\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n\n mockGET(\n /\\/api\\/v2\\/users\\.json\\?email=admin1%40nyaruka\\.com/,\n '/test-assets/api/users/admin1.json'\n );\n\n mockAPI();\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n mockedNow.restore();\n });\n\n // temporarily disabled as it's too flaky in CI\n xit('show history and show chatbox if contact is active', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n\n await assertScreenshot('contacts/chat-for-active-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is archived', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-barack-archived'\n });\n\n await assertScreenshot('contacts/chat-for-archived-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is blocked', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-michelle-blocked'\n });\n\n await assertScreenshot('contacts/chat-for-blocked-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is stopped', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-tim-stopped'\n });\n\n await assertScreenshot('contacts/chat-for-stopped-contact', getClip(chat));\n });\n\n it('sends text without attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n await updateComponent(compose, text);\n\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text: text,\n attachments: []\n }\n }\n };\n mockPOST(/contact\\/chat\\/contact-dave-active\\//, response_body);\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', text, true, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-sends-text-only', getClip(chat));\n });\n\n it('sends attachments without text', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const attachments = getValidAttachments();\n await updateComponent(compose, null, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text: '',\n attachments: response_attachments\n }\n }\n };\n const response_headers = {};\n const response_status = '200';\n mockPOST(\n /contact\\/chat\\/contact-dave-active\\//,\n response_body,\n response_headers,\n response_status\n );\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-attachments-only',\n getClip(chat)\n );\n });\n\n it('sends text with attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n const attachments = getValidAttachments();\n await updateComponent(compose, text, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n event: {\n uuid: 'msg-uuid',\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n msg: {\n text,\n attachments: response_attachments\n }\n }\n };\n mockPOST(/contact\\/chat\\/contact-dave-active\\//, response_body);\n\n // press enter\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-text-and-attachments',\n getClip(chat)\n );\n });\n\n it('shows failure message with retry', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n await updateComponent(compose, getValidText(), getValidAttachments());\n\n const response_body = {};\n const response_headers = {};\n const response_status = '500';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-failure', getClip(chat));\n });\n});\n"]}
|
|
@@ -33,7 +33,6 @@ describe('temba-floating-window', () => {
|
|
|
33
33
|
header: 'Test Window'
|
|
34
34
|
}, '<div>Content</div>'));
|
|
35
35
|
expect(window.hidden).to.equal(true);
|
|
36
|
-
expect(window.classList.contains('hidden')).to.equal(true);
|
|
37
36
|
});
|
|
38
37
|
it('can be shown and hidden', async () => {
|
|
39
38
|
const window = (await getComponent('temba-floating-window', {
|
|
@@ -48,7 +47,6 @@ describe('temba-floating-window', () => {
|
|
|
48
47
|
window.hide();
|
|
49
48
|
await window.updateComplete;
|
|
50
49
|
expect(window.hidden).to.equal(true);
|
|
51
|
-
expect(window.classList.contains('hidden')).to.equal(true);
|
|
52
50
|
});
|
|
53
51
|
it('fires close event when close button clicked', async () => {
|
|
54
52
|
const window = (await getComponent('temba-floating-window', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-floating-window.test.js","sourceRoot":"","sources":["../../test/temba-floating-window.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, assert } from '@open-wc/testing';\nimport { FloatingWindow } from '../src/layout/FloatingWindow';\nimport { assertScreenshot, getComponent } from './utils.test';\n\ndescribe('temba-floating-window', () => {\n it('can be created', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Phone Simulator',\n width: 250,\n maxHeight: 700,\n top: 100\n },\n '<div style=\"padding: 20px;\">Window content goes here</div>',\n 300,\n 750\n )) as FloatingWindow;\n\n assert.instanceOf(window, FloatingWindow);\n expect(window.header).to.equal('Phone Simulator');\n expect(window.width).to.equal(250);\n expect(window.maxHeight).to.equal(700);\n expect(window.top).to.equal(100);\n\n // show the window for screenshot\n window.hidden = false;\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/default', clip);\n });\n\n it('starts hidden by default', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window'\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.hidden).to.equal(true);\n expect(window.classList.contains('hidden')).to.equal(true);\n });\n\n it('can be shown and hidden', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window',\n hidden: true\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.hidden).to.equal(true);\n\n window.show();\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n expect(window.classList.contains('hidden')).to.equal(false);\n\n window.hide();\n await window.updateComplete;\n expect(window.hidden).to.equal(true);\n expect(window.classList.contains('hidden')).to.equal(true);\n });\n\n it('fires close event when close button clicked', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window'\n },\n '<div>Content</div>',\n 300,\n 750\n )) as FloatingWindow;\n\n // show the window first\n window.hidden = false;\n await window.updateComplete;\n\n let closed = false;\n window.addEventListener('temba-dialog-hidden', () => {\n closed = true;\n });\n\n const closeButton = window.shadowRoot.querySelector(\n '.close-button'\n ) as HTMLElement;\n expect(closeButton).to.exist;\n\n closeButton.click();\n await window.updateComplete;\n\n expect(closed).to.equal(true);\n expect(window.hidden).to.equal(true);\n });\n\n it('displays header correctly', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Phone Simulator'\n },\n '<div>Content</div>',\n 300,\n 400\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const titleElement = window.shadowRoot.querySelector('.title');\n expect(titleElement).to.exist;\n expect(titleElement.textContent).to.equal('Phone Simulator');\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/with-header', clip);\n });\n\n it('renders slot content', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test'\n },\n '<div class=\"test-content\">Custom content</div>',\n 300,\n 400\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const slotContent = window.querySelector('.test-content');\n expect(slotContent).to.exist;\n expect(slotContent.textContent).to.equal('Custom content');\n });\n\n it('supports custom dimensions', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Custom Size',\n width: 400,\n maxHeight: 600,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 450,\n 650\n )) as FloatingWindow;\n\n window.show();\n await window.updateComplete;\n expect(window.width).to.equal(400);\n expect(window.maxHeight).to.equal(600);\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n\n await assertScreenshot('floating-window/custom-size', clip);\n });\n\n it('can be dragged by header', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Draggable Window',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const header = window.shadowRoot.querySelector('.header') as HTMLElement;\n expect(header).to.exist;\n\n // simulate drag by setting dragging state\n window.dragging = true;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector('.window');\n expect(windowElement.classList.contains('dragging')).to.equal(true);\n });\n\n it('respects viewport bounds when dragging', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Bounded Window',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div style=\"height: 200px;\">Content with specific height</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // get actual window height\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const actualHeight = windowElement.offsetHeight;\n\n // simulate dragging near bottom of viewport\n const viewportHeight = window.ownerDocument.defaultView.innerHeight;\n const maxAllowedTop = viewportHeight - actualHeight;\n\n // try to drag below the viewport\n window.top = viewportHeight + 100;\n await window.updateComplete;\n\n // the handleMouseMove should clamp this, but we'll test the logic exists\n expect(actualHeight).to.be.greaterThan(0);\n expect(maxAllowedTop).to.be.lessThan(viewportHeight);\n });\n\n it('maintains consistent starting position', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // verify initial position matches properties\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n\n // change position (simulating drag)\n window.top = 200;\n window.left = 200;\n await window.updateComplete;\n\n // hide and show\n window.hide();\n await window.updateComplete;\n window.show();\n await window.updateComplete;\n\n // position should remain at property values (100, 100) not dragged position\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n });\n\n it('can disable chrome', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100,\n chromeless: true\n },\n '<div style=\"background: white; padding: 20px;\">Chromeless content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n expect(window.chromeless).to.equal(true);\n\n window.hidden = false;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n expect(windowElement.classList.contains('chromeless')).to.equal(true);\n\n // header should not be rendered\n const header = window.shadowRoot.querySelector('.header');\n expect(header).to.not.exist;\n\n // body should have no padding\n const body = window.shadowRoot.querySelector('.body') as HTMLElement;\n const bodyStyles = getComputedStyle(body);\n expect(bodyStyles.padding).to.equal('0px');\n\n // use custom clip for fixed positioned element\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/chromeless', clip);\n });\n\n it('defaults to showing chrome', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test'\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.chromeless).to.equal(false);\n });\n\n it('can close via public close() method', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n chromeless: true\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n\n let eventFired = false;\n window.addEventListener('temba-dialog-hidden', () => {\n eventFired = true;\n });\n\n // call public close() method\n window.close();\n await window.updateComplete;\n\n expect(window.hidden).to.equal(true);\n expect(eventFired).to.equal(true);\n });\n\n it('chromeless window has no borders or shadows', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n chromeless: true\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const styles = getComputedStyle(windowElement);\n\n expect(styles.boxShadow).to.equal('none');\n expect(styles.borderRadius).to.equal('0px');\n expect(styles.background.includes('rgba(0, 0, 0, 0)')).to.be.true;\n });\n\n it('supports min and max height constraints', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Min/Max Test',\n width: 300,\n minHeight: 200,\n maxHeight: 500\n },\n '<div style=\"padding: 20px;\">Content that can vary in height</div>',\n 350,\n 550\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n expect(window.minHeight).to.equal(200);\n expect(window.maxHeight).to.equal(500);\n\n // verify the styles are applied\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const styles = getComputedStyle(windowElement);\n expect(styles.minHeight).to.equal('200px');\n expect(styles.maxHeight).to.equal('500px');\n });\n\n it('stays on screen when browser is resized', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Resize Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div style=\"height: 200px;\">Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // position window near right edge\n const originalViewportWidth = window.ownerDocument.defaultView.innerWidth;\n window.left = originalViewportWidth - window.width - 30;\n await window.updateComplete;\n\n // simulate window resize event (the component should constrain position)\n window.dispatchEvent(new Event('resize', { bubbles: true }));\n await window.updateComplete;\n\n // window should still be within viewport bounds with 20px padding\n const padding = 20;\n expect(window.left).to.be.at.least(padding);\n expect(window.left).to.be.at.most(\n window.ownerDocument.defaultView.innerWidth - window.width - padding\n );\n expect(window.top).to.be.at.least(padding);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"temba-floating-window.test.js","sourceRoot":"","sources":["../../test/temba-floating-window.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, assert } from '@open-wc/testing';\nimport { FloatingWindow } from '../src/layout/FloatingWindow';\nimport { assertScreenshot, getComponent } from './utils.test';\n\ndescribe('temba-floating-window', () => {\n it('can be created', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Phone Simulator',\n width: 250,\n maxHeight: 700,\n top: 100\n },\n '<div style=\"padding: 20px;\">Window content goes here</div>',\n 300,\n 750\n )) as FloatingWindow;\n\n assert.instanceOf(window, FloatingWindow);\n expect(window.header).to.equal('Phone Simulator');\n expect(window.width).to.equal(250);\n expect(window.maxHeight).to.equal(700);\n expect(window.top).to.equal(100);\n\n // show the window for screenshot\n window.hidden = false;\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/default', clip);\n });\n\n it('starts hidden by default', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window'\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.hidden).to.equal(true);\n });\n\n it('can be shown and hidden', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window',\n hidden: true\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.hidden).to.equal(true);\n\n window.show();\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n expect(window.classList.contains('hidden')).to.equal(false);\n\n window.hide();\n await window.updateComplete;\n expect(window.hidden).to.equal(true);\n });\n\n it('fires close event when close button clicked', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test Window'\n },\n '<div>Content</div>',\n 300,\n 750\n )) as FloatingWindow;\n\n // show the window first\n window.hidden = false;\n await window.updateComplete;\n\n let closed = false;\n window.addEventListener('temba-dialog-hidden', () => {\n closed = true;\n });\n\n const closeButton = window.shadowRoot.querySelector(\n '.close-button'\n ) as HTMLElement;\n expect(closeButton).to.exist;\n\n closeButton.click();\n await window.updateComplete;\n\n expect(closed).to.equal(true);\n expect(window.hidden).to.equal(true);\n });\n\n it('displays header correctly', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Phone Simulator'\n },\n '<div>Content</div>',\n 300,\n 400\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const titleElement = window.shadowRoot.querySelector('.title');\n expect(titleElement).to.exist;\n expect(titleElement.textContent).to.equal('Phone Simulator');\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/with-header', clip);\n });\n\n it('renders slot content', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test'\n },\n '<div class=\"test-content\">Custom content</div>',\n 300,\n 400\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const slotContent = window.querySelector('.test-content');\n expect(slotContent).to.exist;\n expect(slotContent.textContent).to.equal('Custom content');\n });\n\n it('supports custom dimensions', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Custom Size',\n width: 400,\n maxHeight: 600,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 450,\n 650\n )) as FloatingWindow;\n\n window.show();\n await window.updateComplete;\n expect(window.width).to.equal(400);\n expect(window.maxHeight).to.equal(600);\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n\n // use custom clip for fixed positioned element\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n\n await assertScreenshot('floating-window/custom-size', clip);\n });\n\n it('can be dragged by header', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Draggable Window',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const header = window.shadowRoot.querySelector('.header') as HTMLElement;\n expect(header).to.exist;\n\n // simulate drag by setting dragging state\n window.dragging = true;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector('.window');\n expect(windowElement.classList.contains('dragging')).to.equal(true);\n });\n\n it('respects viewport bounds when dragging', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Bounded Window',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div style=\"height: 200px;\">Content with specific height</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // get actual window height\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const actualHeight = windowElement.offsetHeight;\n\n // simulate dragging near bottom of viewport\n const viewportHeight = window.ownerDocument.defaultView.innerHeight;\n const maxAllowedTop = viewportHeight - actualHeight;\n\n // try to drag below the viewport\n window.top = viewportHeight + 100;\n await window.updateComplete;\n\n // the handleMouseMove should clamp this, but we'll test the logic exists\n expect(actualHeight).to.be.greaterThan(0);\n expect(maxAllowedTop).to.be.lessThan(viewportHeight);\n });\n\n it('maintains consistent starting position', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // verify initial position matches properties\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n\n // change position (simulating drag)\n window.top = 200;\n window.left = 200;\n await window.updateComplete;\n\n // hide and show\n window.hide();\n await window.updateComplete;\n window.show();\n await window.updateComplete;\n\n // position should remain at property values (100, 100) not dragged position\n expect(window.top).to.equal(100);\n expect(window.left).to.equal(100);\n });\n\n it('can disable chrome', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100,\n chromeless: true\n },\n '<div style=\"background: white; padding: 20px;\">Chromeless content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n expect(window.chromeless).to.equal(true);\n\n window.hidden = false;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n expect(windowElement.classList.contains('chromeless')).to.equal(true);\n\n // header should not be rendered\n const header = window.shadowRoot.querySelector('.header');\n expect(header).to.not.exist;\n\n // body should have no padding\n const body = window.shadowRoot.querySelector('.body') as HTMLElement;\n const bodyStyles = getComputedStyle(body);\n expect(bodyStyles.padding).to.equal('0px');\n\n // use custom clip for fixed positioned element\n const clip = {\n x: window.left,\n y: window.top,\n width: window.width,\n height: windowElement.offsetHeight\n };\n await assertScreenshot('floating-window/chromeless', clip);\n });\n\n it('defaults to showing chrome', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test'\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n expect(window.chromeless).to.equal(false);\n });\n\n it('can close via public close() method', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n chromeless: true\n },\n '<div>Content</div>'\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n expect(window.hidden).to.equal(false);\n\n let eventFired = false;\n window.addEventListener('temba-dialog-hidden', () => {\n eventFired = true;\n });\n\n // call public close() method\n window.close();\n await window.updateComplete;\n\n expect(window.hidden).to.equal(true);\n expect(eventFired).to.equal(true);\n });\n\n it('chromeless window has no borders or shadows', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Test',\n width: 250,\n maxHeight: 400,\n chromeless: true\n },\n '<div>Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const styles = getComputedStyle(windowElement);\n\n expect(styles.boxShadow).to.equal('none');\n expect(styles.borderRadius).to.equal('0px');\n expect(styles.background.includes('rgba(0, 0, 0, 0)')).to.be.true;\n });\n\n it('supports min and max height constraints', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Min/Max Test',\n width: 300,\n minHeight: 200,\n maxHeight: 500\n },\n '<div style=\"padding: 20px;\">Content that can vary in height</div>',\n 350,\n 550\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n expect(window.minHeight).to.equal(200);\n expect(window.maxHeight).to.equal(500);\n\n // verify the styles are applied\n const windowElement = window.shadowRoot.querySelector(\n '.window'\n ) as HTMLElement;\n const styles = getComputedStyle(windowElement);\n expect(styles.minHeight).to.equal('200px');\n expect(styles.maxHeight).to.equal('500px');\n });\n\n it('stays on screen when browser is resized', async () => {\n const window = (await getComponent(\n 'temba-floating-window',\n {\n header: 'Resize Test',\n width: 250,\n maxHeight: 400,\n top: 100,\n left: 100\n },\n '<div style=\"height: 200px;\">Content</div>',\n 300,\n 450\n )) as FloatingWindow;\n\n window.hidden = false;\n await window.updateComplete;\n\n // position window near right edge\n const originalViewportWidth = window.ownerDocument.defaultView.innerWidth;\n window.left = originalViewportWidth - window.width - 30;\n await window.updateComplete;\n\n // simulate window resize event (the component should constrain position)\n window.dispatchEvent(new Event('resize', { bubbles: true }));\n await window.updateComplete;\n\n // window should still be within viewport bounds with 20px padding\n const padding = 20;\n expect(window.left).to.be.at.least(padding);\n expect(window.left).to.be.at.most(\n window.ownerDocument.defaultView.innerWidth - window.width - padding\n );\n expect(window.top).to.be.at.least(padding);\n });\n});\n"]}
|